From dmitry.baryshkov at oss.qualcomm.com  Fri Aug  1 00:30:28 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Fri, 1 Aug 2025 10:30:28 +0300
Subject: [PATCH v2 02/13] dt-bindings: phy: Add binding for QCS615
 standalone QMP DP PHY
In-Reply-To: <2de51bf2-baed-4bf9-a40c-1681b2efcf79@oss.qualcomm.com>
References: <20250722-add-displayport-support-for-qcs615-platform-v2-0-42b4037171f8@oss.qualcomm.com>
 <20250722-add-displayport-support-for-qcs615-platform-v2-2-42b4037171f8@oss.qualcomm.com>
 <jemfu5sy7k4a2iar55im5bhyhxzlrwpftmpqmps3b2tco7r6a2@oodls7gi45yy>
 <e673a3a3-6924-49db-9040-e34b82199a43@oss.qualcomm.com>
 <w3rwao5wbmstdyics6qhp7beulbbp5ludqkwpfsmevgqmzz3d6@u2e533zlitkr>
 <e5a3f05f-9775-4e3d-ae7d-ebbca14b4df5@oss.qualcomm.com>
 <ffdvzupefzhqq7fqtloycc3xzu57i55ths73xcjftor2cifuzr@5vhq2hfmkvda>
 <bd8f8643-a8c8-43d7-b293-acdba5ff798a@oss.qualcomm.com>
 <ad4f53eb-2f4b-4e62-a162-461de431e3de@oss.qualcomm.com>
 <2de51bf2-baed-4bf9-a40c-1681b2efcf79@oss.qualcomm.com>
Message-ID: <x4ozwgcti2vrgorgow6nttcjmduk5e4kkd3pjj6xfsgihk6u4n@klfpypor6ya6>

On Fri, Aug 01, 2025 at 11:57:50AM +0800, Xiangxu Yin wrote:
> 
> On 8/1/2025 1:13 AM, Dmitry Baryshkov wrote:
> > On 31/07/2025 08:06, Xiangxu Yin wrote:
> >>
> >> On 7/31/2025 2:35 AM, Dmitry Baryshkov wrote:
> >>> On Wed, Jul 30, 2025 at 04:53:16PM +0800, Xiangxu Yin wrote:
> >>>> On 7/22/2025 8:41 PM, Dmitry Baryshkov wrote:
> >>>>> On Tue, Jul 22, 2025 at 08:05:06PM +0800, Xiangxu Yin wrote:
> >>>>>> On 7/22/2025 4:38 PM, Dmitry Baryshkov wrote:
> >>>>>>> On Tue, Jul 22, 2025 at 03:22:03PM +0800, Xiangxu Yin wrote:
> >>>>>>>> Introduce device tree binding documentation for the Qualcomm QMP DP PHY
> >>>>>>>> on QCS615 SoCs. This PHY supports DisplayPort functionality and is
> >>>>>>>> designed to operate independently from the USB3 PHY.
> >>>>>>>>
> >>>>>>>> Unlike combo PHYs found on other platforms, the QCS615 DP PHY is
> >>>>>>>> standalone and does not support USB/DP multiplexing. The binding
> >>>>>>>> describes the required clocks, resets, TCSR configuration, and clock/PHY
> >>>>>>>> cells for proper integration.
> >>>>>>> Simply put: no, this is not correct. Even if you go to the SM6150 block
> >>>>>>> diagram, it points out that DP uses the USB3 PHY, not a separate DP PHY.
> >>>>>>>
> >>>>>>> I thought that we have discussed it beforehand.
> >>>>>>>
> >>>>>>> I can quote my comment from the previous thread:
> >>>>>>>
> >>>>>>>>> No. It means replacing extending existing entries with bigger reg and
> >>>>>>>>> #phy-cells = <1>. The driver must keep working with old node definitions
> >>>>>>>>> as is to ensure backwards compatibility. New nodes should make it
> >>>>>>>>> register two PHYs (USB3 and DP). On the driver side modify generic code
> >>>>>>>>> paths, all platforms supported by the driver should be able to support
> >>>>>>>>> USB3+DP combination.
> >>>>>>> Looking at the hardware memory maps:
> >>>>>>>
> >>>>>>> MSM8998: USB3 PHY regs at 0xc010000, DP PHY regs at 0xc011000
> >>>>>>> SDM660: USB3 PHY regs at 0xc010000, DP PHY regs at 0xc011000
> >>>>>>> QCM2290: USB3 PHY regs at 0x1615000, DP PHY regs at 0x1616000
> >>>>>>> SM6115: USB3 PHY regs at 0x1615000, DP PHY regs at 0x1616000
> >>>>>>>
> >>>>>>> Now:
> >>>>>>> SM6150: USB3 PHY regs at 0x88e6000
> >>>>>>> ???????? USB3 PHY regs at 0x88e8000, DP PHY regs at 0x88e9000
> >>>>>>>
> >>>>>>> I do not know, why msm-4.14 didn't describe second USB3 PHY. Maybe you
> >>>>>>> can comment on it.
> >>>>>>>
> >>>>>>> But based on that list, the only special case that we need to handle is
> >>>>>>> the first USB3 PHY, which doesn't have a corresponding DP PHY block. But
> >>>>>>> it will be handled anyway by the code that implements support for the
> >>>>>>> existing DT entries. All other hardware blocks are combo USB+DP PHYs.
> >>>>>>>
> >>>>>>> Having all of that in mind, please, for v3 patchset implement USB+DP
> >>>>>>> support in the phy-qcom-qmp-usbc driver and add the following logic
> >>>>>>> that also was requested in v1 review:
> >>>>>>>
> >>>>>>>>> Not quite. Both USB3 and DP drivers should be calling power_on / _off.
> >>>>>>>>> If USB3 is on, powering on DP PHY should fail. Vice versa, if DP is on,
> >>>>>>>>> powering on USB should fail.
> >>>>>>> I think our understanding might not be fully aligned.
> >>>>> I did not write this. Please fix your mailer to quote messages properly.
> >>>>> As you are using Thunderbird, I'm not sure where the issue comes from.
> >>>>>
> >>>>> Also please fix it to wrap your responses somwhere logically.
> >>>>>
> >>>>>>> Perhaps this is because I didn?t accurately update the mutual exclusion relationships and test results for the different PHYs.
> >>>>>>> Let me clarify my latest findings and explain why I believe these are separate PHYs that require mutual exclusion via TCSR.
> >>>>>>>
> >>>>>>> 1. About the TCSR DP_PHYMODE Registers
> >>>>>>>
> >>>>>>> MSM8998/SDM660:
> >>>>>>> ????Only one TCSR_USB3_DP_PHYMODE register at 0x1FCB248.
> >>>>>>> QCM2290/SM6115:
> >>>>>>> ????TCSR_USB3_0_DP_PHYMODE at 0x3CB248
> >>>>>>> ????TCSR_USB3_1_DP_PHYMODE at 0x3CB24C
> >>>>>>> SM6150:
> >>>>>>> ????TCSR_USB3_0_DP_PHYMODE at 0x1FCB248
> >>>>>>> ????TCSR_USB3_1_DP_PHYMODE at 0x1FCB24C
> >>>>> SM6150 has two different sets of output pins, so the first register
> >>>>> covers first set of SS lanes (which are routed to the documented SS
> >>>>> PHY), the second register covers the second set of SS lanes (which are
> >>>>> routed to the DP and secondary USB PHY).
> >>>>>
> >>>>> I can only assume that the same configuration was supposed to be
> >>>>> applicable to QCM2290 / SM6115, but was later removed / disabled, while
> >>>>> the registers were kept in the TCSR block.
> >>>>>
> >>>>>>> Even though MSM8998, SDM660, QCM2290, and SM6115 all have one USB3 PHY and one DP PHY, the TCSR DP_PHYMODE register configuration is different on each platform.
> >>>>>>>
> >>>>>>> Additionally, I found some interesting register documentation for QCM2290/SM6115:
> >>>>>>> ????TCSR_USB3_0_DP_PHYMODE: ?In kamorta this one is for mobile usb. DP not supported.?
> >>>>>>> ????TCSR_USB3_1_DP_PHYMODE: ?DP mode supported for Auto usb in kamorta.?
> >>>>>>> I think the reason for having two different TCSR registers is to allow both the USB3.0 and DP PHYs to be useds at the same time in certain product configurations.
> >>>>> Sure. One for the first PHY (USB), one for the second PHY (USB+DP).
> >>>>> If you check the memory map, you will find the second VLS CLAMP register
> >>>>> for the second USB PHY.
> >>>>>
> >>>>>>> 2. SM6150 Test Results
> >>>>>>> When TCSR_DP_PHYMODE_0 is switched to DP, the USB3 primary PHY cannot work, and the DP PHY is also not functional (possibly due to clock lack or other configuration mismatch with this TCSR setting).
> >>>>>>> When TCSR_DP_PHYMODE_1 is switched to DP, both the USB3 primary PHY and the DP PHY work normally.
> >>>>>>> I think "why msm-4.14 didn't describe second USB3 PHY", because TCSR_DP_PHYMODE_1 always works in DP mode.
> >>>>>>> https://android.googlesource.com/kernel/msm/+/af03eef7d4c3cbd1fe26c67d4f1915b05d0c1488/drivers/gpu/drm/msm/dp/dp_catalog_v200.c
> >>>>> Here it still programs the TCSR register.
> >>>>>
> >>>>>>> Based on these info, I believe these are separate PHYs, and only the
> >>>>>>> TCSR DP_PHYMODE registers determine which USB3/DP PHYs are paired or
> >>>>>>> mutually exclusive. This is why I have maintained separate private
> >>>>>>> data for each PHY and implemented Power on mutex control via TCSR,
> >>>>>>> rather than using a qmp_combo-like structure.
> >>>>> Still, no. Check the block diagram of SM6150.
> >>>>>
> >>>>>>> Given the above, do you think we still need to force USB and DP to be strictly bound together like a combo PHY?
> >>>>> Yes.
> >>>> I checked the related PHY series and block diagrams again.
> >>>>
> >>>> PRI and SEC go to different nodes based on the SoC design, and there are two types of configurations: USB3-only and USB3+DP pairing.
> >>>>
> >>>> Before proceed the v3 patchset, I?d like to double-confirm whether the following structure is what you expect:
> >>>>
> >>>> usb_qmpphy_1: phy at 88e6000 {
> >>>> ???? compatible = "qcom,sm6150-qmp-usb3-prim-phy"; <== rename to PRIM
> >>> No, we already have a compatible name and DT schema for this device.
> >> Then current compatible name is "qcom,qcs615-qmp-usb3-phy" and shall we need update to "qcom,sm6150-qmp-usb3-phy"?
> >
> > Why? You _already_ have a compatible string. You don't need to change it just to follow the SoC name.?
> >
> Ok, but just to confirm ? in this case, the USB3-DP PHY would use "qcom,sm6150-qmp-usb3-dp-phy" while the USB3-only PHY still uses "qcom,qcs615-qmp-usb3-phy"?
> 
> Since both PHYs are on the same SoC, would it make sense to keep the naming consistent and use "qcom,qcs615-..." for both??

Either way is fine with me.

> 

-- 
With best wishes
Dmitry


From xiangxu.yin at oss.qualcomm.com  Fri Aug  1 00:38:39 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Fri, 1 Aug 2025 15:38:39 +0800
Subject: [PATCH v2 02/13] dt-bindings: phy: Add binding for QCS615
 standalone QMP DP PHY
In-Reply-To: <x4ozwgcti2vrgorgow6nttcjmduk5e4kkd3pjj6xfsgihk6u4n@klfpypor6ya6>
References: <20250722-add-displayport-support-for-qcs615-platform-v2-0-42b4037171f8@oss.qualcomm.com>
 <20250722-add-displayport-support-for-qcs615-platform-v2-2-42b4037171f8@oss.qualcomm.com>
 <jemfu5sy7k4a2iar55im5bhyhxzlrwpftmpqmps3b2tco7r6a2@oodls7gi45yy>
 <e673a3a3-6924-49db-9040-e34b82199a43@oss.qualcomm.com>
 <w3rwao5wbmstdyics6qhp7beulbbp5ludqkwpfsmevgqmzz3d6@u2e533zlitkr>
 <e5a3f05f-9775-4e3d-ae7d-ebbca14b4df5@oss.qualcomm.com>
 <ffdvzupefzhqq7fqtloycc3xzu57i55ths73xcjftor2cifuzr@5vhq2hfmkvda>
 <bd8f8643-a8c8-43d7-b293-acdba5ff798a@oss.qualcomm.com>
 <ad4f53eb-2f4b-4e62-a162-461de431e3de@oss.qualcomm.com>
 <2de51bf2-baed-4bf9-a40c-1681b2efcf79@oss.qualcomm.com>
 <x4ozwgcti2vrgorgow6nttcjmduk5e4kkd3pjj6xfsgihk6u4n@klfpypor6ya6>
Message-ID: <80c59c45-e010-4ec2-8ec5-9ebc2884e282@oss.qualcomm.com>


On 8/1/2025 3:30 PM, Dmitry Baryshkov wrote:
> On Fri, Aug 01, 2025 at 11:57:50AM +0800, Xiangxu Yin wrote:
>> On 8/1/2025 1:13 AM, Dmitry Baryshkov wrote:
>>> On 31/07/2025 08:06, Xiangxu Yin wrote:
>>>> On 7/31/2025 2:35 AM, Dmitry Baryshkov wrote:
>>>>> On Wed, Jul 30, 2025 at 04:53:16PM +0800, Xiangxu Yin wrote:
>>>>>> On 7/22/2025 8:41 PM, Dmitry Baryshkov wrote:
>>>>>>> On Tue, Jul 22, 2025 at 08:05:06PM +0800, Xiangxu Yin wrote:
>>>>>>>> On 7/22/2025 4:38 PM, Dmitry Baryshkov wrote:
>>>>>>>>> On Tue, Jul 22, 2025 at 03:22:03PM +0800, Xiangxu Yin wrote:
>>>>>>>>>> Introduce device tree binding documentation for the Qualcomm QMP DP PHY
>>>>>>>>>> on QCS615 SoCs. This PHY supports DisplayPort functionality and is
>>>>>>>>>> designed to operate independently from the USB3 PHY.
>>>>>>>>>>
>>>>>>>>>> Unlike combo PHYs found on other platforms, the QCS615 DP PHY is
>>>>>>>>>> standalone and does not support USB/DP multiplexing. The binding
>>>>>>>>>> describes the required clocks, resets, TCSR configuration, and clock/PHY
>>>>>>>>>> cells for proper integration.
>>>>>>>>> Simply put: no, this is not correct. Even if you go to the SM6150 block
>>>>>>>>> diagram, it points out that DP uses the USB3 PHY, not a separate DP PHY.
>>>>>>>>>
>>>>>>>>> I thought that we have discussed it beforehand.
>>>>>>>>>
>>>>>>>>> I can quote my comment from the previous thread:
>>>>>>>>>
>>>>>>>>>>> No. It means replacing extending existing entries with bigger reg and
>>>>>>>>>>> #phy-cells = <1>. The driver must keep working with old node definitions
>>>>>>>>>>> as is to ensure backwards compatibility. New nodes should make it
>>>>>>>>>>> register two PHYs (USB3 and DP). On the driver side modify generic code
>>>>>>>>>>> paths, all platforms supported by the driver should be able to support
>>>>>>>>>>> USB3+DP combination.
>>>>>>>>> Looking at the hardware memory maps:
>>>>>>>>>
>>>>>>>>> MSM8998: USB3 PHY regs at 0xc010000, DP PHY regs at 0xc011000
>>>>>>>>> SDM660: USB3 PHY regs at 0xc010000, DP PHY regs at 0xc011000
>>>>>>>>> QCM2290: USB3 PHY regs at 0x1615000, DP PHY regs at 0x1616000
>>>>>>>>> SM6115: USB3 PHY regs at 0x1615000, DP PHY regs at 0x1616000
>>>>>>>>>
>>>>>>>>> Now:
>>>>>>>>> SM6150: USB3 PHY regs at 0x88e6000
>>>>>>>>> ???????? USB3 PHY regs at 0x88e8000, DP PHY regs at 0x88e9000
>>>>>>>>>
>>>>>>>>> I do not know, why msm-4.14 didn't describe second USB3 PHY. Maybe you
>>>>>>>>> can comment on it.
>>>>>>>>>
>>>>>>>>> But based on that list, the only special case that we need to handle is
>>>>>>>>> the first USB3 PHY, which doesn't have a corresponding DP PHY block. But
>>>>>>>>> it will be handled anyway by the code that implements support for the
>>>>>>>>> existing DT entries. All other hardware blocks are combo USB+DP PHYs.
>>>>>>>>>
>>>>>>>>> Having all of that in mind, please, for v3 patchset implement USB+DP
>>>>>>>>> support in the phy-qcom-qmp-usbc driver and add the following logic
>>>>>>>>> that also was requested in v1 review:
>>>>>>>>>
>>>>>>>>>>> Not quite. Both USB3 and DP drivers should be calling power_on / _off.
>>>>>>>>>>> If USB3 is on, powering on DP PHY should fail. Vice versa, if DP is on,
>>>>>>>>>>> powering on USB should fail.
>>>>>>>>> I think our understanding might not be fully aligned.
>>>>>>> I did not write this. Please fix your mailer to quote messages properly.
>>>>>>> As you are using Thunderbird, I'm not sure where the issue comes from.
>>>>>>>
>>>>>>> Also please fix it to wrap your responses somwhere logically.
>>>>>>>
>>>>>>>>> Perhaps this is because I didn?t accurately update the mutual exclusion relationships and test results for the different PHYs.
>>>>>>>>> Let me clarify my latest findings and explain why I believe these are separate PHYs that require mutual exclusion via TCSR.
>>>>>>>>>
>>>>>>>>> 1. About the TCSR DP_PHYMODE Registers
>>>>>>>>>
>>>>>>>>> MSM8998/SDM660:
>>>>>>>>> ????Only one TCSR_USB3_DP_PHYMODE register at 0x1FCB248.
>>>>>>>>> QCM2290/SM6115:
>>>>>>>>> ????TCSR_USB3_0_DP_PHYMODE at 0x3CB248
>>>>>>>>> ????TCSR_USB3_1_DP_PHYMODE at 0x3CB24C
>>>>>>>>> SM6150:
>>>>>>>>> ????TCSR_USB3_0_DP_PHYMODE at 0x1FCB248
>>>>>>>>> ????TCSR_USB3_1_DP_PHYMODE at 0x1FCB24C
>>>>>>> SM6150 has two different sets of output pins, so the first register
>>>>>>> covers first set of SS lanes (which are routed to the documented SS
>>>>>>> PHY), the second register covers the second set of SS lanes (which are
>>>>>>> routed to the DP and secondary USB PHY).
>>>>>>>
>>>>>>> I can only assume that the same configuration was supposed to be
>>>>>>> applicable to QCM2290 / SM6115, but was later removed / disabled, while
>>>>>>> the registers were kept in the TCSR block.
>>>>>>>
>>>>>>>>> Even though MSM8998, SDM660, QCM2290, and SM6115 all have one USB3 PHY and one DP PHY, the TCSR DP_PHYMODE register configuration is different on each platform.
>>>>>>>>>
>>>>>>>>> Additionally, I found some interesting register documentation for QCM2290/SM6115:
>>>>>>>>> ????TCSR_USB3_0_DP_PHYMODE: ?In kamorta this one is for mobile usb. DP not supported.?
>>>>>>>>> ????TCSR_USB3_1_DP_PHYMODE: ?DP mode supported for Auto usb in kamorta.?
>>>>>>>>> I think the reason for having two different TCSR registers is to allow both the USB3.0 and DP PHYs to be useds at the same time in certain product configurations.
>>>>>>> Sure. One for the first PHY (USB), one for the second PHY (USB+DP).
>>>>>>> If you check the memory map, you will find the second VLS CLAMP register
>>>>>>> for the second USB PHY.
>>>>>>>
>>>>>>>>> 2. SM6150 Test Results
>>>>>>>>> When TCSR_DP_PHYMODE_0 is switched to DP, the USB3 primary PHY cannot work, and the DP PHY is also not functional (possibly due to clock lack or other configuration mismatch with this TCSR setting).
>>>>>>>>> When TCSR_DP_PHYMODE_1 is switched to DP, both the USB3 primary PHY and the DP PHY work normally.
>>>>>>>>> I think "why msm-4.14 didn't describe second USB3 PHY", because TCSR_DP_PHYMODE_1 always works in DP mode.
>>>>>>>>> https://android.googlesource.com/kernel/msm/+/af03eef7d4c3cbd1fe26c67d4f1915b05d0c1488/drivers/gpu/drm/msm/dp/dp_catalog_v200.c
>>>>>>> Here it still programs the TCSR register.
>>>>>>>
>>>>>>>>> Based on these info, I believe these are separate PHYs, and only the
>>>>>>>>> TCSR DP_PHYMODE registers determine which USB3/DP PHYs are paired or
>>>>>>>>> mutually exclusive. This is why I have maintained separate private
>>>>>>>>> data for each PHY and implemented Power on mutex control via TCSR,
>>>>>>>>> rather than using a qmp_combo-like structure.
>>>>>>> Still, no. Check the block diagram of SM6150.
>>>>>>>
>>>>>>>>> Given the above, do you think we still need to force USB and DP to be strictly bound together like a combo PHY?
>>>>>>> Yes.
>>>>>> I checked the related PHY series and block diagrams again.
>>>>>>
>>>>>> PRI and SEC go to different nodes based on the SoC design, and there are two types of configurations: USB3-only and USB3+DP pairing.
>>>>>>
>>>>>> Before proceed the v3 patchset, I?d like to double-confirm whether the following structure is what you expect:
>>>>>>
>>>>>> usb_qmpphy_1: phy at 88e6000 {
>>>>>> ???? compatible = "qcom,sm6150-qmp-usb3-prim-phy"; <== rename to PRIM
>>>>> No, we already have a compatible name and DT schema for this device.
>>>> Then current compatible name is "qcom,qcs615-qmp-usb3-phy" and shall we need update to "qcom,sm6150-qmp-usb3-phy"?
>>> Why? You _already_ have a compatible string. You don't need to change it just to follow the SoC name.?
>>>
>> Ok, but just to confirm ? in this case, the USB3-DP PHY would use "qcom,sm6150-qmp-usb3-dp-phy" while the USB3-only PHY still uses "qcom,qcs615-qmp-usb3-phy"?
>>
>> Since both PHYs are on the same SoC, would it make sense to keep the naming consistent and use "qcom,qcs615-..." for both??
> Either way is fine with me.
Ok,?then I?ll use?|"qcom,qcs615-qmp-usb3-dp-phy"|?for the USB3-DP PHY in the v3 patch.
>


From h-shenoy at ti.com  Fri Aug  1 04:53:11 2025
From: h-shenoy at ti.com (Harikrishna Shenoy)
Date: Fri, 1 Aug 2025 17:23:11 +0530
Subject: [PATCH] drivers: phy: cadence: cdns-dphy: Enabling lower resolutions in dphy
Message-ID: <20250801115311.1384313-1-h-shenoy@ti.com>

The patch enables cdns dphy for hs_clk_rate in range between
80 Mbps to 160 Mbps as mentioned in TRM [0] by setting the
pll_opdiv field to 16.This change enables lower resolutions
like 640x480 at 60Hz.

[0]: https://www.ti.com/lit/zip/spruil1
(Table 12-552. DPHY_TX_PLL_CTRL Register Field Descriptions)

Signed-off-by: Harikrishna Shenoy <h-shenoy at ti.com>
---
Test log: https://gist.github.com/h-shenoy/3975156baf403a0ff8dbcce5b49b2b89

 drivers/phy/cadence/cdns-dphy.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c
index ed87a3970f83..9abed2ece9b0 100644
--- a/drivers/phy/cadence/cdns-dphy.c
+++ b/drivers/phy/cadence/cdns-dphy.c
@@ -139,7 +139,7 @@ static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy,
 
 	dlane_bps = opts->hs_clk_rate;
 
-	if (dlane_bps > 2500000000UL || dlane_bps < 160000000UL)
+	if (dlane_bps > 2500000000UL || dlane_bps < 80000000UL)
 		return -EINVAL;
 	else if (dlane_bps >= 1250000000)
 		cfg->pll_opdiv = 1;
@@ -149,6 +149,8 @@ static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy,
 		cfg->pll_opdiv = 4;
 	else if (dlane_bps >= 160000000)
 		cfg->pll_opdiv = 8;
+	else if (dlane_bps >= 80000000)
+		cfg->pll_opdiv = 16;
 
 	cfg->pll_fbdiv = DIV_ROUND_UP_ULL(dlane_bps * 2 * cfg->pll_opdiv *
 					  cfg->pll_ipdiv,
-- 
2.34.1



From dmitry.baryshkov at oss.qualcomm.com  Sat Aug  2 02:55:59 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Sat, 2 Aug 2025 12:55:59 +0300
Subject: [PATCH v3 0/5] Add Type-C DP support for RK3399 EVB IND board
In-Reply-To: <63ec11cf-7927-431a-995e-a5fc35ef1ba7@rock-chips.com>
References: <20250729090032.97-1-kernel@airkyi.com>
 <3kefqzjewmsyzfvyi33kvlgjd6jphjg3fsnixb3of7yb3xkgs2@hgi6xfkgd653>
 <63ec11cf-7927-431a-995e-a5fc35ef1ba7@rock-chips.com>
Message-ID: <pk5wecbbpxn7v4bdwtghhdnm76fmrmglelytljwfb4cgvpu2i6@rk5turgyt5xq>

On Thu, Jul 31, 2025 at 10:19:49AM +0800, Chaoyi Chen wrote:
> Hi Dmitry,
> 
> On 7/31/2025 3:13 AM, Dmitry Baryshkov wrote:
> > On Tue, Jul 29, 2025 at 05:00:27PM +0800, Chaoyi Chen wrote:
> > > From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> > > 
> > > This series focuses on adding Type-C DP support for USBDP PHY and DP
> > > driver. The USBDP PHY and DP will perceive the changes in cable status
> > > based on the USB PD and Type-C state machines provided by TCPM. Before
> > > this, the USBDP PHY and DP controller of RK3399 sensed cable state
> > > changes through extcon, and devices such as the RK3399 Gru-Chromebook
> > > rely on them. This series should not break them.
> > > 
> > [....]
> > 
> > > ====
> > > 2. DP HPD event notify
> > > 
> > > The RK3399 has two USB/DP combo PHY and one CDN-DP controller. And
> > > the CDN-DP can be switched to output to one of the PHYs.
> > > 
> > > USB/DP PHY0 ---+
> > >                 | <----> CDN-DP controller
> > > USB/DP PHY1 ---+
> > Could you please clarify this, can you switch DP stream between two
> > USB-C outputs? What happens if user plugs in DP dongles in both USB-C
> > ports?
> 
> Currently, the software simply selects the first available port. So if user
> plugs in DP dongles in both USB-C ports, the DP driver will select the first
> port. This process is implemented in cdn_dp_connected_port() .
> 

I think Stephen Boyd has been looking on similar issues for Chromebooks,
which were sharing DP controller between several USB-C ports. I don't
remember what was his last status. I think there it was easier since the
bifurcation point was the EC.

I think, CDN-DP needs to register up to two encoders and up to two
connectors, having a separate drm_bridge chain for each of the DP
signals paths (in the end, you can not guarantee that both branches will
have the same simple CDN-DP -> PHY -> USB-C configuration: there can be
different retimers, etc).

Both encoders should list the same CRTC in possible_crtcs, etc. Of
course, it should not be possible to enable both of them.

This way if the user plugs in two DP dongles, it would be possible to
select, which output actually gets a signal.

> 
> 
> > 
> > > BTW, one of the important things to do is to implement extcon-like
> > > notifications. I found include/drm/bridge/aux-bridge.h , but if the
> > > aux-bridge is used, the bridge chain would look like this:
> > > 
> > > PHY0 aux-bridge ---+
> > >                     | ----> CDN-DP bridge
> > > PHY1 aux-bridge ---+
> > > 
> > > Oh, CDN-DP bridge has two previous aux-bridge!
> > > 
> > > Now, I try to use drm_connector_oob_hotplug_event() to notify HPD
> > > state between PHY and CDN-DP controller.
> > Does it actually work? The OOB HPD event will be repoted for the usb-c
> > connector's fwnode, but the DP controller isn't connected to that node
> > anyhow. If I'm not mistaken, the HPD signal will not reach DP driver in
> > this case.
> 
> Yes.? What you mentioned is the case in
> drivers/usb/typec/altmodes/displayport.c . I have also added a new OOB event
> notify in the PHY driver in Patch 3, where the expected fwnode is used in
> the PHY. So now we have two OOB HPD events, one from altmodes/displayport.c
> and the other from PHY. Only the HPD from PHY is eventually passed to the DP
> driver.

This way you will loose IRQ_HPD pulse events from the DP. They are used
by DPRX (aka DP Sink) to signal to DPTX (DP Source) that there was a
change on the DPRX side and the DPTX should reread link params and maybe
retrain the link.

> > > Patch1 add new Type-C mode switch for RK3399 USBDP phy binding.
> > > Patch2 add typec_mux and typec_switch for RK3399 USBDP PHY.
> > > Patch3 drops CDN-DP's extcon dependency when Type-C is present.
> > > Patch4 add missing dp_out port for RK3399 CDN-DP.
> > > Patch5 add Type-C DP support for RK3399 EVB IND board.
> > > 
> 
> -- 
> linux-phy mailing list
> linux-phy at lists.infradead.org
> https://lists.infradead.org/mailman/listinfo/linux-phy

-- 
With best wishes
Dmitry


From quanyang.wang at windriver.com  Sat Aug  2 23:15:29 2025
From: quanyang.wang at windriver.com (quanyang.wang at windriver.com)
Date: Sun,  3 Aug 2025 14:15:29 +0800
Subject: [PATCH v2] phy: freescale: imx8qm-hsio: Fix a use of uninitialized mutex
Message-ID: <20250803061529.2303291-1-quanyang.wang@windriver.com>

From: Quanyang Wang <quanyang.wang at windriver.com>

Using an uninitialized mutex leads to the following warning when
CONFIG_DEBUG_MUTEXES is enabled.

 DEBUG_LOCKS_WARN_ON(lock->magic != lock)
 WARNING: CPU: 2 PID: 49 at kernel/locking/mutex.c:577 __mutex_lock+0x690/0x820
 Modules linked in:
 CPU: 2 UID: 0 PID: 49 Comm: kworker/u16:2 Not tainted 6.16.0-04405-g4b290aae788e #23 PREEMPT
 Hardware name: Freescale i.MX8QM MEK (DT)
 Workqueue: events_unbound deferred_probe_work_func
 pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
 pc : __mutex_lock+0x690/0x820
 lr : __mutex_lock+0x690/0x820
 sp : ffff8000830b3900
 x29: ffff8000830b3960 x28: ffff80008223bac0 x27: 0000000000000000
 x26: ffff000802fc4680 x25: ffff000800019a0d x24: 0000000000000000
 x23: ffff8000806f0d6c x22: 0000000000000002 x21: 0000000000000000
 x20: ffff8000830b3930 x19: ffff000802338090 x18: fffffffffffe6138
 x17: 67657220796d6d75 x16: 6420676e69737520 x15: 0000000000000038
 x14: 0000000000000000 x13: ffff8000822636f0 x12: 000000000000044a
 x11: 000000000000016e x10: ffff8000822bd940 x9 : ffff8000822636f0
 x8 : 00000000ffffefff x7 : ffff8000822bb6f0 x6 : 000000000000016e
 x5 : 000000000000016f x4 : 40000000fffff16e x3 : 0000000000000000
 x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff0008003b8000
 Call trace:
  __mutex_lock+0x690/0x820 (P)
  mutex_lock_nested+0x24/0x30
  imx_hsio_power_on+0x4c/0x764
  phy_power_on+0x7c/0x12c
  imx_sata_enable+0x1ec/0x488
  imx_ahci_probe+0x1a4/0x560
  platform_probe+0x5c/0x98
  really_probe+0xac/0x298
  __driver_probe_device+0x78/0x12c
  driver_probe_device+0xd8/0x160
  __device_attach_driver+0xb8/0x138
  bus_for_each_drv+0x88/0xe8
  __device_attach+0xa0/0x190
  device_initial_probe+0x14/0x20
  bus_probe_device+0xac/0xb0
  deferred_probe_work_func+0x8c/0xc8
  process_one_work+0x1e4/0x440
  worker_thread+0x1b4/0x350
  kthread+0x138/0x214
  ret_from_fork+0x10/0x20

Fixes: 82c56b6dd24f ("phy: freescale: imx8qm-hsio: Add i.MX8QM HSIO PHY driver support")
Signed-off-by: Quanyang Wang <quanyang.wang at windriver.com>
---

Changes in v2:
* Use devm_mutex_init instead of mutex_init, as suggested by Frank

 drivers/phy/freescale/phy-fsl-imx8qm-hsio.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/phy/freescale/phy-fsl-imx8qm-hsio.c b/drivers/phy/freescale/phy-fsl-imx8qm-hsio.c
index 5dca93cd325c8..348fefcfe7a5c 100644
--- a/drivers/phy/freescale/phy-fsl-imx8qm-hsio.c
+++ b/drivers/phy/freescale/phy-fsl-imx8qm-hsio.c
@@ -534,6 +534,7 @@ static struct phy *imx_hsio_xlate(struct device *dev,
 static int imx_hsio_probe(struct platform_device *pdev)
 {
 	int i;
+	int ret;
 	void __iomem *off;
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
@@ -590,6 +591,10 @@ static int imx_hsio_probe(struct platform_device *pdev)
 		phy_set_drvdata(phy, lane);
 	}
 
+	ret = devm_mutex_init(dev, &priv->lock);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to initialize lock\n");
+
 	dev_set_drvdata(dev, priv);
 	dev_set_drvdata(&pdev->dev, priv);
 
-- 
2.43.0



From krzk at kernel.org  Sun Aug  3 02:40:28 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sun, 3 Aug 2025 11:40:28 +0200
Subject: [PATCH 1/2] dt-bindings: phy: add support for NXPs TJA1145 CAN
 transceiver
In-Reply-To: <20250731044824.GA3815@legfed1>
References: <20250728-tja1145-support-v1-0-ebd8494d545c@liebherr.com>
 <20250728-tja1145-support-v1-1-ebd8494d545c@liebherr.com>
 <20250730-aromatic-optimistic-hyena-f1db1a@kuoka>
 <20250731044824.GA3815@legfed1>
Message-ID: <0b4b8291-40cf-4faf-a79f-48c56677f9a2@kernel.org>

On 31/07/2025 06:48, Dimitri Fedrau wrote:
>>> +allOf:
>>> +  - $ref: /schemas/spi/spi-peripheral-props.yaml#
>>
>> Missing ref to transceiver properties. Look at other CAN bindings.
>>
> There is only one transceiver property(max-bitrate) which I don't need
> because the max-bitrate is known for the device. So why should I add it
> to the DT ?
> I'm only aware of CAN controller bindings making use of the transceiver
> property which I think is because the PHYs they are supporting with this
> are very simple which need no or little configuration to operate and the
> max-bitrate property is needed to limit the bitrate.

It's fine then, I guess.



Best regards,
Krzysztof


From angelogioacchino.delregno at collabora.com  Mon Aug  4 02:02:44 2025
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 4 Aug 2025 11:02:44 +0200
Subject: [PATCH 14/38] dt-bindings: media: mediatek,mt8195-jpeg: Allow
 range number in node address
In-Reply-To: <70ae6787-ee0b-43a0-851e-1fb6c82f6c31@kernel.org>
References: <20250724083914.61351-1-angelogioacchino.delregno@collabora.com>
 <20250724083914.61351-15-angelogioacchino.delregno@collabora.com>
 <70ae6787-ee0b-43a0-851e-1fb6c82f6c31@kernel.org>
Message-ID: <72934f23-08eb-4214-a946-7aa7a432352e@collabora.com>

Il 24/07/25 11:14, Krzysztof Kozlowski ha scritto:
> On 24/07/2025 10:38, AngeloGioacchino Del Regno wrote:
>> The dual and triple core jpeg encoder and decoder (respectively)
>> on MT8195 are far apart: the only way to have this to make sense
>> is to split those in multiple address ranges in device trees as
>> one big range would overlap with other IP in at least the MT8195
>> SoC.
>>
>> Change both the jpegdec and jpegenc bindings to allow specifying
>> children nodes such as "jpegdec at 0,10000", "jpegdec at 1,0" or for
>> encoder "jpegenc at 0,0", "jpegenc at 1,0" to resolve dtbs_check issues.
> 
> 
> This should not be needed for standard MMIO/simple-bus nodes. I think
> DTS is wrong here.
> 
> Which cases really need the ','?
> 

All of the multi-core JPEG enc/decoders on MT8195 (and newer).

The DT changes are included in the same series as this commit; check:

20250724083914.61351-35-angelogioacchino.delregno at collabora.com

Cheers,
Angelo



From angelogioacchino.delregno at collabora.com  Mon Aug  4 02:08:11 2025
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 4 Aug 2025 11:08:11 +0200
Subject: [PATCH 04/38] ASoC: dt-bindings: mt8192-afe-pcm: Fix clocks and
 clock-names
In-Reply-To: <b7c9f6b8-4f29-4e38-9c93-e22cfed7229d@kernel.org>
References: <20250724083914.61351-1-angelogioacchino.delregno@collabora.com>
 <20250724083914.61351-5-angelogioacchino.delregno@collabora.com>
 <b7c9f6b8-4f29-4e38-9c93-e22cfed7229d@kernel.org>
Message-ID: <fe135942-3040-4858-b2e4-a8e4507b89e9@collabora.com>

Il 24/07/25 11:12, Krzysztof Kozlowski ha scritto:
> On 24/07/2025 10:38, AngeloGioacchino Del Regno wrote:
>>   
>>     clock-names:
>>       items:
>>         - const: aud_afe_clk
>>         - const: aud_dac_clk
>>         - const: aud_dac_predis_clk
>> +      - const: aud_adc_clk
>> +      - const: aud_adda6_adc_clk
>> +      - const: aud_apll22m_clk
>> +      - const: aud_apll24m_clk
>> +      - const: aud_apll1_tuner_clk
>> +      - const: aud_apll2_tuner_clk
>> +      - const: aud_tdm_clk
>> +      - const: aud_tml_clk
>> +      - const: aud_nle
>> +      - const: aud_dac_hires_clk
>> +      - const: aud_adc_hires_clk
>> +      - const: aud_adc_hires_tml
>> +      - const: aud_adda6_adc_hires_clk
>> +      - const: aud_3rd_dac_clk
>> +      - const: aud_3rd_dac_predis_clk
>> +      - const: aud_3rd_dac_tml
>> +      - const: aud_3rd_dac_hires_clk
>>         - const: aud_infra_clk
>>         - const: aud_infra_26m_clk
> 
> 
> You can only add to the end of lists, not in the middle.
> 

The devicetree follows exactly what I've done here, and if I add to the
end of the list (which was wrong from the beginning), I'd have to reorder
all of the clocks in the devicetree node as well.

I know that I'm not supposed to add those there, but this is not about adding
new clocks, it's about adding ones that were missing in the middle.

> Also, please drop all _clk suffixes and aud/top prefixes. These are
> supposed to be clock inputs, so you name them based on this device. Not
> based on the provider's name.

That breaks everything: the driver uses the _clk suffixes and aud/top prefixes
to get clocks by name - I know that "driver" and "binding" are not two words
that go together in that sense, but *otherwise* we'd need to perform way bigger
changes to get this situation resolved.

Those "way bigger changes" would also add bloat to the kernel as we'd need to
parse clocks with old and new names.

Can we please avoid this on SoCs from years ago, which are only getting maintenance
and no new feat/dev?

Thanks,
Angelo



From mwalle at kernel.org  Mon Aug  4 07:06:52 2025
From: mwalle at kernel.org (Michael Walle)
Date: Mon,  4 Aug 2025 16:06:52 +0200
Subject: [PATCH] phy: ti: gmii-sel: Force RGMII TX delay
Message-ID: <20250804140652.539589-1-mwalle@kernel.org>

Some SoCs are just validated with the TX delay enabled. With commit
ca13b249f291 ("net: ethernet: ti: am65-cpsw: fixup PHY mode for fixed
RGMII TX delay"), the network driver will patch the delay setting on the
fly assuming that the TX delay is fixed. In reality, the TX delay is
configurable and just skipped in the documentation. There are
bootloaders, which will disable the TX delay and this will lead to a
transmit path which doesn't add any delays at all. Fix that by always
forcing the TX delay to be enabled.

Fixes: ca13b249f291 ("net: ethernet: ti: am65-cpsw: fixup PHY mode for fixed RGMII TX delay")
Signed-off-by: Michael Walle <mwalle at kernel.org>
---
 drivers/phy/ti/phy-gmii-sel.c | 52 +++++++++++++++++++++++++++++------
 1 file changed, 44 insertions(+), 8 deletions(-)

diff --git a/drivers/phy/ti/phy-gmii-sel.c b/drivers/phy/ti/phy-gmii-sel.c
index ff5d5e29629f..a0c19d00ff3a 100644
--- a/drivers/phy/ti/phy-gmii-sel.c
+++ b/drivers/phy/ti/phy-gmii-sel.c
@@ -34,6 +34,7 @@ enum {
 	PHY_GMII_SEL_PORT_MODE = 0,
 	PHY_GMII_SEL_RGMII_ID_MODE,
 	PHY_GMII_SEL_RMII_IO_CLK_EN,
+	PHY_GMII_SEL_FIXED_TX_DELAY,
 	PHY_GMII_SEL_LAST,
 };
 
@@ -127,6 +128,16 @@ static int phy_gmii_sel_mode(struct phy *phy, enum phy_mode mode, int submode)
 		goto unsupported;
 	}
 
+	/*
+	 * Some SoCs only support fixed MAC side TX delays. According to the
+	 * datasheet, they are always enabled, but that turns out not to be the
+	 * case and the delay is configurable. But according to the vendor that
+	 * mode is not validated and might not work. Some bootloaders disable
+	 * that bit. To work around that enable it again.
+	 */
+	if (soc_data->features & BIT(PHY_GMII_SEL_FIXED_TX_DELAY))
+		rgmii_id = 0;
+
 	if_phy->phy_if_mode = submode;
 
 	dev_dbg(dev, "%s id:%u mode:%u rgmii_id:%d rmii_clk_ext:%d\n",
@@ -210,25 +221,46 @@ struct phy_gmii_sel_soc_data phy_gmii_sel_soc_dm814 = {
 
 static const
 struct reg_field phy_gmii_sel_fields_am654[][PHY_GMII_SEL_LAST] = {
-	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x0, 0, 2), },
-	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x4, 0, 2), },
-	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x8, 0, 2), },
-	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0xC, 0, 2), },
-	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x10, 0, 2), },
-	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x14, 0, 2), },
-	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x18, 0, 2), },
-	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x1C, 0, 2), },
+	{
+		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x0, 0, 2),
+		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x0, 4, 4),
+	}, {
+		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x4, 0, 2),
+		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x4, 4, 4),
+	}, {
+		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x8, 0, 2),
+		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x8, 4, 4),
+	}, {
+		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0xC, 0, 2),
+		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0xC, 4, 4),
+	}, {
+		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x10, 0, 2),
+		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x10, 4, 4),
+	}, {
+		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x14, 0, 2),
+		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x14, 4, 4),
+	}, {
+		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x18, 0, 2),
+		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x18, 4, 4),
+	}, {
+		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x1C, 0, 2),
+		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x1C, 4, 4),
+	},
 };
 
 static const
 struct phy_gmii_sel_soc_data phy_gmii_sel_soc_am654 = {
 	.use_of_data = true,
+	.features = BIT(PHY_GMII_SEL_RGMII_ID_MODE) |
+		    BIT(PHY_GMII_SEL_FIXED_TX_DELAY),
 	.regfields = phy_gmii_sel_fields_am654,
 };
 
 static const
 struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw5g_soc_j7200 = {
 	.use_of_data = true,
+	.features = BIT(PHY_GMII_SEL_RGMII_ID_MODE) |
+		    BIT(PHY_GMII_SEL_FIXED_TX_DELAY),
 	.regfields = phy_gmii_sel_fields_am654,
 	.extra_modes = BIT(PHY_INTERFACE_MODE_QSGMII) | BIT(PHY_INTERFACE_MODE_SGMII) |
 		       BIT(PHY_INTERFACE_MODE_USXGMII),
@@ -239,6 +271,8 @@ struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw5g_soc_j7200 = {
 static const
 struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw9g_soc_j721e = {
 	.use_of_data = true,
+	.features = BIT(PHY_GMII_SEL_RGMII_ID_MODE) |
+		    BIT(PHY_GMII_SEL_FIXED_TX_DELAY),
 	.regfields = phy_gmii_sel_fields_am654,
 	.extra_modes = BIT(PHY_INTERFACE_MODE_QSGMII) | BIT(PHY_INTERFACE_MODE_SGMII),
 	.num_ports = 8,
@@ -248,6 +282,8 @@ struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw9g_soc_j721e = {
 static const
 struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw9g_soc_j784s4 = {
 	.use_of_data = true,
+	.features = BIT(PHY_GMII_SEL_RGMII_ID_MODE) |
+		    BIT(PHY_GMII_SEL_FIXED_TX_DELAY),
 	.regfields = phy_gmii_sel_fields_am654,
 	.extra_modes = BIT(PHY_INTERFACE_MODE_QSGMII) | BIT(PHY_INTERFACE_MODE_SGMII) |
 		       BIT(PHY_INTERFACE_MODE_USXGMII),
-- 
2.39.5



From matthias.schiffer at ew.tq-group.com  Mon Aug  4 07:59:32 2025
From: matthias.schiffer at ew.tq-group.com (Matthias Schiffer)
Date: Mon, 04 Aug 2025 16:59:32 +0200
Subject: [PATCH] phy: ti: gmii-sel: Force RGMII TX delay
In-Reply-To: <20250804140652.539589-1-mwalle@kernel.org>
References: <20250804140652.539589-1-mwalle@kernel.org>
Message-ID: <b2c38da8e02b5d5de3f1a2c514e7e84f43ee2400.camel@ew.tq-group.com>

On Mon, 2025-08-04 at 16:06 +0200, Michael Walle wrote:
> Some SoCs are just validated with the TX delay enabled. With commit
> ca13b249f291 ("net: ethernet: ti: am65-cpsw: fixup PHY mode for fixed
> RGMII TX delay"), the network driver will patch the delay setting on the
> fly assuming that the TX delay is fixed. In reality, the TX delay is
> configurable and just skipped in the documentation. There are
> bootloaders, which will disable the TX delay and this will lead to a
> transmit path which doesn't add any delays at all. Fix that by always
> forcing the TX delay to be enabled.
> 
> Fixes: ca13b249f291 ("net: ethernet: ti: am65-cpsw: fixup PHY mode for fixed RGMII TX delay")
> Signed-off-by: Michael Walle <mwalle at kernel.org>
> ---
>  drivers/phy/ti/phy-gmii-sel.c | 52 +++++++++++++++++++++++++++++------
>  1 file changed, 44 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/phy/ti/phy-gmii-sel.c b/drivers/phy/ti/phy-gmii-sel.c
> index ff5d5e29629f..a0c19d00ff3a 100644
> --- a/drivers/phy/ti/phy-gmii-sel.c
> +++ b/drivers/phy/ti/phy-gmii-sel.c
> @@ -34,6 +34,7 @@ enum {
>  	PHY_GMII_SEL_PORT_MODE = 0,
>  	PHY_GMII_SEL_RGMII_ID_MODE,
>  	PHY_GMII_SEL_RMII_IO_CLK_EN,
> +	PHY_GMII_SEL_FIXED_TX_DELAY,
>  	PHY_GMII_SEL_LAST,
>  };
>  
> @@ -127,6 +128,16 @@ static int phy_gmii_sel_mode(struct phy *phy, enum phy_mode mode, int submode)
>  		goto unsupported;
>  	}
>  
> +	/*
> +	 * Some SoCs only support fixed MAC side TX delays. According to the
> +	 * datasheet, they are always enabled, but that turns out not to be the
> +	 * case and the delay is configurable. But according to the vendor that
> +	 * mode is not validated and might not work. Some bootloaders disable
> +	 * that bit. To work around that enable it again.
> +	 */
> +	if (soc_data->features & BIT(PHY_GMII_SEL_FIXED_TX_DELAY))
> +		rgmii_id = 0;

The mode passed to phy_gmii_sel_mode by am65-cpsw is the same value that is
passed to the Ethernet PHY driver, so a case where rgmii_id == 1 and would be
reset to 0 is unreachable (PHY_INTERFACE_MODE_RGMII_ID and
PHY_INTERFACE_MODE_RGMII_TXID can't occur with the fixup in am65-cpsw).
Therefore we could return EINVAL here if PHY_GMII_SEL_FIXED_TX_DELAY is set and
rgmii_id == 1 instead of effectively ignoring the mode, which seems a bit more
robust to me.

Best,
Matthias


> +
>  	if_phy->phy_if_mode = submode;
>  
>  	dev_dbg(dev, "%s id:%u mode:%u rgmii_id:%d rmii_clk_ext:%d\n",
> @@ -210,25 +221,46 @@ struct phy_gmii_sel_soc_data phy_gmii_sel_soc_dm814 = {
>  
>  static const
>  struct reg_field phy_gmii_sel_fields_am654[][PHY_GMII_SEL_LAST] = {
> -	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x0, 0, 2), },
> -	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x4, 0, 2), },
> -	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x8, 0, 2), },
> -	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0xC, 0, 2), },
> -	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x10, 0, 2), },
> -	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x14, 0, 2), },
> -	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x18, 0, 2), },
> -	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x1C, 0, 2), },
> +	{
> +		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x0, 0, 2),
> +		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x0, 4, 4),
> +	}, {
> +		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x4, 0, 2),
> +		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x4, 4, 4),
> +	}, {
> +		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x8, 0, 2),
> +		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x8, 4, 4),
> +	}, {
> +		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0xC, 0, 2),
> +		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0xC, 4, 4),
> +	}, {
> +		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x10, 0, 2),
> +		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x10, 4, 4),
> +	}, {
> +		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x14, 0, 2),
> +		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x14, 4, 4),
> +	}, {
> +		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x18, 0, 2),
> +		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x18, 4, 4),
> +	}, {
> +		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x1C, 0, 2),
> +		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x1C, 4, 4),
> +	},
>  };
>  
>  static const
>  struct phy_gmii_sel_soc_data phy_gmii_sel_soc_am654 = {
>  	.use_of_data = true,
> +	.features = BIT(PHY_GMII_SEL_RGMII_ID_MODE) |
> +		    BIT(PHY_GMII_SEL_FIXED_TX_DELAY),
>  	.regfields = phy_gmii_sel_fields_am654,
>  };
>  
>  static const
>  struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw5g_soc_j7200 = {
>  	.use_of_data = true,
> +	.features = BIT(PHY_GMII_SEL_RGMII_ID_MODE) |
> +		    BIT(PHY_GMII_SEL_FIXED_TX_DELAY),
>  	.regfields = phy_gmii_sel_fields_am654,
>  	.extra_modes = BIT(PHY_INTERFACE_MODE_QSGMII) | BIT(PHY_INTERFACE_MODE_SGMII) |
>  		       BIT(PHY_INTERFACE_MODE_USXGMII),
> @@ -239,6 +271,8 @@ struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw5g_soc_j7200 = {
>  static const
>  struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw9g_soc_j721e = {
>  	.use_of_data = true,
> +	.features = BIT(PHY_GMII_SEL_RGMII_ID_MODE) |
> +		    BIT(PHY_GMII_SEL_FIXED_TX_DELAY),
>  	.regfields = phy_gmii_sel_fields_am654,
>  	.extra_modes = BIT(PHY_INTERFACE_MODE_QSGMII) | BIT(PHY_INTERFACE_MODE_SGMII),
>  	.num_ports = 8,
> @@ -248,6 +282,8 @@ struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw9g_soc_j721e = {
>  static const
>  struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw9g_soc_j784s4 = {
>  	.use_of_data = true,
> +	.features = BIT(PHY_GMII_SEL_RGMII_ID_MODE) |
> +		    BIT(PHY_GMII_SEL_FIXED_TX_DELAY),
>  	.regfields = phy_gmii_sel_fields_am654,
>  	.extra_modes = BIT(PHY_INTERFACE_MODE_QSGMII) | BIT(PHY_INTERFACE_MODE_SGMII) |
>  		       BIT(PHY_INTERFACE_MODE_USXGMII),

-- 
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
https://www.tq-group.com/


From andrew at lunn.ch  Mon Aug  4 08:19:19 2025
From: andrew at lunn.ch (Andrew Lunn)
Date: Mon, 4 Aug 2025 17:19:19 +0200
Subject: [PATCH] phy: ti: gmii-sel: Force RGMII TX delay
In-Reply-To: <20250804140652.539589-1-mwalle@kernel.org>
References: <20250804140652.539589-1-mwalle@kernel.org>
Message-ID: <3bc6476e-7539-40aa-b499-253273357a1d@lunn.ch>

On Mon, Aug 04, 2025 at 04:06:52PM +0200, Michael Walle wrote:
> Some SoCs are just validated with the TX delay enabled. With commit
> ca13b249f291 ("net: ethernet: ti: am65-cpsw: fixup PHY mode for fixed
> RGMII TX delay"), the network driver will patch the delay setting on the
> fly assuming that the TX delay is fixed. In reality, the TX delay is
> configurable and just skipped in the documentation. There are
> bootloaders, which will disable the TX delay and this will lead to a
> transmit path which doesn't add any delays at all. Fix that by always
> forcing the TX delay to be enabled.

Please could you add a paragraph:

    This is safe to do, and will not break any existing boards
    supported in mainline because...

We have to be careful of regressions, and such a paragraph makes it
clear you have thought it through, and what your assumptions are. If
something does break, listing your assumptions will help finding what
went wrong.

   Andrew


From chaoyi.chen at rock-chips.com  Mon Aug  4 20:43:05 2025
From: chaoyi.chen at rock-chips.com (Chaoyi Chen)
Date: Tue, 5 Aug 2025 11:43:05 +0800
Subject: [PATCH v3 0/5] Add Type-C DP support for RK3399 EVB IND board
In-Reply-To: <pk5wecbbpxn7v4bdwtghhdnm76fmrmglelytljwfb4cgvpu2i6@rk5turgyt5xq>
References: <20250729090032.97-1-kernel@airkyi.com>
 <3kefqzjewmsyzfvyi33kvlgjd6jphjg3fsnixb3of7yb3xkgs2@hgi6xfkgd653>
 <63ec11cf-7927-431a-995e-a5fc35ef1ba7@rock-chips.com>
 <pk5wecbbpxn7v4bdwtghhdnm76fmrmglelytljwfb4cgvpu2i6@rk5turgyt5xq>
Message-ID: <0207826d-a987-4464-b306-29bdbfac45bc@rock-chips.com>

Hi Dmitry,

On 8/2/2025 5:55 PM, Dmitry Baryshkov wrote:

[...]


>> Currently, the software simply selects the first available port. So if user
>> plugs in DP dongles in both USB-C ports, the DP driver will select the first
>> port. This process is implemented in cdn_dp_connected_port() .
>>
> I think Stephen Boyd has been looking on similar issues for Chromebooks,
> which were sharing DP controller between several USB-C ports. I don't
> remember what was his last status. I think there it was easier since the
> bifurcation point was the EC.

I think the latest progress should be here: [0]. It seems that it hasn't 
been updated for a while.

[0]: 
https://lore.kernel.org/all/20240901040658.157425-1-swboyd at chromium.org/


>
> I think, CDN-DP needs to register up to two encoders and up to two
> connectors, having a separate drm_bridge chain for each of the DP
> signals paths (in the end, you can not guarantee that both branches will
> have the same simple CDN-DP -> PHY -> USB-C configuration: there can be
> different retimers, etc).
>
> Both encoders should list the same CRTC in possible_crtcs, etc. Of
> course, it should not be possible to enable both of them.
>
> This way if the user plugs in two DP dongles, it would be possible to
> select, which output actually gets a signal.

That makes sense, but this might make the DP driver quite complex. I 
will see if I can make it happen.


>
>>
>>>> BTW, one of the important things to do is to implement extcon-like
>>>> notifications. I found include/drm/bridge/aux-bridge.h , but if the
>>>> aux-bridge is used, the bridge chain would look like this:
>>>>
>>>> PHY0 aux-bridge ---+
>>>>                      | ----> CDN-DP bridge
>>>> PHY1 aux-bridge ---+
>>>>
>>>> Oh, CDN-DP bridge has two previous aux-bridge!
>>>>
>>>> Now, I try to use drm_connector_oob_hotplug_event() to notify HPD
>>>> state between PHY and CDN-DP controller.
>>> Does it actually work? The OOB HPD event will be repoted for the usb-c
>>> connector's fwnode, but the DP controller isn't connected to that node
>>> anyhow. If I'm not mistaken, the HPD signal will not reach DP driver in
>>> this case.
>> Yes.? What you mentioned is the case in
>> drivers/usb/typec/altmodes/displayport.c . I have also added a new OOB event
>> notify in the PHY driver in Patch 3, where the expected fwnode is used in
>> the PHY. So now we have two OOB HPD events, one from altmodes/displayport.c
>> and the other from PHY. Only the HPD from PHY is eventually passed to the DP
>> driver.
> This way you will loose IRQ_HPD pulse events from the DP. They are used
> by DPRX (aka DP Sink) to signal to DPTX (DP Source) that there was a
> change on the DPRX side and the DPTX should reread link params and maybe
> retrain the link.

Sorry, I still don't quite understand your point. I think the entire 
notification path is as follows:

Type-C mux callback -> RK3399 USBDP PHY -> PHY calls 
drm_connector_oob_hotplug_event() -> DP driver

Are you concerned that the IRQ_HPD event is not being handled somewhere 
along the path? Is it that the Type-C mux callback didn't notify the 
PHY, or that after the PHY passed the event to the DP driver via the OOB 
event, the DP driver didn't handle it?



From dmitry.baryshkov at oss.qualcomm.com  Mon Aug  4 21:26:57 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Tue, 5 Aug 2025 09:56:57 +0530
Subject: [PATCH v3 0/5] Add Type-C DP support for RK3399 EVB IND board
In-Reply-To: <0207826d-a987-4464-b306-29bdbfac45bc@rock-chips.com>
References: <20250729090032.97-1-kernel@airkyi.com>
 <3kefqzjewmsyzfvyi33kvlgjd6jphjg3fsnixb3of7yb3xkgs2@hgi6xfkgd653>
 <63ec11cf-7927-431a-995e-a5fc35ef1ba7@rock-chips.com>
 <pk5wecbbpxn7v4bdwtghhdnm76fmrmglelytljwfb4cgvpu2i6@rk5turgyt5xq>
 <0207826d-a987-4464-b306-29bdbfac45bc@rock-chips.com>
Message-ID: <3e880194-5ac8-4056-929c-ac103bedc737@oss.qualcomm.com>

On 05/08/2025 09:13, Chaoyi Chen wrote:
> Hi Dmitry,
> 
> On 8/2/2025 5:55 PM, Dmitry Baryshkov wrote:
> 
> [...]
> 
> 
>>> Currently, the software simply selects the first available port. So 
>>> if user
>>> plugs in DP dongles in both USB-C ports, the DP driver will select 
>>> the first
>>> port. This process is implemented in cdn_dp_connected_port() .
>>>
>> I think Stephen Boyd has been looking on similar issues for Chromebooks,
>> which were sharing DP controller between several USB-C ports. I don't
>> remember what was his last status. I think there it was easier since the
>> bifurcation point was the EC.
> 
> I think the latest progress should be here: [0]. It seems that it hasn't 
> been updated for a while.

Might be :-(

> 
> [0]: https://lore.kernel.org/all/20240901040658.157425-1- 
> swboyd at chromium.org/
> 
> 
>>
>> I think, CDN-DP needs to register up to two encoders and up to two
>> connectors, having a separate drm_bridge chain for each of the DP
>> signals paths (in the end, you can not guarantee that both branches will
>> have the same simple CDN-DP -> PHY -> USB-C configuration: there can be
>> different retimers, etc).
>>
>> Both encoders should list the same CRTC in possible_crtcs, etc. Of
>> course, it should not be possible to enable both of them.
>>
>> This way if the user plugs in two DP dongles, it would be possible to
>> select, which output actually gets a signal.
> 
> That makes sense, but this might make the DP driver quite complex. I 
> will see if I can make it happen.

I think it's trading one burden for another, because CDN-DP currently 
has a complication of calling cdn_dp_get_port_lanes() / 
cdn_dp_enable_phy() in a loop rather than just enabling one instance.

> 
> 
>>
>>>
>>>>> BTW, one of the important things to do is to implement extcon-like
>>>>> notifications. I found include/drm/bridge/aux-bridge.h , but if the
>>>>> aux-bridge is used, the bridge chain would look like this:
>>>>>
>>>>> PHY0 aux-bridge ---+
>>>>> ???????????????????? | ----> CDN-DP bridge
>>>>> PHY1 aux-bridge ---+
>>>>>
>>>>> Oh, CDN-DP bridge has two previous aux-bridge!
>>>>>
>>>>> Now, I try to use drm_connector_oob_hotplug_event() to notify HPD
>>>>> state between PHY and CDN-DP controller.
>>>> Does it actually work? The OOB HPD event will be repoted for the usb-c
>>>> connector's fwnode, but the DP controller isn't connected to that node
>>>> anyhow. If I'm not mistaken, the HPD signal will not reach DP driver in
>>>> this case.
>>> Yes.? What you mentioned is the case in
>>> drivers/usb/typec/altmodes/displayport.c . I have also added a new 
>>> OOB event
>>> notify in the PHY driver in Patch 3, where the expected fwnode is 
>>> used in
>>> the PHY. So now we have two OOB HPD events, one from altmodes/ 
>>> displayport.c
>>> and the other from PHY. Only the HPD from PHY is eventually passed to 
>>> the DP
>>> driver.
>> This way you will loose IRQ_HPD pulse events from the DP. They are used
>> by DPRX (aka DP Sink) to signal to DPTX (DP Source) that there was a
>> change on the DPRX side and the DPTX should reread link params and maybe
>> retrain the link.
> 
> Sorry, I still don't quite understand your point. I think the entire 
> notification path is as follows:
> 
> Type-C mux callback -> RK3399 USBDP PHY -> PHY calls 
> drm_connector_oob_hotplug_event() -> DP driver
> 
> Are you concerned that the IRQ_HPD event is not being handled somewhere 
> along the path? Is it that the Type-C mux callback didn't notify the 
> PHY, or that after the PHY passed the event to the DP driver via the OOB 
> event, the DP driver didn't handle it?

The IRQ_HPD is an event coming from DPRX, it is delivered as a part of 
the attention VDM, see DP_STATUS_IRQ_HPD. It's being handled by the 
altmode displayport.c driver and is then delivered as an OOB hotplug 
call. However, it's not a mux event, so it is not (and it should not) 
being broadcasted over the typec_mux devices.

The way we were handling that is by having a chain of drm_aux_bridges 
for all interim devices, ending up with a drm_dp_hpd_bridge registered 
by the TCPM. This way when the DPRX triggers the IRQ_HPD event, it is 
being handled by the displayport.c and then delivered through that 
bridge to the DP driver.

-- 
With best wishes
Dmitry


From chaoyi.chen at rock-chips.com  Mon Aug  4 23:32:17 2025
From: chaoyi.chen at rock-chips.com (Chaoyi Chen)
Date: Tue, 5 Aug 2025 14:32:17 +0800
Subject: [PATCH v3 0/5] Add Type-C DP support for RK3399 EVB IND board
In-Reply-To: <3e880194-5ac8-4056-929c-ac103bedc737@oss.qualcomm.com>
References: <20250729090032.97-1-kernel@airkyi.com>
 <3kefqzjewmsyzfvyi33kvlgjd6jphjg3fsnixb3of7yb3xkgs2@hgi6xfkgd653>
 <63ec11cf-7927-431a-995e-a5fc35ef1ba7@rock-chips.com>
 <pk5wecbbpxn7v4bdwtghhdnm76fmrmglelytljwfb4cgvpu2i6@rk5turgyt5xq>
 <0207826d-a987-4464-b306-29bdbfac45bc@rock-chips.com>
 <3e880194-5ac8-4056-929c-ac103bedc737@oss.qualcomm.com>
Message-ID: <f726862a-bd18-43ee-b307-8daef2451e6b@rock-chips.com>

Hi Dmitry,

On 8/5/2025 12:26 PM, Dmitry Baryshkov wrote:
> On 05/08/2025 09:13, Chaoyi Chen wrote:
>> Hi Dmitry,
>>
>> On 8/2/2025 5:55 PM, Dmitry Baryshkov wrote:
>>
>> [...]
>>
>>
>>>> Currently, the software simply selects the first available port. So 
>>>> if user
>>>> plugs in DP dongles in both USB-C ports, the DP driver will select 
>>>> the first
>>>> port. This process is implemented in cdn_dp_connected_port() .
>>>>
>>> I think Stephen Boyd has been looking on similar issues for 
>>> Chromebooks,
>>> which were sharing DP controller between several USB-C ports. I don't
>>> remember what was his last status. I think there it was easier since 
>>> the
>>> bifurcation point was the EC.
>>
>> I think the latest progress should be here: [0]. It seems that it 
>> hasn't been updated for a while.
>
> Might be :-(
>
>>
>> [0]: https://lore.kernel.org/all/20240901040658.157425-1- 
>> swboyd at chromium.org/
>>
>>
>>>
>>> I think, CDN-DP needs to register up to two encoders and up to two
>>> connectors, having a separate drm_bridge chain for each of the DP
>>> signals paths (in the end, you can not guarantee that both branches 
>>> will
>>> have the same simple CDN-DP -> PHY -> USB-C configuration: there can be
>>> different retimers, etc).
>>>
>>> Both encoders should list the same CRTC in possible_crtcs, etc. Of
>>> course, it should not be possible to enable both of them.
>>>
>>> This way if the user plugs in two DP dongles, it would be possible to
>>> select, which output actually gets a signal.
>>
>> That makes sense, but this might make the DP driver quite complex. I 
>> will see if I can make it happen.
>
> I think it's trading one burden for another, because CDN-DP currently 
> has a complication of calling cdn_dp_get_port_lanes() / 
> cdn_dp_enable_phy() in a loop rather than just enabling one instance.

Yep, I will give it a try.


>
>>
>>
>>>
>>>>
>>>>>> BTW, one of the important things to do is to implement extcon-like
>>>>>> notifications. I found include/drm/bridge/aux-bridge.h , but if the
>>>>>> aux-bridge is used, the bridge chain would look like this:
>>>>>>
>>>>>> PHY0 aux-bridge ---+
>>>>>> ???????????????????? | ----> CDN-DP bridge
>>>>>> PHY1 aux-bridge ---+
>>>>>>
>>>>>> Oh, CDN-DP bridge has two previous aux-bridge!
>>>>>>
>>>>>> Now, I try to use drm_connector_oob_hotplug_event() to notify HPD
>>>>>> state between PHY and CDN-DP controller.
>>>>> Does it actually work? The OOB HPD event will be repoted for the 
>>>>> usb-c
>>>>> connector's fwnode, but the DP controller isn't connected to that 
>>>>> node
>>>>> anyhow. If I'm not mistaken, the HPD signal will not reach DP 
>>>>> driver in
>>>>> this case.
>>>> Yes.? What you mentioned is the case in
>>>> drivers/usb/typec/altmodes/displayport.c . I have also added a new 
>>>> OOB event
>>>> notify in the PHY driver in Patch 3, where the expected fwnode is 
>>>> used in
>>>> the PHY. So now we have two OOB HPD events, one from altmodes/ 
>>>> displayport.c
>>>> and the other from PHY. Only the HPD from PHY is eventually passed 
>>>> to the DP
>>>> driver.
>>> This way you will loose IRQ_HPD pulse events from the DP. They are used
>>> by DPRX (aka DP Sink) to signal to DPTX (DP Source) that there was a
>>> change on the DPRX side and the DPTX should reread link params and 
>>> maybe
>>> retrain the link.
>>
>> Sorry, I still don't quite understand your point. I think the entire 
>> notification path is as follows:
>>
>> Type-C mux callback -> RK3399 USBDP PHY -> PHY calls 
>> drm_connector_oob_hotplug_event() -> DP driver
>>
>> Are you concerned that the IRQ_HPD event is not being handled 
>> somewhere along the path? Is it that the Type-C mux callback didn't 
>> notify the PHY, or that after the PHY passed the event to the DP 
>> driver via the OOB event, the DP driver didn't handle it?
>
> The IRQ_HPD is an event coming from DPRX, it is delivered as a part of 
> the attention VDM, see DP_STATUS_IRQ_HPD. It's being handled by the 
> altmode displayport.c driver and is then delivered as an OOB hotplug 
> call. However, it's not a mux event, so it is not (and it should not) 
> being broadcasted over the typec_mux devices.
>
> The way we were handling that is by having a chain of drm_aux_bridges 
> for all interim devices, ending up with a drm_dp_hpd_bridge registered 
> by the TCPM. This way when the DPRX triggers the IRQ_HPD event, it is 
> being handled by the displayport.c and then delivered through that 
> bridge to the DP driver.

I think the issue goes back to the beginning. The key is to reuse the 
logic in displayport.c, and the previous approach of directly setting 
the fwnode has already been rejected. Is it a good idea to register the 
aux hpd bridge in displayport.c? In this way, we don't need to register 
it with a bunch of PD drivers (such as fusb302), which seems like a more 
generic solution.




From waqar.hameed at axis.com  Tue Aug  5 02:33:35 2025
From: waqar.hameed at axis.com (Waqar Hameed)
Date: Tue, 5 Aug 2025 11:33:35 +0200
Subject: [PATCH v2] phy: exynos5-usbdrd: Remove error print for
 devm_add_action_or_reset()
Message-ID: <pnd34a6m7tc.a.out@axis.com>

When `devm_add_action_or_reset()` fails, it is due to a failed memory
allocation and will thus return `-ENOMEM`. `dev_err_probe()` doesn't do
anything when error is `-ENOMEM`. Therefore, remove the useless call to
`dev_err_probe()` when `devm_add_action_or_reset()` fails, and just
return the value instead.

Signed-off-by: Waqar Hameed <waqar.hameed at axis.com>
---
Changes in v2:

* Split the patch to one seperate patch for each sub-system.

Link to v1: https://lore.kernel.org/all/pnd7c0s6ji2.fsf at axis.com/

 drivers/phy/samsung/phy-exynos5-usbdrd.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
index 917a76d584f0..28ba11e42823 100644
--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
+++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
@@ -1859,8 +1859,7 @@ static int exynos5_usbdrd_setup_notifiers(struct exynos5_usbdrd_phy *phy_drd)
 					       exynos5_usbdrd_orien_switch_unregister,
 					       phy_drd);
 		if (ret)
-			return dev_err_probe(phy_drd->dev, ret,
-					     "Failed to register TypeC orientation devm action\n");
+			return ret;
 	}
 
 	return 0;

base-commit: 260f6f4fda93c8485c8037865c941b42b9cba5d2
-- 
2.39.5



From dmitry.baryshkov at oss.qualcomm.com  Tue Aug  5 03:44:37 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Tue, 5 Aug 2025 13:44:37 +0300
Subject: [PATCH v3 0/5] Add Type-C DP support for RK3399 EVB IND board
In-Reply-To: <f726862a-bd18-43ee-b307-8daef2451e6b@rock-chips.com>
References: <20250729090032.97-1-kernel@airkyi.com>
 <3kefqzjewmsyzfvyi33kvlgjd6jphjg3fsnixb3of7yb3xkgs2@hgi6xfkgd653>
 <63ec11cf-7927-431a-995e-a5fc35ef1ba7@rock-chips.com>
 <pk5wecbbpxn7v4bdwtghhdnm76fmrmglelytljwfb4cgvpu2i6@rk5turgyt5xq>
 <0207826d-a987-4464-b306-29bdbfac45bc@rock-chips.com>
 <3e880194-5ac8-4056-929c-ac103bedc737@oss.qualcomm.com>
 <f726862a-bd18-43ee-b307-8daef2451e6b@rock-chips.com>
Message-ID: <6nfmxwtwcvuyo2jaao7fele7jcgcykfpy7czbcbjmjxv7cs5sc@dmbtot73kw63>

On Tue, Aug 05, 2025 at 02:32:17PM +0800, Chaoyi Chen wrote:
> Hi Dmitry,
> 
> On 8/5/2025 12:26 PM, Dmitry Baryshkov wrote:
> > On 05/08/2025 09:13, Chaoyi Chen wrote:
> > > Hi Dmitry,
> > > 
> > > On 8/2/2025 5:55 PM, Dmitry Baryshkov wrote:
> > > 
> > > [...]
> > > 
> > > 
> > > > > > > BTW, one of the important things to do is to implement extcon-like
> > > > > > > notifications. I found include/drm/bridge/aux-bridge.h , but if the
> > > > > > > aux-bridge is used, the bridge chain would look like this:
> > > > > > > 
> > > > > > > PHY0 aux-bridge ---+
> > > > > > > ???????????????????? | ----> CDN-DP bridge
> > > > > > > PHY1 aux-bridge ---+
> > > > > > > 
> > > > > > > Oh, CDN-DP bridge has two previous aux-bridge!
> > > > > > > 
> > > > > > > Now, I try to use drm_connector_oob_hotplug_event() to notify HPD
> > > > > > > state between PHY and CDN-DP controller.
> > > > > > Does it actually work? The OOB HPD event will be repoted
> > > > > > for the usb-c
> > > > > > connector's fwnode, but the DP controller isn't
> > > > > > connected to that node
> > > > > > anyhow. If I'm not mistaken, the HPD signal will not
> > > > > > reach DP driver in
> > > > > > this case.
> > > > > Yes.? What you mentioned is the case in
> > > > > drivers/usb/typec/altmodes/displayport.c . I have also added
> > > > > a new OOB event
> > > > > notify in the PHY driver in Patch 3, where the expected
> > > > > fwnode is used in
> > > > > the PHY. So now we have two OOB HPD events, one from
> > > > > altmodes/ displayport.c
> > > > > and the other from PHY. Only the HPD from PHY is eventually
> > > > > passed to the DP
> > > > > driver.
> > > > This way you will loose IRQ_HPD pulse events from the DP. They are used
> > > > by DPRX (aka DP Sink) to signal to DPTX (DP Source) that there was a
> > > > change on the DPRX side and the DPTX should reread link params
> > > > and maybe
> > > > retrain the link.
> > > 
> > > Sorry, I still don't quite understand your point. I think the entire
> > > notification path is as follows:
> > > 
> > > Type-C mux callback -> RK3399 USBDP PHY -> PHY calls
> > > drm_connector_oob_hotplug_event() -> DP driver
> > > 
> > > Are you concerned that the IRQ_HPD event is not being handled
> > > somewhere along the path? Is it that the Type-C mux callback didn't
> > > notify the PHY, or that after the PHY passed the event to the DP
> > > driver via the OOB event, the DP driver didn't handle it?
> > 
> > The IRQ_HPD is an event coming from DPRX, it is delivered as a part of
> > the attention VDM, see DP_STATUS_IRQ_HPD. It's being handled by the
> > altmode displayport.c driver and is then delivered as an OOB hotplug
> > call. However, it's not a mux event, so it is not (and it should not)
> > being broadcasted over the typec_mux devices.
> > 
> > The way we were handling that is by having a chain of drm_aux_bridges
> > for all interim devices, ending up with a drm_dp_hpd_bridge registered
> > by the TCPM. This way when the DPRX triggers the IRQ_HPD event, it is
> > being handled by the displayport.c and then delivered through that
> > bridge to the DP driver.
> 
> I think the issue goes back to the beginning. The key is to reuse the logic
> in displayport.c, and the previous approach of directly setting the fwnode
> has already been rejected. Is it a good idea to register the aux hpd bridge
> in displayport.c? In this way, we don't need to register it with a bunch of
> PD drivers (such as fusb302), which seems like a more generic solution.

displayport.c comes into play only when you actually attach a DP dongle,
which is too late for bringing up the display pipeline. But your point
is valid, it might be worth moving drm_dp_hpd registration to
typec_port_register_altmode().

-- 
With best wishes
Dmitry


From chaoyi.chen at rock-chips.com  Tue Aug  5 04:07:09 2025
From: chaoyi.chen at rock-chips.com (Chaoyi Chen)
Date: Tue, 5 Aug 2025 19:07:09 +0800
Subject: [PATCH v3 0/5] Add Type-C DP support for RK3399 EVB IND board
In-Reply-To: <6nfmxwtwcvuyo2jaao7fele7jcgcykfpy7czbcbjmjxv7cs5sc@dmbtot73kw63>
References: <20250729090032.97-1-kernel@airkyi.com>
 <3kefqzjewmsyzfvyi33kvlgjd6jphjg3fsnixb3of7yb3xkgs2@hgi6xfkgd653>
 <63ec11cf-7927-431a-995e-a5fc35ef1ba7@rock-chips.com>
 <pk5wecbbpxn7v4bdwtghhdnm76fmrmglelytljwfb4cgvpu2i6@rk5turgyt5xq>
 <0207826d-a987-4464-b306-29bdbfac45bc@rock-chips.com>
 <3e880194-5ac8-4056-929c-ac103bedc737@oss.qualcomm.com>
 <f726862a-bd18-43ee-b307-8daef2451e6b@rock-chips.com>
 <6nfmxwtwcvuyo2jaao7fele7jcgcykfpy7czbcbjmjxv7cs5sc@dmbtot73kw63>
Message-ID: <a7988745-ea31-45cd-8ffd-905e6e4d1315@rock-chips.com>

On 8/5/2025 6:44 PM, Dmitry Baryshkov wrote:

> On Tue, Aug 05, 2025 at 02:32:17PM +0800, Chaoyi Chen wrote:
>> Hi Dmitry,
>>
>> On 8/5/2025 12:26 PM, Dmitry Baryshkov wrote:
>>> On 05/08/2025 09:13, Chaoyi Chen wrote:
>>>> Hi Dmitry,
>>>>
>>>> On 8/2/2025 5:55 PM, Dmitry Baryshkov wrote:
>>>>
>>>> [...]
>>>>
>>>>
>>>>>>>> BTW, one of the important things to do is to implement extcon-like
>>>>>>>> notifications. I found include/drm/bridge/aux-bridge.h , but if the
>>>>>>>> aux-bridge is used, the bridge chain would look like this:
>>>>>>>>
>>>>>>>> PHY0 aux-bridge ---+
>>>>>>>>  ???????????????????? | ----> CDN-DP bridge
>>>>>>>> PHY1 aux-bridge ---+
>>>>>>>>
>>>>>>>> Oh, CDN-DP bridge has two previous aux-bridge!
>>>>>>>>
>>>>>>>> Now, I try to use drm_connector_oob_hotplug_event() to notify HPD
>>>>>>>> state between PHY and CDN-DP controller.
>>>>>>> Does it actually work? The OOB HPD event will be repoted
>>>>>>> for the usb-c
>>>>>>> connector's fwnode, but the DP controller isn't
>>>>>>> connected to that node
>>>>>>> anyhow. If I'm not mistaken, the HPD signal will not
>>>>>>> reach DP driver in
>>>>>>> this case.
>>>>>> Yes.? What you mentioned is the case in
>>>>>> drivers/usb/typec/altmodes/displayport.c . I have also added
>>>>>> a new OOB event
>>>>>> notify in the PHY driver in Patch 3, where the expected
>>>>>> fwnode is used in
>>>>>> the PHY. So now we have two OOB HPD events, one from
>>>>>> altmodes/ displayport.c
>>>>>> and the other from PHY. Only the HPD from PHY is eventually
>>>>>> passed to the DP
>>>>>> driver.
>>>>> This way you will loose IRQ_HPD pulse events from the DP. They are used
>>>>> by DPRX (aka DP Sink) to signal to DPTX (DP Source) that there was a
>>>>> change on the DPRX side and the DPTX should reread link params
>>>>> and maybe
>>>>> retrain the link.
>>>> Sorry, I still don't quite understand your point. I think the entire
>>>> notification path is as follows:
>>>>
>>>> Type-C mux callback -> RK3399 USBDP PHY -> PHY calls
>>>> drm_connector_oob_hotplug_event() -> DP driver
>>>>
>>>> Are you concerned that the IRQ_HPD event is not being handled
>>>> somewhere along the path? Is it that the Type-C mux callback didn't
>>>> notify the PHY, or that after the PHY passed the event to the DP
>>>> driver via the OOB event, the DP driver didn't handle it?
>>> The IRQ_HPD is an event coming from DPRX, it is delivered as a part of
>>> the attention VDM, see DP_STATUS_IRQ_HPD. It's being handled by the
>>> altmode displayport.c driver and is then delivered as an OOB hotplug
>>> call. However, it's not a mux event, so it is not (and it should not)
>>> being broadcasted over the typec_mux devices.
>>>
>>> The way we were handling that is by having a chain of drm_aux_bridges
>>> for all interim devices, ending up with a drm_dp_hpd_bridge registered
>>> by the TCPM. This way when the DPRX triggers the IRQ_HPD event, it is
>>> being handled by the displayport.c and then delivered through that
>>> bridge to the DP driver.
>> I think the issue goes back to the beginning. The key is to reuse the logic
>> in displayport.c, and the previous approach of directly setting the fwnode
>> has already been rejected. Is it a good idea to register the aux hpd bridge
>> in displayport.c? In this way, we don't need to register it with a bunch of
>> PD drivers (such as fusb302), which seems like a more generic solution.
> displayport.c comes into play only when you actually attach a DP dongle,
> which is too late for bringing up the display pipeline. But your point
> is valid, it might be worth moving drm_dp_hpd registration to
> typec_port_register_altmode().

Very insightful, thank you! I will try to do this in v4 :)




From cristian.ciocaltea at collabora.com  Tue Aug  5 04:56:43 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 05 Aug 2025 14:56:43 +0300
Subject: [PATCH v2 01/14] phy: hdmi: Add HDMI 2.1 FRL configuration options
In-Reply-To: <20250805-phy-hdptx-frl-v2-0-d118bd4b6e0b@collabora.com>
References: <20250805-phy-hdptx-frl-v2-0-d118bd4b6e0b@collabora.com>
Message-ID: <20250805-phy-hdptx-frl-v2-1-d118bd4b6e0b@collabora.com>

Add support for configuring the Fixed Rate Link (FRL) mode for HDMI
PHYs.

For improved clarity, also rename existing HDMI mode to HDMI_TMDS.
Since this mode is currently not being used explicitly, no further
changes are needed.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 include/linux/phy/phy-hdmi.h | 14 ++++++++++++--
 include/linux/phy/phy.h      |  3 ++-
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/include/linux/phy/phy-hdmi.h b/include/linux/phy/phy-hdmi.h
index f0ec963c6e84f1b7728acafc824dff191c6b873d..0b26472d8defcc9ded142d4283e29861dc2b3746 100644
--- a/include/linux/phy/phy-hdmi.h
+++ b/include/linux/phy/phy-hdmi.h
@@ -6,16 +6,26 @@
 #ifndef __PHY_HDMI_H_
 #define __PHY_HDMI_H_
 
+#include <linux/types.h>
+
 /**
  * struct phy_configure_opts_hdmi - HDMI configuration set
- * @tmds_char_rate: HDMI TMDS Character Rate in Hertz.
  * @bpc: Bits per color channel.
+ * @tmds_char_rate: HDMI TMDS Character Rate in Hertz.
+ * @frl.rate_per_lane: HDMI FRL Rate per Lane in Gbps.
+ * @frl.lanes: HDMI FRL lanes count.
  *
  * This structure is used to represent the configuration state of a HDMI phy.
  */
 struct phy_configure_opts_hdmi {
-	unsigned long long tmds_char_rate;
 	unsigned int bpc;
+	union {
+		unsigned long long tmds_char_rate;
+		struct {
+			u8 rate_per_lane;
+			u8 lanes;
+		} frl;
+	};
 };
 
 #endif /* __PHY_HDMI_H_ */
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index 13add0c2c40721fe9ca3f0350d13c035cd25af45..04c84c1dbd6dac55fd04c54203cff4f9d939d970 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -44,7 +44,8 @@ enum phy_mode {
 	PHY_MODE_SATA,
 	PHY_MODE_LVDS,
 	PHY_MODE_DP,
-	PHY_MODE_HDMI,
+	PHY_MODE_HDMI_TMDS,
+	PHY_MODE_HDMI_FRL,
 };
 
 enum phy_media {

-- 
2.50.0



From cristian.ciocaltea at collabora.com  Tue Aug  5 04:56:42 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 05 Aug 2025 14:56:42 +0300
Subject: [PATCH v2 00/14] Add HDMI 2.1 FRL support to
 phy-rockchip-samsung-hdptx
Message-ID: <20250805-phy-hdptx-frl-v2-0-d118bd4b6e0b@collabora.com>

The Samsung HDMI/eDP Transmitter Combo PHY is capable of handling four
HDMI 2.1 Fixed Rate Link (FRL) lanes, while each lane can operate at
3Gbps, 6Gbps, 8Gbps, 10Gbps or 12Gbps.

This patchset extends the HDMI PHY configuration API to manage the FRL
mode and provides all the required HDMI driver changes to enable FRL in
addition to the already supported TMDS mode.

The series also contains a few driver fixes/improvements that are not
directly related, but are not deemed critical enough to warrant separate
submission.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
Changes in v2:
- Added a couple of new patches:
  * Fix reported clock rate in high bpc mode
  * Drop hw_rate driver data
- Applied several tweaks to the following patches:
  * Compute clk rate from PLL config
  * Switch to driver specific HDMI config
  * Add HDMI 2.1 FRL support
- Rebased series onto next-20250804
- Link to v1: https://lore.kernel.org/r/20250708-phy-hdptx-frl-v1-0-cfe096e224f4 at collabora.com

---
Cristian Ciocaltea (14):
      phy: hdmi: Add HDMI 2.1 FRL configuration options
      phy: rockchip: samsung-hdptx: Fix reported clock rate in high bpc mode
      phy: rockchip: samsung-hdptx: Reduce ROPLL loop bandwidth
      phy: rockchip: samsung-hdptx: Prevent Inter-Pair Skew from exceeding the limits
      phy: rockchip: samsung-hdptx: Use usleep_range() instead of udelay()
      phy: rockchip: samsung-hdptx: Fix coding style alignment
      phy: rockchip: samsung-hdptx: Consistently use [rk_]hdptx_[tmds_] prefixes
      phy: rockchip: samsung-hdptx: Enable lane output in common helper
      phy: rockchip: samsung-hdptx: Cleanup *_cmn_init_seq lists
      phy: rockchip: samsung-hdptx: Compute clk rate from PLL config
      phy: rockchip: samsung-hdptx: Drop hw_rate driver data
      phy: rockchip: samsung-hdptx: Switch to driver specific HDMI config
      phy: rockchip: samsung-hdptx: Extend rk_hdptx_phy_verify_hdmi_config() helper
      phy: rockchip: samsung-hdptx: Add HDMI 2.1 FRL support

 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 670 ++++++++++++++++++----
 include/linux/phy/phy-hdmi.h                      |  14 +-
 include/linux/phy/phy.h                           |   3 +-
 3 files changed, 581 insertions(+), 106 deletions(-)
---
base-commit: 5c5a10f0be967a8950a2309ea965bae54251b50e
change-id: 20250708-phy-hdptx-frl-fc3377db9f2e



From cristian.ciocaltea at collabora.com  Tue Aug  5 04:56:45 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 05 Aug 2025 14:56:45 +0300
Subject: [PATCH v2 03/14] phy: rockchip: samsung-hdptx: Reduce ROPLL loop
 bandwidth
In-Reply-To: <20250805-phy-hdptx-frl-v2-0-d118bd4b6e0b@collabora.com>
References: <20250805-phy-hdptx-frl-v2-0-d118bd4b6e0b@collabora.com>
Message-ID: <20250805-phy-hdptx-frl-v2-3-d118bd4b6e0b@collabora.com>

Due to its relatively low frequency, a noise stemming from the 24MHz PLL
reference clock may traverse the low-pass loop filter of ROPLL, which
could potentially generate some HDMI flash artifacts.

Reduce ROPLL loop bandwidth in an attempt to mitigate the problem.

Fixes: 553be2830c5f ("phy: rockchip: Add Samsung HDMI/eDP Combo PHY driver")
Co-developed-by: Algea Cao <algea.cao at rock-chips.com>
Signed-off-by: Algea Cao <algea.cao at rock-chips.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index 8adf6e84fc0b762a7a6042459601c3271572de8e..9751f7ad00f4faf7041dbf4339f633e09f97b107 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -500,9 +500,7 @@ static const struct reg_sequence rk_hdtpx_common_cmn_init_seq[] = {
 	REG_SEQ0(CMN_REG(0043), 0x00),
 	REG_SEQ0(CMN_REG(0044), 0x46),
 	REG_SEQ0(CMN_REG(0045), 0x24),
-	REG_SEQ0(CMN_REG(0046), 0xff),
 	REG_SEQ0(CMN_REG(0047), 0x00),
-	REG_SEQ0(CMN_REG(0048), 0x44),
 	REG_SEQ0(CMN_REG(0049), 0xfa),
 	REG_SEQ0(CMN_REG(004a), 0x08),
 	REG_SEQ0(CMN_REG(004b), 0x00),
@@ -575,6 +573,8 @@ static const struct reg_sequence rk_hdtpx_tmds_cmn_init_seq[] = {
 	REG_SEQ0(CMN_REG(0034), 0x00),
 	REG_SEQ0(CMN_REG(003d), 0x40),
 	REG_SEQ0(CMN_REG(0042), 0x78),
+	REG_SEQ0(CMN_REG(0046), 0xdd),
+	REG_SEQ0(CMN_REG(0048), 0x11),
 	REG_SEQ0(CMN_REG(004e), 0x34),
 	REG_SEQ0(CMN_REG(005c), 0x25),
 	REG_SEQ0(CMN_REG(005e), 0x4f),

-- 
2.50.0



From cristian.ciocaltea at collabora.com  Tue Aug  5 04:56:44 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 05 Aug 2025 14:56:44 +0300
Subject: [PATCH v2 02/14] phy: rockchip: samsung-hdptx: Fix reported clock
 rate in high bpc mode
In-Reply-To: <20250805-phy-hdptx-frl-v2-0-d118bd4b6e0b@collabora.com>
References: <20250805-phy-hdptx-frl-v2-0-d118bd4b6e0b@collabora.com>
Message-ID: <20250805-phy-hdptx-frl-v2-2-d118bd4b6e0b@collabora.com>

When making use of the clock provider functionality, the output clock
does normally match the TMDS character rate, which is what the PHY PLL
gets configured to.

However, this is only applicable for default color depth of 8 bpc.  For
higher depths, the output clock is further divided by the hardware
according to the formula:

  output_clock_rate = tmds_char_rate * 8 / bpc

Since the existence of the clock divider wasn't taken into account when
support for high bpc has been introduced, make the necessary adjustments
to report the correct clock rate.

Fixes: 9d0ec51d7c22 ("phy: rockchip: samsung-hdptx: Add high color depth management")
Reported-by: Andy Yan <andy.yan at rock-chips.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index 79db57ee90d1487b51f4ddadde870a275dd7b17b..8adf6e84fc0b762a7a6042459601c3271572de8e 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -1038,7 +1038,8 @@ static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx)
 
 	ret = rk_hdptx_post_enable_pll(hdptx);
 	if (!ret)
-		hdptx->hw_rate = hdptx->hdmi_cfg.tmds_char_rate;
+		hdptx->hw_rate = DIV_ROUND_CLOSEST_ULL(hdptx->hdmi_cfg.tmds_char_rate * 8,
+						       hdptx->hdmi_cfg.bpc);
 
 	return ret;
 }
@@ -1896,19 +1897,20 @@ static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
 	 * hence ensure rk_hdptx_phy_clk_set_rate() won't be invoked with
 	 * a different rate argument.
 	 */
-	return hdptx->hdmi_cfg.tmds_char_rate;
+	return DIV_ROUND_CLOSEST_ULL(hdptx->hdmi_cfg.tmds_char_rate * 8, hdptx->hdmi_cfg.bpc);
 }
 
 static int rk_hdptx_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate,
 				     unsigned long parent_rate)
 {
 	struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);
+	unsigned long long tmds_rate = DIV_ROUND_CLOSEST_ULL(rate * hdptx->hdmi_cfg.bpc, 8);
 
 	/* Revert any unlikely TMDS char rate change since round_rate() */
-	if (hdptx->hdmi_cfg.tmds_char_rate != rate) {
-		dev_warn(hdptx->dev, "Reverting unexpected rate change from %lu to %llu\n",
-			 rate, hdptx->hdmi_cfg.tmds_char_rate);
-		hdptx->hdmi_cfg.tmds_char_rate = rate;
+	if (hdptx->hdmi_cfg.tmds_char_rate != tmds_rate) {
+		dev_warn(hdptx->dev, "Reverting unexpected rate change from %llu to %llu\n",
+			 tmds_rate, hdptx->hdmi_cfg.tmds_char_rate);
+		hdptx->hdmi_cfg.tmds_char_rate = tmds_rate;
 	}
 
 	/*

-- 
2.50.0



From cristian.ciocaltea at collabora.com  Tue Aug  5 04:56:46 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 05 Aug 2025 14:56:46 +0300
Subject: [PATCH v2 04/14] phy: rockchip: samsung-hdptx: Prevent Inter-Pair
 Skew from exceeding the limits
In-Reply-To: <20250805-phy-hdptx-frl-v2-0-d118bd4b6e0b@collabora.com>
References: <20250805-phy-hdptx-frl-v2-0-d118bd4b6e0b@collabora.com>
Message-ID: <20250805-phy-hdptx-frl-v2-4-d118bd4b6e0b@collabora.com>

Fixup PHY deskew FIFO to prevent the phase of D2 lane going ahead of
other lanes.  It's worth noting this might only happen when dealing with
HDMI 2.0 rates.

Fixes: 553be2830c5f ("phy: rockchip: Add Samsung HDMI/eDP Combo PHY driver")
Co-developed-by: Algea Cao <algea.cao at rock-chips.com>
Signed-off-by: Algea Cao <algea.cao at rock-chips.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index 9751f7ad00f4faf7041dbf4339f633e09f97b107..5605610465bc812737f773e0f6232cb6dbdc78a4 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -668,13 +668,9 @@ static const struct reg_sequence rk_hdtpx_common_lane_init_seq[] = {
 
 static const struct reg_sequence rk_hdtpx_tmds_lane_init_seq[] = {
 	REG_SEQ0(LANE_REG(0312), 0x00),
-	REG_SEQ0(LANE_REG(031e), 0x00),
 	REG_SEQ0(LANE_REG(0412), 0x00),
-	REG_SEQ0(LANE_REG(041e), 0x00),
 	REG_SEQ0(LANE_REG(0512), 0x00),
-	REG_SEQ0(LANE_REG(051e), 0x00),
 	REG_SEQ0(LANE_REG(0612), 0x00),
-	REG_SEQ0(LANE_REG(061e), 0x08),
 	REG_SEQ0(LANE_REG(0303), 0x2f),
 	REG_SEQ0(LANE_REG(0403), 0x2f),
 	REG_SEQ0(LANE_REG(0503), 0x2f),
@@ -687,6 +683,11 @@ static const struct reg_sequence rk_hdtpx_tmds_lane_init_seq[] = {
 	REG_SEQ0(LANE_REG(0406), 0x1c),
 	REG_SEQ0(LANE_REG(0506), 0x1c),
 	REG_SEQ0(LANE_REG(0606), 0x1c),
+	/* Keep Inter-Pair Skew in the limits */
+	REG_SEQ0(LANE_REG(031e), 0x02),
+	REG_SEQ0(LANE_REG(041e), 0x02),
+	REG_SEQ0(LANE_REG(051e), 0x02),
+	REG_SEQ0(LANE_REG(061e), 0x0a),
 };
 
 static struct tx_drv_ctrl tx_drv_ctrl_rbr[4][4] = {

-- 
2.50.0



From cristian.ciocaltea at collabora.com  Tue Aug  5 04:56:47 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 05 Aug 2025 14:56:47 +0300
Subject: [PATCH v2 05/14] phy: rockchip: samsung-hdptx: Use usleep_range()
 instead of udelay()
In-Reply-To: <20250805-phy-hdptx-frl-v2-0-d118bd4b6e0b@collabora.com>
References: <20250805-phy-hdptx-frl-v2-0-d118bd4b6e0b@collabora.com>
Message-ID: <20250805-phy-hdptx-frl-v2-5-d118bd4b6e0b@collabora.com>

rk_hdptx_dp_reset() is allowed to sleep, hence replace the busy waiting
with usleep_range(), to allow other threads to run.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index 5605610465bc812737f773e0f6232cb6dbdc78a4..83ec892bd6760865fc9e361f4003c5bfbef55608 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -1075,7 +1075,7 @@ static void rk_hdptx_dp_reset(struct rk_hdptx_phy *hdptx)
 	reset_control_assert(hdptx->rsts[RST_INIT].rstc);
 
 	reset_control_assert(hdptx->rsts[RST_APB].rstc);
-	udelay(10);
+	usleep_range(10, 15);
 	reset_control_deassert(hdptx->rsts[RST_APB].rstc);
 
 	regmap_update_bits(hdptx->regmap, LANE_REG(0301),

-- 
2.50.0



From cristian.ciocaltea at collabora.com  Tue Aug  5 04:56:48 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 05 Aug 2025 14:56:48 +0300
Subject: [PATCH v2 06/14] phy: rockchip: samsung-hdptx: Fix coding style
 alignment
In-Reply-To: <20250805-phy-hdptx-frl-v2-0-d118bd4b6e0b@collabora.com>
References: <20250805-phy-hdptx-frl-v2-0-d118bd4b6e0b@collabora.com>
Message-ID: <20250805-phy-hdptx-frl-v2-6-d118bd4b6e0b@collabora.com>

Handle a bunch of reported checkpatch.pl complaints:

  CHECK: Alignment should match open parenthesis

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index 83ec892bd6760865fc9e361f4003c5bfbef55608..495427fc44b385e23da02cd21eefdb137d8b5fdb 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -1657,11 +1657,11 @@ static void rk_hdptx_phy_set_voltage(struct rk_hdptx_phy *hdptx,
 		regmap_update_bits(hdptx->regmap, LANE_REG(030a) + offset,
 				   LN_TX_JEQ_EVEN_CTRL_RBR_MASK,
 				   FIELD_PREP(LN_TX_JEQ_EVEN_CTRL_RBR_MASK,
-				   ctrl->tx_jeq_even_ctrl));
+					      ctrl->tx_jeq_even_ctrl));
 		regmap_update_bits(hdptx->regmap, LANE_REG(030c) + offset,
 				   LN_TX_JEQ_ODD_CTRL_RBR_MASK,
 				   FIELD_PREP(LN_TX_JEQ_ODD_CTRL_RBR_MASK,
-				   ctrl->tx_jeq_odd_ctrl));
+					      ctrl->tx_jeq_odd_ctrl));
 		regmap_update_bits(hdptx->regmap, LANE_REG(0311) + offset,
 				   LN_TX_SER_40BIT_EN_RBR_MASK,
 				   FIELD_PREP(LN_TX_SER_40BIT_EN_RBR_MASK, 0x1));
@@ -1671,11 +1671,11 @@ static void rk_hdptx_phy_set_voltage(struct rk_hdptx_phy *hdptx,
 		regmap_update_bits(hdptx->regmap, LANE_REG(030b) + offset,
 				   LN_TX_JEQ_EVEN_CTRL_HBR_MASK,
 				   FIELD_PREP(LN_TX_JEQ_EVEN_CTRL_HBR_MASK,
-				   ctrl->tx_jeq_even_ctrl));
+					      ctrl->tx_jeq_even_ctrl));
 		regmap_update_bits(hdptx->regmap, LANE_REG(030d) + offset,
 				   LN_TX_JEQ_ODD_CTRL_HBR_MASK,
 				   FIELD_PREP(LN_TX_JEQ_ODD_CTRL_HBR_MASK,
-				   ctrl->tx_jeq_odd_ctrl));
+					      ctrl->tx_jeq_odd_ctrl));
 		regmap_update_bits(hdptx->regmap, LANE_REG(0311) + offset,
 				   LN_TX_SER_40BIT_EN_HBR_MASK,
 				   FIELD_PREP(LN_TX_SER_40BIT_EN_HBR_MASK, 0x1));
@@ -1686,11 +1686,11 @@ static void rk_hdptx_phy_set_voltage(struct rk_hdptx_phy *hdptx,
 		regmap_update_bits(hdptx->regmap, LANE_REG(030b) + offset,
 				   LN_TX_JEQ_EVEN_CTRL_HBR2_MASK,
 				   FIELD_PREP(LN_TX_JEQ_EVEN_CTRL_HBR2_MASK,
-				   ctrl->tx_jeq_even_ctrl));
+					      ctrl->tx_jeq_even_ctrl));
 		regmap_update_bits(hdptx->regmap, LANE_REG(030d) + offset,
 				   LN_TX_JEQ_ODD_CTRL_HBR2_MASK,
 				   FIELD_PREP(LN_TX_JEQ_ODD_CTRL_HBR2_MASK,
-				   ctrl->tx_jeq_odd_ctrl));
+					      ctrl->tx_jeq_odd_ctrl));
 		regmap_update_bits(hdptx->regmap, LANE_REG(0311) + offset,
 				   LN_TX_SER_40BIT_EN_HBR2_MASK,
 				   FIELD_PREP(LN_TX_SER_40BIT_EN_HBR2_MASK, 0x1));

-- 
2.50.0



From cristian.ciocaltea at collabora.com  Tue Aug  5 04:56:49 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 05 Aug 2025 14:56:49 +0300
Subject: [PATCH v2 07/14] phy: rockchip: samsung-hdptx: Consistently use
 [rk_]hdptx_[tmds_] prefixes
In-Reply-To: <20250805-phy-hdptx-frl-v2-0-d118bd4b6e0b@collabora.com>
References: <20250805-phy-hdptx-frl-v2-0-d118bd4b6e0b@collabora.com>
Message-ID: <20250805-phy-hdptx-frl-v2-7-d118bd4b6e0b@collabora.com>

Fix the naming inconsistencies for some of the functions and global
variables:

* Add the missing 'rk_hdptx_' prefix to ropll_tmds_cfg variable
* Replace '_ropll_tmds_' with '_tmds_ropll_' globally
* Replace 'hdtpx' with 'hdptx' globally

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 62 +++++++++++------------
 1 file changed, 31 insertions(+), 31 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index 495427fc44b385e23da02cd21eefdb137d8b5fdb..f2202b1195e7f24c455acdfa9bf2482ddddd6866 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -32,17 +32,17 @@
 #define HDPTX_O_PHY_RDY			BIT(1)
 #define HDPTX_O_SB_RDY			BIT(0)
 
-#define HDTPX_REG(_n, _min, _max)				\
+#define HDPTX_REG(_n, _min, _max)				\
 	(							\
 		BUILD_BUG_ON_ZERO((0x##_n) < (0x##_min)) +	\
 		BUILD_BUG_ON_ZERO((0x##_n) > (0x##_max)) +	\
 		((0x##_n) * 4)					\
 	)
 
-#define CMN_REG(n)			HDTPX_REG(n, 0000, 00a7)
-#define SB_REG(n)			HDTPX_REG(n, 0100, 0129)
-#define LNTOP_REG(n)			HDTPX_REG(n, 0200, 0229)
-#define LANE_REG(n)			HDTPX_REG(n, 0300, 062d)
+#define CMN_REG(n)			HDPTX_REG(n, 0000, 00a7)
+#define SB_REG(n)			HDPTX_REG(n, 0100, 0129)
+#define LNTOP_REG(n)			HDPTX_REG(n, 0200, 0229)
+#define LANE_REG(n)			HDPTX_REG(n, 0300, 062d)
 
 /* CMN_REG(0008) */
 #define OVRD_LCPLL_EN_MASK		BIT(7)
@@ -411,7 +411,7 @@ struct rk_hdptx_phy {
 	unsigned int lanes;
 };
 
-static const struct ropll_config ropll_tmds_cfg[] = {
+static const struct ropll_config rk_hdptx_tmds_ropll_cfg[] = {
 	{ 594000000ULL, 124, 124, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
 	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
 	{ 371250000ULL, 155, 155, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
@@ -456,7 +456,7 @@ static const struct ropll_config ropll_tmds_cfg[] = {
 	  1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
 };
 
-static const struct reg_sequence rk_hdtpx_common_cmn_init_seq[] = {
+static const struct reg_sequence rk_hdptx_common_cmn_init_seq[] = {
 	REG_SEQ0(CMN_REG(0009), 0x0c),
 	REG_SEQ0(CMN_REG(000a), 0x83),
 	REG_SEQ0(CMN_REG(000b), 0x06),
@@ -546,7 +546,7 @@ static const struct reg_sequence rk_hdtpx_common_cmn_init_seq[] = {
 	REG_SEQ0(CMN_REG(009b), 0x10),
 };
 
-static const struct reg_sequence rk_hdtpx_tmds_cmn_init_seq[] = {
+static const struct reg_sequence rk_hdptx_tmds_cmn_init_seq[] = {
 	REG_SEQ0(CMN_REG(0008), 0x00),
 	REG_SEQ0(CMN_REG(0011), 0x01),
 	REG_SEQ0(CMN_REG(0017), 0x20),
@@ -588,14 +588,14 @@ static const struct reg_sequence rk_hdtpx_tmds_cmn_init_seq[] = {
 	REG_SEQ0(CMN_REG(009b), 0x00),
 };
 
-static const struct reg_sequence rk_hdtpx_common_sb_init_seq[] = {
+static const struct reg_sequence rk_hdptx_common_sb_init_seq[] = {
 	REG_SEQ0(SB_REG(0114), 0x00),
 	REG_SEQ0(SB_REG(0115), 0x00),
 	REG_SEQ0(SB_REG(0116), 0x00),
 	REG_SEQ0(SB_REG(0117), 0x00),
 };
 
-static const struct reg_sequence rk_hdtpx_tmds_lntop_highbr_seq[] = {
+static const struct reg_sequence rk_hdptx_tmds_lntop_highbr_seq[] = {
 	REG_SEQ0(LNTOP_REG(0201), 0x00),
 	REG_SEQ0(LNTOP_REG(0202), 0x00),
 	REG_SEQ0(LNTOP_REG(0203), 0x0f),
@@ -603,7 +603,7 @@ static const struct reg_sequence rk_hdtpx_tmds_lntop_highbr_seq[] = {
 	REG_SEQ0(LNTOP_REG(0205), 0xff),
 };
 
-static const struct reg_sequence rk_hdtpx_tmds_lntop_lowbr_seq[] = {
+static const struct reg_sequence rk_hdptx_tmds_lntop_lowbr_seq[] = {
 	REG_SEQ0(LNTOP_REG(0201), 0x07),
 	REG_SEQ0(LNTOP_REG(0202), 0xc1),
 	REG_SEQ0(LNTOP_REG(0203), 0xf0),
@@ -611,7 +611,7 @@ static const struct reg_sequence rk_hdtpx_tmds_lntop_lowbr_seq[] = {
 	REG_SEQ0(LNTOP_REG(0205), 0x1f),
 };
 
-static const struct reg_sequence rk_hdtpx_common_lane_init_seq[] = {
+static const struct reg_sequence rk_hdptx_common_lane_init_seq[] = {
 	REG_SEQ0(LANE_REG(0303), 0x0c),
 	REG_SEQ0(LANE_REG(0307), 0x20),
 	REG_SEQ0(LANE_REG(030a), 0x17),
@@ -666,7 +666,7 @@ static const struct reg_sequence rk_hdtpx_common_lane_init_seq[] = {
 	REG_SEQ0(LANE_REG(0620), 0xa0),
 };
 
-static const struct reg_sequence rk_hdtpx_tmds_lane_init_seq[] = {
+static const struct reg_sequence rk_hdptx_tmds_lane_init_seq[] = {
 	REG_SEQ0(LANE_REG(0312), 0x00),
 	REG_SEQ0(LANE_REG(0412), 0x00),
 	REG_SEQ0(LANE_REG(0512), 0x00),
@@ -971,7 +971,7 @@ static bool rk_hdptx_phy_clk_pll_calc(unsigned long long rate,
 	return true;
 }
 
-static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx)
+static int rk_hdptx_tmds_ropll_cmn_config(struct rk_hdptx_phy *hdptx)
 {
 	const struct ropll_config *cfg = NULL;
 	struct ropll_config rc = {0};
@@ -980,9 +980,9 @@ static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx)
 	if (!hdptx->hdmi_cfg.tmds_char_rate)
 		return 0;
 
-	for (i = 0; i < ARRAY_SIZE(ropll_tmds_cfg); i++)
-		if (hdptx->hdmi_cfg.tmds_char_rate == ropll_tmds_cfg[i].rate) {
-			cfg = &ropll_tmds_cfg[i];
+	for (i = 0; i < ARRAY_SIZE(rk_hdptx_tmds_ropll_cfg); i++)
+		if (hdptx->hdmi_cfg.tmds_char_rate == rk_hdptx_tmds_ropll_cfg[i].rate) {
+			cfg = &rk_hdptx_tmds_ropll_cfg[i];
 			break;
 		}
 
@@ -1002,8 +1002,8 @@ static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx)
 
 	rk_hdptx_pre_power_up(hdptx);
 
-	rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_cmn_init_seq);
-	rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_cmn_init_seq);
+	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_cmn_init_seq);
+	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_tmds_cmn_init_seq);
 
 	regmap_write(hdptx->regmap, CMN_REG(0051), cfg->pms_mdiv);
 	regmap_write(hdptx->regmap, CMN_REG(0055), cfg->pms_mdiv_afc);
@@ -1045,25 +1045,25 @@ static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx)
 	return ret;
 }
 
-static int rk_hdptx_ropll_tmds_mode_config(struct rk_hdptx_phy *hdptx)
+static int rk_hdptx_tmds_ropll_mode_config(struct rk_hdptx_phy *hdptx)
 {
-	rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_sb_init_seq);
+	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_sb_init_seq);
 
 	regmap_write(hdptx->regmap, LNTOP_REG(0200), 0x06);
 
 	if (hdptx->hdmi_cfg.tmds_char_rate > HDMI14_MAX_RATE) {
 		/* For 1/40 bitrate clk */
-		rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lntop_highbr_seq);
+		rk_hdptx_multi_reg_write(hdptx, rk_hdptx_tmds_lntop_highbr_seq);
 	} else {
 		/* For 1/10 bitrate clk */
-		rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lntop_lowbr_seq);
+		rk_hdptx_multi_reg_write(hdptx, rk_hdptx_tmds_lntop_lowbr_seq);
 	}
 
 	regmap_write(hdptx->regmap, LNTOP_REG(0206), 0x07);
 	regmap_write(hdptx->regmap, LNTOP_REG(0207), 0x0f);
 
-	rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_lane_init_seq);
-	rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lane_init_seq);
+	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_lane_init_seq);
+	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_tmds_lane_init_seq);
 
 	return rk_hdptx_post_enable_lane(hdptx);
 }
@@ -1122,7 +1122,7 @@ static int rk_hdptx_phy_consumer_get(struct rk_hdptx_phy *hdptx)
 	if (mode == PHY_MODE_DP) {
 		rk_hdptx_dp_reset(hdptx);
 	} else {
-		ret = rk_hdptx_ropll_tmds_cmn_config(hdptx);
+		ret = rk_hdptx_tmds_ropll_cmn_config(hdptx);
 		if (ret)
 			goto dec_usage;
 	}
@@ -1469,7 +1469,7 @@ static int rk_hdptx_phy_power_on(struct phy *phy)
 		regmap_write(hdptx->grf, GRF_HDPTX_CON0,
 			     HDPTX_MODE_SEL << 16 | FIELD_PREP(HDPTX_MODE_SEL, 0x0));
 
-		ret = rk_hdptx_ropll_tmds_mode_config(hdptx);
+		ret = rk_hdptx_tmds_ropll_mode_config(hdptx);
 		if (ret)
 			rk_hdptx_phy_consumer_put(hdptx, true);
 	}
@@ -1492,11 +1492,11 @@ static int rk_hdptx_phy_verify_hdmi_config(struct rk_hdptx_phy *hdptx,
 	if (!hdmi->tmds_char_rate || hdmi->tmds_char_rate > HDMI20_MAX_RATE)
 		return -EINVAL;
 
-	for (i = 0; i < ARRAY_SIZE(ropll_tmds_cfg); i++)
-		if (hdmi->tmds_char_rate == ropll_tmds_cfg[i].rate)
+	for (i = 0; i < ARRAY_SIZE(rk_hdptx_tmds_ropll_cfg); i++)
+		if (hdmi->tmds_char_rate == rk_hdptx_tmds_ropll_cfg[i].rate)
 			break;
 
-	if (i == ARRAY_SIZE(ropll_tmds_cfg) &&
+	if (i == ARRAY_SIZE(rk_hdptx_tmds_ropll_cfg) &&
 	    !rk_hdptx_phy_clk_pll_calc(hdmi->tmds_char_rate, NULL))
 		return -EINVAL;
 
@@ -1921,7 +1921,7 @@ static int rk_hdptx_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate,
 	 * while the latter being executed only once, i.e. when clock remains
 	 * in the prepared state during rate changes.
 	 */
-	return rk_hdptx_ropll_tmds_cmn_config(hdptx);
+	return rk_hdptx_tmds_ropll_cmn_config(hdptx);
 }
 
 static const struct clk_ops hdptx_phy_clk_ops = {

-- 
2.50.0



From cristian.ciocaltea at collabora.com  Tue Aug  5 04:56:50 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 05 Aug 2025 14:56:50 +0300
Subject: [PATCH v2 08/14] phy: rockchip: samsung-hdptx: Enable lane output
 in common helper
In-Reply-To: <20250805-phy-hdptx-frl-v2-0-d118bd4b6e0b@collabora.com>
References: <20250805-phy-hdptx-frl-v2-0-d118bd4b6e0b@collabora.com>
Message-ID: <20250805-phy-hdptx-frl-v2-8-d118bd4b6e0b@collabora.com>

In preparation to support FRL mode, move the PHY lane output enablement
from the TMDS specific configuration to the common *_post_enable_lane()
helper and make sure it gets turned off in *_phy_disable().

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index f2202b1195e7f24c455acdfa9bf2482ddddd6866..3bb4ce993088b4a6c17a40ecb235ce98dc0eb9da 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -830,6 +830,8 @@ static int rk_hdptx_post_enable_lane(struct rk_hdptx_phy *hdptx)
 	       HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN;
 	regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);
 
+	regmap_write(hdptx->regmap, LNTOP_REG(0207), 0x0f);
+
 	ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS, val,
 				       (val & HDPTX_O_PHY_RDY) &&
 				       (val & HDPTX_O_PLL_LOCK_DONE),
@@ -883,6 +885,7 @@ static void rk_hdptx_phy_disable(struct rk_hdptx_phy *hdptx)
 	usleep_range(20, 30);
 	reset_control_deassert(hdptx->rsts[RST_APB].rstc);
 
+	regmap_write(hdptx->regmap, LNTOP_REG(0207), 0x0);
 	regmap_write(hdptx->regmap, LANE_REG(0300), 0x82);
 	regmap_write(hdptx->regmap, SB_REG(010f), 0xc1);
 	regmap_write(hdptx->regmap, SB_REG(0110), 0x1);
@@ -1060,7 +1063,6 @@ static int rk_hdptx_tmds_ropll_mode_config(struct rk_hdptx_phy *hdptx)
 	}
 
 	regmap_write(hdptx->regmap, LNTOP_REG(0206), 0x07);
-	regmap_write(hdptx->regmap, LNTOP_REG(0207), 0x0f);
 
 	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_lane_init_seq);
 	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_tmds_lane_init_seq);

-- 
2.50.0



From cristian.ciocaltea at collabora.com  Tue Aug  5 04:56:51 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 05 Aug 2025 14:56:51 +0300
Subject: [PATCH v2 09/14] phy: rockchip: samsung-hdptx: Cleanup
 *_cmn_init_seq lists
In-Reply-To: <20250805-phy-hdptx-frl-v2-0-d118bd4b6e0b@collabora.com>
References: <20250805-phy-hdptx-frl-v2-0-d118bd4b6e0b@collabora.com>
Message-ID: <20250805-phy-hdptx-frl-v2-9-d118bd4b6e0b@collabora.com>

Drop redundant reg_sequence entries from rk_hdptx_common_cmn_init_seq[],
i.e. those that are either duplicated or overridden in
rk_hdptx_tmds_cmn_init_seq[].

Additionally, a few items do not really belong to the former, hence move
them to the latter.  That's mostly a preparatory step for adding FRL
support.

No functional changes intended at this point.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 22 ++++------------------
 1 file changed, 4 insertions(+), 18 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index 3bb4ce993088b4a6c17a40ecb235ce98dc0eb9da..699b86732b8d7d77b3f9ec3a7a8c801392b796f6 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -465,13 +465,11 @@ static const struct reg_sequence rk_hdptx_common_cmn_init_seq[] = {
 	REG_SEQ0(CMN_REG(000e), 0x0f),
 	REG_SEQ0(CMN_REG(000f), 0x0f),
 	REG_SEQ0(CMN_REG(0010), 0x04),
-	REG_SEQ0(CMN_REG(0011), 0x00),
 	REG_SEQ0(CMN_REG(0012), 0x26),
 	REG_SEQ0(CMN_REG(0013), 0x22),
 	REG_SEQ0(CMN_REG(0014), 0x24),
 	REG_SEQ0(CMN_REG(0015), 0x77),
 	REG_SEQ0(CMN_REG(0016), 0x08),
-	REG_SEQ0(CMN_REG(0017), 0x00),
 	REG_SEQ0(CMN_REG(0018), 0x04),
 	REG_SEQ0(CMN_REG(0019), 0x48),
 	REG_SEQ0(CMN_REG(001a), 0x01),
@@ -479,13 +477,7 @@ static const struct reg_sequence rk_hdptx_common_cmn_init_seq[] = {
 	REG_SEQ0(CMN_REG(001c), 0x01),
 	REG_SEQ0(CMN_REG(001d), 0x64),
 	REG_SEQ0(CMN_REG(001f), 0x00),
-	REG_SEQ0(CMN_REG(0026), 0x53),
 	REG_SEQ0(CMN_REG(0029), 0x01),
-	REG_SEQ0(CMN_REG(0030), 0x00),
-	REG_SEQ0(CMN_REG(0031), 0x20),
-	REG_SEQ0(CMN_REG(0032), 0x30),
-	REG_SEQ0(CMN_REG(0033), 0x0b),
-	REG_SEQ0(CMN_REG(0034), 0x23),
 	REG_SEQ0(CMN_REG(0035), 0x00),
 	REG_SEQ0(CMN_REG(0038), 0x00),
 	REG_SEQ0(CMN_REG(0039), 0x00),
@@ -496,7 +488,6 @@ static const struct reg_sequence rk_hdptx_common_cmn_init_seq[] = {
 	REG_SEQ0(CMN_REG(003f), 0x83),
 	REG_SEQ0(CMN_REG(0040), 0x06),
 	REG_SEQ0(CMN_REG(0041), 0x20),
-	REG_SEQ0(CMN_REG(0042), 0xb8),
 	REG_SEQ0(CMN_REG(0043), 0x00),
 	REG_SEQ0(CMN_REG(0044), 0x46),
 	REG_SEQ0(CMN_REG(0045), 0x24),
@@ -506,14 +497,9 @@ static const struct reg_sequence rk_hdptx_common_cmn_init_seq[] = {
 	REG_SEQ0(CMN_REG(004b), 0x00),
 	REG_SEQ0(CMN_REG(004c), 0x01),
 	REG_SEQ0(CMN_REG(004d), 0x64),
-	REG_SEQ0(CMN_REG(004e), 0x14),
 	REG_SEQ0(CMN_REG(004f), 0x00),
 	REG_SEQ0(CMN_REG(0050), 0x00),
-	REG_SEQ0(CMN_REG(005d), 0x0c),
 	REG_SEQ0(CMN_REG(005f), 0x01),
-	REG_SEQ0(CMN_REG(006b), 0x04),
-	REG_SEQ0(CMN_REG(0073), 0x30),
-	REG_SEQ0(CMN_REG(0074), 0x00),
 	REG_SEQ0(CMN_REG(0075), 0x20),
 	REG_SEQ0(CMN_REG(0076), 0x30),
 	REG_SEQ0(CMN_REG(0077), 0x08),
@@ -525,13 +511,10 @@ static const struct reg_sequence rk_hdptx_common_cmn_init_seq[] = {
 	REG_SEQ0(CMN_REG(007e), 0x00),
 	REG_SEQ0(CMN_REG(007f), 0x00),
 	REG_SEQ0(CMN_REG(0080), 0x00),
-	REG_SEQ0(CMN_REG(0081), 0x09),
 	REG_SEQ0(CMN_REG(0082), 0x04),
 	REG_SEQ0(CMN_REG(0083), 0x24),
 	REG_SEQ0(CMN_REG(0084), 0x20),
 	REG_SEQ0(CMN_REG(0085), 0x03),
-	REG_SEQ0(CMN_REG(0086), 0x01),
-	REG_SEQ0(CMN_REG(0087), 0x0c),
 	REG_SEQ0(CMN_REG(008a), 0x55),
 	REG_SEQ0(CMN_REG(008b), 0x25),
 	REG_SEQ0(CMN_REG(008c), 0x2c),
@@ -543,7 +526,6 @@ static const struct reg_sequence rk_hdptx_common_cmn_init_seq[] = {
 	REG_SEQ0(CMN_REG(0092), 0x00),
 	REG_SEQ0(CMN_REG(0093), 0x00),
 	REG_SEQ0(CMN_REG(009a), 0x11),
-	REG_SEQ0(CMN_REG(009b), 0x10),
 };
 
 static const struct reg_sequence rk_hdptx_tmds_cmn_init_seq[] = {
@@ -577,9 +559,13 @@ static const struct reg_sequence rk_hdptx_tmds_cmn_init_seq[] = {
 	REG_SEQ0(CMN_REG(0048), 0x11),
 	REG_SEQ0(CMN_REG(004e), 0x34),
 	REG_SEQ0(CMN_REG(005c), 0x25),
+	REG_SEQ0(CMN_REG(005d), 0x0c),
 	REG_SEQ0(CMN_REG(005e), 0x4f),
+	REG_SEQ0(CMN_REG(006b), 0x04),
+	REG_SEQ0(CMN_REG(0073), 0x30),
 	REG_SEQ0(CMN_REG(0074), 0x04),
 	REG_SEQ0(CMN_REG(0081), 0x01),
+	REG_SEQ0(CMN_REG(0086), 0x01),
 	REG_SEQ0(CMN_REG(0087), 0x04),
 	REG_SEQ0(CMN_REG(0089), 0x00),
 	REG_SEQ0(CMN_REG(0095), 0x00),

-- 
2.50.0



From cristian.ciocaltea at collabora.com  Tue Aug  5 04:56:52 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 05 Aug 2025 14:56:52 +0300
Subject: [PATCH v2 10/14] phy: rockchip: samsung-hdptx: Compute clk rate
 from PLL config
In-Reply-To: <20250805-phy-hdptx-frl-v2-0-d118bd4b6e0b@collabora.com>
References: <20250805-phy-hdptx-frl-v2-0-d118bd4b6e0b@collabora.com>
Message-ID: <20250805-phy-hdptx-frl-v2-10-d118bd4b6e0b@collabora.com>

Improve ->recalc_rate() callback of hdptx_phy_clk_ops to calculate the
initial clock rate based on the actual PHY PLL configuration as
retrieved from the related hardware registers.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 91 ++++++++++++++++++++++-
 1 file changed, 90 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index 699b86732b8d7d77b3f9ec3a7a8c801392b796f6..6e2443f78968948b84e4261e33761fe0d189553b 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -1851,12 +1851,101 @@ static void rk_hdptx_phy_clk_unprepare(struct clk_hw *hw)
 	rk_hdptx_phy_consumer_put(hdptx, true);
 }
 
+#define PLL_REF_CLK 24000000ULL
+
+static u64 rk_hdptx_phy_clk_calc_rate_from_pll_cfg(struct rk_hdptx_phy *hdptx)
+{
+	struct ropll_config ropll_hw;
+	u64 fout, sdm;
+	u32 mode, val;
+	int ret;
+
+	ret = regmap_read(hdptx->regmap, CMN_REG(0008), &mode);
+	if (ret)
+		return 0;
+
+	if (mode & LCPLL_LCVCO_MODE_EN_MASK)
+		return 0;
+
+	ret = regmap_read(hdptx->regmap, CMN_REG(0051), &val);
+	if (ret)
+		return 0;
+	ropll_hw.pms_mdiv = val;
+
+	ret = regmap_read(hdptx->regmap, CMN_REG(005E), &val);
+	if (ret)
+		return 0;
+	ropll_hw.sdm_en = val & ROPLL_SDM_EN_MASK;
+
+	ret = regmap_read(hdptx->regmap, CMN_REG(0064), &val);
+	if (ret)
+		return 0;
+	ropll_hw.sdm_num_sign = val & ROPLL_SDM_NUM_SIGN_RBR_MASK;
+
+	ret = regmap_read(hdptx->regmap, CMN_REG(0065), &val);
+	if (ret)
+		return 0;
+	ropll_hw.sdm_num = val;
+
+	ret = regmap_read(hdptx->regmap, CMN_REG(0060), &val);
+	if (ret)
+		return 0;
+	ropll_hw.sdm_deno = val;
+
+	ret = regmap_read(hdptx->regmap, CMN_REG(0069), &val);
+	if (ret)
+		return 0;
+	ropll_hw.sdc_n = (val & ROPLL_SDC_N_RBR_MASK) + 3;
+
+	ret = regmap_read(hdptx->regmap, CMN_REG(006c), &val);
+	if (ret)
+		return 0;
+	ropll_hw.sdc_num = val;
+
+	ret = regmap_read(hdptx->regmap, CMN_REG(0070), &val);
+	if (ret)
+		return 0;
+	ropll_hw.sdc_deno = val;
+
+	ret = regmap_read(hdptx->regmap, CMN_REG(0086), &val);
+	if (ret)
+		return 0;
+	ropll_hw.pms_sdiv = ((val & PLL_PCG_POSTDIV_SEL_MASK) >> 4) + 1;
+
+	fout = PLL_REF_CLK * ropll_hw.pms_mdiv;
+	if (ropll_hw.sdm_en) {
+		sdm = div_u64(PLL_REF_CLK * ropll_hw.sdc_deno *
+			      ropll_hw.pms_mdiv * ropll_hw.sdm_num,
+			      16 * ropll_hw.sdm_deno *
+			      (ropll_hw.sdc_deno * ropll_hw.sdc_n - ropll_hw.sdc_num));
+
+		if (ropll_hw.sdm_num_sign)
+			fout = fout - sdm;
+		else
+			fout = fout + sdm;
+	}
+
+	return div_u64(fout * 2, ropll_hw.pms_sdiv * 10);
+}
+
 static unsigned long rk_hdptx_phy_clk_recalc_rate(struct clk_hw *hw,
 						  unsigned long parent_rate)
 {
 	struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);
+	u32 status;
+	u64 rate;
+	int ret;
+
+	if (hdptx->hw_rate)
+		return hdptx->hw_rate;
+
+	ret = regmap_read(hdptx->grf, GRF_HDPTX_CON0, &status);
+	if (ret || !(status & HDPTX_I_PLL_EN))
+		return 0;
+
+	rate = rk_hdptx_phy_clk_calc_rate_from_pll_cfg(hdptx);
 
-	return hdptx->hw_rate;
+	return DIV_ROUND_CLOSEST_ULL(rate * 8, hdptx->hdmi_cfg.bpc);
 }
 
 static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,

-- 
2.50.0



From cristian.ciocaltea at collabora.com  Tue Aug  5 04:56:53 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 05 Aug 2025 14:56:53 +0300
Subject: [PATCH v2 11/14] phy: rockchip: samsung-hdptx: Drop hw_rate driver
 data
In-Reply-To: <20250805-phy-hdptx-frl-v2-0-d118bd4b6e0b@collabora.com>
References: <20250805-phy-hdptx-frl-v2-0-d118bd4b6e0b@collabora.com>
Message-ID: <20250805-phy-hdptx-frl-v2-11-d118bd4b6e0b@collabora.com>

The ->hw_rate member of struct rk_hdptx_phy was mainly used to keep
track of the clock rate programmed in hardware and support implementing
the ->recalc_rate() callback in hdptx_phy_clk_ops.

Computing the clock rate from the actual PHY PLL configuration seems to
work reliably, hence remove the now redundant struct member.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 13 ++-----------
 1 file changed, 2 insertions(+), 11 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index 6e2443f78968948b84e4261e33761fe0d189553b..4195387108d8786c2b7cabb6d2f3c07315fefd88 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -401,7 +401,6 @@ struct rk_hdptx_phy {
 
 	/* clk provider */
 	struct clk_hw hw;
-	unsigned long hw_rate;
 	bool restrict_rate_change;
 
 	atomic_t usage_count;
@@ -964,7 +963,7 @@ static int rk_hdptx_tmds_ropll_cmn_config(struct rk_hdptx_phy *hdptx)
 {
 	const struct ropll_config *cfg = NULL;
 	struct ropll_config rc = {0};
-	int ret, i;
+	int i;
 
 	if (!hdptx->hdmi_cfg.tmds_char_rate)
 		return 0;
@@ -1026,12 +1025,7 @@ static int rk_hdptx_tmds_ropll_cmn_config(struct rk_hdptx_phy *hdptx)
 	regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_CLK_EN_MASK,
 			   FIELD_PREP(PLL_PCG_CLK_EN_MASK, 0x1));
 
-	ret = rk_hdptx_post_enable_pll(hdptx);
-	if (!ret)
-		hdptx->hw_rate = DIV_ROUND_CLOSEST_ULL(hdptx->hdmi_cfg.tmds_char_rate * 8,
-						       hdptx->hdmi_cfg.bpc);
-
-	return ret;
+	return rk_hdptx_post_enable_pll(hdptx);
 }
 
 static int rk_hdptx_tmds_ropll_mode_config(struct rk_hdptx_phy *hdptx)
@@ -1936,9 +1930,6 @@ static unsigned long rk_hdptx_phy_clk_recalc_rate(struct clk_hw *hw,
 	u64 rate;
 	int ret;
 
-	if (hdptx->hw_rate)
-		return hdptx->hw_rate;
-
 	ret = regmap_read(hdptx->grf, GRF_HDPTX_CON0, &status);
 	if (ret || !(status & HDPTX_I_PLL_EN))
 		return 0;

-- 
2.50.0



From cristian.ciocaltea at collabora.com  Tue Aug  5 04:56:54 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 05 Aug 2025 14:56:54 +0300
Subject: [PATCH v2 12/14] phy: rockchip: samsung-hdptx: Switch to driver
 specific HDMI config
In-Reply-To: <20250805-phy-hdptx-frl-v2-0-d118bd4b6e0b@collabora.com>
References: <20250805-phy-hdptx-frl-v2-0-d118bd4b6e0b@collabora.com>
Message-ID: <20250805-phy-hdptx-frl-v2-12-d118bd4b6e0b@collabora.com>

In preparation to support the FRL operation mode which gets configured
via the lanes and rate per lane tuple, switch to a driver specific
struct for configuring the link rate and bpc.

This simplifies and optimizes the implementation by allowing implicit
switches between TMDS and FRL rates, without requiring additional checks
of the active PHY mode followed by recalculations of the link rate when
operating in FRL mode.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 44 +++++++++++++----------
 1 file changed, 25 insertions(+), 19 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index 4195387108d8786c2b7cabb6d2f3c07315fefd88..a44614bc73e9461d4d38663776f547f595169c3b 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -387,6 +387,11 @@ struct rk_hdptx_phy_cfg {
 	unsigned int phy_ids[MAX_HDPTX_PHY_NUM];
 };
 
+struct rk_hdptx_hdmi_cfg {
+	unsigned long long rate;
+	unsigned int bpc;
+};
+
 struct rk_hdptx_phy {
 	struct device *dev;
 	struct regmap *regmap;
@@ -394,7 +399,7 @@ struct rk_hdptx_phy {
 
 	int phy_id;
 	struct phy *phy;
-	struct phy_configure_opts_hdmi hdmi_cfg;
+	struct rk_hdptx_hdmi_cfg hdmi_cfg;
 	struct clk_bulk_data *clks;
 	int nr_clks;
 	struct reset_control_bulk_data rsts[RST_MAX];
@@ -965,19 +970,19 @@ static int rk_hdptx_tmds_ropll_cmn_config(struct rk_hdptx_phy *hdptx)
 	struct ropll_config rc = {0};
 	int i;
 
-	if (!hdptx->hdmi_cfg.tmds_char_rate)
+	if (!hdptx->hdmi_cfg.rate)
 		return 0;
 
 	for (i = 0; i < ARRAY_SIZE(rk_hdptx_tmds_ropll_cfg); i++)
-		if (hdptx->hdmi_cfg.tmds_char_rate == rk_hdptx_tmds_ropll_cfg[i].rate) {
+		if (hdptx->hdmi_cfg.rate == rk_hdptx_tmds_ropll_cfg[i].rate) {
 			cfg = &rk_hdptx_tmds_ropll_cfg[i];
 			break;
 		}
 
 	if (!cfg) {
-		if (!rk_hdptx_phy_clk_pll_calc(hdptx->hdmi_cfg.tmds_char_rate, &rc)) {
+		if (!rk_hdptx_phy_clk_pll_calc(hdptx->hdmi_cfg.rate, &rc)) {
 			dev_err(hdptx->dev, "%s cannot find pll cfg for rate=%llu\n",
-				__func__, hdptx->hdmi_cfg.tmds_char_rate);
+				__func__, hdptx->hdmi_cfg.rate);
 			return -EINVAL;
 		}
 
@@ -985,7 +990,7 @@ static int rk_hdptx_tmds_ropll_cmn_config(struct rk_hdptx_phy *hdptx)
 	}
 
 	dev_dbg(hdptx->dev, "%s rate=%llu mdiv=%u sdiv=%u sdm_en=%u k_sign=%u k=%u lc=%u\n",
-		__func__, hdptx->hdmi_cfg.tmds_char_rate, cfg->pms_mdiv, cfg->pms_sdiv + 1,
+		__func__, hdptx->hdmi_cfg.rate, cfg->pms_mdiv, cfg->pms_sdiv + 1,
 		cfg->sdm_en, cfg->sdm_num_sign, cfg->sdm_num, cfg->sdm_deno);
 
 	rk_hdptx_pre_power_up(hdptx);
@@ -1034,7 +1039,7 @@ static int rk_hdptx_tmds_ropll_mode_config(struct rk_hdptx_phy *hdptx)
 
 	regmap_write(hdptx->regmap, LNTOP_REG(0200), 0x06);
 
-	if (hdptx->hdmi_cfg.tmds_char_rate > HDMI14_MAX_RATE) {
+	if (hdptx->hdmi_cfg.rate > HDMI14_MAX_RATE) {
 		/* For 1/40 bitrate clk */
 		rk_hdptx_multi_reg_write(hdptx, rk_hdptx_tmds_lntop_highbr_seq);
 	} else {
@@ -1405,19 +1410,19 @@ static int rk_hdptx_phy_power_on(struct phy *phy)
 	int ret, lane;
 
 	if (mode != PHY_MODE_DP) {
-		if (!hdptx->hdmi_cfg.tmds_char_rate) {
+		if (!hdptx->hdmi_cfg.rate) {
 			/*
 			 * FIXME: Temporary workaround to setup TMDS char rate
 			 * from the RK DW HDMI QP bridge driver.
 			 * Will be removed as soon the switch to the HDMI PHY
 			 * configuration API has been completed on both ends.
 			 */
-			hdptx->hdmi_cfg.tmds_char_rate = phy_get_bus_width(hdptx->phy) & 0xfffffff;
-			hdptx->hdmi_cfg.tmds_char_rate *= 100;
+			hdptx->hdmi_cfg.rate = phy_get_bus_width(hdptx->phy) & 0xfffffff;
+			hdptx->hdmi_cfg.rate *= 100;
 		}
 
 		dev_dbg(hdptx->dev, "%s rate=%llu bpc=%u\n", __func__,
-			hdptx->hdmi_cfg.tmds_char_rate, hdptx->hdmi_cfg.bpc);
+			hdptx->hdmi_cfg.rate, hdptx->hdmi_cfg.bpc);
 	}
 
 	ret = rk_hdptx_phy_consumer_get(hdptx);
@@ -1764,12 +1769,13 @@ static int rk_hdptx_phy_configure(struct phy *phy, union phy_configure_opts *opt
 		if (ret) {
 			dev_err(hdptx->dev, "invalid hdmi params for phy configure\n");
 		} else {
-			hdptx->hdmi_cfg = opts->hdmi;
+			hdptx->hdmi_cfg.rate = opts->hdmi.tmds_char_rate;
+			hdptx->hdmi_cfg.bpc = opts->hdmi.bpc;
 			hdptx->restrict_rate_change = true;
 		}
 
 		dev_dbg(hdptx->dev, "%s rate=%llu bpc=%u\n", __func__,
-			hdptx->hdmi_cfg.tmds_char_rate, hdptx->hdmi_cfg.bpc);
+			hdptx->hdmi_cfg.rate, hdptx->hdmi_cfg.bpc);
 		return ret;
 	}
 
@@ -1949,7 +1955,7 @@ static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
 	 * To be dropped as soon as the RK DW HDMI QP bridge driver
 	 * switches to make use of phy_configure().
 	 */
-	if (!hdptx->restrict_rate_change && rate != hdptx->hdmi_cfg.tmds_char_rate) {
+	if (!hdptx->restrict_rate_change && rate != hdptx->hdmi_cfg.rate) {
 		struct phy_configure_opts_hdmi hdmi = {
 			.tmds_char_rate = rate,
 		};
@@ -1958,7 +1964,7 @@ static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
 		if (ret)
 			return ret;
 
-		hdptx->hdmi_cfg = hdmi;
+		hdptx->hdmi_cfg.rate = rate;
 	}
 
 	/*
@@ -1966,7 +1972,7 @@ static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
 	 * hence ensure rk_hdptx_phy_clk_set_rate() won't be invoked with
 	 * a different rate argument.
 	 */
-	return DIV_ROUND_CLOSEST_ULL(hdptx->hdmi_cfg.tmds_char_rate * 8, hdptx->hdmi_cfg.bpc);
+	return DIV_ROUND_CLOSEST_ULL(hdptx->hdmi_cfg.rate * 8, hdptx->hdmi_cfg.bpc);
 }
 
 static int rk_hdptx_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -1976,10 +1982,10 @@ static int rk_hdptx_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate,
 	unsigned long long tmds_rate = DIV_ROUND_CLOSEST_ULL(rate * hdptx->hdmi_cfg.bpc, 8);
 
 	/* Revert any unlikely TMDS char rate change since round_rate() */
-	if (hdptx->hdmi_cfg.tmds_char_rate != tmds_rate) {
+	if (hdptx->hdmi_cfg.rate != tmds_rate) {
 		dev_warn(hdptx->dev, "Reverting unexpected rate change from %llu to %llu\n",
-			 tmds_rate, hdptx->hdmi_cfg.tmds_char_rate);
-		hdptx->hdmi_cfg.tmds_char_rate = tmds_rate;
+			 tmds_rate, hdptx->hdmi_cfg.rate);
+		hdptx->hdmi_cfg.rate = tmds_rate;
 	}
 
 	/*

-- 
2.50.0



From cristian.ciocaltea at collabora.com  Tue Aug  5 04:56:55 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 05 Aug 2025 14:56:55 +0300
Subject: [PATCH v2 13/14] phy: rockchip: samsung-hdptx: Extend
 rk_hdptx_phy_verify_hdmi_config() helper
In-Reply-To: <20250805-phy-hdptx-frl-v2-0-d118bd4b6e0b@collabora.com>
References: <20250805-phy-hdptx-frl-v2-0-d118bd4b6e0b@collabora.com>
Message-ID: <20250805-phy-hdptx-frl-v2-13-d118bd4b6e0b@collabora.com>

In order to facilitate introduction of HDMI 2.1 FRL support and to avoid
recomputing the link rate after verifying the HDMI configuration given
as input, extend rk_hdptx_phy_verify_hdmi_config() by providing an
optional output parameter to store the validated configuration.

For improved code readability, also rename the existing hdmi input
parameter.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 35 ++++++++++++-----------
 1 file changed, 18 insertions(+), 17 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index a44614bc73e9461d4d38663776f547f595169c3b..58eac67cc3b21c17939c303bbea3fcdc5e6b0518 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -1472,25 +1472,24 @@ static int rk_hdptx_phy_power_off(struct phy *phy)
 }
 
 static int rk_hdptx_phy_verify_hdmi_config(struct rk_hdptx_phy *hdptx,
-					   struct phy_configure_opts_hdmi *hdmi)
+					   struct phy_configure_opts_hdmi *hdmi_in,
+					   struct rk_hdptx_hdmi_cfg *hdmi_out)
 {
 	int i;
 
-	if (!hdmi->tmds_char_rate || hdmi->tmds_char_rate > HDMI20_MAX_RATE)
+	if (!hdmi_in->tmds_char_rate || hdmi_in->tmds_char_rate > HDMI20_MAX_RATE)
 		return -EINVAL;
 
 	for (i = 0; i < ARRAY_SIZE(rk_hdptx_tmds_ropll_cfg); i++)
-		if (hdmi->tmds_char_rate == rk_hdptx_tmds_ropll_cfg[i].rate)
+		if (hdmi_in->tmds_char_rate == rk_hdptx_tmds_ropll_cfg[i].rate)
 			break;
 
 	if (i == ARRAY_SIZE(rk_hdptx_tmds_ropll_cfg) &&
-	    !rk_hdptx_phy_clk_pll_calc(hdmi->tmds_char_rate, NULL))
+	    !rk_hdptx_phy_clk_pll_calc(hdmi_in->tmds_char_rate, NULL))
 		return -EINVAL;
 
-	if (!hdmi->bpc)
-		hdmi->bpc = 8;
-
-	switch (hdmi->bpc) {
+	switch (hdmi_in->bpc) {
+	case 0:
 	case 8:
 	case 10:
 	case 12:
@@ -1500,6 +1499,11 @@ static int rk_hdptx_phy_verify_hdmi_config(struct rk_hdptx_phy *hdptx,
 		return -EINVAL;
 	}
 
+	if (hdmi_out) {
+		hdmi_out->rate = hdmi_in->tmds_char_rate;
+		hdmi_out->bpc = hdmi_in->bpc ?: 8;
+	}
+
 	return 0;
 }
 
@@ -1765,17 +1769,15 @@ static int rk_hdptx_phy_configure(struct phy *phy, union phy_configure_opts *opt
 	int ret;
 
 	if (mode != PHY_MODE_DP) {
-		ret = rk_hdptx_phy_verify_hdmi_config(hdptx, &opts->hdmi);
+		ret = rk_hdptx_phy_verify_hdmi_config(hdptx, &opts->hdmi, &hdptx->hdmi_cfg);
 		if (ret) {
 			dev_err(hdptx->dev, "invalid hdmi params for phy configure\n");
 		} else {
-			hdptx->hdmi_cfg.rate = opts->hdmi.tmds_char_rate;
-			hdptx->hdmi_cfg.bpc = opts->hdmi.bpc;
 			hdptx->restrict_rate_change = true;
+			dev_dbg(hdptx->dev, "%s rate=%llu bpc=%u\n", __func__,
+				hdptx->hdmi_cfg.rate, hdptx->hdmi_cfg.bpc);
 		}
 
-		dev_dbg(hdptx->dev, "%s rate=%llu bpc=%u\n", __func__,
-			hdptx->hdmi_cfg.rate, hdptx->hdmi_cfg.bpc);
 		return ret;
 	}
 
@@ -1819,7 +1821,7 @@ static int rk_hdptx_phy_validate(struct phy *phy, enum phy_mode mode,
 	struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy);
 
 	if (mode != PHY_MODE_DP)
-		return rk_hdptx_phy_verify_hdmi_config(hdptx, &opts->hdmi);
+		return rk_hdptx_phy_verify_hdmi_config(hdptx, &opts->hdmi, NULL);
 
 	return rk_hdptx_phy_verify_dp_config(hdptx, &opts->dp);
 }
@@ -1959,12 +1961,11 @@ static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
 		struct phy_configure_opts_hdmi hdmi = {
 			.tmds_char_rate = rate,
 		};
-		int ret = rk_hdptx_phy_verify_hdmi_config(hdptx, &hdmi);
+
+		int ret = rk_hdptx_phy_verify_hdmi_config(hdptx, &hdmi, &hdptx->hdmi_cfg);
 
 		if (ret)
 			return ret;
-
-		hdptx->hdmi_cfg.rate = rate;
 	}
 
 	/*

-- 
2.50.0



From cristian.ciocaltea at collabora.com  Tue Aug  5 04:56:56 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 05 Aug 2025 14:56:56 +0300
Subject: [PATCH v2 14/14] phy: rockchip: samsung-hdptx: Add HDMI 2.1 FRL
 support
In-Reply-To: <20250805-phy-hdptx-frl-v2-0-d118bd4b6e0b@collabora.com>
References: <20250805-phy-hdptx-frl-v2-0-d118bd4b6e0b@collabora.com>
Message-ID: <20250805-phy-hdptx-frl-v2-14-d118bd4b6e0b@collabora.com>

The PHY is capable of handling four HDMI 2.1 Fixed Rate Link (FRL)
lanes, and each one can operate at any of the rates of 3Gbps, 6Gbps,
8Gbps, 10Gbps or 12Gbps.

Add the necessary driver changes to support the feature.

Co-developed-by: Algea Cao <algea.cao at rock-chips.com>
Signed-off-by: Algea Cao <algea.cao at rock-chips.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 432 ++++++++++++++++++++--
 1 file changed, 409 insertions(+), 23 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index 58eac67cc3b21c17939c303bbea3fcdc5e6b0518..d63b248f173268936e88399f21479fff80dc9c11 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -22,6 +22,7 @@
 #include <linux/reset.h>
 
 #define GRF_HDPTX_CON0			0x00
+#define LC_REF_CLK_SEL			BIT(11)
 #define HDPTX_I_PLL_EN			BIT(7)
 #define HDPTX_I_BIAS_EN			BIT(6)
 #define HDPTX_I_BGR_EN			BIT(5)
@@ -322,6 +323,9 @@
 
 #define HDMI14_MAX_RATE			340000000
 #define HDMI20_MAX_RATE			600000000
+#define FRL_8G4L_RATE			3200000000
+#define FRL_6G3L_RATE			1800000000
+#define FRL_3G3L_RATE			900000000
 
 enum dp_link_rate {
 	DP_BW_RBR,
@@ -329,6 +333,37 @@ enum dp_link_rate {
 	DP_BW_HBR2,
 };
 
+struct lcpll_config {
+	unsigned long long rate;
+	u8 lcvco_mode_en;
+	u8 pi_en;
+	u8 clk_en_100m;
+	u8 pms_mdiv;
+	u8 pms_mdiv_afc;
+	u8 pms_pdiv;
+	u8 pms_refdiv;
+	u8 pms_sdiv;
+	u8 pi_cdiv_rstn;
+	u8 pi_cdiv_sel;
+	u8 sdm_en;
+	u8 sdm_rstn;
+	u8 sdc_frac_en;
+	u8 sdc_rstn;
+	u8 sdm_deno;
+	u8 sdm_num_sign;
+	u8 sdm_num;
+	u8 sdc_n;
+	u8 sdc_n2;
+	u8 sdc_num;
+	u8 sdc_deno;
+	u8 sdc_ndiv_rstn;
+	u8 ssc_en;
+	u8 ssc_fm_dev;
+	u8 ssc_fm_freq;
+	u8 ssc_clk_div_sel;
+	u8 cd_tx_ser_rate_sel;
+};
+
 struct ropll_config {
 	unsigned long long rate;
 	u8 pms_mdiv;
@@ -415,6 +450,19 @@ struct rk_hdptx_phy {
 	unsigned int lanes;
 };
 
+static const struct lcpll_config rk_hdptx_frl_lcpll_cfg[] = {
+	{ 4800000000ULL, 1, 0, 0, 0x7d, 0x7d, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 2,
+	  0, 0x13, 0x18, 1, 0, 0x20, 0x0c, 1, 0, },
+	{ 4000000000ULL, 1, 1, 0, 0x68, 0x68, 1, 1, 0, 0, 0, 1, 1, 1, 1, 9, 0, 1, 1,
+	  0, 2, 3, 1, 0, 0x20, 0x0c, 1, 0, },
+	{ 2400000000ULL, 1, 0, 0, 0x7d, 0x7d, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 2,
+	  0, 0x13, 0x18, 1, 0, 0x20, 0x0c, 1, 0, },
+	{ 1800000000ULL, 1, 0, 0, 0x7d, 0x7d, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 2,
+	  0, 0x13, 0x18, 1, 0, 0x20, 0x0c, 1, 0, },
+	{ 900000000ULL, 1, 0, 0, 0x7d, 0x7d, 1, 1, 3, 0, 0, 0, 0, 1, 1, 1, 0, 0, 2,
+	  0, 0x13, 0x18, 1, 0, 0x20, 0x0c, 1, 0, },
+};
+
 static const struct ropll_config rk_hdptx_tmds_ropll_cfg[] = {
 	{ 594000000ULL, 124, 124, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
 	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
@@ -532,6 +580,110 @@ static const struct reg_sequence rk_hdptx_common_cmn_init_seq[] = {
 	REG_SEQ0(CMN_REG(009a), 0x11),
 };
 
+static const struct reg_sequence rk_hdptx_frl_lcpll_cmn_init_seq[] = {
+	REG_SEQ0(CMN_REG(0011), 0x00),
+	REG_SEQ0(CMN_REG(0017), 0x00),
+	REG_SEQ0(CMN_REG(0025), 0x10),
+	REG_SEQ0(CMN_REG(0026), 0x53),
+	REG_SEQ0(CMN_REG(0027), 0x01),
+	REG_SEQ0(CMN_REG(0028), 0x0d),
+	REG_SEQ0(CMN_REG(002e), 0x02),
+	REG_SEQ0(CMN_REG(002f), 0x0d),
+	REG_SEQ0(CMN_REG(0030), 0x00),
+	REG_SEQ0(CMN_REG(0031), 0x20),
+	REG_SEQ0(CMN_REG(0032), 0x30),
+	REG_SEQ0(CMN_REG(0033), 0x0b),
+	REG_SEQ0(CMN_REG(0034), 0x23),
+	REG_SEQ0(CMN_REG(003d), 0x00),
+	REG_SEQ0(CMN_REG(0042), 0xb8),
+	REG_SEQ0(CMN_REG(0046), 0xff),
+	REG_SEQ0(CMN_REG(0048), 0x44),
+	REG_SEQ0(CMN_REG(004e), 0x14),
+	REG_SEQ0(CMN_REG(0051), 0x00),
+	REG_SEQ0(CMN_REG(0055), 0x00),
+	REG_SEQ0(CMN_REG(0059), 0x11),
+	REG_SEQ0(CMN_REG(005a), 0x03),
+	REG_SEQ0(CMN_REG(005c), 0x05),
+	REG_SEQ0(CMN_REG(005d), 0x0c),
+	REG_SEQ0(CMN_REG(005e), 0x07),
+	REG_SEQ0(CMN_REG(0060), 0x01),
+	REG_SEQ0(CMN_REG(0064), 0x07),
+	REG_SEQ0(CMN_REG(0065), 0x00),
+	REG_SEQ0(CMN_REG(0069), 0x00),
+	REG_SEQ0(CMN_REG(006b), 0x04),
+	REG_SEQ0(CMN_REG(006c), 0x00),
+	REG_SEQ0(CMN_REG(0070), 0x01),
+	REG_SEQ0(CMN_REG(0073), 0x30),
+	REG_SEQ0(CMN_REG(0074), 0x00),
+	REG_SEQ0(CMN_REG(0081), 0x09),
+	REG_SEQ0(CMN_REG(0086), 0x01),
+	REG_SEQ0(CMN_REG(0087), 0x0c),
+	REG_SEQ0(CMN_REG(0089), 0x02),
+	REG_SEQ0(CMN_REG(0095), 0x00),
+	REG_SEQ0(CMN_REG(0097), 0x00),
+	REG_SEQ0(CMN_REG(0099), 0x00),
+	REG_SEQ0(CMN_REG(009b), 0x10),
+};
+
+static const struct reg_sequence rk_hdptx_frl_lcpll_ropll_cmn_init_seq[] = {
+	REG_SEQ0(CMN_REG(0008), 0xd0),
+	REG_SEQ0(CMN_REG(0011), 0x00),
+	REG_SEQ0(CMN_REG(0017), 0x00),
+	REG_SEQ0(CMN_REG(001e), 0x35),
+	REG_SEQ0(CMN_REG(0020), 0x6b),
+	REG_SEQ0(CMN_REG(0021), 0x6b),
+	REG_SEQ0(CMN_REG(0022), 0x11),
+	REG_SEQ0(CMN_REG(0024), 0x00),
+	REG_SEQ0(CMN_REG(0025), 0x10),
+	REG_SEQ0(CMN_REG(0026), 0x53),
+	REG_SEQ0(CMN_REG(0027), 0x15),
+	REG_SEQ0(CMN_REG(0028), 0x0d),
+	REG_SEQ0(CMN_REG(002a), 0x09),
+	REG_SEQ0(CMN_REG(002b), 0x01),
+	REG_SEQ0(CMN_REG(002c), 0x02),
+	REG_SEQ0(CMN_REG(002d), 0x02),
+	REG_SEQ0(CMN_REG(002e), 0x0d),
+	REG_SEQ0(CMN_REG(002f), 0x61),
+	REG_SEQ0(CMN_REG(0030), 0x00),
+	REG_SEQ0(CMN_REG(0031), 0x20),
+	REG_SEQ0(CMN_REG(0032), 0x30),
+	REG_SEQ0(CMN_REG(0033), 0x0b),
+	REG_SEQ0(CMN_REG(0034), 0x23),
+	REG_SEQ0(CMN_REG(0037), 0x00),
+	REG_SEQ0(CMN_REG(003d), 0xc0),
+	REG_SEQ0(CMN_REG(0042), 0xb8),
+	REG_SEQ0(CMN_REG(0046), 0xff),
+	REG_SEQ0(CMN_REG(0048), 0x44),
+	REG_SEQ0(CMN_REG(004e), 0x14),
+	REG_SEQ0(CMN_REG(0054), 0x19),
+	REG_SEQ0(CMN_REG(0058), 0x19),
+	REG_SEQ0(CMN_REG(0059), 0x11),
+	REG_SEQ0(CMN_REG(005b), 0x30),
+	REG_SEQ0(CMN_REG(005c), 0x25),
+	REG_SEQ0(CMN_REG(005d), 0x14),
+	REG_SEQ0(CMN_REG(005e), 0x0e),
+	REG_SEQ0(CMN_REG(0063), 0x01),
+	REG_SEQ0(CMN_REG(0064), 0x0e),
+	REG_SEQ0(CMN_REG(0068), 0x00),
+	REG_SEQ0(CMN_REG(0069), 0x02),
+	REG_SEQ0(CMN_REG(006b), 0x00),
+	REG_SEQ0(CMN_REG(006f), 0x00),
+	REG_SEQ0(CMN_REG(0073), 0x02),
+	REG_SEQ0(CMN_REG(0074), 0x00),
+	REG_SEQ0(CMN_REG(007a), 0x00),
+	REG_SEQ0(CMN_REG(0081), 0x09),
+	REG_SEQ0(CMN_REG(0086), 0x11),
+	REG_SEQ0(CMN_REG(0087), 0x0c),
+	REG_SEQ0(CMN_REG(0089), 0x00),
+	REG_SEQ0(CMN_REG(0095), 0x03),
+	REG_SEQ0(CMN_REG(0097), 0x00),
+	REG_SEQ0(CMN_REG(0099), 0x00),
+	REG_SEQ0(CMN_REG(009b), 0x10),
+	REG_SEQ0(CMN_REG(009e), 0x03),
+	REG_SEQ0(CMN_REG(009f), 0xff),
+	REG_SEQ0(CMN_REG(00a0), 0x60),
+};
+
 static const struct reg_sequence rk_hdptx_tmds_cmn_init_seq[] = {
 	REG_SEQ0(CMN_REG(0008), 0x00),
 	REG_SEQ0(CMN_REG(0011), 0x01),
@@ -585,6 +737,16 @@ static const struct reg_sequence rk_hdptx_common_sb_init_seq[] = {
 	REG_SEQ0(SB_REG(0117), 0x00),
 };
 
+static const struct reg_sequence rk_hdptx_frl_lntop_init_seq[] = {
+	REG_SEQ0(LNTOP_REG(0200), 0x04),
+	REG_SEQ0(LNTOP_REG(0201), 0x00),
+	REG_SEQ0(LNTOP_REG(0202), 0x00),
+	REG_SEQ0(LNTOP_REG(0203), 0xf0),
+	REG_SEQ0(LNTOP_REG(0204), 0xff),
+	REG_SEQ0(LNTOP_REG(0205), 0xff),
+	REG_SEQ0(LNTOP_REG(0206), 0x05),
+};
+
 static const struct reg_sequence rk_hdptx_tmds_lntop_highbr_seq[] = {
 	REG_SEQ0(LNTOP_REG(0201), 0x00),
 	REG_SEQ0(LNTOP_REG(0202), 0x00),
@@ -656,6 +818,38 @@ static const struct reg_sequence rk_hdptx_common_lane_init_seq[] = {
 	REG_SEQ0(LANE_REG(0620), 0xa0),
 };
 
+static const struct reg_sequence rk_hdptx_frl_lane_init_seq[] = {
+	REG_SEQ0(LANE_REG(0312), 0x3c),
+	REG_SEQ0(LANE_REG(0412), 0x3c),
+	REG_SEQ0(LANE_REG(0512), 0x3c),
+	REG_SEQ0(LANE_REG(0612), 0x3c),
+	REG_SEQ0(LANE_REG(0303), 0x2f),
+	REG_SEQ0(LANE_REG(0403), 0x2f),
+	REG_SEQ0(LANE_REG(0503), 0x2f),
+	REG_SEQ0(LANE_REG(0603), 0x2f),
+	REG_SEQ0(LANE_REG(0305), 0x03),
+	REG_SEQ0(LANE_REG(0405), 0x03),
+	REG_SEQ0(LANE_REG(0505), 0x03),
+	REG_SEQ0(LANE_REG(0605), 0x03),
+	REG_SEQ0(LANE_REG(0306), 0xfc),
+	REG_SEQ0(LANE_REG(0406), 0xfc),
+	REG_SEQ0(LANE_REG(0506), 0xfc),
+	REG_SEQ0(LANE_REG(0606), 0xfc),
+	REG_SEQ0(LANE_REG(0305), 0x4f),
+	REG_SEQ0(LANE_REG(0405), 0x4f),
+	REG_SEQ0(LANE_REG(0505), 0x4f),
+	REG_SEQ0(LANE_REG(0605), 0x4f),
+	REG_SEQ0(LANE_REG(0304), 0x14),
+	REG_SEQ0(LANE_REG(0404), 0x14),
+	REG_SEQ0(LANE_REG(0504), 0x14),
+	REG_SEQ0(LANE_REG(0604), 0x14),
+	/* Keep Inter-Pair Skew in the limits */
+	REG_SEQ0(LANE_REG(031e), 0x02),
+	REG_SEQ0(LANE_REG(041e), 0x02),
+	REG_SEQ0(LANE_REG(051e), 0x02),
+	REG_SEQ0(LANE_REG(061e), 0x02),
+};
+
 static const struct reg_sequence rk_hdptx_tmds_lane_init_seq[] = {
 	REG_SEQ0(LANE_REG(0312), 0x00),
 	REG_SEQ0(LANE_REG(0412), 0x00),
@@ -820,7 +1014,12 @@ static int rk_hdptx_post_enable_lane(struct rk_hdptx_phy *hdptx)
 	       HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN;
 	regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);
 
-	regmap_write(hdptx->regmap, LNTOP_REG(0207), 0x0f);
+	/* 3 lanes FRL mode */
+	if (hdptx->hdmi_cfg.rate == FRL_6G3L_RATE ||
+	    hdptx->hdmi_cfg.rate == FRL_3G3L_RATE)
+		regmap_write(hdptx->regmap, LNTOP_REG(0207), 0x07);
+	else
+		regmap_write(hdptx->regmap, LNTOP_REG(0207), 0x0f);
 
 	ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS, val,
 				       (val & HDPTX_O_PHY_RDY) &&
@@ -964,6 +1163,80 @@ static bool rk_hdptx_phy_clk_pll_calc(unsigned long long rate,
 	return true;
 }
 
+static int rk_hdptx_frl_lcpll_cmn_config(struct rk_hdptx_phy *hdptx)
+{
+	const struct lcpll_config *cfg = NULL;
+	int i;
+
+	dev_dbg(hdptx->dev, "%s rate=%llu\n", __func__, hdptx->hdmi_cfg.rate);
+
+	for (i = 0; i < ARRAY_SIZE(rk_hdptx_frl_lcpll_cfg); i++) {
+		if (hdptx->hdmi_cfg.rate == rk_hdptx_frl_lcpll_cfg[i].rate) {
+			cfg = &rk_hdptx_frl_lcpll_cfg[i];
+			break;
+		}
+	}
+
+	if (!cfg) {
+		dev_err(hdptx->dev, "%s cannot find pll cfg for rate=%llu\n",
+			__func__, hdptx->hdmi_cfg.rate);
+		return -EINVAL;
+	}
+
+	rk_hdptx_pre_power_up(hdptx);
+
+	regmap_write(hdptx->grf, GRF_HDPTX_CON0, LC_REF_CLK_SEL << 16);
+
+	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_cmn_init_seq);
+	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_frl_lcpll_cmn_init_seq);
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0008),
+			   LCPLL_EN_MASK | LCPLL_LCVCO_MODE_EN_MASK,
+			   FIELD_PREP(LCPLL_EN_MASK, 1) |
+			   FIELD_PREP(LCPLL_LCVCO_MODE_EN_MASK, cfg->lcvco_mode_en));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(001e),
+			   LCPLL_PI_EN_MASK | LCPLL_100M_CLK_EN_MASK,
+			   FIELD_PREP(LCPLL_PI_EN_MASK, cfg->pi_en) |
+			   FIELD_PREP(LCPLL_100M_CLK_EN_MASK, cfg->clk_en_100m));
+
+	regmap_write(hdptx->regmap, CMN_REG(0020), cfg->pms_mdiv);
+	regmap_write(hdptx->regmap, CMN_REG(0021), cfg->pms_mdiv_afc);
+	regmap_write(hdptx->regmap, CMN_REG(0022),
+		     (cfg->pms_pdiv << 4) | cfg->pms_refdiv);
+	regmap_write(hdptx->regmap, CMN_REG(0023),
+		     (cfg->pms_sdiv << 4) | cfg->pms_sdiv);
+	regmap_write(hdptx->regmap, CMN_REG(002a), cfg->sdm_deno);
+	regmap_write(hdptx->regmap, CMN_REG(002b), cfg->sdm_num_sign);
+	regmap_write(hdptx->regmap, CMN_REG(002c), cfg->sdm_num);
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(002d), LCPLL_SDC_N_MASK,
+			   FIELD_PREP(LCPLL_SDC_N_MASK, cfg->sdc_n));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_POSTDIV_SEL_MASK,
+			   FIELD_PREP(PLL_PCG_POSTDIV_SEL_MASK, cfg->pms_sdiv));
+	regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_CLK_SEL_MASK,
+			   FIELD_PREP(PLL_PCG_CLK_SEL_MASK, (hdptx->hdmi_cfg.bpc - 8) >> 1));
+
+	return rk_hdptx_post_enable_pll(hdptx);
+}
+
+static int rk_hdptx_frl_lcpll_ropll_cmn_config(struct rk_hdptx_phy *hdptx)
+{
+	dev_dbg(hdptx->dev, "%s rate=%llu\n", __func__, hdptx->hdmi_cfg.rate);
+
+	rk_hdptx_pre_power_up(hdptx);
+
+	/* ROPLL input reference clock from LCPLL (cascade mode) */
+	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
+		     (LC_REF_CLK_SEL << 16) | LC_REF_CLK_SEL);
+
+	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_cmn_init_seq);
+	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_frl_lcpll_ropll_cmn_init_seq);
+
+	return rk_hdptx_post_enable_pll(hdptx);
+}
+
 static int rk_hdptx_tmds_ropll_cmn_config(struct rk_hdptx_phy *hdptx)
 {
 	const struct ropll_config *cfg = NULL;
@@ -995,6 +1268,8 @@ static int rk_hdptx_tmds_ropll_cmn_config(struct rk_hdptx_phy *hdptx)
 
 	rk_hdptx_pre_power_up(hdptx);
 
+	regmap_write(hdptx->grf, GRF_HDPTX_CON0, LC_REF_CLK_SEL << 16);
+
 	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_cmn_init_seq);
 	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_tmds_cmn_init_seq);
 
@@ -1033,6 +1308,28 @@ static int rk_hdptx_tmds_ropll_cmn_config(struct rk_hdptx_phy *hdptx)
 	return rk_hdptx_post_enable_pll(hdptx);
 }
 
+static int rk_hdptx_pll_cmn_config(struct rk_hdptx_phy *hdptx)
+{
+	if (hdptx->hdmi_cfg.rate <= HDMI20_MAX_RATE)
+		return rk_hdptx_tmds_ropll_cmn_config(hdptx);
+
+	if (hdptx->hdmi_cfg.rate == FRL_8G4L_RATE)
+		return rk_hdptx_frl_lcpll_ropll_cmn_config(hdptx);
+
+	return rk_hdptx_frl_lcpll_cmn_config(hdptx);
+}
+
+static int rk_hdptx_frl_lcpll_mode_config(struct rk_hdptx_phy *hdptx)
+{
+	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_sb_init_seq);
+	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_frl_lntop_init_seq);
+
+	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_lane_init_seq);
+	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_frl_lane_init_seq);
+
+	return rk_hdptx_post_enable_lane(hdptx);
+}
+
 static int rk_hdptx_tmds_ropll_mode_config(struct rk_hdptx_phy *hdptx)
 {
 	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_sb_init_seq);
@@ -1109,7 +1406,7 @@ static int rk_hdptx_phy_consumer_get(struct rk_hdptx_phy *hdptx)
 	if (mode == PHY_MODE_DP) {
 		rk_hdptx_dp_reset(hdptx);
 	} else {
-		ret = rk_hdptx_tmds_ropll_cmn_config(hdptx);
+		ret = rk_hdptx_pll_cmn_config(hdptx);
 		if (ret)
 			goto dec_usage;
 	}
@@ -1410,7 +1707,7 @@ static int rk_hdptx_phy_power_on(struct phy *phy)
 	int ret, lane;
 
 	if (mode != PHY_MODE_DP) {
-		if (!hdptx->hdmi_cfg.rate) {
+		if (!hdptx->hdmi_cfg.rate && mode != PHY_MODE_HDMI_FRL) {
 			/*
 			 * FIXME: Temporary workaround to setup TMDS char rate
 			 * from the RK DW HDMI QP bridge driver.
@@ -1456,7 +1753,11 @@ static int rk_hdptx_phy_power_on(struct phy *phy)
 		regmap_write(hdptx->grf, GRF_HDPTX_CON0,
 			     HDPTX_MODE_SEL << 16 | FIELD_PREP(HDPTX_MODE_SEL, 0x0));
 
-		ret = rk_hdptx_tmds_ropll_mode_config(hdptx);
+		if (mode == PHY_MODE_HDMI_FRL)
+			ret = rk_hdptx_frl_lcpll_mode_config(hdptx);
+		else
+			ret = rk_hdptx_tmds_ropll_mode_config(hdptx);
+
 		if (ret)
 			rk_hdptx_phy_consumer_put(hdptx, true);
 	}
@@ -1477,16 +1778,49 @@ static int rk_hdptx_phy_verify_hdmi_config(struct rk_hdptx_phy *hdptx,
 {
 	int i;
 
-	if (!hdmi_in->tmds_char_rate || hdmi_in->tmds_char_rate > HDMI20_MAX_RATE)
-		return -EINVAL;
+	if (phy_get_mode(hdptx->phy) == PHY_MODE_HDMI_FRL) {
+		unsigned long long frl_rate = 100000000ULL * hdmi_in->frl.lanes *
+					      hdmi_in->frl.rate_per_lane;
 
-	for (i = 0; i < ARRAY_SIZE(rk_hdptx_tmds_ropll_cfg); i++)
-		if (hdmi_in->tmds_char_rate == rk_hdptx_tmds_ropll_cfg[i].rate)
+		switch (hdmi_in->frl.rate_per_lane) {
+		case 3:
+		case 6:
+		case 8:
+		case 10:
+		case 12:
 			break;
+		default:
+			return -EINVAL;
+		}
 
-	if (i == ARRAY_SIZE(rk_hdptx_tmds_ropll_cfg) &&
-	    !rk_hdptx_phy_clk_pll_calc(hdmi_in->tmds_char_rate, NULL))
-		return -EINVAL;
+		if (!hdmi_in->frl.lanes || hdmi_in->frl.lanes > 4)
+			return -EINVAL;
+
+		if (frl_rate != FRL_8G4L_RATE) {
+			for (i = 0; i < ARRAY_SIZE(rk_hdptx_frl_lcpll_cfg); i++)
+				if (frl_rate == rk_hdptx_frl_lcpll_cfg[i].rate)
+					break;
+			if (i == ARRAY_SIZE(rk_hdptx_frl_lcpll_cfg))
+				return -EINVAL;
+		}
+
+		if (hdmi_out)
+			hdmi_out->rate = frl_rate;
+	} else {
+		if (!hdmi_in->tmds_char_rate || hdmi_in->tmds_char_rate > HDMI20_MAX_RATE)
+			return -EINVAL;
+
+		for (i = 0; i < ARRAY_SIZE(rk_hdptx_tmds_ropll_cfg); i++)
+			if (hdmi_in->tmds_char_rate == rk_hdptx_tmds_ropll_cfg[i].rate)
+				break;
+
+		if (i == ARRAY_SIZE(rk_hdptx_tmds_ropll_cfg) &&
+		    !rk_hdptx_phy_clk_pll_calc(hdmi_in->tmds_char_rate, NULL))
+			return -EINVAL;
+
+		if (hdmi_out)
+			hdmi_out->rate = hdmi_in->tmds_char_rate;
+	}
 
 	switch (hdmi_in->bpc) {
 	case 0:
@@ -1499,10 +1833,8 @@ static int rk_hdptx_phy_verify_hdmi_config(struct rk_hdptx_phy *hdptx,
 		return -EINVAL;
 	}
 
-	if (hdmi_out) {
-		hdmi_out->rate = hdmi_in->tmds_char_rate;
+	if (hdmi_out)
 		hdmi_out->bpc = hdmi_in->bpc ?: 8;
-	}
 
 	return 0;
 }
@@ -1857,17 +2189,62 @@ static void rk_hdptx_phy_clk_unprepare(struct clk_hw *hw)
 
 static u64 rk_hdptx_phy_clk_calc_rate_from_pll_cfg(struct rk_hdptx_phy *hdptx)
 {
+	struct lcpll_config lcpll_hw;
 	struct ropll_config ropll_hw;
 	u64 fout, sdm;
 	u32 mode, val;
-	int ret;
+	int ret, i;
 
 	ret = regmap_read(hdptx->regmap, CMN_REG(0008), &mode);
 	if (ret)
 		return 0;
 
-	if (mode & LCPLL_LCVCO_MODE_EN_MASK)
+	if (mode & LCPLL_LCVCO_MODE_EN_MASK) {
+		ret = regmap_read(hdptx->regmap, CMN_REG(0020), &val);
+		if (ret)
+			return 0;
+		lcpll_hw.pms_mdiv = val;
+
+		ret = regmap_read(hdptx->regmap, CMN_REG(0023), &val);
+		if (ret)
+			return 0;
+		lcpll_hw.pms_sdiv = val & 0xf;
+
+		ret = regmap_read(hdptx->regmap, CMN_REG(002B), &val);
+		if (ret)
+			return 0;
+		lcpll_hw.sdm_num_sign = val;
+
+		ret = regmap_read(hdptx->regmap, CMN_REG(002C), &val);
+		if (ret)
+			return 0;
+		lcpll_hw.sdm_num = val;
+
+		ret = regmap_read(hdptx->regmap, CMN_REG(002A), &val);
+		if (ret)
+			return 0;
+		lcpll_hw.sdm_deno = val;
+
+		ret = regmap_read(hdptx->regmap, CMN_REG(002D), &val);
+		if (ret)
+			return 0;
+		lcpll_hw.sdc_n = (val & LCPLL_SDC_N_MASK) >> 1;
+
+		for (i = 0; i < ARRAY_SIZE(rk_hdptx_frl_lcpll_cfg); i++) {
+			const struct lcpll_config *cfg = &rk_hdptx_frl_lcpll_cfg[i];
+
+			if (cfg->pms_mdiv == lcpll_hw.pms_mdiv &&
+			    cfg->pms_sdiv == lcpll_hw.pms_sdiv &&
+			    cfg->sdm_num_sign == lcpll_hw.sdm_num_sign &&
+			    cfg->sdm_num == lcpll_hw.sdm_num &&
+			    cfg->sdm_deno == lcpll_hw.sdm_deno &&
+			    cfg->sdc_n == lcpll_hw.sdc_n)
+				return cfg->rate;
+		}
+
+		dev_dbg(hdptx->dev, "%s no FRL match found\n", __func__);
 		return 0;
+	}
 
 	ret = regmap_read(hdptx->regmap, CMN_REG(0051), &val);
 	if (ret)
@@ -1944,6 +2321,9 @@ static unsigned long rk_hdptx_phy_clk_recalc_rate(struct clk_hw *hw,
 
 	rate = rk_hdptx_phy_clk_calc_rate_from_pll_cfg(hdptx);
 
+	if (phy_get_mode(hdptx->phy) == PHY_MODE_HDMI_FRL)
+		return rate;
+
 	return DIV_ROUND_CLOSEST_ULL(rate * 8, hdptx->hdmi_cfg.bpc);
 }
 
@@ -1952,6 +2332,9 @@ static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
 {
 	struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);
 
+	if (phy_get_mode(hdptx->phy) == PHY_MODE_HDMI_FRL)
+		return hdptx->hdmi_cfg.rate;
+
 	/*
 	 * FIXME: Temporarily allow altering TMDS char rate via CCF.
 	 * To be dropped as soon as the RK DW HDMI QP bridge driver
@@ -1980,23 +2363,26 @@ static int rk_hdptx_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate,
 				     unsigned long parent_rate)
 {
 	struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);
-	unsigned long long tmds_rate = DIV_ROUND_CLOSEST_ULL(rate * hdptx->hdmi_cfg.bpc, 8);
+	unsigned long long link_rate = rate;
+
+	if (phy_get_mode(hdptx->phy) != PHY_MODE_HDMI_FRL)
+		link_rate = DIV_ROUND_CLOSEST_ULL(rate * hdptx->hdmi_cfg.bpc, 8);
 
-	/* Revert any unlikely TMDS char rate change since round_rate() */
-	if (hdptx->hdmi_cfg.rate != tmds_rate) {
+	/* Revert any unlikely link rate change since round_rate() */
+	if (hdptx->hdmi_cfg.rate != link_rate) {
 		dev_warn(hdptx->dev, "Reverting unexpected rate change from %llu to %llu\n",
-			 tmds_rate, hdptx->hdmi_cfg.rate);
-		hdptx->hdmi_cfg.rate = tmds_rate;
+			 link_rate, hdptx->hdmi_cfg.rate);
+		hdptx->hdmi_cfg.rate = link_rate;
 	}
 
 	/*
-	 * The TMDS char rate would be normally programmed in HW during
+	 * The link rate would be normally programmed in HW during
 	 * phy_ops.power_on() or clk_ops.prepare() callbacks, but it might
 	 * happen that the former gets fired too late, i.e. after this call,
 	 * while the latter being executed only once, i.e. when clock remains
 	 * in the prepared state during rate changes.
 	 */
-	return rk_hdptx_tmds_ropll_cmn_config(hdptx);
+	return rk_hdptx_pll_cmn_config(hdptx);
 }
 
 static const struct clk_ops hdptx_phy_clk_ops = {

-- 
2.50.0



From tomi.valkeinen at ideasonboard.com  Tue Aug  5 05:03:44 2025
From: tomi.valkeinen at ideasonboard.com (Tomi Valkeinen)
Date: Tue, 5 Aug 2025 15:03:44 +0300
Subject: [PATCH 0/2] phy: cdns-dphy: hs-clk improvement and a cleanup
In-Reply-To: <20250723-cdns-dphy-hs-clk-rate-fix-v1-0-d4539d44cbe7@ideasonboard.com>
References: <20250723-cdns-dphy-hs-clk-rate-fix-v1-0-d4539d44cbe7@ideasonboard.com>
Message-ID: <cc0e4cf5-1bd9-4ae3-a130-0483dbfc6335@ideasonboard.com>

Hi Vinod, Kishon,

On 23/07/2025 13:01, Tomi Valkeinen wrote:
> A cdns-dphy improvement to return the actual hs clock rate, and a
> cleanup to remove leftover code.
> 
> These were part of a Cadence DSI series:
> 
> https://lore.kernel.org/all/20250618-cdns-dsi-impro-v4-0-862c841dbe02%40ideasonboard.com/
> 
> but are now separately here for easier merging.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
> ---
> Tomi Valkeinen (2):
>       phy: cdns-dphy: Store hs_clk_rate and return it
>       phy: cdns-dphy: Remove leftover code
> 
>  drivers/phy/cadence/cdns-dphy.c | 24 +++++++++---------------
>  1 file changed, 9 insertions(+), 15 deletions(-)
> ---
> base-commit: 89be9a83ccf1f88522317ce02f854f30d6115c41
> change-id: 20250723-cdns-dphy-hs-clk-rate-fix-a8857a5789dd

Is this good to merge, and if so, do you have any estimate when? While
this is independent from the DSI series, I'd rather push the DSI series
into drm-misc about the same time, so both would appear in linux-next
relatively together.

 Tomi



From prabhakar.csengg at gmail.com  Tue Aug  5 05:25:24 2025
From: prabhakar.csengg at gmail.com (Prabhakar)
Date: Tue,  5 Aug 2025 13:25:24 +0100
Subject: [PATCH 0/5] Add USB2 PHY support for RZ/T2H and RZ/N2H SoCs
Message-ID: <20250805122529.2566580-1-prabhakar.mahadev-lad.rj@bp.renesas.com>

From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>

Hi All,

This patch series adds support for the USB2 PHY on the Renesas RZ/T2H
and RZ/N2H SoCs. The USB2 PHY driver has been updated to handle
differences in clocking, reset handling, and register configurations
specific to these SoCs.

Cheers,
Prabhakar

Lad Prabhakar (5):
  dt-bindings: phy: renesas,usb2-phy: Add RZ/T2H and RZ/N2H support
  phy: renesas: rcar-gen3-usb2: Store drvdata pointer in channel
  phy: renesas: rcar-gen3-usb2: Allow SoC-specific OBINT bits via
    phy_data
  phy: renesas: rcar-gen3-usb2: Add support for RZ/T2H SoC
  phy: renesas: rcar-gen3-usb2: Move debug print after register value is
    updated

 .../bindings/phy/renesas,usb2-phy.yaml        |  17 +++
 drivers/phy/renesas/phy-rcar-gen3-usb2.c      | 127 ++++++++++++++----
 2 files changed, 115 insertions(+), 29 deletions(-)

-- 
2.50.1



From prabhakar.csengg at gmail.com  Tue Aug  5 05:25:25 2025
From: prabhakar.csengg at gmail.com (Prabhakar)
Date: Tue,  5 Aug 2025 13:25:25 +0100
Subject: [PATCH 1/5] dt-bindings: phy: renesas,usb2-phy: Add RZ/T2H and RZ/N2H support
In-Reply-To: <20250805122529.2566580-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20250805122529.2566580-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <20250805122529.2566580-2-prabhakar.mahadev-lad.rj@bp.renesas.com>

From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>

Document the USB2 PHY controller for the Renesas RZ/T2H (r9a09g077) and
RZ/N2H (r9a09g087) SoCs. These SoCs share the same PHY block, which is
similar to the one on RZ/G2L but differs in clocks, resets, and register
bits. To account for these differences, a new compatible string
`renesas,usb2-phy-r9a09g077` is introduced.

The RZ/N2H SoC uses the same PHY as RZ/T2H, so it reuses the RZ/T2H
compatible string as a fallback.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
---
 .../bindings/phy/renesas,usb2-phy.yaml          | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml b/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml
index f45c5f039ae8..179cb4bfc424 100644
--- a/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml
@@ -44,6 +44,12 @@ properties:
           - const: renesas,usb2-phy-r9a09g056 # RZ/V2N
           - const: renesas,usb2-phy-r9a09g057
 
+      - const: renesas,usb2-phy-r9a09g077 # RZ/T2H
+
+      - items:
+          - const: renesas,usb2-phy-r9a09g087 # RZ/N2H
+          - const: renesas,usb2-phy-r9a09g077
+
   reg:
     maxItems: 1
 
@@ -120,6 +126,17 @@ allOf:
       required:
         - resets
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: renesas,usb2-phy-r9a09g077
+    then:
+      properties:
+        clocks:
+          minItems: 2
+        resets: false
+
 additionalProperties: false
 
 examples:
-- 
2.50.1



From prabhakar.csengg at gmail.com  Tue Aug  5 05:25:26 2025
From: prabhakar.csengg at gmail.com (Prabhakar)
Date: Tue,  5 Aug 2025 13:25:26 +0100
Subject: [PATCH 2/5] phy: renesas: rcar-gen3-usb2: Store drvdata pointer in channel
In-Reply-To: <20250805122529.2566580-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20250805122529.2566580-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <20250805122529.2566580-3-prabhakar.mahadev-lad.rj@bp.renesas.com>

From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>

Store the SoC-specific driver data pointer (struct rcar_gen3_phy_drv_data)
directly in struct rcar_gen3_chan instead of copying individual flags
into separate fields. Update all references to use channel->drvdata->flags,
removing the redundant soc_no_adp_ctrl and utmi_ctrl members from the
channel structure.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
---
 drivers/phy/renesas/phy-rcar-gen3-usb2.c | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index 47beb94cd424..cfa9667c7680 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -122,6 +122,7 @@ struct rcar_gen3_phy {
 struct rcar_gen3_chan {
 	void __iomem *base;
 	struct device *dev;	/* platform_device's device */
+	const struct rcar_gen3_phy_drv_data *drvdata;
 	struct extcon_dev *extcon;
 	struct rcar_gen3_phy rphys[NUM_OF_PHYS];
 	struct regulator *vbus;
@@ -133,8 +134,6 @@ struct rcar_gen3_chan {
 	bool extcon_host;
 	bool is_otg_channel;
 	bool uses_otg_pins;
-	bool soc_no_adp_ctrl;
-	bool utmi_ctrl;
 };
 
 struct rcar_gen3_phy_drv_data {
@@ -204,7 +203,7 @@ static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus)
 	u32 val;
 
 	dev_vdbg(ch->dev, "%s: %08x, %d\n", __func__, val, vbus);
-	if (ch->soc_no_adp_ctrl) {
+	if (ch->drvdata->no_adp_ctrl) {
 		if (ch->vbus)
 			regulator_hardware_enable(ch->vbus, vbus);
 
@@ -290,7 +289,7 @@ static bool rcar_gen3_check_id(struct rcar_gen3_chan *ch)
 	if (!ch->uses_otg_pins)
 		return (ch->dr_mode == USB_DR_MODE_HOST) ? false : true;
 
-	if (ch->soc_no_adp_ctrl)
+	if (ch->drvdata->no_adp_ctrl)
 		return !!(readl(ch->base + USB2_LINECTRL1) & USB2_LINECTRL1_USB2_IDMON);
 
 	return !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG);
@@ -421,7 +420,7 @@ static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch)
 	      USB2_LINECTRL1_DMRPD_EN | USB2_LINECTRL1_DM_RPD;
 	writel(val, usb2_base + USB2_LINECTRL1);
 
-	if (!ch->soc_no_adp_ctrl) {
+	if (!ch->drvdata->no_adp_ctrl) {
 		val = readl(usb2_base + USB2_VBCTRL);
 		val &= ~USB2_VBCTRL_OCCLREN;
 		writel(val | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL);
@@ -487,7 +486,7 @@ static int rcar_gen3_phy_usb2_init(struct phy *p)
 	if (rphy->int_enable_bits)
 		rcar_gen3_init_otg(channel);
 
-	if (channel->utmi_ctrl) {
+	if (channel->drvdata->utmi_ctrl) {
 		val = readl(usb2_base + USB2_REGEN_CG_CTRL) | USB2_REGEN_CG_CTRL_UPHY_WEN;
 		writel(val, usb2_base + USB2_REGEN_CG_CTRL);
 
@@ -778,6 +777,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
 		ret = -EINVAL;
 		goto error;
 	}
+	channel->drvdata = phy_data;
 
 	platform_set_drvdata(pdev, channel);
 	channel->dev = dev;
@@ -788,12 +788,9 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
 			goto error;
 	}
 
-	channel->soc_no_adp_ctrl = phy_data->no_adp_ctrl;
 	if (phy_data->no_adp_ctrl)
 		channel->obint_enable_bits = USB2_OBINT_IDCHG_EN;
 
-	channel->utmi_ctrl = phy_data->utmi_ctrl;
-
 	spin_lock_init(&channel->lock);
 	for (i = 0; i < NUM_OF_PHYS; i++) {
 		channel->rphys[i].phy = devm_phy_create(dev, NULL,
@@ -808,7 +805,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
 		phy_set_drvdata(channel->rphys[i].phy, &channel->rphys[i]);
 	}
 
-	if (channel->soc_no_adp_ctrl && channel->is_otg_channel)
+	if (channel->drvdata->no_adp_ctrl && channel->is_otg_channel)
 		channel->vbus = devm_regulator_get_exclusive(dev, "vbus");
 	else
 		channel->vbus = devm_regulator_get_optional(dev, "vbus");
-- 
2.50.1



From prabhakar.csengg at gmail.com  Tue Aug  5 05:25:27 2025
From: prabhakar.csengg at gmail.com (Prabhakar)
Date: Tue,  5 Aug 2025 13:25:27 +0100
Subject: [PATCH 3/5] phy: renesas: rcar-gen3-usb2: Allow SoC-specific OBINT bits via phy_data
In-Reply-To: <20250805122529.2566580-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20250805122529.2566580-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <20250805122529.2566580-4-prabhakar.mahadev-lad.rj@bp.renesas.com>

From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>

Update the PHY driver to support SoC-specific OBINT enable bits by
introducing the `obint_enable_bits` field in the `rcar_gen3_phy_drv_data`
structure. This allows each SoC to specify bits required.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
---
 drivers/phy/renesas/phy-rcar-gen3-usb2.c | 27 ++++++++++++------------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index cfa9667c7680..ea387941c6f7 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -71,8 +71,7 @@
 /* OBINTSTA and OBINTEN */
 #define USB2_OBINT_SESSVLDCHG		BIT(12)
 #define USB2_OBINT_IDDIGCHG		BIT(11)
-#define USB2_OBINT_BITS			(USB2_OBINT_SESSVLDCHG | \
-					 USB2_OBINT_IDDIGCHG)
+#define USB2_OBINT_IDCHG_EN		BIT(0) /*  RZ/G2L specific */
 
 /* VBCTRL */
 #define USB2_VBCTRL_OCCLREN		BIT(16)
@@ -93,7 +92,6 @@
 #define USB2_ADPCTRL_DRVVBUS		BIT(4)
 
 /*  RZ/G2L specific */
-#define USB2_OBINT_IDCHG_EN		BIT(0)
 #define USB2_LINECTRL1_USB2_IDMON	BIT(0)
 
 #define NUM_OF_PHYS			4
@@ -130,7 +128,6 @@ struct rcar_gen3_chan {
 	struct work_struct work;
 	spinlock_t lock;	/* protects access to hardware and driver data structure. */
 	enum usb_dr_mode dr_mode;
-	u32 obint_enable_bits;
 	bool extcon_host;
 	bool is_otg_channel;
 	bool uses_otg_pins;
@@ -141,6 +138,7 @@ struct rcar_gen3_phy_drv_data {
 	bool no_adp_ctrl;
 	bool init_bus;
 	bool utmi_ctrl;
+	u32 obint_enable_bits;
 };
 
 /*
@@ -225,9 +223,9 @@ static void rcar_gen3_control_otg_irq(struct rcar_gen3_chan *ch, int enable)
 	u32 val = readl(usb2_base + USB2_OBINTEN);
 
 	if (ch->uses_otg_pins && enable)
-		val |= ch->obint_enable_bits;
+		val |= ch->drvdata->obint_enable_bits;
 	else
-		val &= ~ch->obint_enable_bits;
+		val &= ~ch->drvdata->obint_enable_bits;
 	writel(val, usb2_base + USB2_OBINTEN);
 }
 
@@ -430,7 +428,7 @@ static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch)
 	mdelay(20);
 
 	writel(0xffffffff, usb2_base + USB2_OBINTSTA);
-	writel(ch->obint_enable_bits, usb2_base + USB2_OBINTEN);
+	writel(ch->drvdata->obint_enable_bits, usb2_base + USB2_OBINTEN);
 
 	rcar_gen3_device_recognition(ch);
 }
@@ -450,9 +448,9 @@ static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch)
 
 	scoped_guard(spinlock, &ch->lock) {
 		status = readl(usb2_base + USB2_OBINTSTA);
-		if (status & ch->obint_enable_bits) {
+		if (status & ch->drvdata->obint_enable_bits) {
 			dev_vdbg(dev, "%s: %08x\n", __func__, status);
-			writel(ch->obint_enable_bits, usb2_base + USB2_OBINTSTA);
+			writel(ch->drvdata->obint_enable_bits, usb2_base + USB2_OBINTSTA);
 			rcar_gen3_device_recognition(ch);
 			ret = IRQ_HANDLED;
 		}
@@ -591,28 +589,35 @@ static const struct phy_ops rz_g1c_phy_usb2_ops = {
 static const struct rcar_gen3_phy_drv_data rcar_gen3_phy_usb2_data = {
 	.phy_usb2_ops = &rcar_gen3_phy_usb2_ops,
 	.no_adp_ctrl = false,
+	.obint_enable_bits = USB2_OBINT_SESSVLDCHG |
+			     USB2_OBINT_IDDIGCHG,
 };
 
 static const struct rcar_gen3_phy_drv_data rz_g1c_phy_usb2_data = {
 	.phy_usb2_ops = &rz_g1c_phy_usb2_ops,
 	.no_adp_ctrl = false,
+	.obint_enable_bits = USB2_OBINT_SESSVLDCHG |
+			     USB2_OBINT_IDDIGCHG,
 };
 
 static const struct rcar_gen3_phy_drv_data rz_g2l_phy_usb2_data = {
 	.phy_usb2_ops = &rcar_gen3_phy_usb2_ops,
 	.no_adp_ctrl = true,
+	.obint_enable_bits = USB2_OBINT_IDCHG_EN,
 };
 
 static const struct rcar_gen3_phy_drv_data rz_g3s_phy_usb2_data = {
 	.phy_usb2_ops = &rcar_gen3_phy_usb2_ops,
 	.no_adp_ctrl = true,
 	.init_bus = true,
+	.obint_enable_bits = USB2_OBINT_IDCHG_EN,
 };
 
 static const struct rcar_gen3_phy_drv_data rz_v2h_phy_usb2_data = {
 	.phy_usb2_ops = &rcar_gen3_phy_usb2_ops,
 	.no_adp_ctrl = true,
 	.utmi_ctrl = true,
+	.obint_enable_bits = USB2_OBINT_IDCHG_EN,
 };
 
 static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = {
@@ -748,7 +753,6 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
 	if (IS_ERR(channel->base))
 		return PTR_ERR(channel->base);
 
-	channel->obint_enable_bits = USB2_OBINT_BITS;
 	channel->dr_mode = rcar_gen3_get_dr_mode(dev->of_node);
 	if (channel->dr_mode != USB_DR_MODE_UNKNOWN) {
 		channel->is_otg_channel = true;
@@ -788,9 +792,6 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
 			goto error;
 	}
 
-	if (phy_data->no_adp_ctrl)
-		channel->obint_enable_bits = USB2_OBINT_IDCHG_EN;
-
 	spin_lock_init(&channel->lock);
 	for (i = 0; i < NUM_OF_PHYS; i++) {
 		channel->rphys[i].phy = devm_phy_create(dev, NULL,
-- 
2.50.1



From prabhakar.csengg at gmail.com  Tue Aug  5 05:25:28 2025
From: prabhakar.csengg at gmail.com (Prabhakar)
Date: Tue,  5 Aug 2025 13:25:28 +0100
Subject: [PATCH 4/5] phy: renesas: rcar-gen3-usb2: Add support for RZ/T2H SoC
In-Reply-To: <20250805122529.2566580-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20250805122529.2566580-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <20250805122529.2566580-5-prabhakar.mahadev-lad.rj@bp.renesas.com>

From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>

Add initial support for the Renesas RZ/T2H SoC to the R-Car Gen3 USB2 PHY
driver. The RZ/T2H SoC requires configuration of additional
hardware-specific bits for proper VBUS level control and OTG operation.

Introduce the `vblvl_ctrl` flag in the SoC-specific driver data to enable
handling of VBUS level selection logic using `VBCTRL.VBLVL` bits. This is
required for managing the VBUS status detection and drive logic based on
SoC-specific needs.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
---
 drivers/phy/renesas/phy-rcar-gen3-usb2.c | 85 ++++++++++++++++++++++--
 1 file changed, 78 insertions(+), 7 deletions(-)

diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index ea387941c6f7..bc841982a19a 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -69,13 +69,20 @@
 #define USB2_COMMCTRL_OTG_PERI		BIT(31)	/* 1 = Peripheral mode */
 
 /* OBINTSTA and OBINTEN */
+#define USB2_OBINTSTA_CLEAR		GENMASK(31, 0)
 #define USB2_OBINT_SESSVLDCHG		BIT(12)
 #define USB2_OBINT_IDDIGCHG		BIT(11)
+#define USB2_OBINT_VBSTAINT		BIT(3)
 #define USB2_OBINT_IDCHG_EN		BIT(0) /*  RZ/G2L specific */
 
 /* VBCTRL */
+#define USB2_VBCTRL_VBSTA_MASK		GENMASK(31, 28)
+#define USB2_VBCTRL_VBSTA_DEFAULT	2
+#define USB2_VBCTRL_VBLVL_MASK		GENMASK(23, 20)
+#define USB2_VBCTRL_VBLVL(m)		FIELD_PREP_CONST(USB2_VBCTRL_VBLVL_MASK, (m))
 #define USB2_VBCTRL_OCCLREN		BIT(16)
 #define USB2_VBCTRL_DRVVBUSSEL		BIT(8)
+#define USB2_VBCTRL_SIDDQREL		BIT(2)
 #define USB2_VBCTRL_VBOUT		BIT(0)
 
 /* LINECTRL1 */
@@ -88,6 +95,7 @@
 /* ADPCTRL */
 #define USB2_ADPCTRL_OTGSESSVLD		BIT(20)
 #define USB2_ADPCTRL_IDDIG		BIT(19)
+#define USB2_ADPCTRL_VBUSVALID		BIT(18)
 #define USB2_ADPCTRL_IDPULLUP		BIT(5)	/* 1 = ID sampling is enabled */
 #define USB2_ADPCTRL_DRVVBUS		BIT(4)
 
@@ -138,6 +146,7 @@ struct rcar_gen3_phy_drv_data {
 	bool no_adp_ctrl;
 	bool init_bus;
 	bool utmi_ctrl;
+	bool vblvl_ctrl;
 	u32 obint_enable_bits;
 };
 
@@ -201,7 +210,7 @@ static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus)
 	u32 val;
 
 	dev_vdbg(ch->dev, "%s: %08x, %d\n", __func__, val, vbus);
-	if (ch->drvdata->no_adp_ctrl) {
+	if (ch->drvdata->no_adp_ctrl || ch->drvdata->vblvl_ctrl) {
 		if (ch->vbus)
 			regulator_hardware_enable(ch->vbus, vbus);
 
@@ -284,6 +293,21 @@ static void rcar_gen3_init_from_a_peri_to_a_host(struct rcar_gen3_chan *ch)
 
 static bool rcar_gen3_check_id(struct rcar_gen3_chan *ch)
 {
+	if (ch->drvdata->vblvl_ctrl) {
+		bool vbus_valid = false;
+		bool device = false;
+
+		device = !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG);
+		vbus_valid = !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_VBUSVALID);
+
+		if (device && vbus_valid)
+			return true;
+		else if (!device && vbus_valid)
+			return false;
+
+		return !(device && !vbus_valid);
+	}
+
 	if (!ch->uses_otg_pins)
 		return (ch->dr_mode == USB_DR_MODE_HOST) ? false : true;
 
@@ -419,11 +443,20 @@ static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch)
 	writel(val, usb2_base + USB2_LINECTRL1);
 
 	if (!ch->drvdata->no_adp_ctrl) {
-		val = readl(usb2_base + USB2_VBCTRL);
-		val &= ~USB2_VBCTRL_OCCLREN;
-		writel(val | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL);
-		val = readl(usb2_base + USB2_ADPCTRL);
-		writel(val | USB2_ADPCTRL_IDPULLUP, usb2_base + USB2_ADPCTRL);
+		if (ch->drvdata->vblvl_ctrl) {
+			val = readl(usb2_base + USB2_VBCTRL);
+			val = (val & ~USB2_VBCTRL_VBLVL_MASK) | USB2_VBCTRL_VBLVL(2);
+			writel(val, usb2_base + USB2_VBCTRL);
+			val = readl(usb2_base + USB2_ADPCTRL);
+			writel(val | USB2_ADPCTRL_IDPULLUP | USB2_ADPCTRL_DRVVBUS,
+			       usb2_base + USB2_ADPCTRL);
+		} else {
+			val = readl(usb2_base + USB2_VBCTRL);
+			val &= ~USB2_VBCTRL_OCCLREN;
+			writel(val | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL);
+			val = readl(usb2_base + USB2_ADPCTRL);
+			writel(val | USB2_ADPCTRL_IDPULLUP, usb2_base + USB2_ADPCTRL);
+		}
 	}
 	mdelay(20);
 
@@ -433,6 +466,23 @@ static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch)
 	rcar_gen3_device_recognition(ch);
 }
 
+static void rcar_gen3_configure_vblvl_ctrl(struct rcar_gen3_chan *ch)
+{
+	void __iomem *usb2_base = ch->base;
+	u32 val;
+
+	if (!ch->drvdata->vblvl_ctrl)
+		return;
+
+	val = readl(usb2_base + USB2_VBCTRL);
+	if ((val & USB2_VBCTRL_VBSTA_MASK) ==
+	    FIELD_PREP_CONST(USB2_VBCTRL_VBSTA_MASK, USB2_VBCTRL_VBSTA_DEFAULT))
+		val &= ~USB2_VBCTRL_VBLVL_MASK;
+	else
+		val |= USB2_VBCTRL_VBLVL(USB2_VBCTRL_VBSTA_DEFAULT);
+	writel(val, usb2_base + USB2_VBCTRL);
+}
+
 static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch)
 {
 	struct rcar_gen3_chan *ch = _ch;
@@ -450,8 +500,12 @@ static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch)
 		status = readl(usb2_base + USB2_OBINTSTA);
 		if (status & ch->drvdata->obint_enable_bits) {
 			dev_vdbg(dev, "%s: %08x\n", __func__, status);
-			writel(ch->drvdata->obint_enable_bits, usb2_base + USB2_OBINTSTA);
+			if (ch->drvdata->vblvl_ctrl)
+				writel(USB2_OBINTSTA_CLEAR, usb2_base + USB2_OBINTSTA);
+			else
+				writel(ch->drvdata->obint_enable_bits, usb2_base + USB2_OBINTSTA);
 			rcar_gen3_device_recognition(ch);
+			rcar_gen3_configure_vblvl_ctrl(ch);
 			ret = IRQ_HANDLED;
 		}
 	}
@@ -484,6 +538,13 @@ static int rcar_gen3_phy_usb2_init(struct phy *p)
 	if (rphy->int_enable_bits)
 		rcar_gen3_init_otg(channel);
 
+	if (channel->drvdata->vblvl_ctrl) {
+		/* SIDDQ mode release */
+		writel(readl(usb2_base + USB2_VBCTRL) | USB2_VBCTRL_SIDDQREL,
+		       usb2_base + USB2_VBCTRL);
+		udelay(250);
+	}
+
 	if (channel->drvdata->utmi_ctrl) {
 		val = readl(usb2_base + USB2_REGEN_CG_CTRL) | USB2_REGEN_CG_CTRL_UPHY_WEN;
 		writel(val, usb2_base + USB2_REGEN_CG_CTRL);
@@ -613,6 +674,12 @@ static const struct rcar_gen3_phy_drv_data rz_g3s_phy_usb2_data = {
 	.obint_enable_bits = USB2_OBINT_IDCHG_EN,
 };
 
+static const struct rcar_gen3_phy_drv_data rz_t2h_phy_usb2_data = {
+	.phy_usb2_ops = &rcar_gen3_phy_usb2_ops,
+	.vblvl_ctrl = true,
+	.obint_enable_bits = USB2_OBINT_IDCHG_EN | USB2_OBINT_VBSTAINT,
+};
+
 static const struct rcar_gen3_phy_drv_data rz_v2h_phy_usb2_data = {
 	.phy_usb2_ops = &rcar_gen3_phy_usb2_ops,
 	.no_adp_ctrl = true,
@@ -645,6 +712,10 @@ static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = {
 		.compatible = "renesas,usb2-phy-r9a09g057",
 		.data = &rz_v2h_phy_usb2_data,
 	},
+	{
+		.compatible = "renesas,usb2-phy-r9a09g077",
+		.data = &rz_t2h_phy_usb2_data,
+	},
 	{
 		.compatible = "renesas,rzg2l-usb2-phy",
 		.data = &rz_g2l_phy_usb2_data,
-- 
2.50.1



From prabhakar.csengg at gmail.com  Tue Aug  5 05:25:29 2025
From: prabhakar.csengg at gmail.com (Prabhakar)
Date: Tue,  5 Aug 2025 13:25:29 +0100
Subject: [PATCH 5/5] phy: renesas: rcar-gen3-usb2: Move debug print after register value is updated
In-Reply-To: <20250805122529.2566580-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20250805122529.2566580-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <20250805122529.2566580-6-prabhakar.mahadev-lad.rj@bp.renesas.com>

From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>

Relocate the debug print in rcar_gen3_enable_vbus_ctrl() to appear after
the `val` variable is assigned and updated based on the VBUS state. This
ensures that the debug log reflects the actual register value being
written, improving debugging accuracy.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
---
 drivers/phy/renesas/phy-rcar-gen3-usb2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index bc841982a19a..86689d0cf74a 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -209,7 +209,6 @@ static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus)
 	u32 vbus_ctrl_val = USB2_ADPCTRL_DRVVBUS;
 	u32 val;
 
-	dev_vdbg(ch->dev, "%s: %08x, %d\n", __func__, val, vbus);
 	if (ch->drvdata->no_adp_ctrl || ch->drvdata->vblvl_ctrl) {
 		if (ch->vbus)
 			regulator_hardware_enable(ch->vbus, vbus);
@@ -223,6 +222,7 @@ static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus)
 		val |= vbus_ctrl_val;
 	else
 		val &= ~vbus_ctrl_val;
+	dev_vdbg(ch->dev, "%s: %08x, %d\n", __func__, val, vbus);
 	writel(val, usb2_base + vbus_ctrl_reg);
 }
 
-- 
2.50.1



From conor at kernel.org  Tue Aug  5 10:09:09 2025
From: conor at kernel.org (Conor Dooley)
Date: Tue, 5 Aug 2025 18:09:09 +0100
Subject: [PATCH 1/5] dt-bindings: phy: renesas,usb2-phy: Add RZ/T2H and
 RZ/N2H support
In-Reply-To: <20250805122529.2566580-2-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20250805122529.2566580-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <20250805122529.2566580-2-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <20250805-shifty-gloater-93e1744e38f2@spud>

On Tue, Aug 05, 2025 at 01:25:25PM +0100, Prabhakar wrote:
> From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> 
> Document the USB2 PHY controller for the Renesas RZ/T2H (r9a09g077) and
> RZ/N2H (r9a09g087) SoCs. These SoCs share the same PHY block, which is
> similar to the one on RZ/G2L but differs in clocks, resets, and register
> bits. To account for these differences, a new compatible string
> `renesas,usb2-phy-r9a09g077` is introduced.
> 
> The RZ/N2H SoC uses the same PHY as RZ/T2H, so it reuses the RZ/T2H
> compatible string as a fallback.
> 
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.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/20250805/bfcad6d1/attachment.sig>

From pritam.sutar at samsung.com  Tue Aug  5 04:52:10 2025
From: pritam.sutar at samsung.com (Pritam Manohar Sutar)
Date: Tue,  5 Aug 2025 17:22:10 +0530
Subject: [PATCH v5 0/6] initial usbdrd phy support for Exynosautov920 soc
References: <CGME20250805114303epcas5p4c88843b7e38d86b722e60e386c637160@epcas5p4.samsung.com>
Message-ID: <20250805115216.3798121-1-pritam.sutar@samsung.com>

This SoC has a single USB 3.1 DRD combo phy and three USB2.0 only
DRD phy controllers as mentined below

  * Combo phy supports USB3.1 SSP+(10Gbps) protocol and is backwards
    compatible to the USB3.0 SS(5Gbps). 'Add-on USB2.0' phy is added
    to support USB2.0 HS(480Mbps), FS(12Mbps) and LS(1.5Mbps) data rates.
    These two phys are combined to form a combo phy as mentioned below.


   USB30DRD_0 port

 +------------------------------------------------------------+
 |                                                            |
 |                (combo) USB phy controller                  |
 |      +----------------------------------------------+      |
 |      |                  USB HSPHY                   |      |
 |      |  (samsung,exynosautov920-usbdrd-combo-hsphy) |      |
 |      +----------------------------------------------+      |
 |                                                            |
 |    +--------------------------------------------------+    |
 |    |                   USB SSPHY                      |    |
 |    |   (samsung,exynosautov920-usb31drd-combo-ssphy)  |    |
 |    +--------------------------------------------------+-   |
 |                                                            |
 +------------------------------------------------------------+
 |                     USBDRD30 Link                          |
 |                       Controller                           |
 +------------------------------------------------------------+

  * USB2.0 phy supports only UTMI+ interface. USB2.0DRD phy
    is very similar to the existing Exynos850 support in this driver.

   USB20DRD_0/1/2 ports

      +---------------------------------------------------+
      |                                                   |
      |                USB PHY controller                 |
      |    +-----------------------------------------+    |
      |    |              USB HSPHY                  |    |
      |    |  (samsung,exynosautov920-usbdrd-phy)    |    |
      |    +-----------------------------------------+    |
      |                                                   |
      +---------------------------------------------------+
      |             USBDRD20_* Link                       |
      |                Controller                         |
      +---------------------------------------------------+

The "USB20 phy output isolation" is shared across the USB20 phys.
We have to bypass isolation when any one of the USBs is configured
and enable it when all are turned off. The "USB31 phy isolation"
is seperate for USB31 phy.

There are 3 types of the phys in this SoC as mentioned in above
above block diagram.    
 - one is simmilar with exynos850 as mentioned in patch no.1.
 - second supports only USB2.0 HS as in patch no 3.
 - third supports only USB3.1 SSP+ and denoted in patch no 5.
 
These three phys(usbdrd-phy, combo-hsphy, combo-ssphy) are totally
deferent, "NOT" same, hence added three compatible for three phys.

This patchset only supports device mode and same is verified with
as NCM device.

changelog
----------
Changes in v5:
- removed "Reviewed-by" tag.
- addressed comments from v4 patchset.
  - DTS style is corrected and added required supplies in code 
    and schema.
  - new schema block added for supplies to resolve below failure 
    during 'dtbs_check'.
    Unevaluated properties are not allowed ('dvdd075-usb-supply', 'vdd18-usb20-supply', 'vdd33-usb20-supply' were unexpected.
  - removed usage_counter(will take this later in subsequent patch-sets)
  link for v4: https://lore.kernel.org/linux-phy/20250701120706.2219355-1-pritam.sutar at samsung.com/

Changes in v4:
- addressed comments from v3 patchset
  - removed dts related patches, to be posted in new patchset.
  - added regulator, pmu and power sequences.
  - phy isol is shared across USBs, added usage counter to bypass or
    enable phy isolation.
  - modified schemas with hs and combo phy compatible names
    (used "combo" to denote combo phy) and regulators
- modified code to work with binding and unbinding devices/drivers
- added "Reviewed-by" tag.
  link for v3: https://lore.kernel.org/linux-phy/20250613055613.866909-1-pritam.sutar at samsung.com/

Changes in v3:
- Updated dt-bindings for USB2.0 only.
- Added dt-bindings for combo phy.
- Added implementation for combo phy (SS and HS phy).
- Added added DTS nodes for all the phys
  link for v2: https://lore.kernel.org/linux-phy/20250516102650.2144487-1-pritam.sutar at samsung.com/

Changes in v2:
- Used standard GENMASK() and FIELD_GET() to get the major version
  from controller version register.
  link for v1: https://lore.kernel.org/linux-phy/20250514134813.380807-1-pritam.sutar at samsung.com/

Pritam Manohar Sutar (6):
  dt-bindings: phy: samsung,usb3-drd-phy: add ExynosAutov920 HS phy
    compatible
  phy: exynos5-usbdrd: support HS phy for ExynosAutov920
  dt-bindings: phy: samsung,usb3-drd-phy: add ExynosAutov920 combo hsphy
  phy: exynos5-usbdrd: support HS combo phy for ExynosAutov920
  dt-bindings: phy: samsung,usb3-drd-phy: add ExynosAutov920 combo ssphy
  phy: exynos5-usbdrd: support SS combo phy for ExynosAutov920

 .../bindings/phy/samsung,usb3-drd-phy.yaml    |  41 ++
 drivers/phy/samsung/phy-exynos5-usbdrd.c      | 652 ++++++++++++++++++
 include/linux/soc/samsung/exynos-regs-pmu.h   |   3 +
 3 files changed, 696 insertions(+)

-- 
2.34.1



From pritam.sutar at samsung.com  Tue Aug  5 04:52:11 2025
From: pritam.sutar at samsung.com (Pritam Manohar Sutar)
Date: Tue,  5 Aug 2025 17:22:11 +0530
Subject: [PATCH v5 1/6] dt-bindings: phy: samsung,usb3-drd-phy: add
 ExynosAutov920 HS phy compatible
In-Reply-To: <20250805115216.3798121-1-pritam.sutar@samsung.com>
References: <20250805115216.3798121-1-pritam.sutar@samsung.com>
	<CGME20250805114306epcas5p37782c02ae0ddc6b77094786c90af247a@epcas5p3.samsung.com>
Message-ID: <20250805115216.3798121-2-pritam.sutar@samsung.com>

This SoC has USB2.0 phy and supports only UTMI+ interface. This phy
requires two clocks, named as "phy" and "ref". The required supplies for
this phy are vdd075_usb20(0.75v), vdd18_usb20(1.8v), vdd33_usb20(3.3v).

Add a dedicated compatible string for USB HS phy found in this SoC.

Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
---
 .../bindings/phy/samsung,usb3-drd-phy.yaml    | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
index e906403208c0..1932a2272ef9 100644
--- a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
@@ -34,6 +34,7 @@ properties:
       - samsung,exynos7870-usbdrd-phy
       - samsung,exynos850-usbdrd-phy
       - samsung,exynos990-usbdrd-phy
+      - samsung,exynosautov920-usbdrd-phy
 
   clocks:
     minItems: 1
@@ -110,6 +111,12 @@ properties:
   vddh-usbdp-supply:
     description: VDDh power supply for the USB DP phy.
 
+  dvdd075-usb20-supply:
+    description: 0.75V power supply for the USB 2.0 phy.
+
+  vdd18-usb20-supply:
+    description: 1.8V power supply for the USB 2.0 phy.
+
 required:
   - compatible
   - clocks
@@ -219,6 +226,7 @@ allOf:
               - samsung,exynos7870-usbdrd-phy
               - samsung,exynos850-usbdrd-phy
               - samsung,exynos990-usbdrd-phy
+              - samsung,exynosautov920-usbdrd-phy
     then:
       properties:
         clocks:
@@ -235,6 +243,17 @@ allOf:
 
         reg-names:
           maxItems: 1
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - samsung,exynosautov920-usbdrd-phy
+    then:
+      required:
+        - dvdd075-usb20-supply
+        - vdd18-usb20-supply
+        - vdd33-usb20-supply
 
 unevaluatedProperties: false
 
-- 
2.34.1



From pritam.sutar at samsung.com  Tue Aug  5 04:52:12 2025
From: pritam.sutar at samsung.com (Pritam Manohar Sutar)
Date: Tue,  5 Aug 2025 17:22:12 +0530
Subject: [PATCH v5 2/6] phy: exynos5-usbdrd: support HS phy for
 ExynosAutov920
In-Reply-To: <20250805115216.3798121-1-pritam.sutar@samsung.com>
References: <20250805115216.3798121-1-pritam.sutar@samsung.com>
	<CGME20250805114310epcas5p459aa232884d22501f5fefe42f239fecc@epcas5p4.samsung.com>
Message-ID: <20250805115216.3798121-3-pritam.sutar@samsung.com>

Enable UTMI+ phy support for this SoC which is very similar to what
the existing Exynos850 supports.

Add required change in phy driver to support HS phy for this SoC.

Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
---
 drivers/phy/samsung/phy-exynos5-usbdrd.c    | 123 ++++++++++++++++++++
 include/linux/soc/samsung/exynos-regs-pmu.h |   2 +
 2 files changed, 125 insertions(+)

diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
index dd660ebe8045..5400dd23e500 100644
--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
+++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
@@ -2054,6 +2054,126 @@ static const struct exynos5_usbdrd_phy_drvdata exynos990_usbdrd_phy = {
 	.n_regulators		= ARRAY_SIZE(exynos5_regulator_names),
 };
 
+static int exynosautov920_usbdrd_phy_init(struct phy *phy)
+{
+	struct phy_usb_instance *inst = phy_get_drvdata(phy);
+	struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
+	int ret;
+
+	ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks);
+	if (ret)
+		return ret;
+
+	/* Bypass PHY isol */
+	inst->phy_cfg->phy_isol(inst, false);
+
+	/* UTMI or PIPE3 specific init */
+	inst->phy_cfg->phy_init(phy_drd);
+
+	clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks);
+
+	return 0;
+}
+
+static int exynosautov920_usbdrd_phy_exit(struct phy *phy)
+{
+	struct phy_usb_instance *inst = phy_get_drvdata(phy);
+	struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
+	int ret = 0;
+
+	ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks);
+	if (ret)
+		return ret;
+
+	exynos850_usbdrd_phy_exit(phy);
+
+	/* enable PHY isol */
+	inst->phy_cfg->phy_isol(inst, true);
+
+	clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks);
+
+	return 0;
+}
+
+static int exynosautov920_usbdrd_phy_power_on(struct phy *phy)
+{
+	int ret;
+	struct phy_usb_instance *inst = phy_get_drvdata(phy);
+	struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
+
+	dev_dbg(phy_drd->dev, "Request to power_on usbdrd_phy phy\n");
+
+	ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_core_clks,
+				      phy_drd->core_clks);
+	if (ret)
+		return ret;
+
+	/* Enable supply */
+	ret = regulator_bulk_enable(phy_drd->drv_data->n_regulators,
+				    phy_drd->regulators);
+	if (ret) {
+		dev_err(phy_drd->dev, "Failed to enable PHY regulator(s)\n");
+		goto fail_supply;
+	}
+
+	return 0;
+
+fail_supply:
+	clk_bulk_disable_unprepare(phy_drd->drv_data->n_core_clks,
+				   phy_drd->core_clks);
+
+	return ret;
+}
+
+static int exynosautov920_usbdrd_phy_power_off(struct phy *phy)
+{
+	struct phy_usb_instance *inst = phy_get_drvdata(phy);
+	struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
+
+	dev_dbg(phy_drd->dev, "Request to power_off usbdrd_phy phy\n");
+
+	/* Disable supply */
+	regulator_bulk_disable(phy_drd->drv_data->n_regulators,
+			       phy_drd->regulators);
+
+	clk_bulk_disable_unprepare(phy_drd->drv_data->n_core_clks,
+				   phy_drd->core_clks);
+
+	return 0;
+}
+
+static const char * const exynosautov920_usb20_regulators[] = {
+	"dvdd075-usb20", "vdd18-usb20", "vdd33-usb20",
+};
+
+static const struct phy_ops exynosautov920_usbdrd_phy_ops = {
+	.init		= exynosautov920_usbdrd_phy_init,
+	.exit		= exynosautov920_usbdrd_phy_exit,
+	.power_on       = exynosautov920_usbdrd_phy_power_on,
+	.power_off      = exynosautov920_usbdrd_phy_power_off,
+	.owner		= THIS_MODULE,
+};
+
+static const struct exynos5_usbdrd_phy_config phy_cfg_exynosautov920[] = {
+	{
+		.id		= EXYNOS5_DRDPHY_UTMI,
+		.phy_isol	= exynos5_usbdrd_phy_isol,
+		.phy_init	= exynos850_usbdrd_utmi_init,
+	},
+};
+
+static const struct exynos5_usbdrd_phy_drvdata exynosautov920_usbdrd_phy = {
+	.phy_cfg		= phy_cfg_exynosautov920,
+	.phy_ops		= &exynosautov920_usbdrd_phy_ops,
+	.pmu_offset_usbdrd0_phy	= EXYNOSAUTOV920_PHY_CTRL_USB20,
+	.clk_names		= exynos5_clk_names,
+	.n_clks			= ARRAY_SIZE(exynos5_clk_names),
+	.core_clk_names		= exynos5_core_clk_names,
+	.n_core_clks		= ARRAY_SIZE(exynos5_core_clk_names),
+	.regulator_names	= exynosautov920_usb20_regulators,
+	.n_regulators		= ARRAY_SIZE(exynosautov920_usb20_regulators),
+};
+
 static const struct exynos5_usbdrd_phy_config phy_cfg_gs101[] = {
 	{
 		.id		= EXYNOS5_DRDPHY_UTMI,
@@ -2260,6 +2380,9 @@ static const struct of_device_id exynos5_usbdrd_phy_of_match[] = {
 	}, {
 		.compatible = "samsung,exynos990-usbdrd-phy",
 		.data = &exynos990_usbdrd_phy
+	}, {
+		.compatible = "samsung,exynosautov920-usbdrd-phy",
+		.data = &exynosautov920_usbdrd_phy
 	},
 	{ },
 };
diff --git a/include/linux/soc/samsung/exynos-regs-pmu.h b/include/linux/soc/samsung/exynos-regs-pmu.h
index 71e0c09a49eb..4923f9be3d1f 100644
--- a/include/linux/soc/samsung/exynos-regs-pmu.h
+++ b/include/linux/soc/samsung/exynos-regs-pmu.h
@@ -688,4 +688,6 @@
 #define GS101_GRP2_INTR_BID_UPEND				(0x0208)
 #define GS101_GRP2_INTR_BID_CLEAR				(0x020c)
 
+/* exynosautov920 */
+#define EXYNOSAUTOV920_PHY_CTRL_USB20				(0x0710)
 #endif /* __LINUX_SOC_EXYNOS_REGS_PMU_H */
-- 
2.34.1



From pritam.sutar at samsung.com  Tue Aug  5 04:52:13 2025
From: pritam.sutar at samsung.com (Pritam Manohar Sutar)
Date: Tue,  5 Aug 2025 17:22:13 +0530
Subject: [PATCH v5 3/6] dt-bindings: phy: samsung,usb3-drd-phy: add
 ExynosAutov920 combo hsphy
In-Reply-To: <20250805115216.3798121-1-pritam.sutar@samsung.com>
References: <20250805115216.3798121-1-pritam.sutar@samsung.com>
	<CGME20250805114313epcas5p15b843d7fe692feb20828a789cef49dc0@epcas5p1.samsung.com>
Message-ID: <20250805115216.3798121-4-pritam.sutar@samsung.com>

This phy only supports USB2.0 HS(480Mbps), FS(12Mbps) and
LS(1.5Mbps) data rates. It requires two clocks, named as "phy" and "ref".
The required supplies for this phy, named as vdd075_usb20(0.75v),
vdd18_usb20(1.8v), vdd33_usb20(3.3v).

Add schema for combo hsphy found on this SoC.

Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
---
 .../devicetree/bindings/phy/samsung,usb3-drd-phy.yaml          | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
index 1932a2272ef9..4a84b5405cd2 100644
--- a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
@@ -34,6 +34,7 @@ properties:
       - samsung,exynos7870-usbdrd-phy
       - samsung,exynos850-usbdrd-phy
       - samsung,exynos990-usbdrd-phy
+      - samsung,exynosautov920-usbdrd-combo-hsphy
       - samsung,exynosautov920-usbdrd-phy
 
   clocks:
@@ -226,6 +227,7 @@ allOf:
               - samsung,exynos7870-usbdrd-phy
               - samsung,exynos850-usbdrd-phy
               - samsung,exynos990-usbdrd-phy
+              - samsung,exynosautov920-usbdrd-combo-hsphy
               - samsung,exynosautov920-usbdrd-phy
     then:
       properties:
@@ -248,6 +250,7 @@ allOf:
         compatible:
           contains:
             enum:
+              - samsung,exynosautov920-usbdrd-combo-hsphy
               - samsung,exynosautov920-usbdrd-phy
     then:
       required:
-- 
2.34.1



From pritam.sutar at samsung.com  Tue Aug  5 04:52:14 2025
From: pritam.sutar at samsung.com (Pritam Manohar Sutar)
Date: Tue,  5 Aug 2025 17:22:14 +0530
Subject: [PATCH v5 4/6] phy: exynos5-usbdrd: support HS combo phy for
 ExynosAutov920
In-Reply-To: <20250805115216.3798121-1-pritam.sutar@samsung.com>
References: <20250805115216.3798121-1-pritam.sutar@samsung.com>
	<CGME20250805114316epcas5p49b78db499c2e37a1fe68f4b2f0be62a7@epcas5p4.samsung.com>
Message-ID: <20250805115216.3798121-5-pritam.sutar@samsung.com>

Support UTMI+ combo phy for this SoC which is somewhat simmilar to
what the existing Exynos850 support does. The difference is that
some register offsets and bit fields are defferent from Exynos850.

Add required change in phy driver to support combo HS phy for this SoC.

Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
---
 drivers/phy/samsung/phy-exynos5-usbdrd.c | 210 +++++++++++++++++++++++
 1 file changed, 210 insertions(+)

diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
index 5400dd23e500..c22f4de7d094 100644
--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
+++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
@@ -41,6 +41,13 @@
 #define EXYNOS2200_CLKRST_LINK_PCLK_SEL		BIT(1)
 
 #define EXYNOS2200_DRD_UTMI			0x10
+
+/* ExynosAutov920 bits */
+#define UTMICTL_FORCE_UTMI_SUSPEND		BIT(13)
+#define UTMICTL_FORCE_UTMI_SLEEP		BIT(12)
+#define UTMICTL_FORCE_DPPULLDOWN		BIT(9)
+#define UTMICTL_FORCE_DMPULLDOWN		BIT(8)
+
 #define EXYNOS2200_UTMI_FORCE_VBUSVALID		BIT(1)
 #define EXYNOS2200_UTMI_FORCE_BVALID		BIT(0)
 
@@ -250,6 +257,22 @@
 #define EXYNOS850_DRD_HSP_TEST			0x5c
 #define HSP_TEST_SIDDQ				BIT(24)
 
+#define EXYNOSAUTOV920_DRD_HSP_CLKRST		0x100
+#define HSPCLKRST_PHY20_SW_PORTRESET		BIT(3)
+#define HSPCLKRST_PHY20_SW_POR			BIT(1)
+#define HSPCLKRST_PHY20_SW_POR_SEL		BIT(0)
+
+#define EXYNOSAUTOV920_DRD_HSPCTL		0x104
+#define HSPCTRL_VBUSVLDEXTSEL			BIT(13)
+#define HSPCTRL_VBUSVLDEXT			BIT(12)
+#define HSPCTRL_EN_UTMISUSPEND			BIT(9)
+#define HSPCTRL_COMMONONN			BIT(8)
+
+#define EXYNOSAUTOV920_DRD_HSP_TEST		0x10c
+
+#define EXYNOSAUTOV920_DRD_HSPPLLTUNE		0x110
+#define HSPPLLTUNE_FSEL				GENMASK(18, 16)
+
 /* Exynos9 - GS101 */
 #define EXYNOS850_DRD_SECPMACTL			0x48
 #define SECPMACTL_PMA_ROPLL_REF_CLK_SEL		GENMASK(13, 12)
@@ -2054,6 +2077,139 @@ static const struct exynos5_usbdrd_phy_drvdata exynos990_usbdrd_phy = {
 	.n_regulators		= ARRAY_SIZE(exynos5_regulator_names),
 };
 
+static void
+exynosautov920_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd)
+{
+	void __iomem *reg_phy = phy_drd->reg_phy;
+	u32 reg;
+
+	/*
+	 * Disable HWACG (hardware auto clock gating control). This
+	 * forces QACTIVE signal in Q-Channel interface to HIGH level,
+	 * to make sure the PHY clock is not gated by the hardware.
+	 */
+	reg = readl(reg_phy + EXYNOS850_DRD_LINKCTRL);
+	reg |= LINKCTRL_FORCE_QACT;
+	writel(reg, reg_phy + EXYNOS850_DRD_LINKCTRL);
+
+	/* De-assert link reset */
+	reg = readl(reg_phy + EXYNOS2200_DRD_CLKRST);
+	reg &= ~CLKRST_LINK_SW_RST;
+	writel(reg, reg_phy + EXYNOS2200_DRD_CLKRST);
+
+	/* Set PHY POR High */
+	reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSP_CLKRST);
+	reg |= HSPCLKRST_PHY20_SW_POR | HSPCLKRST_PHY20_SW_POR_SEL;
+	writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSP_CLKRST);
+
+	/* Enable UTMI+ */
+	reg = readl(reg_phy + EXYNOS2200_DRD_UTMI);
+	reg &= ~(UTMICTL_FORCE_UTMI_SUSPEND | UTMICTL_FORCE_UTMI_SLEEP |
+		UTMICTL_FORCE_DPPULLDOWN | UTMICTL_FORCE_DMPULLDOWN);
+	writel(reg, reg_phy + EXYNOS2200_DRD_UTMI);
+
+	/* set phy clock & control HS phy */
+	reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSPCTL);
+	reg |= HSPCTRL_EN_UTMISUSPEND | HSPCTRL_COMMONONN;
+	writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSPCTL);
+
+	fsleep(100);
+
+	/* Set VBUS Valid and DP-Pull up control by VBUS pad usage */
+	reg = readl(reg_phy + EXYNOS850_DRD_LINKCTRL);
+	reg |= FIELD_PREP_CONST(LINKCTRL_BUS_FILTER_BYPASS, 0xf);
+	writel(reg, reg_phy + EXYNOS850_DRD_LINKCTRL);
+
+	reg = readl(reg_phy + EXYNOS2200_DRD_UTMI);
+	reg |= EXYNOS2200_UTMI_FORCE_VBUSVALID | EXYNOS2200_UTMI_FORCE_BVALID;
+	writel(reg, reg_phy + EXYNOS2200_DRD_UTMI);
+
+	reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSPCTL);
+	reg |= HSPCTRL_VBUSVLDEXTSEL | HSPCTRL_VBUSVLDEXT;
+	writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSPCTL);
+
+	/* Setting FSEL for refference clock */
+	reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSPPLLTUNE);
+	reg &= ~HSPPLLTUNE_FSEL;
+	switch (phy_drd->extrefclk) {
+	case EXYNOS5_FSEL_50MHZ:
+		reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 7);
+		break;
+	case EXYNOS5_FSEL_26MHZ:
+		reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 6);
+		break;
+	case EXYNOS5_FSEL_24MHZ:
+		reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 2);
+		break;
+	case EXYNOS5_FSEL_20MHZ:
+		reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 1);
+		break;
+	case EXYNOS5_FSEL_19MHZ2:
+		reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 0);
+		break;
+	default:
+		dev_warn(phy_drd->dev, "unsupported ref clk: %#.2x\n",
+			 phy_drd->extrefclk);
+		break;
+	}
+	writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSPPLLTUNE);
+
+	/* Enable PHY Power Mode */
+	reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSP_TEST);
+	reg &= ~HSP_TEST_SIDDQ;
+	writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSP_TEST);
+
+	/* before POR low, 10us delay is needed to Finish PHY reset */
+	fsleep(10);
+
+	/* Set PHY POR Low */
+	reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSP_CLKRST);
+	reg |= HSPCLKRST_PHY20_SW_POR_SEL;
+	reg &= ~(HSPCLKRST_PHY20_SW_POR | HSPCLKRST_PHY20_SW_PORTRESET);
+	writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSP_CLKRST);
+
+	/* after POR low and delay 75us, PHYCLOCK is guaranteed. */
+	fsleep(75);
+
+	/* force pipe3 signal for link */
+	reg = readl(reg_phy + EXYNOS850_DRD_LINKCTRL);
+	reg |= LINKCTRL_FORCE_PIPE_EN;
+	reg &= ~LINKCTRL_FORCE_PHYSTATUS;
+	reg |= LINKCTRL_FORCE_RXELECIDLE;
+	writel(reg, reg_phy + EXYNOS850_DRD_LINKCTRL);
+}
+
+static void
+exynosautov920_usbdrd_hsphy_disable(struct exynos5_usbdrd_phy *phy_drd)
+{
+	u32 reg;
+	void __iomem *reg_phy = phy_drd->reg_phy;
+
+	/* set phy clock & control HS phy */
+	reg = readl(reg_phy + EXYNOS2200_DRD_UTMI);
+	reg |= UTMICTL_FORCE_UTMI_SUSPEND | UTMICTL_FORCE_UTMI_SLEEP;
+	reg &= ~(UTMICTL_FORCE_DPPULLDOWN | UTMICTL_FORCE_DMPULLDOWN);
+	writel(reg, reg_phy + EXYNOS2200_DRD_UTMI);
+
+	/* Disable PHY Power Mode */
+	reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSP_TEST);
+	reg |= HSP_TEST_SIDDQ;
+	writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSP_TEST);
+
+	/* clear force q-channel */
+	reg = readl(reg_phy + EXYNOS850_DRD_LINKCTRL);
+	reg &= ~LINKCTRL_FORCE_QACT;
+	writel(reg, reg_phy + EXYNOS850_DRD_LINKCTRL);
+
+	/* link sw reset is need for USB_DP/DM high-z in host mode */
+	reg = readl(reg_phy + EXYNOS2200_DRD_CLKRST);
+	reg |= CLKRST_LINK_SW_RST;
+	writel(reg, reg_phy + EXYNOS2200_DRD_CLKRST);
+	fsleep(10);
+	reg &= ~CLKRST_LINK_SW_RST;
+	writel(reg, reg_phy + EXYNOS2200_DRD_CLKRST);
+}
+
 static int exynosautov920_usbdrd_phy_init(struct phy *phy)
 {
 	struct phy_usb_instance *inst = phy_get_drvdata(phy);
@@ -2095,6 +2251,27 @@ static int exynosautov920_usbdrd_phy_exit(struct phy *phy)
 	return 0;
 }
 
+static int exynosautov920_usbdrd_combo_phy_exit(struct phy *phy)
+{
+	struct phy_usb_instance *inst = phy_get_drvdata(phy);
+	struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
+	int ret = 0;
+
+	ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks);
+	if (ret)
+		return ret;
+
+	if (inst->phy_cfg->id == EXYNOS5_DRDPHY_UTMI)
+		exynosautov920_usbdrd_hsphy_disable(phy_drd);
+
+	/* enable PHY isol */
+	inst->phy_cfg->phy_isol(inst, true);
+
+	clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks);
+
+	return 0;
+}
+
 static int exynosautov920_usbdrd_phy_power_on(struct phy *phy)
 {
 	int ret;
@@ -2146,6 +2323,36 @@ static const char * const exynosautov920_usb20_regulators[] = {
 	"dvdd075-usb20", "vdd18-usb20", "vdd33-usb20",
 };
 
+static const struct phy_ops exynosautov920_usbdrd_combo_hsphy_ops = {
+	.init		= exynosautov920_usbdrd_phy_init,
+	.exit		= exynosautov920_usbdrd_combo_phy_exit,
+	.power_on	= exynosautov920_usbdrd_phy_power_on,
+	.power_off	= exynosautov920_usbdrd_phy_power_off,
+	.owner		= THIS_MODULE,
+};
+
+static const struct
+exynos5_usbdrd_phy_config usbdrd_hsphy_cfg_exynosautov920[] = {
+	{
+		.id		= EXYNOS5_DRDPHY_UTMI,
+		.phy_isol	= exynos5_usbdrd_phy_isol,
+		.phy_init	= exynosautov920_usbdrd_utmi_init,
+	},
+};
+
+static const
+struct exynos5_usbdrd_phy_drvdata exynosautov920_usbdrd_combo_hsphy = {
+	.phy_cfg		= usbdrd_hsphy_cfg_exynosautov920,
+	.phy_ops		= &exynosautov920_usbdrd_combo_hsphy_ops,
+	.pmu_offset_usbdrd0_phy	= EXYNOSAUTOV920_PHY_CTRL_USB20,
+	.clk_names		= exynos5_clk_names,
+	.n_clks			= ARRAY_SIZE(exynos5_clk_names),
+	.core_clk_names		= exynos5_core_clk_names,
+	.n_core_clks		= ARRAY_SIZE(exynos5_core_clk_names),
+	.regulator_names	= exynosautov920_usb20_regulators,
+	.n_regulators		= ARRAY_SIZE(exynosautov920_usb20_regulators),
+};
+
 static const struct phy_ops exynosautov920_usbdrd_phy_ops = {
 	.init		= exynosautov920_usbdrd_phy_init,
 	.exit		= exynosautov920_usbdrd_phy_exit,
@@ -2380,6 +2587,9 @@ static const struct of_device_id exynos5_usbdrd_phy_of_match[] = {
 	}, {
 		.compatible = "samsung,exynos990-usbdrd-phy",
 		.data = &exynos990_usbdrd_phy
+	}, {
+		.compatible = "samsung,exynosautov920-usbdrd-combo-hsphy",
+		.data = &exynosautov920_usbdrd_combo_hsphy
 	}, {
 		.compatible = "samsung,exynosautov920-usbdrd-phy",
 		.data = &exynosautov920_usbdrd_phy
-- 
2.34.1



From pritam.sutar at samsung.com  Tue Aug  5 04:52:15 2025
From: pritam.sutar at samsung.com (Pritam Manohar Sutar)
Date: Tue,  5 Aug 2025 17:22:15 +0530
Subject: [PATCH v5 5/6] dt-bindings: phy: samsung,usb3-drd-phy: add
 ExynosAutov920 combo ssphy
In-Reply-To: <20250805115216.3798121-1-pritam.sutar@samsung.com>
References: <20250805115216.3798121-1-pritam.sutar@samsung.com>
	<CGME20250805114320epcas5p3968288f8d01944d3d730b3094a7befe4@epcas5p3.samsung.com>
Message-ID: <20250805115216.3798121-6-pritam.sutar@samsung.com>

This phy supports USB3.1 SSP+(10Gbps) protocol and is backwards
compatible to the USB3.0 SS(5Gbps). It requires two clocks, named
"phy" and "ref". The required supplies for USB3.1 are named as
vdd075_usb30(0.75v), vdd18_usb30(1.8v).

Add schemas for combo ssphy found on this SoC.

Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
---
 .../bindings/phy/samsung,usb3-drd-phy.yaml    | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
index 4a84b5405cd2..7a71cff10fb5 100644
--- a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
@@ -34,6 +34,7 @@ properties:
       - samsung,exynos7870-usbdrd-phy
       - samsung,exynos850-usbdrd-phy
       - samsung,exynos990-usbdrd-phy
+      - samsung,exynosautov920-usb31drd-combo-ssphy
       - samsung,exynosautov920-usbdrd-combo-hsphy
       - samsung,exynosautov920-usbdrd-phy
 
@@ -118,6 +119,12 @@ properties:
   vdd18-usb20-supply:
     description: 1.8V power supply for the USB 2.0 phy.
 
+  dvdd075-usb30-supply:
+    description: 0.75V power supply for the USB 3.0 phy.
+
+  vdd18-usb30-supply:
+    description: 1.8V power supply for the USB 3.0 phy.
+
 required:
   - compatible
   - clocks
@@ -227,6 +234,7 @@ allOf:
               - samsung,exynos7870-usbdrd-phy
               - samsung,exynos850-usbdrd-phy
               - samsung,exynos990-usbdrd-phy
+              - samsung,exynosautov920-usb31drd-combo-ssphy
               - samsung,exynosautov920-usbdrd-combo-hsphy
               - samsung,exynosautov920-usbdrd-phy
     then:
@@ -258,6 +266,17 @@ allOf:
         - vdd18-usb20-supply
         - vdd33-usb20-supply
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - samsung,exynosautov920-usb31drd-combo-ssphy
+    then:
+      required:
+        - dvdd075-usb30-supply
+        - vdd18-usb30-supply
+
 unevaluatedProperties: false
 
 examples:
-- 
2.34.1



From pritam.sutar at samsung.com  Tue Aug  5 04:52:16 2025
From: pritam.sutar at samsung.com (Pritam Manohar Sutar)
Date: Tue,  5 Aug 2025 17:22:16 +0530
Subject: [PATCH v5 6/6] phy: exynos5-usbdrd: support SS combo phy for
 ExynosAutov920
In-Reply-To: <20250805115216.3798121-1-pritam.sutar@samsung.com>
References: <20250805115216.3798121-1-pritam.sutar@samsung.com>
	<CGME20250805114323epcas5p39bf73c5e0a9382ff54b1832724804cc9@epcas5p3.samsung.com>
Message-ID: <20250805115216.3798121-7-pritam.sutar@samsung.com>

Add required change in phy driver to support combo SS phy for this SoC.

Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
---
 drivers/phy/samsung/phy-exynos5-usbdrd.c    | 327 +++++++++++++++++++-
 include/linux/soc/samsung/exynos-regs-pmu.h |   1 +
 2 files changed, 324 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
index c22f4de7d094..1108f0c07755 100644
--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
+++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
@@ -273,6 +273,36 @@
 #define EXYNOSAUTOV920_DRD_HSPPLLTUNE		0x110
 #define HSPPLLTUNE_FSEL				GENMASK(18, 16)
 
+/* ExynosAutov920 phy usb31drd port reg */
+#define EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL	0x000
+#define PHY_RST_CTRL_PIPE_LANE0_RESET_N_OVRD_EN	BIT(5)
+#define PHY_RST_CTRL_PIPE_LANE0_RESET_N		BIT(4)
+#define PHY_RST_CTRL_PHY_RESET_OVRD_EN		BIT(1)
+#define PHY_RST_CTRL_PHY_RESET			BIT(0)
+
+#define EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0	0x0004
+#define PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR		GENMASK(31, 16)
+#define PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK		BIT(8)
+#define PHY_CR_PARA_CON0_PHY0_CR_PARA_ACK		BIT(4)
+#define PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL		BIT(0)
+
+#define EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON1	0x0008
+
+#define EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2	0x000c
+#define PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_EN		BIT(0)
+#define PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_DATA		GENMASK(31, 16)
+
+#define EXYNOSAUTOV920_USB31DRD_PHY_CONFIG0	0x100
+#define PHY_CONFIG0_PHY0_PMA_PWR_STABLE		BIT(14)
+#define PHY_CONFIG0_PHY0_PCS_PWR_STABLE		BIT(13)
+#define PHY_CONFIG0_PHY0_ANA_PWR_EN		BIT(1)
+
+#define EXYNOSAUTOV920_USB31DRD_PHY_CONFIG7	0x11c
+#define PHY_CONFIG7_PHY_TEST_POWERDOWN		BIT(24)
+
+#define EXYNOSAUTOV920_USB31DRD_PHY_CONFIG4	0x110
+#define PHY_CONFIG4_PIPE_RX0_SRIS_MODE_EN	BIT(2)
+
 /* Exynos9 - GS101 */
 #define EXYNOS850_DRD_SECPMACTL			0x48
 #define SECPMACTL_PMA_ROPLL_REF_CLK_SEL		GENMASK(13, 12)
@@ -2077,6 +2107,253 @@ static const struct exynos5_usbdrd_phy_drvdata exynos990_usbdrd_phy = {
 	.n_regulators		= ARRAY_SIZE(exynos5_regulator_names),
 };
 
+static void
+exynosautov920_usb31drd_cr_clk(struct exynos5_usbdrd_phy *phy_drd, bool high)
+{
+	void __iomem *reg_phy = phy_drd->reg_phy;
+	u32 reg = 0;
+
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
+	if (high)
+		reg |= PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK;
+	else
+		reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK;
+
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
+	fsleep(1);
+}
+
+static void
+exynosautov920_usb31drd_port_phy_ready(struct exynos5_usbdrd_phy *phy_drd)
+{
+	struct device *dev = phy_drd->dev;
+	void __iomem *reg_phy = phy_drd->reg_phy;
+	static const unsigned int timeout_us = 20000;
+	static const unsigned int sleep_us = 40;
+	u32 reg = 0;
+	int err;
+
+	/* Clear cr_para_con */
+	reg &= ~(PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK |
+			PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR);
+	reg |= PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
+	writel(0x0, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON1);
+	writel(0x0, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2);
+
+	exynosautov920_usb31drd_cr_clk(phy_drd, true);
+	exynosautov920_usb31drd_cr_clk(phy_drd, false);
+
+	/*
+	 * The maximum time from phy reset de-assertion to de-assertion of
+	 * tx/rx_ack can be as high as 5ms in fast simulation mode.
+	 * Time to phy ready is < 20ms
+	 */
+	err = readl_poll_timeout(reg_phy +
+				EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0,
+			reg, !(reg & PHY_CR_PARA_CON0_PHY0_CR_PARA_ACK),
+			sleep_us, timeout_us);
+	if (err)
+		dev_err(dev, "timed out waiting for rx/tx_ack: %#.8x\n", reg);
+
+	reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
+}
+
+static void
+exynosautov920_usb31drd_cr_write(struct exynos5_usbdrd_phy *phy_drd,
+				 u16 addr, u16 data)
+{
+	struct device *dev = phy_drd->dev;
+	void __iomem *reg_phy = phy_drd->reg_phy;
+	u32 cnt = 0;
+	u32 reg = 0;
+
+	/* Pre Clocking */
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
+	reg |= PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
+
+	/*
+	 * tx clks must be available prior to assertion of tx req.
+	 * tx pstate p2 to p0 transition directly is not permitted.
+	 * tx clk ready must be asserted synchronously on tx clk prior
+	 * to internal transmit clk alignment sequence in the phy
+	 * when entering from p2 to p1 to p0.
+	 */
+	do {
+		exynosautov920_usb31drd_cr_clk(phy_drd, true);
+		exynosautov920_usb31drd_cr_clk(phy_drd, false);
+		cnt++;
+	} while (cnt < 15);
+
+	reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
+
+	/*
+	 * tx data path is active when tx lane is in p0 state
+	 * and tx data en asserted. enable cr_para_wr_en.
+	 */
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2);
+	reg &= ~PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_DATA;
+	reg |= FIELD_PREP(PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_DATA, data) |
+		PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_EN;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2);
+
+	/* write addr */
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
+	reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR;
+	reg |= FIELD_PREP(PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR, addr) |
+		PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK |
+		PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
+
+	/* check cr_para_ack*/
+	cnt = 0;
+	do {
+		/*
+		 * data symbols are captured by phy on rising edge of the
+		 * tx_clk when tx data enabled.
+		 * completion of the write cycle is acknowledged by assertion
+		 * of the cr_para_ack.
+		 */
+		exynosautov920_usb31drd_cr_clk(phy_drd, true);
+		reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
+		if ((reg & PHY_CR_PARA_CON0_PHY0_CR_PARA_ACK))
+			break;
+
+		exynosautov920_usb31drd_cr_clk(phy_drd, false);
+
+		/*
+		 * wait for minimum of 10 cr_para_clk cycles after phy reset
+		 * is negated, before accessing control regs to allow for
+		 * internal resets.
+		 */
+		cnt++;
+	} while (cnt < 10);
+
+	if (cnt == 10)
+		dev_dbg(dev, "CR write failed to 0x%04x\n", addr);
+	else
+		exynosautov920_usb31drd_cr_clk(phy_drd, false);
+}
+
+static void
+exynosautov920_usb31drd_phy_reset(struct exynos5_usbdrd_phy *phy_drd, int val)
+{
+	void __iomem *reg_phy = phy_drd->reg_phy;
+	u32 reg;
+
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL);
+	reg &= ~PHY_RST_CTRL_PHY_RESET_OVRD_EN;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL);
+
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL);
+	if (val)
+		reg |= PHY_RST_CTRL_PHY_RESET;
+	else
+		reg &= ~PHY_RST_CTRL_PHY_RESET;
+
+	reg |= PHY_RST_CTRL_PHY_RESET_OVRD_EN;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL);
+}
+
+static void
+exynosautov920_usb31drd_lane0_reset(struct exynos5_usbdrd_phy *phy_drd, int val)
+{
+	void __iomem *reg_phy = phy_drd->reg_phy;
+	u32 reg;
+
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL);
+	reg |= PHY_RST_CTRL_PIPE_LANE0_RESET_N_OVRD_EN;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL);
+
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL);
+	if (val)
+		reg &= ~PHY_RST_CTRL_PIPE_LANE0_RESET_N;
+	else
+		reg |= PHY_RST_CTRL_PIPE_LANE0_RESET_N;
+
+	reg &= ~PHY_RST_CTRL_PIPE_LANE0_RESET_N_OVRD_EN;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL);
+}
+
+static void
+exynosautov920_usb31drd_pipe3_init(struct exynos5_usbdrd_phy *phy_drd)
+{
+	void __iomem *reg_phy = phy_drd->reg_phy;
+	u32 reg;
+
+	/*
+	 * Phy and Pipe Lane reset assert.
+	 * assert reset (phy_reset = 1).
+	 * The lane-ack outputs are asserted during reset (tx_ack = rx_ack = 1)
+	 */
+	exynosautov920_usb31drd_phy_reset(phy_drd, 1);
+	exynosautov920_usb31drd_lane0_reset(phy_drd, 1);
+
+	/*
+	 * ANA Power En, PCS & PMA PWR Stable Set
+	 * ramp-up power suppiles
+	 */
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG0);
+	reg |= PHY_CONFIG0_PHY0_ANA_PWR_EN | PHY_CONFIG0_PHY0_PCS_PWR_STABLE |
+		PHY_CONFIG0_PHY0_PMA_PWR_STABLE;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG0);
+
+	fsleep(10);
+
+	/*
+	 * phy is not functional in test_powerdown mode, test_powerdown to be
+	 * de-asserted for normal operation
+	 */
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG7);
+	reg &= ~PHY_CONFIG7_PHY_TEST_POWERDOWN;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG7);
+
+	/*
+	 * phy reset signal be asserted for minimum 10us after power
+	 * supplies are ramped-up
+	 */
+	fsleep(10);
+
+	/*
+	 * Phy and Pipe Lane reset assert de-assert
+	 */
+	exynosautov920_usb31drd_phy_reset(phy_drd, 0);
+	exynosautov920_usb31drd_lane0_reset(phy_drd, 0);
+
+	/* Pipe_rx0_sris_mode_en  = 1 */
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG4);
+	reg |= PHY_CONFIG4_PIPE_RX0_SRIS_MODE_EN;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG4);
+
+	/*
+	 * wait for lane ack outputs to de-assert (tx_ack = rx_ack = 0)
+	 * Exit from the reset state is indicated by de-assertion of *_ack
+	 */
+	exynosautov920_usb31drd_port_phy_ready(phy_drd);
+
+	/* override values for level settings */
+	exynosautov920_usb31drd_cr_write(phy_drd, 0x22, 0x00F5);
+}
+
+static void
+exynosautov920_usb31drd_ssphy_disable(struct exynos5_usbdrd_phy *phy_drd)
+{
+	void __iomem *reg_phy = phy_drd->reg_phy;
+	u32 reg;
+
+	/* 1. Assert reset (phy_reset = 1) */
+	exynosautov920_usb31drd_lane0_reset(phy_drd, 1);
+	exynosautov920_usb31drd_phy_reset(phy_drd, 1);
+
+	/* phy test power down */
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG7);
+	reg |= PHY_CONFIG7_PHY_TEST_POWERDOWN;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG7);
+}
+
 static void
 exynosautov920_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd)
 {
@@ -2171,12 +2448,15 @@ exynosautov920_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd)
 	/* after POR low and delay 75us, PHYCLOCK is guaranteed. */
 	fsleep(75);
 
-	/* force pipe3 signal for link */
+	/* Disable forcing pipe interface */
 	reg = readl(reg_phy + EXYNOS850_DRD_LINKCTRL);
-	reg |= LINKCTRL_FORCE_PIPE_EN;
-	reg &= ~LINKCTRL_FORCE_PHYSTATUS;
-	reg |= LINKCTRL_FORCE_RXELECIDLE;
+	reg &= ~LINKCTRL_FORCE_PIPE_EN;
 	writel(reg, reg_phy + EXYNOS850_DRD_LINKCTRL);
+
+	/* Pclk to pipe_clk */
+	reg = readl(reg_phy + EXYNOS2200_DRD_CLKRST);
+	reg |= EXYNOS2200_CLKRST_LINK_PCLK_SEL;
+	writel(reg, reg_phy + EXYNOS2200_DRD_CLKRST);
 }
 
 static void
@@ -2263,6 +2543,8 @@ static int exynosautov920_usbdrd_combo_phy_exit(struct phy *phy)
 
 	if (inst->phy_cfg->id == EXYNOS5_DRDPHY_UTMI)
 		exynosautov920_usbdrd_hsphy_disable(phy_drd);
+	else if (inst->phy_cfg->id == EXYNOS5_DRDPHY_PIPE3)
+		exynosautov920_usb31drd_ssphy_disable(phy_drd);
 
 	/* enable PHY isol */
 	inst->phy_cfg->phy_isol(inst, true);
@@ -2319,10 +2601,44 @@ static int exynosautov920_usbdrd_phy_power_off(struct phy *phy)
 	return 0;
 }
 
+static const char * const exynosautov920_usb30_regulators[] = {
+	"dvdd075-usb30", "vdd18-usb30",
+};
+
 static const char * const exynosautov920_usb20_regulators[] = {
 	"dvdd075-usb20", "vdd18-usb20", "vdd33-usb20",
 };
 
+static const struct
+exynos5_usbdrd_phy_config usb31drd_phy_cfg_exynosautov920[] = {
+	{
+		.id		= EXYNOS5_DRDPHY_PIPE3,
+		.phy_isol	= exynos5_usbdrd_phy_isol,
+		.phy_init	= exynosautov920_usb31drd_pipe3_init,
+	},
+};
+
+static const struct phy_ops exynosautov920_usb31drd_combo_ssphy_ops = {
+	.init		= exynosautov920_usbdrd_phy_init,
+	.exit		= exynosautov920_usbdrd_combo_phy_exit,
+	.power_on	= exynosautov920_usbdrd_phy_power_on,
+	.power_off	= exynosautov920_usbdrd_phy_power_off,
+	.owner		= THIS_MODULE,
+};
+
+static const
+struct exynos5_usbdrd_phy_drvdata exynosautov920_usb31drd_combo_ssphy = {
+	.phy_cfg		= usb31drd_phy_cfg_exynosautov920,
+	.phy_ops		= &exynosautov920_usb31drd_combo_ssphy_ops,
+	.pmu_offset_usbdrd0_phy	= EXYNOSAUTOV920_PHY_CTRL_USB31,
+	.clk_names		= exynos5_clk_names,
+	.n_clks			= ARRAY_SIZE(exynos5_clk_names),
+	.core_clk_names		= exynos5_core_clk_names,
+	.n_core_clks		= ARRAY_SIZE(exynos5_core_clk_names),
+	.regulator_names	= exynosautov920_usb30_regulators,
+	.n_regulators		= ARRAY_SIZE(exynosautov920_usb30_regulators),
+};
+
 static const struct phy_ops exynosautov920_usbdrd_combo_hsphy_ops = {
 	.init		= exynosautov920_usbdrd_phy_init,
 	.exit		= exynosautov920_usbdrd_combo_phy_exit,
@@ -2587,6 +2903,9 @@ static const struct of_device_id exynos5_usbdrd_phy_of_match[] = {
 	}, {
 		.compatible = "samsung,exynos990-usbdrd-phy",
 		.data = &exynos990_usbdrd_phy
+	}, {
+		.compatible = "samsung,exynosautov920-usb31drd-combo-ssphy",
+		.data = &exynosautov920_usb31drd_combo_ssphy
 	}, {
 		.compatible = "samsung,exynosautov920-usbdrd-combo-hsphy",
 		.data = &exynosautov920_usbdrd_combo_hsphy
diff --git a/include/linux/soc/samsung/exynos-regs-pmu.h b/include/linux/soc/samsung/exynos-regs-pmu.h
index 4923f9be3d1f..f96c773b85c9 100644
--- a/include/linux/soc/samsung/exynos-regs-pmu.h
+++ b/include/linux/soc/samsung/exynos-regs-pmu.h
@@ -690,4 +690,5 @@
 
 /* exynosautov920 */
 #define EXYNOSAUTOV920_PHY_CTRL_USB20				(0x0710)
+#define EXYNOSAUTOV920_PHY_CTRL_USB31				(0x0714)
 #endif /* __LINUX_SOC_EXYNOS_REGS_PMU_H */
-- 
2.34.1



From Frank.li at nxp.com  Tue Aug  5 14:14:35 2025
From: Frank.li at nxp.com (Frank Li)
Date: Tue, 5 Aug 2025 17:14:35 -0400
Subject: [PATCH v2] phy: freescale: imx8qm-hsio: Fix a use of
 uninitialized mutex
In-Reply-To: <20250803061529.2303291-1-quanyang.wang@windriver.com>
References: <20250803061529.2303291-1-quanyang.wang@windriver.com>
Message-ID: <aJJ0O2fZgn5kvOIv@lizhi-Precision-Tower-5810>

On Sun, Aug 03, 2025 at 02:15:29PM +0800, quanyang.wang at windriver.com wrote:
> From: Quanyang Wang <quanyang.wang at windriver.com>
>
> Using an uninitialized mutex leads to the following warning when
> CONFIG_DEBUG_MUTEXES is enabled.
>
>  DEBUG_LOCKS_WARN_ON(lock->magic != lock)
>  WARNING: CPU: 2 PID: 49 at kernel/locking/mutex.c:577 __mutex_lock+0x690/0x820
>  Modules linked in:
>  CPU: 2 UID: 0 PID: 49 Comm: kworker/u16:2 Not tainted 6.16.0-04405-g4b290aae788e #23 PREEMPT
>  Hardware name: Freescale i.MX8QM MEK (DT)
>  Workqueue: events_unbound deferred_probe_work_func
>  pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
>  pc : __mutex_lock+0x690/0x820
>  lr : __mutex_lock+0x690/0x820
>  sp : ffff8000830b3900
>  x29: ffff8000830b3960 x28: ffff80008223bac0 x27: 0000000000000000
>  x26: ffff000802fc4680 x25: ffff000800019a0d x24: 0000000000000000
>  x23: ffff8000806f0d6c x22: 0000000000000002 x21: 0000000000000000
>  x20: ffff8000830b3930 x19: ffff000802338090 x18: fffffffffffe6138
>  x17: 67657220796d6d75 x16: 6420676e69737520 x15: 0000000000000038
>  x14: 0000000000000000 x13: ffff8000822636f0 x12: 000000000000044a
>  x11: 000000000000016e x10: ffff8000822bd940 x9 : ffff8000822636f0
>  x8 : 00000000ffffefff x7 : ffff8000822bb6f0 x6 : 000000000000016e
>  x5 : 000000000000016f x4 : 40000000fffff16e x3 : 0000000000000000
>  x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff0008003b8000
>  Call trace:
>   __mutex_lock+0x690/0x820 (P)
>   mutex_lock_nested+0x24/0x30
>   imx_hsio_power_on+0x4c/0x764
>   phy_power_on+0x7c/0x12c
>   imx_sata_enable+0x1ec/0x488
>   imx_ahci_probe+0x1a4/0x560
>   platform_probe+0x5c/0x98
>   really_probe+0xac/0x298
>   __driver_probe_device+0x78/0x12c
>   driver_probe_device+0xd8/0x160
>   __device_attach_driver+0xb8/0x138
>   bus_for_each_drv+0x88/0xe8
>   __device_attach+0xa0/0x190
>   device_initial_probe+0x14/0x20
>   bus_probe_device+0xac/0xb0
>   deferred_probe_work_func+0x8c/0xc8
>   process_one_work+0x1e4/0x440
>   worker_thread+0x1b4/0x350
>   kthread+0x138/0x214
>   ret_from_fork+0x10/0x20
>
> Fixes: 82c56b6dd24f ("phy: freescale: imx8qm-hsio: Add i.MX8QM HSIO PHY driver support")
> Signed-off-by: Quanyang Wang <quanyang.wang at windriver.com>

Reviewed-by: Frank Li <Frank.Li at nxp.com>

> ---
>
> Changes in v2:
> * Use devm_mutex_init instead of mutex_init, as suggested by Frank
>
>  drivers/phy/freescale/phy-fsl-imx8qm-hsio.c | 5 +++++
>  1 file changed, 5 insertions(+)
>
> diff --git a/drivers/phy/freescale/phy-fsl-imx8qm-hsio.c b/drivers/phy/freescale/phy-fsl-imx8qm-hsio.c
> index 5dca93cd325c8..348fefcfe7a5c 100644
> --- a/drivers/phy/freescale/phy-fsl-imx8qm-hsio.c
> +++ b/drivers/phy/freescale/phy-fsl-imx8qm-hsio.c
> @@ -534,6 +534,7 @@ static struct phy *imx_hsio_xlate(struct device *dev,
>  static int imx_hsio_probe(struct platform_device *pdev)
>  {
>  	int i;
> +	int ret;
>  	void __iomem *off;
>  	struct device *dev = &pdev->dev;
>  	struct device_node *np = dev->of_node;
> @@ -590,6 +591,10 @@ static int imx_hsio_probe(struct platform_device *pdev)
>  		phy_set_drvdata(phy, lane);
>  	}
>
> +	ret = devm_mutex_init(dev, &priv->lock);
> +	if (ret)
> +		return dev_err_probe(dev, ret, "Failed to initialize lock\n");
> +
>  	dev_set_drvdata(dev, priv);
>  	dev_set_drvdata(&pdev->dev, priv);
>
> --
> 2.43.0
>


From lkp at intel.com  Tue Aug  5 19:04:06 2025
From: lkp at intel.com (kernel test robot)
Date: Wed, 6 Aug 2025 10:04:06 +0800
Subject: [PATCH v3 2/5] phy: rockchip: phy-rockchip-typec: Add
 typec_mux/typec_switch support
In-Reply-To: <20250729090032.97-3-kernel@airkyi.com>
References: <20250729090032.97-3-kernel@airkyi.com>
Message-ID: <202508060926.LBB36bfZ-lkp@intel.com>

Hi Chaoyi,

kernel test robot noticed the following build warnings:

[auto build test WARNING on next-20250729]
[also build test WARNING on linus/master v6.16]
[cannot apply to robh/for-next rockchip/for-next krzk/for-next krzk-dt/for-next v6.16 v6.16-rc7 v6.16-rc6]
[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/Chaoyi-Chen/dt-bindings-phy-rockchip-rk3399-typec-phy-Support-mode-switch/20250729-170255
base:   next-20250729
patch link:    https://lore.kernel.org/r/20250729090032.97-3-kernel%40airkyi.com
patch subject: [PATCH v3 2/5] phy: rockchip: phy-rockchip-typec: Add typec_mux/typec_switch support
config: loongarch-randconfig-002-20250730 (https://download.01.org/0day-ci/archive/20250806/202508060926.LBB36bfZ-lkp at intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250806/202508060926.LBB36bfZ-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/202508060926.LBB36bfZ-lkp at intel.com/

All warnings (new ones prefixed by >>):

   vmlinux.o: warning: objtool: iov_iter_zero+0x1c4: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: copy_folio_from_iter_atomic+0x3e8: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: iov_iter_advance+0xbc: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: iov_iter_revert+0xd4: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: iov_iter_single_seg_count+0x78: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: iov_iter_is_aligned+0xe0: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: iov_iter_alignment+0xa8: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: iov_iter_npages+0xd8: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: iov_iter_extract_pages+0x1dc: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: rhashtable_jhash2+0x128: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: refcount_warn_saturate+0x50: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: string_unescape+0x2ac: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: string_escape_mem+0x3d4: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: kstrtobool+0xa0: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: vvar_fault.llvm.2652528131661753876+0x4c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: __devm_ioremap.llvm.2872827248248264962+0x78: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: zlib_inflate+0x174: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: find_poly_roots+0x5cc: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: HUF_compress1X_usingCTable_internal.llvm.16785660852261606571+0x118: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ZSTD_cParam_getBounds+0x84: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ZSTD_CCtx_setParameter+0x144: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ZSTD_CCtxParams_setParameter+0xb0: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ZSTD_CCtxParams_getParameter+0x8c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ZSTD_CCtx_setCParams+0x184: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize+0x150: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ZSTD_loadDictionaryContent+0x45c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ZSTD_buildCTable+0x84: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ZSTD_compressSuperBlock+0x180: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ZSTD_fillDoubleHashTable+0x428: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ZSTD_compressBlock_doubleFast_extDict+0x2a0: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ZSTD_fillHashTable+0x484: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ZSTD_compressBlock_fast_extDict+0x2f4: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ZSTD_dedicatedDictSearch_lazy_loadDictionary+0x680: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ZSTD_insertAndFindFirstIndex+0x240: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ZSTD_insertBt1+0x88: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: HUF_readDTableX1_wksp+0x4d4: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: HUF_decompress1X2_usingDTable_internal+0x118: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: HUF_decompress1X1_usingDTable_internal+0x128: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: HUF_decompress4X2_usingDTable_internal+0x1014: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: HUF_decompress4X1_usingDTable_internal+0xeac: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: HUF_fillDTableX2ForWeight+0x8c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: BIT_initDStream+0x104: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: BIT_initDStream+0x104: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ZSTD_getFrameHeader_advanced+0x30c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ZSTD_nextInputType+0x44: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ZSTD_decompressContinue+0x12c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ZSTD_dParam_getBounds+0x40: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ZSTD_DCtx_setParameter+0x84: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ZSTD_DCtx_getParameter+0x50: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ZSTD_decompressStream+0x33c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ZSTD_decodeLiteralsBlock+0x108: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ZSTD_buildSeqTable+0x80: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ZSTD_decompressSequencesLong+0x208: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ZSTD_decompressSequencesSplitLitBuffer+0x1e4: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ZSTD_decompressSequences+0x20c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ERR_getErrorString+0xb0: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: FSE_decompress_wksp_bmi2+0x3bc: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: xz_dec_run+0x100: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: xz_dec_lzma2_run+0xec: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: bcj_apply+0x8c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: xz_dec_bcj_reset+0x4c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ei_seq_show+0x50: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: stack_depot_save_flags+0x128: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: asn1_ber_decoder+0x1a4: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: msi_lib_init_dev_msi_info+0x90: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: rza1_irqc_set_type+0x5c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: rzv2h_icu_set_type+0xe8: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: lpic_get_gsi_domain_id+0x44: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: complete_irq_moving+0xbc: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: liointc_set_type+0x68: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: pch_pic_set_type+0x60: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: mchp_eic_domain_alloc+0xc4: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: mchp_eic_irq_set_type+0x70: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: mhi_intvec_threaded_handler+0x130: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: mhi_process_ctrl_ev_ring+0x270: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: parse_xfer_event+0xf0: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: mhi_pm_st_worker+0x154: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: mhi_async_power_up+0x14c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: phy_g12a_mipi_dphy_analog_power_on+0x8c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: brcm_sata_phy_init+0x60: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: brcm_pm_notifier+0x48: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: brcm_usb_phy_xlate+0x50: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: usb_init_xhci+0x1c0: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: cdns_torrent_phy_probe+0x824: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: cdns_torrent_phy_configure_multilink+0x8f4: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: cdns_sierra_get_optional+0xf4: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: mtk_phy_xlate+0xe0: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: mtk_phy_xlate+0xd8: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: mtk_phy_init+0x28c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: mtk_phy_init+0xb4: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: phy_type_show+0x4c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: u2_phy_params_write+0xd4: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: u2_phy_params_show+0x60: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: u3_phy_params_write+0xd4: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: u3_phy_params_show+0x58: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: mtk_xfi_tphy_set_mode+0x88: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: mtk_hdmi_pll_set_rate+0x5e8: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: rockchip_usb2phy_otg_sm_work+0xe0: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: rockchip_chg_detect_work+0x7c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: rk3588_usb2phy_tuning+0x54: sibling call from callable instruction with modified stack frame
>> vmlinux.o: warning: objtool: tcphy_typec_mux_set+0x68: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: omap_control_phy_power+0xe4: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: tusb1210_chg_det_work+0x60: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: wiz_phy_reset_deassert+0x90: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: xpsgtr_xlate+0x10c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: xpsgtr_lane_set_protocol+0x50: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: amd_gpio_dbg_show+0x144: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: amd_pinconf_get+0x8c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: amd_pinconf_set+0xdc: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: amd_gpio_irq_set_type+0x80: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: alt_gpio_irq_type+0x64: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: at91_pmx_set+0x230: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: at91_pinconf_dbg_show+0x33c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: aw9523_pconf_get+0xe0: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: aw9523_pconf_set+0x108: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: aw9523_pcfg_param_to_reg+0x54: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: cy8c95x0_writeable_register+0xa4: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: cy8c95x0_readable_register+0xa0: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: cy8c95x0_volatile_register+0x3c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: cy8c95x0_irq_set_type+0x70: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: cy8c95x0_pinconf_get+0x74: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: cy8c95x0_pinconf_set+0x110: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: eqbr_pinconf_get+0x18c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: eqbr_pinconf_set+0x14c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: funcs_utils+0x1a0: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: eqbr_gpio_set_irq_type+0x88: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: lpc18xx_pconf_get+0x1dc: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: lpc18xx_pconf_set+0x258: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: max77620_pinconf_get+0x60: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: max77620_pinconf_set+0x160: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: max77620_set_fps_param+0x7c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: pistachio_pinconf_get+0x5c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: pistachio_pinconf_set+0x124: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: pistachio_gpio_irq_set_type+0x60: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: pcs_pinconf_set+0x1a8: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: th1520_pinconf_get+0xcc: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: th1520_pinconf_set+0x11c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: owl_pin_config_get+0x7c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: owl_pin_config_set+0xcc: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: owl_group_config_get+0x12c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: owl_group_config_set+0x1e4: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: irq_set_type+0x68: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: bcm281xx_pinctrl_pin_config_set+0x354: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: bcm2835_gpio_irq_set_type+0x140: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: bcm2835_gpio_irq_config+0x60: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: bcm6362_pinctrl_set_mux+0xfc: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: bcm63268_pinctrl_set_mux+0xfc: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: iproc_gpio_irq_set_type+0x74: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: iproc_gpio_irq_set_type+0x7c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: iproc_pin_config_get+0xec: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: iproc_pin_config_set+0x174: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: nsp_gpio_irq_set_type+0xe8: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: nsp_pin_config_get+0x78: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: nsp_pin_config_set+0xc4: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: madera_pin_probe+0x90: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: madera_pin_conf_get+0xd8: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: madera_pin_conf_set+0xe4: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: mtk_pctrl_spec_pull_set_samereg+0x11c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: mtk_pconf_group_set+0xdc: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: mtk_pconf_group_set+0x158: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: mtk_pinconf_bias_set_combo+0x418: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: mtk_pinconf_get+0xfc: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: mtk_pinconf_get+0xd4: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: mtk_pinconf_set+0x130: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: mtk_pctrl_show_one_pin+0x180: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: airoha_pinconf_get+0x6c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: airoha_pinconf_set+0x100: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: airoha_irq_unmask+0xa8: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: npcm7xx_config_get+0xa0: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: npcm7xx_config_set+0xf0: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: npcmgpio_set_irq_type+0x6c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ma35_pinconf_get+0x84: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ma35_pinconf_set+0x1b8: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: ma35_irq_irqtype+0x60: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: msm_config_group_get+0xfc: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: msm_config_group_set+0xec: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: msm_config_reg+0x58: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: msm_gpio_irq_set_type+0x430: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: pm8xxx_pin_config_get+0x78: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: pm8xxx_pin_config_get+0xa0: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: pm8xxx_pin_config_set+0xc8: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: pm8xxx_pin_config_set+0xec: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: pm8xxx_mpp_probe+0x1b4: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: lpi_config_get+0x78: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: lpi_config_set+0x110: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: sh_pfc_config_mux+0x70: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: sh_pfc_pinconf_get+0x94: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: sh_pfc_pinconf_set+0xc4: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: sh_pfc_pinconf_validate+0x6c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: r8a77990_pin_to_pocctrl+0x48: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: r8a7794_pin_to_pocctrl+0x84: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: r8a77970_pin_to_pocctrl+0x48: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: r8a779h0_pin_to_pocctrl+0x4c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: rzg2l_pinctrl_pinconf_get+0x164: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: rzg2l_pinctrl_pinconf_set+0x338: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: rzv2h_hw_to_bias_param+0x3c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: rzn1_pinconf_get+0xa4: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: rzn1_pinconf_set+0xec: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: s3c64xx_gpio_irq_set_type+0x5c: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: s3c64xx_eint0_irq_set_type+0x68: sibling call from callable instruction with modified stack frame
   vmlinux.o: warning: objtool: sg2042_pconf_get+0xa4: sibling call from callable instruction with modified stack frame

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


From u-kumar1 at ti.com  Tue Aug  5 21:13:48 2025
From: u-kumar1 at ti.com (Kumar, Udit)
Date: Wed, 6 Aug 2025 09:43:48 +0530
Subject: [PATCH] drivers: phy: cadence: cdns-dphy: Enabling lower
 resolutions in dphy
In-Reply-To: <20250801115311.1384313-1-h-shenoy@ti.com>
References: <20250801115311.1384313-1-h-shenoy@ti.com>
Message-ID: <1ebb82ea-4b6c-4496-b7c0-17d4168d8ddf@ti.com>

Thanks Hari for this patch

On 8/1/2025 5:23 PM, Harikrishna Shenoy wrote:
> The patch enables cdns dphy for hs_clk_rate in range between

No need of 'The patch' word

> 80 Mbps to 160 Mbps as mentioned in TRM [0] by setting the
> pll_opdiv field to 16.This change enables lower resolutions
> like 640x480 at 60Hz.

If you like to reword commit message, please feel free to use below

Enable support for hs_clk_rate between 80-160 Mbps cdns dphy
as mentioned in TRM [0] .....
With update in commit message, Please use
Reviewed-by: Udit Kumar <u-kumar1 at ti.com>
> [0]: https://www.ti.com/lit/zip/spruil1
> (Table 12-552. DPHY_TX_PLL_CTRL Register Field Descriptions)
>
> Signed-off-by: Harikrishna Shenoy <h-shenoy at ti.com>
> ---
> Test log: https://gist.github.com/h-shenoy/3975156baf403a0ff8dbcce5b49b2b89
>
>   drivers/phy/cadence/cdns-dphy.c | 4 +++-
>   1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c
> index ed87a3970f83..9abed2ece9b0 100644
> --- a/drivers/phy/cadence/cdns-dphy.c
> +++ b/drivers/phy/cadence/cdns-dphy.c
> @@ -139,7 +139,7 @@ static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy,
>   
>   	dlane_bps = opts->hs_clk_rate;
>   
> -	if (dlane_bps > 2500000000UL || dlane_bps < 160000000UL)
> +	if (dlane_bps > 2500000000UL || dlane_bps < 80000000UL)
>   		return -EINVAL;
>   	else if (dlane_bps >= 1250000000)
>   		cfg->pll_opdiv = 1;
> @@ -149,6 +149,8 @@ static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy,
>   		cfg->pll_opdiv = 4;
>   	else if (dlane_bps >= 160000000)
>   		cfg->pll_opdiv = 8;
> +	else if (dlane_bps >= 80000000)
> +		cfg->pll_opdiv = 16;
>   
>   	cfg->pll_fbdiv = DIV_ROUND_UP_ULL(dlane_bps * 2 * cfg->pll_opdiv *
>   					  cfg->pll_ipdiv,


From h-shenoy at ti.com  Tue Aug  5 22:26:50 2025
From: h-shenoy at ti.com (Harikrishna Shenoy)
Date: Wed, 6 Aug 2025 10:56:50 +0530
Subject: [PATCH v2] drivers: phy: cadence: cdns-dphy: Enable lower resolutions in dphy
Message-ID: <20250806052650.429767-1-h-shenoy@ti.com>

Enable support for hs_clk_rate between 80-160 Mbps cdns dphy
as mentioned in TRM [0] by setting the pll_opdiv field to 16.
This change enables lower resolutions like 640x480 at 60Hz.

[0]: https://www.ti.com/lit/zip/spruil1
(Table 12-552. DPHY_TX_PLL_CTRL Register Field Descriptions)

Reviewed-by: Udit Kumar <u-kumar1 at ti.com>
Signed-off-by: Harikrishna Shenoy <h-shenoy at ti.com>
---
Changes in v2:
- Updated commit message and title.
- Added Reviewed-by tag.
- Link to v1: https://lore.kernel.org/all/1ebb82ea-4b6c-4496-b7c0-17d4168d8ddf at ti.com/

Test log: https://gist.github.com/h-shenoy/3975156baf403a0ff8dbcce5b49b2b89

 drivers/phy/cadence/cdns-dphy.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c
index ed87a3970f83..9abed2ece9b0 100644
--- a/drivers/phy/cadence/cdns-dphy.c
+++ b/drivers/phy/cadence/cdns-dphy.c
@@ -139,7 +139,7 @@ static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy,
 
 	dlane_bps = opts->hs_clk_rate;
 
-	if (dlane_bps > 2500000000UL || dlane_bps < 160000000UL)
+	if (dlane_bps > 2500000000UL || dlane_bps < 80000000UL)
 		return -EINVAL;
 	else if (dlane_bps >= 1250000000)
 		cfg->pll_opdiv = 1;
@@ -149,6 +149,8 @@ static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy,
 		cfg->pll_opdiv = 4;
 	else if (dlane_bps >= 160000000)
 		cfg->pll_opdiv = 8;
+	else if (dlane_bps >= 80000000)
+		cfg->pll_opdiv = 16;
 
 	cfg->pll_fbdiv = DIV_ROUND_UP_ULL(dlane_bps * 2 * cfg->pll_opdiv *
 					  cfg->pll_ipdiv,
-- 
2.34.1



From devarsht at ti.com  Tue Aug  5 22:55:19 2025
From: devarsht at ti.com (devarsh)
Date: Wed, 6 Aug 2025 11:25:19 +0530
Subject: [PATCH v2] drivers: phy: cadence: cdns-dphy: Enable lower
 resolutions in dphy
In-Reply-To: <20250806052650.429767-1-h-shenoy@ti.com>
References: <20250806052650.429767-1-h-shenoy@ti.com>
Message-ID: <385d9185-e187-48c2-9854-10cdd98d2f1b@ti.com>

On 06/08/25 10:56, Harikrishna Shenoy wrote:
> Enable support for hs_clk_rate between 80-160 Mbps cdns dphy

Enable support for data lane rates between 80-160 Mbps

> as mentioned in TRM [0] by setting the pll_opdiv field to 16.
> This change enables lower resolutions like 640x480 at 60Hz.
> 
> [0]: https://www.ti.com/lit/zip/spruil1
> (Table 12-552. DPHY_TX_PLL_CTRL Register Field Descriptions)
> 
> Reviewed-by: Udit Kumar <u-kumar1 at ti.com>
> Signed-off-by: Harikrishna Shenoy <h-shenoy at ti.com>

With suggested change,
Reviewed-by: Devarsh Thakkar <devarsht at ti.com>

Regards
Devarsh
> ---
> Changes in v2:
> - Updated commit message and title.
> - Added Reviewed-by tag.
> - Link to v1: https://lore.kernel.org/all/1ebb82ea-4b6c-4496-b7c0-17d4168d8ddf at ti.com/
> 
> Test log: https://gist.github.com/h-shenoy/3975156baf403a0ff8dbcce5b49b2b89
> 
>  drivers/phy/cadence/cdns-dphy.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c
> index ed87a3970f83..9abed2ece9b0 100644
> --- a/drivers/phy/cadence/cdns-dphy.c
> +++ b/drivers/phy/cadence/cdns-dphy.c
> @@ -139,7 +139,7 @@ static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy,
>  
>  	dlane_bps = opts->hs_clk_rate;
>  
> -	if (dlane_bps > 2500000000UL || dlane_bps < 160000000UL)
> +	if (dlane_bps > 2500000000UL || dlane_bps < 80000000UL)
>  		return -EINVAL;
>  	else if (dlane_bps >= 1250000000)
>  		cfg->pll_opdiv = 1;
> @@ -149,6 +149,8 @@ static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy,
>  		cfg->pll_opdiv = 4;
>  	else if (dlane_bps >= 160000000)
>  		cfg->pll_opdiv = 8;
> +	else if (dlane_bps >= 80000000)
> +		cfg->pll_opdiv = 16;
>  
>  	cfg->pll_fbdiv = DIV_ROUND_UP_ULL(dlane_bps * 2 * cfg->pll_opdiv *
>  					  cfg->pll_ipdiv,



From vkoul at kernel.org  Wed Aug  6 03:54:16 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 6 Aug 2025 16:24:16 +0530
Subject: [PATCH 0/2] phy: cdns-dphy: hs-clk improvement and a cleanup
In-Reply-To: <cc0e4cf5-1bd9-4ae3-a130-0483dbfc6335@ideasonboard.com>
References: <20250723-cdns-dphy-hs-clk-rate-fix-v1-0-d4539d44cbe7@ideasonboard.com>
 <cc0e4cf5-1bd9-4ae3-a130-0483dbfc6335@ideasonboard.com>
Message-ID: <aJM0WPVDUkte9E_D@vaman>

On 05-08-25, 15:03, Tomi Valkeinen wrote:
> Hi Vinod, Kishon,
> 
> On 23/07/2025 13:01, Tomi Valkeinen wrote:
> > A cdns-dphy improvement to return the actual hs clock rate, and a
> > cleanup to remove leftover code.
> > 
> > These were part of a Cadence DSI series:
> > 
> > https://lore.kernel.org/all/20250618-cdns-dsi-impro-v4-0-862c841dbe02%40ideasonboard.com/
> > 
> > but are now separately here for easier merging.
> > 
> > Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
> > ---
> > Tomi Valkeinen (2):
> >       phy: cdns-dphy: Store hs_clk_rate and return it
> >       phy: cdns-dphy: Remove leftover code
> > 
> >  drivers/phy/cadence/cdns-dphy.c | 24 +++++++++---------------
> >  1 file changed, 9 insertions(+), 15 deletions(-)
> > ---
> > base-commit: 89be9a83ccf1f88522317ce02f854f30d6115c41
> > change-id: 20250723-cdns-dphy-hs-clk-rate-fix-a8857a5789dd
> 
> Is this good to merge, and if so, do you have any estimate when? While
> this is independent from the DSI series, I'd rather push the DSI series
> into drm-misc about the same time, so both would appear in linux-next
> relatively together.

I will start taking patches after merge window closes next monday, so
next week should be a good estimate

-- 
~Vinod


From rick.wertenbroek at gmail.com  Wed Aug  6 06:38:20 2025
From: rick.wertenbroek at gmail.com (Rick Wertenbroek)
Date: Wed,  6 Aug 2025 15:38:20 +0200
Subject: [PATCH v2 0/3] phy: rockchip-snps-pcie3: add support for rockchip,phy-ref-use-pad
Message-ID: <20250806133824.525871-1-rick.wertenbroek@gmail.com>

Add the possibility for the RK3588 PCIe PHYs to use an internal clock instead of
a clock provided on a pin of the device. This allows boards that don't have a
PCIe clock connected to the reference pad to still function in separate clock
mode by using an internal reference clock for the PCIe PHYs.

This was tested with a CM3588 compute module on a custom PCB.

Without the new option, the default behaviour (PHYs using external pad for clock)
is applied, to keep compatibility with existing device trees.

Differences from V1 [1] :

- Documented the phy-ref-use-pad option in the DT bindings.
- Documented the extra optional differential clocks for the PHYs in the DT
  bindings.

[1] https://lore.kernel.org/all/20250715105820.4037272-1-rick.wertenbroek at gmail.com/

Rick Wertenbroek (3):
  dt-bindings: phy: rockchip,pcie3-phy: add optional differential phy
    clocks
  phy: rockchip-snps-pcie3: add support for rockchip,phy-ref-use-pad
  dt-bindings: phy: rockchip,pcie3-phy: add rockchip,phy-ref-use-pad

 .../bindings/phy/rockchip,pcie3-phy.yaml      | 21 ++++++++++--
 .../phy/rockchip/phy-rockchip-snps-pcie3.c    | 32 +++++++++++++++++++
 2 files changed, 50 insertions(+), 3 deletions(-)

-- 
2.25.1



From rick.wertenbroek at gmail.com  Wed Aug  6 06:38:21 2025
From: rick.wertenbroek at gmail.com (Rick Wertenbroek)
Date: Wed,  6 Aug 2025 15:38:21 +0200
Subject: [PATCH v2 1/3] dt-bindings: phy: rockchip,pcie3-phy: add optional differential phy clocks
In-Reply-To: <20250806133824.525871-1-rick.wertenbroek@gmail.com>
References: <20250806133824.525871-1-rick.wertenbroek@gmail.com>
Message-ID: <20250806133824.525871-2-rick.wertenbroek@gmail.com>

Both PHYs can use an alternate reference differential clock, add the clocks
to the DT bindings

Signed-off-by: Rick Wertenbroek <rick.wertenbroek at gmail.com>
---
 .../devicetree/bindings/phy/rockchip,pcie3-phy.yaml   | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/rockchip,pcie3-phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,pcie3-phy.yaml
index d7de8b527c5c..b747930b18f1 100644
--- a/Documentation/devicetree/bindings/phy/rockchip,pcie3-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/rockchip,pcie3-phy.yaml
@@ -20,11 +20,11 @@ properties:
 
   clocks:
     minItems: 1
-    maxItems: 3
+    maxItems: 5
 
   clock-names:
     minItems: 1
-    maxItems: 3
+    maxItems: 5
 
   data-lanes:
     description: which lanes (by position) should be mapped to which
@@ -82,10 +82,15 @@ allOf:
     then:
       properties:
         clocks:
-          maxItems: 1
+          minItems: 1
+          maxItems: 5
         clock-names:
           items:
             - const: pclk
+            - const: phy0_ref_alt_p
+            - const: phy0_ref_alt_m
+            - const: phy1_ref_alt_p
+            - const: phy1_ref_alt_m
     else:
       properties:
         clocks:
-- 
2.25.1



From rick.wertenbroek at gmail.com  Wed Aug  6 06:38:22 2025
From: rick.wertenbroek at gmail.com (Rick Wertenbroek)
Date: Wed,  6 Aug 2025 15:38:22 +0200
Subject: [PATCH v2 2/3] phy: rockchip-snps-pcie3: add support for rockchip,phy-ref-use-pad
In-Reply-To: <20250806133824.525871-1-rick.wertenbroek@gmail.com>
References: <20250806133824.525871-1-rick.wertenbroek@gmail.com>
Message-ID: <20250806133824.525871-3-rick.wertenbroek@gmail.com>

>From the RK3588 Technical Reference Manual, Part1,
section 6.19 PCIe3PHY_GRF Register Description: "ref_use_pad"

"Select reference clock connected to ref_pad_clk_p/ref_pad_clk_m.
Selects the external ref_pad_clk_p and ref_pad_clk_m inputs as the
reference clock source when asserted. When de-asserted, ref_alt_clk_p
and ref_alt_clk_m are the sources of the reference clock."

The hardware reset value for this field is 0x1 (enabled).
Note that this register field is only available on RK3588, not on RK3568.

Add support for the device tree property rockchip,phy-ref-use-pad,
such that the PCIe PHY can be used on boards where there is no PCIe
reference clock generated or connected to the external pad, by setting
this property to 0 so that the internal clock is used.

DT bindings for internal clocks are CLK_PHY0_REF_ALT_P/M and
CLK_PHY1_REF_ALT_P/M and clock rate should be set to 100MHz in
the RK3588 cru clock controller (PLL_PPLL).

Example DT overlay where PHY0 uses internal clock (the first clock of
the cru (PLL_PPLL) must be set to 100MHz, other values are copied from
rk3588-base.dtsi) and PHY1 uses the external pad (the default):

---
&cru {
        assigned-clock-rates =
                <100000000>, <786432000>,
                <850000000>, <1188000000>,
                <702000000>,
                <400000000>, <500000000>,
                <800000000>, <100000000>,
                <400000000>, <100000000>,
                <200000000>, <500000000>,
                <375000000>, <150000000>,
                <200000000>;
};

&pcie30phy {
        rockchip,rx-common-refclk-mode = <0 0 1 1>;
        rockchip,phy-ref-use-pad = <0 1>;
        clocks = <&cru PCLK_PCIE_COMBO_PIPE_PHY>, <&cru CLK_PHY0_REF_ALT_P>,
                         <&cru CLK_PHY0_REF_ALT_M>, <&cru CLK_PHY1_REF_ALT_P>,
                         <&cru CLK_PHY1_REF_ALT_M>;
        clock-names = "pclk", "phy0_ref_alt_p",
                              "phy0_ref_alt_m", "phy1_ref_alt_p",
                              "phy1_ref_alt_m";
};
---

Signed-off-by: Rick Wertenbroek <rick.wertenbroek at gmail.com>
---
 .../phy/rockchip/phy-rockchip-snps-pcie3.c    | 32 +++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c
index 4e8ffd173096..0859c7960167 100644
--- a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c
+++ b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c
@@ -33,6 +33,8 @@
 /* Register for RK3588 */
 #define PHP_GRF_PCIESEL_CON			0x100
 #define RK3588_PCIE3PHY_GRF_CMN_CON0		0x0
+#define RK3588_PCIE3PHY_GRF_PHY0_CONTROL6	0x118
+#define RK3588_PCIE3PHY_GRF_PHY1_CONTROL6	0x218
 #define RK3588_PCIE3PHY_GRF_PHY0_STATUS1	0x904
 #define RK3588_PCIE3PHY_GRF_PHY1_STATUS1	0xa04
 #define RK3588_PCIE3PHY_GRF_PHY0_LN0_CON1	0x1004
@@ -44,6 +46,8 @@
 #define RK3588_BIFURCATION_LANE_0_1		BIT(0)
 #define RK3588_BIFURCATION_LANE_2_3		BIT(1)
 #define RK3588_LANE_AGGREGATION		BIT(2)
+#define RK3588_PHY_REF_USE_PAD_EN		((BIT(2) << 16 | BIT(2)))
+#define RK3588_PHY_REF_USE_PAD_DIS		((BIT(2) << 16))
 #define RK3588_RX_CMN_REFCLK_MODE_EN		((BIT(7) << 16) |  BIT(7))
 #define RK3588_RX_CMN_REFCLK_MODE_DIS		(BIT(7) << 16)
 #define RK3588_PCIE1LN_SEL_EN			(GENMASK(1, 0) << 16)
@@ -67,6 +71,7 @@ struct rockchip_p3phy_priv {
 	int num_lanes;
 	u32 lanes[4];
 	u32 rx_cmn_refclk_mode[4];
+	u32 phy_ref_use_pad[2];
 };
 
 struct rockchip_p3phy_ops {
@@ -157,6 +162,14 @@ static int rockchip_p3phy_rk3588_init(struct rockchip_p3phy_priv *priv)
 		     priv->rx_cmn_refclk_mode[3] ? RK3588_RX_CMN_REFCLK_MODE_EN :
 		     RK3588_RX_CMN_REFCLK_MODE_DIS);
 
+	/* Select PHY reference clock, external pad or internal clock */
+	regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_PHY0_CONTROL6,
+		     priv->phy_ref_use_pad[0] ? RK3588_PHY_REF_USE_PAD_EN :
+		     RK3588_PHY_REF_USE_PAD_DIS);
+	regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_PHY1_CONTROL6,
+		     priv->phy_ref_use_pad[1] ? RK3588_PHY_REF_USE_PAD_EN :
+		     RK3588_PHY_REF_USE_PAD_DIS);
+
 	/* Deassert PCIe PMA output clamp mode */
 	regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_CMN_CON0, BIT(8) | BIT(24));
 
@@ -312,6 +325,25 @@ static int rockchip_p3phy_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	ret = of_property_read_variable_u32_array(dev->of_node,
+						  "rockchip,phy-ref-use-pad",
+						  priv->phy_ref_use_pad, 1,
+						  ARRAY_SIZE(priv->phy_ref_use_pad));
+
+	/*
+	 * if no rockhip,phy-use-internal-clk, assume PHY uses pad for the
+	 * reference clock in order to be DT backwards compatible. (Since HW
+	 * reset val is enabled.)
+	 */
+	if (ret == -EINVAL) {
+		for (int i = 0; i < ARRAY_SIZE(priv->phy_ref_use_pad); i++)
+			priv->phy_ref_use_pad[i] = 1;
+	} else if (ret < 0) {
+		dev_err(dev, "failed to read rockchip,phy-ref-use-pad property %d\n",
+			ret);
+		return ret;
+	}
+
 	priv->phy = devm_phy_create(dev, NULL, &rockchip_p3phy_ops);
 	if (IS_ERR(priv->phy)) {
 		dev_err(dev, "failed to create combphy\n");
-- 
2.25.1



From rick.wertenbroek at gmail.com  Wed Aug  6 06:38:23 2025
From: rick.wertenbroek at gmail.com (Rick Wertenbroek)
Date: Wed,  6 Aug 2025 15:38:23 +0200
Subject: [PATCH v2 3/3] dt-bindings: phy: rockchip,pcie3-phy: add rockchip,phy-ref-use-pad
In-Reply-To: <20250806133824.525871-1-rick.wertenbroek@gmail.com>
References: <20250806133824.525871-1-rick.wertenbroek@gmail.com>
Message-ID: <20250806133824.525871-4-rick.wertenbroek@gmail.com>

>From the RK3588 Technical Reference Manual, Part1,
section 6.19 PCIe3PHY_GRF Register Description: "ref_use_pad"

"Select reference clock connected to ref_pad_clk_p/ref_pad_clk_m.
Selects the external ref_pad_clk_p and ref_pad_clk_m inputs as the
reference clock source when asserted. When de-asserted, ref_alt_clk_p
and ref_alt_clk_m are the sources of the reference clock."

The hardware reset value for this field is 0x1 (enabled).
Note that this register field is only available on RK3588, not on RK3568.

Add support for the device tree property rockchip,phy-ref-use-pad,
such that the PCIe PHY can be used on boards where there is no PCIe
reference clock generated or connected to the external pad, by setting
this property to 0 so that the internal clock is used.

DT bindings for internal clocks are CLK_PHY0_REF_ALT_P/M and
CLK_PHY1_REF_ALT_P/M and clock rate should be set to 100MHz in
the RK3588 cru clock controller (PLL_PPLL).

Example DT overlay where PHY0 uses internal clock (the first clock of
the cru (PLL_PPLL) must be set to 100MHz, other values are copied from
rk3588-base.dtsi) and PHY1 uses the external pad (the default):

---
&cru {
        assigned-clock-rates =
                <100000000>, <786432000>,
                <850000000>, <1188000000>,
                <702000000>,
                <400000000>, <500000000>,
                <800000000>, <100000000>,
                <400000000>, <100000000>,
                <200000000>, <500000000>,
                <375000000>, <150000000>,
                <200000000>;
};

&pcie30phy {
        rockchip,rx-common-refclk-mode = <0 0 1 1>;
        rockchip,phy-ref-use-pad = <0 1>;
        clocks = <&cru PCLK_PCIE_COMBO_PIPE_PHY>, <&cru CLK_PHY0_REF_ALT_P>,
                         <&cru CLK_PHY0_REF_ALT_M>, <&cru CLK_PHY1_REF_ALT_P>,
                         <&cru CLK_PHY1_REF_ALT_M>;
        clock-names = "pclk", "phy0_ref_alt_p",
                              "phy0_ref_alt_m", "phy1_ref_alt_p",
                              "phy1_ref_alt_m";
};
---

Signed-off-by: Rick Wertenbroek <rick.wertenbroek at gmail.com>
---
 .../devicetree/bindings/phy/rockchip,pcie3-phy.yaml    | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/rockchip,pcie3-phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,pcie3-phy.yaml
index b747930b18f1..d9b9d7eabb81 100644
--- a/Documentation/devicetree/bindings/phy/rockchip,pcie3-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/rockchip,pcie3-phy.yaml
@@ -67,6 +67,16 @@ properties:
       minimum: 0
       maximum: 1
 
+  rockchip,phy-ref-use-pad:
+    description: which PHY should use the external pad as PCIe reference clock.
+      1 means use pad (default), 0 means use internal clock (PLL_PPLL).
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    minItems: 2
+    maxItems: 2
+    items:
+      minimum: 0
+      maximum: 1
+
 required:
   - compatible
   - reg
-- 
2.25.1



From mwalle at kernel.org  Wed Aug  6 06:59:13 2025
From: mwalle at kernel.org (Michael Walle)
Date: Wed,  6 Aug 2025 15:59:13 +0200
Subject: [PATCH v2] phy: ti: gmii-sel: Force RGMII TX delay
Message-ID: <20250806135913.662340-1-mwalle@kernel.org>

Some SoCs are just validated with the TX delay enabled. With commit
ca13b249f291 ("net: ethernet: ti: am65-cpsw: fixup PHY mode for fixed
RGMII TX delay"), the network driver will patch the delay setting on the
fly assuming that the TX delay is fixed. In reality, the TX delay is
configurable and just skipped in the documentation. There are
bootloaders, which will disable the TX delay and this will lead to a
transmit path which doesn't add any delays at all. Fix that by always
forcing the TX delay to be enabled.

This is safe to do and shouldn't break any boards in mainline because
the fixed delay is only introduced for gmii-sel compatibles which are
used together with the am65-cpsw-nuss driver and are affected by the
commit above.

Fixes: ca13b249f291 ("net: ethernet: ti: am65-cpsw: fixup PHY mode for fixed RGMII TX delay")
Signed-off-by: Michael Walle <mwalle at kernel.org>
---
v2:
 - reject invalid PHY modes. Thanks Matthias.
 - add a paragraph to the commit message that this patch shouldn't
   break any existing boards. Thanks Andrew.

 drivers/phy/ti/phy-gmii-sel.c | 58 ++++++++++++++++++++++++++++++-----
 1 file changed, 50 insertions(+), 8 deletions(-)

diff --git a/drivers/phy/ti/phy-gmii-sel.c b/drivers/phy/ti/phy-gmii-sel.c
index ff5d5e29629f..ed078475c4cb 100644
--- a/drivers/phy/ti/phy-gmii-sel.c
+++ b/drivers/phy/ti/phy-gmii-sel.c
@@ -34,6 +34,7 @@ enum {
 	PHY_GMII_SEL_PORT_MODE = 0,
 	PHY_GMII_SEL_RGMII_ID_MODE,
 	PHY_GMII_SEL_RMII_IO_CLK_EN,
+	PHY_GMII_SEL_FIXED_TX_DELAY,
 	PHY_GMII_SEL_LAST,
 };
 
@@ -127,6 +128,22 @@ static int phy_gmii_sel_mode(struct phy *phy, enum phy_mode mode, int submode)
 		goto unsupported;
 	}
 
+	/*
+	 * Some SoCs only support fixed MAC side TX delays. According to the
+	 * datasheet, they are always enabled, but that turns out not to be the
+	 * case and the delay is configurable. But according to the vendor that
+	 * mode is not validated and might not work. Some bootloaders disable
+	 * this bit. To work around that, enable it again.
+	 */
+	if (soc_data->features & BIT(PHY_GMII_SEL_FIXED_TX_DELAY)) {
+		/* With a fixed delay, some modes are not supported at all. */
+		if (submode == PHY_INTERFACE_MODE_RGMII_ID ||
+		    submode == PHY_INTERFACE_MODE_RGMII_TXID)
+			return -EINVAL;
+
+		rgmii_id = 0;
+	}
+
 	if_phy->phy_if_mode = submode;
 
 	dev_dbg(dev, "%s id:%u mode:%u rgmii_id:%d rmii_clk_ext:%d\n",
@@ -210,25 +227,46 @@ struct phy_gmii_sel_soc_data phy_gmii_sel_soc_dm814 = {
 
 static const
 struct reg_field phy_gmii_sel_fields_am654[][PHY_GMII_SEL_LAST] = {
-	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x0, 0, 2), },
-	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x4, 0, 2), },
-	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x8, 0, 2), },
-	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0xC, 0, 2), },
-	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x10, 0, 2), },
-	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x14, 0, 2), },
-	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x18, 0, 2), },
-	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x1C, 0, 2), },
+	{
+		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x0, 0, 2),
+		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x0, 4, 4),
+	}, {
+		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x4, 0, 2),
+		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x4, 4, 4),
+	}, {
+		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x8, 0, 2),
+		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x8, 4, 4),
+	}, {
+		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0xC, 0, 2),
+		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0xC, 4, 4),
+	}, {
+		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x10, 0, 2),
+		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x10, 4, 4),
+	}, {
+		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x14, 0, 2),
+		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x14, 4, 4),
+	}, {
+		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x18, 0, 2),
+		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x18, 4, 4),
+	}, {
+		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x1C, 0, 2),
+		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x1C, 4, 4),
+	},
 };
 
 static const
 struct phy_gmii_sel_soc_data phy_gmii_sel_soc_am654 = {
 	.use_of_data = true,
+	.features = BIT(PHY_GMII_SEL_RGMII_ID_MODE) |
+		    BIT(PHY_GMII_SEL_FIXED_TX_DELAY),
 	.regfields = phy_gmii_sel_fields_am654,
 };
 
 static const
 struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw5g_soc_j7200 = {
 	.use_of_data = true,
+	.features = BIT(PHY_GMII_SEL_RGMII_ID_MODE) |
+		    BIT(PHY_GMII_SEL_FIXED_TX_DELAY),
 	.regfields = phy_gmii_sel_fields_am654,
 	.extra_modes = BIT(PHY_INTERFACE_MODE_QSGMII) | BIT(PHY_INTERFACE_MODE_SGMII) |
 		       BIT(PHY_INTERFACE_MODE_USXGMII),
@@ -239,6 +277,8 @@ struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw5g_soc_j7200 = {
 static const
 struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw9g_soc_j721e = {
 	.use_of_data = true,
+	.features = BIT(PHY_GMII_SEL_RGMII_ID_MODE) |
+		    BIT(PHY_GMII_SEL_FIXED_TX_DELAY),
 	.regfields = phy_gmii_sel_fields_am654,
 	.extra_modes = BIT(PHY_INTERFACE_MODE_QSGMII) | BIT(PHY_INTERFACE_MODE_SGMII),
 	.num_ports = 8,
@@ -248,6 +288,8 @@ struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw9g_soc_j721e = {
 static const
 struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw9g_soc_j784s4 = {
 	.use_of_data = true,
+	.features = BIT(PHY_GMII_SEL_RGMII_ID_MODE) |
+		    BIT(PHY_GMII_SEL_FIXED_TX_DELAY),
 	.regfields = phy_gmii_sel_fields_am654,
 	.extra_modes = BIT(PHY_INTERFACE_MODE_QSGMII) | BIT(PHY_INTERFACE_MODE_SGMII) |
 		       BIT(PHY_INTERFACE_MODE_USXGMII),
-- 
2.39.5



From neil.armstrong at linaro.org  Wed Aug  6 07:06:02 2025
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Wed, 6 Aug 2025 16:06:02 +0200
Subject: [PATCH 2/5] phy: renesas: rcar-gen3-usb2: Store drvdata pointer
 in channel
In-Reply-To: <20250805122529.2566580-3-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20250805122529.2566580-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <20250805122529.2566580-3-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <9549b800-2205-428a-8056-cfc6b5255850@linaro.org>

On 05/08/2025 14:25, Prabhakar wrote:
> From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> 
> Store the SoC-specific driver data pointer (struct rcar_gen3_phy_drv_data)
> directly in struct rcar_gen3_chan instead of copying individual flags
> into separate fields. Update all references to use channel->drvdata->flags,
> removing the redundant soc_no_adp_ctrl and utmi_ctrl members from the
> channel structure.
> 
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> ---
>   drivers/phy/renesas/phy-rcar-gen3-usb2.c | 17 +++++++----------
>   1 file changed, 7 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> index 47beb94cd424..cfa9667c7680 100644
> --- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> +++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> @@ -122,6 +122,7 @@ struct rcar_gen3_phy {
>   struct rcar_gen3_chan {
>   	void __iomem *base;
>   	struct device *dev;	/* platform_device's device */
> +	const struct rcar_gen3_phy_drv_data *drvdata;

Why not phy_data ?

>   	struct extcon_dev *extcon;
>   	struct rcar_gen3_phy rphys[NUM_OF_PHYS];
>   	struct regulator *vbus;
> @@ -133,8 +134,6 @@ struct rcar_gen3_chan {
>   	bool extcon_host;
>   	bool is_otg_channel;
>   	bool uses_otg_pins;
> -	bool soc_no_adp_ctrl;
> -	bool utmi_ctrl;
>   };
>   
>   struct rcar_gen3_phy_drv_data {
> @@ -204,7 +203,7 @@ static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus)
>   	u32 val;
>   
>   	dev_vdbg(ch->dev, "%s: %08x, %d\n", __func__, val, vbus);
> -	if (ch->soc_no_adp_ctrl) {
> +	if (ch->drvdata->no_adp_ctrl) {
>   		if (ch->vbus)
>   			regulator_hardware_enable(ch->vbus, vbus);
>   
> @@ -290,7 +289,7 @@ static bool rcar_gen3_check_id(struct rcar_gen3_chan *ch)
>   	if (!ch->uses_otg_pins)
>   		return (ch->dr_mode == USB_DR_MODE_HOST) ? false : true;
>   
> -	if (ch->soc_no_adp_ctrl)
> +	if (ch->drvdata->no_adp_ctrl)
>   		return !!(readl(ch->base + USB2_LINECTRL1) & USB2_LINECTRL1_USB2_IDMON);
>   
>   	return !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG);
> @@ -421,7 +420,7 @@ static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch)
>   	      USB2_LINECTRL1_DMRPD_EN | USB2_LINECTRL1_DM_RPD;
>   	writel(val, usb2_base + USB2_LINECTRL1);
>   
> -	if (!ch->soc_no_adp_ctrl) {
> +	if (!ch->drvdata->no_adp_ctrl) {
>   		val = readl(usb2_base + USB2_VBCTRL);
>   		val &= ~USB2_VBCTRL_OCCLREN;
>   		writel(val | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL);
> @@ -487,7 +486,7 @@ static int rcar_gen3_phy_usb2_init(struct phy *p)
>   	if (rphy->int_enable_bits)
>   		rcar_gen3_init_otg(channel);
>   
> -	if (channel->utmi_ctrl) {
> +	if (channel->drvdata->utmi_ctrl) {
>   		val = readl(usb2_base + USB2_REGEN_CG_CTRL) | USB2_REGEN_CG_CTRL_UPHY_WEN;
>   		writel(val, usb2_base + USB2_REGEN_CG_CTRL);
>   
> @@ -778,6 +777,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
>   		ret = -EINVAL;
>   		goto error;
>   	}
> +	channel->drvdata = phy_data;

Replace the whole block with:
	
	channel->drvdata = device_get_match_data(dev);
	if (!channel->drvdata) {
		ret = -EINVAL;
		goto error;
	}

and drop the local phy_data.

>   
>   	platform_set_drvdata(pdev, channel);
>   	channel->dev = dev;
> @@ -788,12 +788,9 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
>   			goto error;
>   	}
>   
> -	channel->soc_no_adp_ctrl = phy_data->no_adp_ctrl;
>   	if (phy_data->no_adp_ctrl)
>   		channel->obint_enable_bits = USB2_OBINT_IDCHG_EN;
>   
> -	channel->utmi_ctrl = phy_data->utmi_ctrl;
> -
>   	spin_lock_init(&channel->lock);
>   	for (i = 0; i < NUM_OF_PHYS; i++) {
>   		channel->rphys[i].phy = devm_phy_create(dev, NULL,
> @@ -808,7 +805,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
>   		phy_set_drvdata(channel->rphys[i].phy, &channel->rphys[i]);
>   	}
>   

Thanks,
Neil
> -	if (channel->soc_no_adp_ctrl && channel->is_otg_channel)
> +	if (channel->drvdata->no_adp_ctrl && channel->is_otg_channel)
>   		channel->vbus = devm_regulator_get_exclusive(dev, "vbus");
>   	else
>   		channel->vbus = devm_regulator_get_optional(dev, "vbus");



From neil.armstrong at linaro.org  Wed Aug  6 07:07:14 2025
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Wed, 6 Aug 2025 16:07:14 +0200
Subject: [PATCH 3/5] phy: renesas: rcar-gen3-usb2: Allow SoC-specific
 OBINT bits via phy_data
In-Reply-To: <20250805122529.2566580-4-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20250805122529.2566580-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <20250805122529.2566580-4-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <313c8333-3a02-439f-825f-35ebe0592a4d@linaro.org>

On 05/08/2025 14:25, Prabhakar wrote:
> From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> 
> Update the PHY driver to support SoC-specific OBINT enable bits by
> introducing the `obint_enable_bits` field in the `rcar_gen3_phy_drv_data`
> structure. This allows each SoC to specify bits required.
> 
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> ---
>   drivers/phy/renesas/phy-rcar-gen3-usb2.c | 27 ++++++++++++------------
>   1 file changed, 14 insertions(+), 13 deletions(-)
> 

<snip>

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>



From neil.armstrong at linaro.org  Wed Aug  6 07:07:53 2025
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Wed, 6 Aug 2025 16:07:53 +0200
Subject: [PATCH 4/5] phy: renesas: rcar-gen3-usb2: Add support for RZ/T2H
 SoC
In-Reply-To: <20250805122529.2566580-5-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20250805122529.2566580-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <20250805122529.2566580-5-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <6ecd2cac-87cb-4921-8c8c-0f04112dff2d@linaro.org>

On 05/08/2025 14:25, Prabhakar wrote:
> From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> 
> Add initial support for the Renesas RZ/T2H SoC to the R-Car Gen3 USB2 PHY
> driver. The RZ/T2H SoC requires configuration of additional
> hardware-specific bits for proper VBUS level control and OTG operation.
> 
> Introduce the `vblvl_ctrl` flag in the SoC-specific driver data to enable
> handling of VBUS level selection logic using `VBCTRL.VBLVL` bits. This is
> required for managing the VBUS status detection and drive logic based on
> SoC-specific needs.
> 
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> ---
>   drivers/phy/renesas/phy-rcar-gen3-usb2.c | 85 ++++++++++++++++++++++--
>   1 file changed, 78 insertions(+), 7 deletions(-)
> 
<snip>

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From neil.armstrong at linaro.org  Wed Aug  6 07:08:17 2025
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Wed, 6 Aug 2025 16:08:17 +0200
Subject: [PATCH 5/5] phy: renesas: rcar-gen3-usb2: Move debug print after
 register value is updated
In-Reply-To: <20250805122529.2566580-6-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20250805122529.2566580-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <20250805122529.2566580-6-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <8f1ded5f-430d-4e9d-a328-aecaef1e6d60@linaro.org>

On 05/08/2025 14:25, Prabhakar wrote:
> From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> 
> Relocate the debug print in rcar_gen3_enable_vbus_ctrl() to appear after
> the `val` variable is assigned and updated based on the VBUS state. This
> ensures that the debug log reflects the actual register value being
> written, improving debugging accuracy.
> 
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> ---
>   drivers/phy/renesas/phy-rcar-gen3-usb2.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
<snip>

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From neil.armstrong at linaro.org  Wed Aug  6 07:29:54 2025
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Wed, 6 Aug 2025 16:29:54 +0200
Subject: [PATCH 00/11] phy: drop unused module aliases
In-Reply-To: <20250724154823.15998-1-johan@kernel.org>
References: <20250724154823.15998-1-johan@kernel.org>
Message-ID: <0befef79-561d-4b8b-827b-e6258f0d7a89@linaro.org>

On 24/07/2025 17:48, Johan Hovold wrote:
> When fixing up some device leaks in the TI drivers I noticed that the
> commits introducing the leaks had also converted the drivers to only
> support OF probe.
> 
> This series drops the unused platform module alias from the PHY drivers
> that never have supported or no longer supports anything but OF probing.
> 
> Johan
> 
> 
> Johan Hovold (11):
>    phy: broadcom: brcm-sata: drop unused module alias
>    phy: broadcom: brcm-usb: drop unused module alias
>    phy: cadence: Sierra: drop unused module alias
>    phy: hisilicon: hi6220-usb: drop unused module alias
>    phy: qualcomm: ipq806x-usb: drop unused module alias
>    phy: samsung: exynos5-usbdrd: drop unused module alias
>    phy: samsung: usb2: drop unused module alias
>    phy: ti: omap-usb2: drop unused module alias
>    phy: ti: ti-pipe3: drop unused module alias
>    phy: ti: dm816x-usb: drop unused module alias
>    phy: ti: omap-control: drop unused module alias
> 
>   drivers/phy/broadcom/phy-brcm-sata.c        | 1 -
>   drivers/phy/broadcom/phy-brcm-usb.c         | 1 -
>   drivers/phy/cadence/phy-cadence-sierra.c    | 1 -
>   drivers/phy/hisilicon/phy-hi6220-usb.c      | 1 -
>   drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c | 1 -
>   drivers/phy/samsung/phy-exynos5-usbdrd.c    | 1 -
>   drivers/phy/samsung/phy-samsung-usb2.c      | 1 -
>   drivers/phy/ti/phy-dm816x-usb.c             | 1 -
>   drivers/phy/ti/phy-omap-control.c           | 1 -
>   drivers/phy/ti/phy-omap-usb2.c              | 1 -
>   drivers/phy/ti/phy-ti-pipe3.c               | 1 -
>   11 files changed, 11 deletions(-)
> 

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From neil.armstrong at linaro.org  Wed Aug  6 07:35:09 2025
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Wed, 6 Aug 2025 16:35:09 +0200
Subject: [PATCH 1/3] phy: tegra: xusb: fix device and OF node leak at
 probe
In-Reply-To: <20250724131206.2211-2-johan@kernel.org>
References: <20250724131206.2211-1-johan@kernel.org>
 <20250724131206.2211-2-johan@kernel.org>
Message-ID: <92042af6-e498-460e-be88-8c1f1b4d74f9@linaro.org>

On 24/07/2025 15:12, Johan Hovold wrote:
> Make sure to drop the references taken to the PMC OF node and device by
> of_parse_phandle() and of_find_device_by_node() during probe.
> 
> Note the holding a reference to the PMC device does not prevent the
> PMC regmap from going away (e.g. if the PMC driver is unbound) so there
> is no need to keep the reference.
> 
> Fixes: 2d1021487273 ("phy: tegra: xusb: Add wake/sleepwalk for Tegra210")
> Cc: stable at vger.kernel.org	# 5.14
> Cc: JC Kuo <jckuo at nvidia.com>
> Signed-off-by: Johan Hovold <johan at kernel.org>
> ---
>   drivers/phy/tegra/xusb-tegra210.c | 6 +++++-
>   1 file changed, 5 insertions(+), 1 deletion(-)
> 

<snip>


Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From neil.armstrong at linaro.org  Wed Aug  6 07:35:52 2025
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Wed, 6 Aug 2025 16:35:52 +0200
Subject: [PATCH] phy: ti: omap-usb2: enable compile testing
In-Reply-To: <20250724131623.2662-1-johan@kernel.org>
References: <20250724131623.2662-1-johan@kernel.org>
Message-ID: <ede3c0a2-d174-4893-9550-6dcb51457053@linaro.org>

On 24/07/2025 15:16, Johan Hovold wrote:
> Nothing seems to prevent the driver from being built on non-TI platforms
> so enable compile testing for wider build coverage.
> 
> Signed-off-by: Johan Hovold <johan at kernel.org>
> ---
>   drivers/phy/ti/Kconfig | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/phy/ti/Kconfig b/drivers/phy/ti/Kconfig
> index b905902d5750..b40f28019131 100644
> --- a/drivers/phy/ti/Kconfig
> +++ b/drivers/phy/ti/Kconfig
> @@ -62,7 +62,7 @@ config OMAP_CONTROL_PHY
>   
>   config OMAP_USB2
>   	tristate "OMAP USB2 PHY Driver"
> -	depends on ARCH_OMAP2PLUS || ARCH_K3
> +	depends on ARCH_OMAP2PLUS || ARCH_K3 || COMPILE_TEST
>   	depends on USB_SUPPORT
>   	select GENERIC_PHY
>   	select USB_PHY

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From neil.armstrong at linaro.org  Wed Aug  6 07:35:57 2025
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Wed, 6 Aug 2025 16:35:57 +0200
Subject: [PATCH] phy: ti: omap-usb2: enable compile testing
In-Reply-To: <20250724131623.2662-1-johan@kernel.org>
References: <20250724131623.2662-1-johan@kernel.org>
Message-ID: <4b224859-bee3-49ca-ba06-cf07c55b8ac7@linaro.org>

On 24/07/2025 15:16, Johan Hovold wrote:
> Nothing seems to prevent the driver from being built on non-TI platforms
> so enable compile testing for wider build coverage.
> 
> Signed-off-by: Johan Hovold <johan at kernel.org>
> ---
>   drivers/phy/ti/Kconfig | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/phy/ti/Kconfig b/drivers/phy/ti/Kconfig
> index b905902d5750..b40f28019131 100644
> --- a/drivers/phy/ti/Kconfig
> +++ b/drivers/phy/ti/Kconfig
> @@ -62,7 +62,7 @@ config OMAP_CONTROL_PHY
>   
>   config OMAP_USB2
>   	tristate "OMAP USB2 PHY Driver"
> -	depends on ARCH_OMAP2PLUS || ARCH_K3
> +	depends on ARCH_OMAP2PLUS || ARCH_K3 || COMPILE_TEST
>   	depends on USB_SUPPORT
>   	select GENERIC_PHY
>   	select USB_PHY

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From neil.armstrong at linaro.org  Wed Aug  6 07:40:39 2025
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Wed, 6 Aug 2025 16:40:39 +0200
Subject: [PATCH v2 1/2] phy: add new phy_notify_pmstate() api
In-Reply-To: <CADrjBPpE0ab3MD6tAS-JQns1HaPfmngRhixkUpqqAfj_2D5nmw@mail.gmail.com>
References: <20250703-phy-notify-pmstate-v2-0-fc1690439117@linaro.org>
 <20250703-phy-notify-pmstate-v2-1-fc1690439117@linaro.org>
 <e2lhm237c3xtbdjux2wuesq5fwu7nky3w7oq2fnsgn2pqcg5kh@xhxktriooyes>
 <aICKM-ebp9SMAkZ_@vaman>
 <yaz4ozb55t3pkwd2gj4l4d2hdspdcsqjm2dfsux7lfdxy6lxjl@uae2qz2vjo64>
 <CADrjBPpE0ab3MD6tAS-JQns1HaPfmngRhixkUpqqAfj_2D5nmw@mail.gmail.com>
Message-ID: <4f67b4f5-3dfe-4f5b-81a9-24fa7009b9af@linaro.org>

Hi,

On 25/07/2025 12:21, Peter Griffin wrote:
> Hi Vinod, Mani & Neil,
> 
> Thanks a lot for the valuable review feedback.
> 
> On Wed, 23 Jul 2025 at 09:04, Manivannan Sadhasivam <mani at kernel.org> wrote:
>>
>> On Wed, Jul 23, 2025 at 12:37:31PM GMT, Vinod Koul wrote:
>>> On 22-07-25, 22:04, Manivannan Sadhasivam wrote:
>>>> On Thu, Jul 03, 2025 at 02:03:22PM GMT, Peter Griffin wrote:
>>>>> Add a new phy_notify_pmstate() api that notifies and configures a phy for a
>>>>> given PM link state transition.
>>>>>
>>>>> This is intended to be by phy drivers which need to do some runtime
>>>>> configuration of parameters during the transition that can't be handled by
>>>>> phy_calibrate() or phy_power_{on|off}().
>>>>>
>>>>> The first usage of this API is in the Samsung UFS phy that needs to issue
>>>>> some register writes when entering and exiting the hibernate link state.
>>>>>
>>>>> Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
>>>>> ---
>>>>>   drivers/phy/phy-core.c  | 25 +++++++++++++++++++++++++
>>>>>   include/linux/phy/phy.h | 25 +++++++++++++++++++++++++
>>>>>   2 files changed, 50 insertions(+)
>>>>>
>>>>> diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
>>>>> index 04a5a34e7a950ae94fae915673c25d476fc071c1..0b29bc2c709890d7fc27d1480a35cda6a826fd30 100644
>>>>> --- a/drivers/phy/phy-core.c
>>>>> +++ b/drivers/phy/phy-core.c
>>>>> @@ -520,6 +520,31 @@ int phy_notify_disconnect(struct phy *phy, int port)
>>>>>   }
>>>>>   EXPORT_SYMBOL_GPL(phy_notify_disconnect);
>>>>>
>>>>> +/**
>>>>> + * phy_notify_pmstate() - phy link state notification
>>>>
>>>> 'pmstate' doesn't correspond to 'link state'. So how about,
>>>> phy_notify_link_state()?
>>>>
>>>> s/phy/PHY (here and below)
> 
> will fix
> 
>>>>
>>>>> + * @phy: the phy returned by phy_get()
>>>>> + * @state: the link state
>>>>> + *
>>>>> + * Notify the phy of some PM link state transition. Used to notify and
>>>>
>>>> Link state change is common for the PHY. So remove 'PM'.
>>>
>>> Is it really link or phy state?
> 
> I think it is likely both link and phy state.
> 
> Looking at the wording in section '9.5 Hibernate' in mipi unipro 1.8
> spec we have phrases such as
> 
> 9.5 Hibernate "Hibernate is a UniPro state in which the PHY is in the
> HIBERNATE_STATE, and the UniPro stack keeps only a minimal set of
> features active."
> 
> 9.5 Figure 99 describes Link hibernation where one Device, typically a
> Host Device, initiates Link hibernation with a peer Device.

So this is part handled by the PHY

> 
> 9.5.1.2 The local PA Layer receives this request and places the M-PHY
> Link into hibernate using the PACP protocol (detailed description of
> PACP protocol can be found in Section 5.7.7). Once the PA Layer has
> successfully hibernated the M-PHY Link, subsequent layers of the local
> and peer
> UniPro stack (L4 to L2) shall be hibernated by the DME by sending a
> <layer-identifer>_LM_HIBERNATE_ENTER.req SAP primitive to the
> respective layers.
> 

And this by the controller, so yeah we set the PHY state, and the PHY will
set the link state accordingly.

>>>
>>
>> This is a bit of ambiguity. But as per the spec, Hibern8 is the low power state
>> of the M-PHY and Unipro controller.
>>
>> Maybe, phy_notify_state()?
>>
> 
> phy_notify_state() seems like a good name. It might be better suited
> for other peripherals as well rather than narrowing it with link_state
> or pmstate.

Ack

> 
> Vinod, any thoughts on your preferred name?
> 
>>>>
> 
>>>>> + * configure the phy accordingly.
>>>>> + *
>>>>> + * Returns: %0 if successful, a negative error code otherwise
>>>>> + */
>>>>> +int phy_notify_pmstate(struct phy *phy, enum phy_linkstate state)
>>>>
>>>> I think you need to use 'int state' and let drivers pass their own link state
>>>> values. You cannot have generic link states across all peripherals.
>>>
>>> I would avoid that, people start overloading this if we let it keep
>>> open! I would like to avoid the api -(ab)use
>>>
>>
>> Then we will end up with peripheral specific enums in include/linux/phy/phy.h.
>> If you are OK with that, fine with me.
> 
> Ok I'll add peripheral specific enums to include/linux/phy/phy.h in
> the next version.
> 
> Thanks,
> 
> Peter
> 

Thanks,
Neil


From geert at linux-m68k.org  Wed Aug  6 07:51:48 2025
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Wed, 6 Aug 2025 16:51:48 +0200
Subject: [PATCH 4/5] phy: renesas: rcar-gen3-usb2: Add support for RZ/T2H SoC
In-Reply-To: <20250805122529.2566580-5-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20250805122529.2566580-1-prabhakar.mahadev-lad.rj@bp.renesas.com> <20250805122529.2566580-5-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <CAMuHMdVMKzJtomQzzZaHXbhhEJ_3u71Kj7QcMhRgCXcDWY-Kqw@mail.gmail.com>

Hi Prabhakar,

On Tue, 5 Aug 2025 at 14:25, Prabhakar <prabhakar.csengg at gmail.com> wrote:
> From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
>
> Add initial support for the Renesas RZ/T2H SoC to the R-Car Gen3 USB2 PHY
> driver. The RZ/T2H SoC requires configuration of additional
> hardware-specific bits for proper VBUS level control and OTG operation.
>
> Introduce the `vblvl_ctrl` flag in the SoC-specific driver data to enable
> handling of VBUS level selection logic using `VBCTRL.VBLVL` bits. This is
> required for managing the VBUS status detection and drive logic based on
> SoC-specific needs.
>
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>

Thanks for your patch!

> --- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> +++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c

> @@ -284,6 +293,21 @@ static void rcar_gen3_init_from_a_peri_to_a_host(struct rcar_gen3_chan *ch)
>
>  static bool rcar_gen3_check_id(struct rcar_gen3_chan *ch)
>  {
> +       if (ch->drvdata->vblvl_ctrl) {
> +               bool vbus_valid = false;
> +               bool device = false;

No need to preinitialize these two variables.

> +
> +               device = !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG);
> +               vbus_valid = !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_VBUSVALID);
> +
> +               if (device && vbus_valid)
> +                       return true;
> +               else if (!device && vbus_valid)

No need for else after return, but...

> +                       return false;
> +
> +               return !(device && !vbus_valid);

... all logic above can be simplified to

    return vbus_valid ? device : !device;

> +       }
> +
>         if (!ch->uses_otg_pins)
>                 return (ch->dr_mode == USB_DR_MODE_HOST) ? false : true;
>

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 quic_nitirawa at quicinc.com  Wed Aug  6 08:43:36 2025
From: quic_nitirawa at quicinc.com (Nitin Rawat)
Date: Wed,  6 Aug 2025 21:13:36 +0530
Subject: [PATCH V1 0/4] Add support to configure regulator load for UFS QMP PHY
Message-ID: <20250806154340.20122-1-quic_nitirawa@quicinc.com>

Add support in the Qualcomm QMP UFS PHY driver to configure regulator
load using max-microamp values from the device tree.

Patch introduces two optional properties in the SC8280XP QMP UFS
PHY binding.

These properties define the expected maximum current (in microamps) for
each supply. The driver uses this information to configure regulators
more accurately and ensure they operate in the correct mode based on
client load requirements.

This change is tested on m8550-qrd, m8750-mtp and sm8650-mtp.

Nitin Rawat (4):
  dt-bindings: phy: Add max-microamp properties for PHY and PLL supplies
  arm64: dts: qcom: sm8750: add max-microamp for UFS PHY and PLL
    supplies
  arm64: dts: qcom: sm8650: add max-microamp for UFS PHY and PLL
    supplies
  phy: qcom-qmp-ufs: read max-microamp values from device tree

 .../phy/qcom,sc8280xp-qmp-ufs-phy.yaml        | 10 +++++++++
 arch/arm64/boot/dts/qcom/sm8650-hdk.dts       |  2 ++
 arch/arm64/boot/dts/qcom/sm8650-mtp.dts       |  3 ++-
 arch/arm64/boot/dts/qcom/sm8650-qrd.dts       |  2 ++
 arch/arm64/boot/dts/qcom/sm8750-mtp.dts       |  2 ++
 arch/arm64/boot/dts/qcom/sm8750-qrd.dts       |  2 ++
 drivers/phy/qualcomm/phy-qcom-qmp-ufs.c       | 22 ++++++++++++++++---
 7 files changed, 39 insertions(+), 4 deletions(-)

--
2.48.1



From quic_nitirawa at quicinc.com  Wed Aug  6 08:43:37 2025
From: quic_nitirawa at quicinc.com (Nitin Rawat)
Date: Wed,  6 Aug 2025 21:13:37 +0530
Subject: [PATCH V1 1/4] dt-bindings: phy: Add max-microamp properties for PHY and PLL supplies
In-Reply-To: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
Message-ID: <20250806154340.20122-2-quic_nitirawa@quicinc.com>

Add two new optional properties to the SC8280XP QMP UFS PHY
device tree binding:

- `vdda-phy-max-microamp`: Specifies the maximum current (in microamps)
			   that can be drawn from the PHY supply.
- `vdda-pll-max-microamp`: Specifies the maximum current (in microamps)
			   that can be drawn from the PLL supply.

These additions help define power requirements more precisely for
regulators supplying the PHY and PLL blocks and ensuring the regulators
is kept in correct mode based on the client load requirements.

Signed-off-by: Nitin Rawat <quic_nitirawa at quicinc.com>
---
 .../bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml        | 10 ++++++++++
 1 file changed, 10 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 a58370a6a5d3..4648642dc974 100644
--- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
@@ -71,6 +71,16 @@ properties:
 
   vdda-pll-supply: true
 
+  vdda-phy-max-microamp:
+    maxItems: 1
+    description:
+      Specifies max. load that can be drawn from phy supply.
+
+  vdda-pll-max-microamp:
+    maxItems: 1
+    description:
+      Specifies max. load that can be drawn from pll supply.
+
   "#clock-cells":
     const: 1
 
-- 
2.48.1



From quic_nitirawa at quicinc.com  Wed Aug  6 08:43:39 2025
From: quic_nitirawa at quicinc.com (Nitin Rawat)
Date: Wed,  6 Aug 2025 21:13:39 +0530
Subject: [PATCH V1 3/4] arm64: dts: qcom: sm8650: add max-microamp for UFS PHY and PLL supplies
In-Reply-To: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
Message-ID: <20250806154340.20122-4-quic_nitirawa@quicinc.com>

Add `vdda-phy-max-microamp` and `vdda-pll-max-microamp` properties to
the UFS PHY node in the device tree.

These properties define the maximum current (in microamps) expected
from the PHY and PLL regulators. This allows the PHY driver to
configure regulator load accurately and ensure proper regulator mode
based on load requirements.

Signed-off-by: Nitin Rawat <quic_nitirawa at quicinc.com>
---
 arch/arm64/boot/dts/qcom/sm8650-hdk.dts | 2 ++
 arch/arm64/boot/dts/qcom/sm8650-mtp.dts | 3 ++-
 arch/arm64/boot/dts/qcom/sm8650-qrd.dts | 2 ++
 3 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/sm8650-hdk.dts b/arch/arm64/boot/dts/qcom/sm8650-hdk.dts
index d0912735b54e..356254b11906 100644
--- a/arch/arm64/boot/dts/qcom/sm8650-hdk.dts
+++ b/arch/arm64/boot/dts/qcom/sm8650-hdk.dts
@@ -1294,7 +1294,9 @@ &ufs_mem_hc {
 
 &ufs_mem_phy {
 	vdda-phy-supply = <&vreg_l1d_0p88>;
+	vdda-phy-max-microamp = <211000>;
 	vdda-pll-supply = <&vreg_l3i_1p2>;
+	vdda-pll-max-microamp = <18300>;
 
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/qcom/sm8650-mtp.dts b/arch/arm64/boot/dts/qcom/sm8650-mtp.dts
index 76ef43c10f77..f47f62e0b0d9 100644
--- a/arch/arm64/boot/dts/qcom/sm8650-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/sm8650-mtp.dts
@@ -841,8 +841,9 @@ &ufs_mem_hc {
 
 &ufs_mem_phy {
 	vdda-phy-supply = <&vreg_l1d_0p88>;
+	vdda-phy-max-microamp = <211000>;
 	vdda-pll-supply = <&vreg_l3i_1p2>;
-
+	vdda-pll-max-microamp = <18300>;
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/qcom/sm8650-qrd.dts b/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
index 71033fba21b5..c4359f8033e3 100644
--- a/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
+++ b/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
@@ -1277,7 +1277,9 @@ &ufs_mem_hc {
 
 &ufs_mem_phy {
 	vdda-phy-supply = <&vreg_l1d_0p88>;
+	vdda-phy-max-microamp = <211000>;
 	vdda-pll-supply = <&vreg_l3i_1p2>;
+	vdda-pll-max-microamp = <18300>;
 
 	status = "okay";
 };
-- 
2.48.1



From quic_nitirawa at quicinc.com  Wed Aug  6 08:43:38 2025
From: quic_nitirawa at quicinc.com (Nitin Rawat)
Date: Wed,  6 Aug 2025 21:13:38 +0530
Subject: [PATCH V1 2/4] arm64: dts: qcom: sm8750: add max-microamp for UFS PHY and PLL supplies
In-Reply-To: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
Message-ID: <20250806154340.20122-3-quic_nitirawa@quicinc.com>

Add `vdda-phy-max-microamp` and `vdda-pll-max-microamp` properties to
the UFS PHY node in the device tree.

These properties define the maximum current (in microamps) expected
from the PHY and PLL regulators. This allows the PHY driver to
configure regulator load accurately and ensure proper regulator
mode based on load requirements.

Signed-off-by: Nitin Rawat <quic_nitirawa at quicinc.com>
---
 arch/arm64/boot/dts/qcom/sm8750-mtp.dts | 2 ++
 arch/arm64/boot/dts/qcom/sm8750-qrd.dts | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sm8750-mtp.dts b/arch/arm64/boot/dts/qcom/sm8750-mtp.dts
index 75cfbb510be5..2ae5915fe38d 100644
--- a/arch/arm64/boot/dts/qcom/sm8750-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/sm8750-mtp.dts
@@ -1032,7 +1032,9 @@ wcd_default: wcd-reset-n-active-state {
 
 &ufs_mem_phy {
 	vdda-phy-supply = <&vreg_l1j_0p91>;
+	vdda-phy-max-microamp = <213000>;
 	vdda-pll-supply = <&vreg_l3g_1p2>;
+	vdda-pll-max-microamp = <18300>;
 
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/qcom/sm8750-qrd.dts b/arch/arm64/boot/dts/qcom/sm8750-qrd.dts
index 13c7b9664c89..e9a41d34e2d6 100644
--- a/arch/arm64/boot/dts/qcom/sm8750-qrd.dts
+++ b/arch/arm64/boot/dts/qcom/sm8750-qrd.dts
@@ -1039,7 +1039,9 @@ &uart7 {
 
 &ufs_mem_phy {
 	vdda-phy-supply = <&vreg_l1j_0p91>;
+	vdda-phy-max-microamp = <213000>;
 	vdda-pll-supply = <&vreg_l3g_1p2>;
+	vdda-pll-max-microamp = <18300>;
 
 	status = "okay";
 };
-- 
2.48.1



From quic_nitirawa at quicinc.com  Wed Aug  6 08:43:40 2025
From: quic_nitirawa at quicinc.com (Nitin Rawat)
Date: Wed,  6 Aug 2025 21:13:40 +0530
Subject: [PATCH V1 4/4] phy: qcom-qmp-ufs: read max-microamp values from device tree
In-Reply-To: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
Message-ID: <20250806154340.20122-5-quic_nitirawa@quicinc.com>

Add support in QMP PHY driver to read optional vdda-phy-max-microamp
and vdda-pll-max-microamp properties from the device tree.

These properties define the expected maximum current (in microamps) for
each supply. The driver uses this information to configure regulators
more accurately and ensure they operate in the correct mode based on
client load requirements.

If the property is not present, the driver defaults load to
`QMP_VREG_UNUSED`.

Signed-off-by: Nitin Rawat <quic_nitirawa at quicinc.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
index 9c69c77d10c8..6e116f7370c3 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
@@ -39,6 +39,8 @@
 #define PHY_INIT_COMPLETE_TIMEOUT		10000
 
 #define NUM_OVERLAY				2
+#define QMP_VREG_UNUSED				-1
+#define MAX_PROP_NAME				32
 
 /* set of registers with offsets different per-PHY */
 enum qphy_reg_layout {
@@ -1894,15 +1896,29 @@ static int qmp_ufs_vreg_init(struct qmp_ufs *qmp)
 {
 	const struct qmp_phy_cfg *cfg = qmp->cfg;
 	struct device *dev = qmp->dev;
+	struct device_node *np = dev->of_node;
+	char prop_name[MAX_PROP_NAME];
 	int num = cfg->num_vregs;
-	int i;
+	const char *supply;
+	int i, ret;
 
 	qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL);
 	if (!qmp->vregs)
 		return -ENOMEM;
 
-	for (i = 0; i < num; i++)
-		qmp->vregs[i].supply = cfg->vreg_list[i];
+	for (i = 0; i < num; i++) {
+		supply = cfg->vreg_list[i];
+		qmp->vregs[i].supply = supply;
+
+		/* Defaults to unused */
+		qmp->vregs[i].init_load_uA = QMP_VREG_UNUSED;
+
+		snprintf(prop_name, sizeof(prop_name), "%s-max-microamp", supply);
+		ret = of_property_read_u32(np, prop_name, &qmp->vregs[i].init_load_uA);
+		if (ret)
+			dev_dbg(qmp->dev, "No max microamp for %s, using default %d\n",
+				supply, QMP_VREG_UNUSED);
+	}
 
 	return devm_regulator_bulk_get(dev, num, qmp->vregs);
 }
-- 
2.48.1



From konrad.dybcio at oss.qualcomm.com  Wed Aug  6 08:48:55 2025
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Wed, 6 Aug 2025 17:48:55 +0200
Subject: [PATCH v3 0/6] arm64: qcom: allow up to 4 lanes for the Type-C
 DisplayPort Altmode
In-Reply-To: <fhzdhzxdwcoiuhx2eogpshwt5cxagjkrygrefqikmfbx3cfcov@awmhgrvurnfi>
References: <20250527-topic-4ln_dp_respin-v3-0-f9a0763ec289@oss.qualcomm.com>
 <styd5gjksbsqt7efylpfn6bgwgyvt6zexxiooihjsnmp25yigp@unq7dor6gso2>
 <447c3b13-8d6d-4bcb-83c1-9456b915a77e@oss.qualcomm.com>
 <inpfuxskvmrebxitqtqwzvpnpicibo6zakgk4ujpcrqrpef2vw@nhclj5rg7axr>
 <9037fefe-aa40-4884-97ee-b81ff8346944@oss.qualcomm.com>
 <htufwjvfgdtav2gtgrytc356py6xqhrffbwjg42sgo7k4zzxof@z4xaf35qz7kq>
 <aa17d7d4-b77d-4a0a-88c3-86255dfbc29d@oss.qualcomm.com>
 <75dde9a2-3c0d-481b-bc73-089ba89a77e0@linaro.org>
 <71196aad-6d80-4356-bbe5-3070f6b74bfe@oss.qualcomm.com>
 <fhzdhzxdwcoiuhx2eogpshwt5cxagjkrygrefqikmfbx3cfcov@awmhgrvurnfi>
Message-ID: <f21b7d52-4c3f-4e5b-bee7-f8b2945b5b02@oss.qualcomm.com>

On 6/3/25 3:17 PM, Dmitry Baryshkov wrote:
> On Tue, Jun 03, 2025 at 01:03:11PM +0200, Konrad Dybcio wrote:
>> On 6/2/25 10:55 AM, Neil Armstrong wrote:
>>> On 28/05/2025 18:56, Konrad Dybcio wrote:
>>>> On 5/28/25 1:22 PM, Dmitry Baryshkov wrote:
>>>>> On Wed, May 28, 2025 at 01:13:26PM +0200, Konrad Dybcio wrote:
>>>>>> On 5/28/25 11:00 AM, Dmitry Baryshkov wrote:
>>>>>>> On Wed, May 28, 2025 at 12:24:02AM +0200, Konrad Dybcio wrote:
>>>>>>>> On 5/27/25 11:10 PM, Dmitry Baryshkov wrote:
>>>>>>>>> On Tue, May 27, 2025 at 10:40:02PM +0200, Konrad Dybcio wrote:
>>>>>>>>>> Register a typec mux in order to change the PHY mode on the Type-C
>>>>>>>>>> mux events depending on the mode and the svid when in Altmode setup.
>>>>>>>>>>
>>>>>>>>>> The DisplayPort phy should be left enabled if is still powered on
>>>>>>>>>> by the DRM DisplayPort controller, so bail out until the DisplayPort
>>>>>>>>>> PHY is not powered off.
>>>>>>>>>
>>>>>>>>> This series doesn't seem to solve the USB side of a problem. When the
>>>>>>>>> PHY is being switch to the 4-lane mode, USB controller looses PIPE
>>>>>>>>> clock, so it needs to be switched to the USB-2 mode.
>>>>>>>>
>>>>>>>> I didn't find issues with that on X13s.. Not sure if it's related, but
>>>>>>>> on the SL7, after plugging in a 4ln DP connection, I need to plug in
>>>>>>>> the USB thumb drive twice for the first time (only in that sequence)
>>>>>>>
>>>>>>> Might be.
>>>>>>>
>>>>>>>> But there's nothing interesting in dmesg and the phy seems to be
>>>>>>>> programmed with the same values on both the initial and the subsequent
>>>>>>>> working plug-in
>>>>>>>
>>>>>>> Please try using a DP dongle with USB 2 passthrough (there are some).
>>>>>>> Or just emulate this by enabling DP PHY / DP chain for plugged in USB3
>>>>>>> devices. Would you be able to see the USB device on a bus?
>>>>>>
>>>>>> I only have a dongle with both display and usb that does 2ln dp
>>>>>> (I tested 4ln dp on a type-c display that I don't think has a hub)
>>>>>>
>>>>>> USB3 - yes, USB2 - no (but it works after a replug)
>>>>>>
>>>>>> Are you talking about essentially doing qcom,select-utmi-as-pipe-clk
>>>>>> at runtime?
>>>>>
>>>>> I think so.
>>>>
>>>> So after quite some time playing with that, I noticed that the USB2
>>>> device was never actually kicked off the bus.. and works totally fine
>>>> after connecting the display output (2ln DP)
>>>>
>>>> I was looking at dmesg, checking for discovery/disconnect messages,
>>>> but the device was simply never disconnected (which makes sense given
>>>> repurposing USB3 TX/RX lanes doesn't affect the D+/D- of USB2)
>>>>
>>>> I also read some docs and learnt that what we call
>>>> qcom,select-utmi-as-pipe-clk is suppossed to be a debug feature
>>>> and is unnecessary to set on USB2.0-only controllers
>>>>
>>>> The USB controller programming guide though doesn't talk about DP,
>>>> but I'd expect that we may need to set that override for 4lnDP+USB2
>>>> use cases (which I don't have a dongle for)
>>>
>>> Yeah basically we need to:
>>> 1) power-off the USB3 PHY
>>> 2) switch to UTMI clock
>>>
>>> In the following states:
>>> - USB safe mode (USB2 lanes may still be connected)
>>> - 4lanes DP mode
>>> - DP-only mode
>>>
>>> But for this, the dwc3 should also get USB-C events with an addition mode-switch property.
>>> The flatten DWC3 node now allows that !
>>
>> Yeah, I got even more confirmation this is intended..
>>
>> I hacked up something that boils down to:
>>
>> diff --git a/drivers/usb/dwc3/drd.c b/drivers/usb/dwc3/drd.c
>> index 7977860932b1..e5a0a8ec624d 100644
>> --- a/drivers/usb/dwc3/drd.c
>> +++ b/drivers/usb/dwc3/drd.c
>> @@ -464,6 +464,11 @@ static int dwc3_usb_role_switch_set(struct usb_role_switch *sw,
>>  		break;
>>  	}
>>  
>> +	if (dwc->mode_fn)
>> +		dwc->mode_fn(dwc, mode);
>>
>> diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c
>> index 7334de85ad10..ea56f5087ecb 100644
>> --- a/drivers/usb/dwc3/dwc3-qcom.c
>> +++ b/drivers/usb/dwc3/dwc3-qcom.c
>> +static void mode_fn(struct dwc3 *dwc, enum usb_role role)
>> +{
>> +	struct dwc3_qcom *qcom = to_dwc3_qcom(dwc);
>> +
>> +	if (dwc->usb3_generic_phy[0])
>> +		dwc3_qcom_select_utmi_clk(qcom, role == USB_ROLE_NONE);
> 
> This part is a hack for devices with no USB-2 passthrough, isn't it?
> 
>>  }
>>
>>
>> It was easy to tap into because there's already mode switch handling..
>> But obviously it's a hack - should I register a typec_mux in there?
> 
> I think so, we should listen to mode changes, instead of host/device
> changes.
> 
>> Should it go to dwc3-common or dwc3-qcom?
> 
> I'd say, dwc3-qcom. Not all dwc3 controllers are USB 3 capable, not
> talking about the USB-C.

I did some coding and we can't switch clock sources at runtime (not a
huge shocker), but the bigger issue is that, paraphrasing the HPG, the
DWC3 controller must be programmed as if it was not SS-capable (probably
skipping starting some subcores), which is not trivial

I also came up with a sneaky workaround of simply keeping the USB PLL
always-on, but the hardware disagrees to do so if the PHY is configured
in the DP_ONLY mode (which I suppose makes sense)

All in all, I was not able to find people with a device that actually
does 4ln DP + USB2 and IIUC the only drawback would be that USB2 would
not work (and not stall the system). Not sure if/how it recovers after
you'd plug something else into that port later on, but again, I don't
have anyone that could test it.

With that in mind, would you be okay with me resubmitting this series
with just a rebase & taking care of the comment to patch 5 (pertaining
to the default mode setting if svid != DP)?

Konrad


From neil.armstrong at linaro.org  Wed Aug  6 08:57:02 2025
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Wed, 6 Aug 2025 17:57:02 +0200
Subject: [PATCH 00/11] phy: drop unused module aliases
In-Reply-To: <20250724154823.15998-1-johan@kernel.org>
References: <20250724154823.15998-1-johan@kernel.org>
Message-ID: <3a073dc8-bda5-46ea-9db0-48155b0bce37@linaro.org>

On 24/07/2025 17:48, Johan Hovold wrote:
> When fixing up some device leaks in the TI drivers I noticed that the
> commits introducing the leaks had also converted the drivers to only
> support OF probe.
> 
> This series drops the unused platform module alias from the PHY drivers
> that never have supported or no longer supports anything but OF probing.
> 
> Johan
> 
> 
> Johan Hovold (11):
>    phy: broadcom: brcm-sata: drop unused module alias
>    phy: broadcom: brcm-usb: drop unused module alias
>    phy: cadence: Sierra: drop unused module alias
>    phy: hisilicon: hi6220-usb: drop unused module alias
>    phy: qualcomm: ipq806x-usb: drop unused module alias
>    phy: samsung: exynos5-usbdrd: drop unused module alias
>    phy: samsung: usb2: drop unused module alias
>    phy: ti: omap-usb2: drop unused module alias
>    phy: ti: ti-pipe3: drop unused module alias
>    phy: ti: dm816x-usb: drop unused module alias
>    phy: ti: omap-control: drop unused module alias
> 
>   drivers/phy/broadcom/phy-brcm-sata.c        | 1 -
>   drivers/phy/broadcom/phy-brcm-usb.c         | 1 -
>   drivers/phy/cadence/phy-cadence-sierra.c    | 1 -
>   drivers/phy/hisilicon/phy-hi6220-usb.c      | 1 -
>   drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c | 1 -
>   drivers/phy/samsung/phy-exynos5-usbdrd.c    | 1 -
>   drivers/phy/samsung/phy-samsung-usb2.c      | 1 -
>   drivers/phy/ti/phy-dm816x-usb.c             | 1 -
>   drivers/phy/ti/phy-omap-control.c           | 1 -
>   drivers/phy/ti/phy-omap-usb2.c              | 1 -
>   drivers/phy/ti/phy-ti-pipe3.c               | 1 -
>   11 files changed, 11 deletions(-)
> 

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>



From konrad.dybcio at oss.qualcomm.com  Wed Aug  6 08:58:30 2025
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Wed, 6 Aug 2025 17:58:30 +0200
Subject: [PATCH V1 4/4] phy: qcom-qmp-ufs: read max-microamp values from
 device tree
In-Reply-To: <20250806154340.20122-5-quic_nitirawa@quicinc.com>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
 <20250806154340.20122-5-quic_nitirawa@quicinc.com>
Message-ID: <f368b6da-1aa3-4b8e-9106-3c29d4ab5c5e@oss.qualcomm.com>

On 8/6/25 5:43 PM, Nitin Rawat wrote:
> Add support in QMP PHY driver to read optional vdda-phy-max-microamp
> and vdda-pll-max-microamp properties from the device tree.
> 
> These properties define the expected maximum current (in microamps) for
> each supply. The driver uses this information to configure regulators
> more accurately and ensure they operate in the correct mode based on
> client load requirements.
> 
> If the property is not present, the driver defaults load to
> `QMP_VREG_UNUSED`.
> 
> Signed-off-by: Nitin Rawat <quic_nitirawa at quicinc.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 22 +++++++++++++++++++---
>  1 file changed, 19 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> index 9c69c77d10c8..6e116f7370c3 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> @@ -39,6 +39,8 @@
>  #define PHY_INIT_COMPLETE_TIMEOUT		10000
>  
>  #define NUM_OVERLAY				2
> +#define QMP_VREG_UNUSED				-1
> +#define MAX_PROP_NAME				32
>  
>  /* set of registers with offsets different per-PHY */
>  enum qphy_reg_layout {
> @@ -1894,15 +1896,29 @@ static int qmp_ufs_vreg_init(struct qmp_ufs *qmp)
>  {
>  	const struct qmp_phy_cfg *cfg = qmp->cfg;
>  	struct device *dev = qmp->dev;
> +	struct device_node *np = dev->of_node;
> +	char prop_name[MAX_PROP_NAME];
>  	int num = cfg->num_vregs;
> -	int i;
> +	const char *supply;
> +	int i, ret;
>  
>  	qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL);
>  	if (!qmp->vregs)
>  		return -ENOMEM;
>  
> -	for (i = 0; i < num; i++)
> -		qmp->vregs[i].supply = cfg->vreg_list[i];
> +	for (i = 0; i < num; i++) {
> +		supply = cfg->vreg_list[i];
> +		qmp->vregs[i].supply = supply;
> +
> +		/* Defaults to unused */
> +		qmp->vregs[i].init_load_uA = QMP_VREG_UNUSED;
> +
> +		snprintf(prop_name, sizeof(prop_name), "%s-max-microamp", supply);
> +		ret = of_property_read_u32(np, prop_name, &qmp->vregs[i].init_load_uA);
> +		if (ret)
> +			dev_dbg(qmp->dev, "No max microamp for %s, using default %d\n",
> +				supply, QMP_VREG_UNUSED);

+Mark

do you think having this in regulator core would make sense?

Konrad


From broonie at kernel.org  Wed Aug  6 09:51:04 2025
From: broonie at kernel.org (Mark Brown)
Date: Wed, 6 Aug 2025 17:51:04 +0100
Subject: [PATCH V1 4/4] phy: qcom-qmp-ufs: read max-microamp values from
 device tree
In-Reply-To: <f368b6da-1aa3-4b8e-9106-3c29d4ab5c5e@oss.qualcomm.com>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
 <20250806154340.20122-5-quic_nitirawa@quicinc.com>
 <f368b6da-1aa3-4b8e-9106-3c29d4ab5c5e@oss.qualcomm.com>
Message-ID: <fe2bc07c-8fe9-47fd-bcd7-c2f0ebbd596f@sirena.org.uk>

On Wed, Aug 06, 2025 at 05:58:30PM +0200, Konrad Dybcio wrote:
> On 8/6/25 5:43 PM, Nitin Rawat wrote:

> > Add support in QMP PHY driver to read optional vdda-phy-max-microamp
> > and vdda-pll-max-microamp properties from the device tree.

> > These properties define the expected maximum current (in microamps) for
> > each supply. The driver uses this information to configure regulators
> > more accurately and ensure they operate in the correct mode based on
> > client load requirements.

> > If the property is not present, the driver defaults load to
> > `QMP_VREG_UNUSED`.

> do you think having this in regulator core would make sense?

I'm not clear why the driver is trying to do this at all, the driver is
AFAICT making no other effort to manage the load at all.  We already
impose any constraints that are defined for a regulator while initially
parsing them so it's not clear to me what this is supposed to
accomplish, and it'll be broken if the supply is ever shared since it'll
set the load from this individual consumer to the maximum that's
permitted for the regulator as a whole.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-phy/attachments/20250806/f90e05b6/attachment.sig>

From jkeeping at inmusicbrands.com  Wed Aug  6 10:10:43 2025
From: jkeeping at inmusicbrands.com (John Keeping)
Date: Wed, 6 Aug 2025 18:10:43 +0100
Subject: [RFC/PATCH 1/2] usb: dwc3: disable for USB_ROLE_NONE
In-Reply-To: <20250729221027.jvg3bpqhc3z5j7xn@synopsys.com>
References: <20250710152252.2532020-1-jkeeping@inmusicbrands.com>
 <20250710152252.2532020-2-jkeeping@inmusicbrands.com>
 <20250712001131.ax3rw24h3deekxfv@synopsys.com>
 <aHUfFGnGZP4z7UgK-jkeeping@inmusicbrands.com>
 <20250729221027.jvg3bpqhc3z5j7xn@synopsys.com>
Message-ID: <aJOMk_PVasn-tvV6-jkeeping@inmusicbrands.com>

On Tue, Jul 29, 2025 at 10:10:35PM +0000, Thinh Nguyen wrote:
> On Mon, Jul 14, 2025, John Keeping wrote:
> > On Sat, Jul 12, 2025 at 12:11:38AM +0000, Thinh Nguyen wrote:
> > > On Thu, Jul 10, 2025, John Keeping wrote:
> > > > When the phy is acting as a Type C mux, it may need to reset when the
> > > > cable direction changes.  But this should not happen while DWC3 is
> > > > trying to use the USB connection.
> > > > 
> > > > In this case, there must be a connection manager to notify the phy of
> > > > the orientation change and tcpm_mux_set() ensures this happens before
> > > > DWC3's role switch is informed of a change.
> > > > 
> > > > It should not be possible to go directly from device->device or
> > > > host->host with a change in orientation without transitioning through
> > > > the "none" role as the cable is unplugged.  So ensuring that DWC3 always
> > > 
> > > The controller is either host or device mode. It's odd to use "none" to
> > > indicate connection.
> > 
> > There is no connection in this state.  When the type C controller
> > indicates that the role is "none" then there cannot be a USB connection.
> > 
> 
> It's not about connection. It's about the current mode of the USB
> controller. The mode of the controller isn't "none" on disconnection
> even if you try to role-switch to that via the typec switch.
> 
> > > > informs the phy of the new mode whenever a plug is detected should be
> > > > sufficient for the phy to safely reset itself at a time that is safe for
> > > > DWC3.
> > > 
> > > Couldn't the phy do this as it detects connection/disconnection.
> > 
> > I don't think the phy can detect a connection.  If it is configured for
> > the wrong orientation then it will not monitor the correct data lines.
> > The phy hardware does not signal any interrupts to the CPU for the
> > driver to react to.
> 
> Ok.
> 
> > 
> > > It seems what you need is a full controller initialization upon new
> > > connection on orientation change, and you're using role_switch selecting
> > > "none" to do so.
> > 
> > I'm not sure whether a complete initialization is necessary, but what I
> > want to avoid is the phy resetting while the controller is part-way
> > through device enumeration or setting up a gadget configuration.
> > 
> > It may be that simply avoiding resetting the phy if the orientation is
> > unchanged is enough to avoid some of this problem, but I suspect there
> > are still problems if the clocks from the phy to the controller are
> > stopped unexpectedly.  However, I have run some tests of this change and
> > it looks promising.
> 
> That sounds like the the phy reset is done after asserting the vbus
> valid line indicating connection to the controller. Can this be fixed in
> the phy or type-c driver?

I don't think so.  I've tried implementing this in the phy driver and it
does not work reliably.

> > > I'm not sure if role-switch has the right interface to do so. Perhaps we
> > > can introduce one? I don't think we should change the behavior of the
> > > current flow and apply that to all other platforms.
> > 
> > I don't think it's unreasonable for the controller to be idle when there
> > is an external type C controller notifying the connection state.
> > 
> > The hardware setup looks like this, with the Linux type C code notifying
> > the phy driver of the orientation change and the DWC3 driver of the role
> > change:
> > 
> >                       +------+          
> >                       | DWC3 |<----+    
> >                       +--^---+     |    
> >                          |         |    
> >                       +--v--+      |    
> >                 +---->| PHY |      |Role
> >                 |     +--^--+      |    
> >     Orientation |        |         |    
> >                 |   +----v----+    |    
> >                 +---+ FUSB302 +----+    
> >                     +---------+
> > 
> > The advantage of using the role hook is that we are guaranteed that it
> > is called after the phy has been notified of the orientation change.
> > 
> > Do you have an idea of a new interface?  Or do you think it is safe to
> > reset the phy underneath the controller when that will halt the clocks
> > from the phy to the controller for some period of time?
> 
> The proper fix should be in the phy where it should only assert vbus
> valid after processing orientation and phy reset. I'm not familiar on
> the communication between your PHY and FUSB302. There should be some
> indication from the phy that it's ready before you can assert vbus-valid
> (that can be from a callback, a status register etc).

The FUSB302 is connected to the CPU via I2C, there is no direct
communication between it and the phy, it all goes via the kernel's tcpm
subsystem.

The problem with re-initializing the phy is that this causes dwc3 gadget
configuration to fail with "failed to enable ep0out", and this happens
when VBUS valid is de-asserted.  This is 100% reproducible on boot for
me where the init scripts are setting up a gadget via configfs.

So it seems the timing of the phy setup needs to coordinate with the
dwc3 controller.

> What you've done is a teardown and reinit of the driver, triggering a
> soft-reset. This can re-sync the phy. That probably takes long enough
> that a phy-reset after orientation change will be completed before the
> initialization complete.
> 
> If there's no way for you to know when the phy complete its reset, we
> can add a quirk for your platform to always reinit on role-switch call.
> 
> Let me know if this is reasonable.

I'm happy to test patches.


Kind regards,
John


From robh at kernel.org  Wed Aug  6 13:01:37 2025
From: robh at kernel.org (Rob Herring (Arm))
Date: Wed,  6 Aug 2025 15:01:37 -0500
Subject: [PATCH] dt-bindings: phy: marvell,comphy-cp110: Fix clock and child node constraints
Message-ID: <20250806200138.1366189-1-robh@kernel.org>

In converting marvell,comphy-cp110 to schema, the constraints for clocks on
marvell,comphy-a3700 are wrong, the maximum number of child nodes are wrong,
and the phy nodes may have a 'connector' child node:

phy at 18300 (marvell,comphy-a3700): clock-names: False schema does not allow ['xtal']
phy at 120000 (marvell,comphy-cp110): 'phy at 3', 'phy at 4', 'phy at 5' do not match any of the regexes: '^phy@[0-2]$', '^pinctrl-[0-9]+$'
phy at 120000 (marvell,comphy-cp110): phy at 2: 'connector' does not match any of the regexes: '^pinctrl-[0-9]+$'

Fixes: 50355ac70d4f ("dt-bindings: phy: Convert marvell,comphy-cp110 to DT schema")
Signed-off-by: Rob Herring (Arm) <robh at kernel.org>
---
 .../bindings/phy/marvell,comphy-cp110.yaml    | 29 ++++++++++++++-----
 1 file changed, 21 insertions(+), 8 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/marvell,comphy-cp110.yaml b/Documentation/devicetree/bindings/phy/marvell,comphy-cp110.yaml
index d9501df42886..c35d31642805 100644
--- a/Documentation/devicetree/bindings/phy/marvell,comphy-cp110.yaml
+++ b/Documentation/devicetree/bindings/phy/marvell,comphy-cp110.yaml
@@ -47,21 +47,19 @@ properties:
     const: 0
 
   clocks:
+    minItems: 1
     maxItems: 3
-    description: Reference clocks for CP110; MG clock, MG Core clock, AXI clock
 
   clock-names:
-    items:
-      - const: mg_clk
-      - const: mg_core_clk
-      - const: axi_clk
+    minItems: 1
+    maxItems: 3
 
   marvell,system-controller:
     description: Phandle to the Marvell system controller (CP110 only)
     $ref: /schemas/types.yaml#/definitions/phandle
 
 patternProperties:
-  '^phy@[0-2]$':
+  '^phy@[0-5]$':
     description: A COMPHY lane child node
     type: object
     additionalProperties: false
@@ -69,10 +67,14 @@ patternProperties:
     properties:
       reg:
         description: COMPHY lane number
+        maximum: 5
 
       '#phy-cells':
         const: 1
 
+      connector:
+        type: object
+
     required:
       - reg
       - '#phy-cells'
@@ -91,13 +93,24 @@ allOf:
 
     then:
       properties:
-        clocks: false
-        clock-names: false
+        clocks:
+          maxItems: 1
+        clock-names:
+          const: xtal
 
       required:
         - reg-names
 
     else:
+      properties:
+        clocks:
+          minItems: 3
+        clock-names:
+          items:
+            - const: mg_clk
+            - const: mg_core_clk
+            - const: axi_clk
+
       required:
         - marvell,system-controller
 
-- 
2.47.2



From prabhakar.csengg at gmail.com  Wed Aug  6 13:01:53 2025
From: prabhakar.csengg at gmail.com (Lad, Prabhakar)
Date: Wed, 6 Aug 2025 21:01:53 +0100
Subject: [PATCH 2/5] phy: renesas: rcar-gen3-usb2: Store drvdata pointer
 in channel
In-Reply-To: <9549b800-2205-428a-8056-cfc6b5255850@linaro.org>
References: <20250805122529.2566580-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <20250805122529.2566580-3-prabhakar.mahadev-lad.rj@bp.renesas.com> <9549b800-2205-428a-8056-cfc6b5255850@linaro.org>
Message-ID: <CA+V-a8s9MzrpyCSQ-nYiX+gDGHWhUONfc=F2Aqh_jAyar4Kceg@mail.gmail.com>

Hi Neil,

Thank you for the review.

On Wed, Aug 6, 2025 at 3:06?PM Neil Armstrong <neil.armstrong at linaro.org> wrote:
>
> On 05/08/2025 14:25, Prabhakar wrote:
> > From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> >
> > Store the SoC-specific driver data pointer (struct rcar_gen3_phy_drv_data)
> > directly in struct rcar_gen3_chan instead of copying individual flags
> > into separate fields. Update all references to use channel->drvdata->flags,
> > removing the redundant soc_no_adp_ctrl and utmi_ctrl members from the
> > channel structure.
> >
> > Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> > ---
> >   drivers/phy/renesas/phy-rcar-gen3-usb2.c | 17 +++++++----------
> >   1 file changed, 7 insertions(+), 10 deletions(-)
> >
> > diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> > index 47beb94cd424..cfa9667c7680 100644
> > --- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> > +++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> > @@ -122,6 +122,7 @@ struct rcar_gen3_phy {
> >   struct rcar_gen3_chan {
> >       void __iomem *base;
> >       struct device *dev;     /* platform_device's device */
> > +     const struct rcar_gen3_phy_drv_data *drvdata;
>
> Why not phy_data ?
>
Agreed, I will rename it.

> >       struct extcon_dev *extcon;
> >       struct rcar_gen3_phy rphys[NUM_OF_PHYS];
> >       struct regulator *vbus;
> > @@ -133,8 +134,6 @@ struct rcar_gen3_chan {
> >       bool extcon_host;
> >       bool is_otg_channel;
> >       bool uses_otg_pins;
> > -     bool soc_no_adp_ctrl;
> > -     bool utmi_ctrl;
> >   };
> >
> >   struct rcar_gen3_phy_drv_data {
> > @@ -204,7 +203,7 @@ static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus)
> >       u32 val;
> >
> >       dev_vdbg(ch->dev, "%s: %08x, %d\n", __func__, val, vbus);
> > -     if (ch->soc_no_adp_ctrl) {
> > +     if (ch->drvdata->no_adp_ctrl) {
> >               if (ch->vbus)
> >                       regulator_hardware_enable(ch->vbus, vbus);
> >
> > @@ -290,7 +289,7 @@ static bool rcar_gen3_check_id(struct rcar_gen3_chan *ch)
> >       if (!ch->uses_otg_pins)
> >               return (ch->dr_mode == USB_DR_MODE_HOST) ? false : true;
> >
> > -     if (ch->soc_no_adp_ctrl)
> > +     if (ch->drvdata->no_adp_ctrl)
> >               return !!(readl(ch->base + USB2_LINECTRL1) & USB2_LINECTRL1_USB2_IDMON);
> >
> >       return !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG);
> > @@ -421,7 +420,7 @@ static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch)
> >             USB2_LINECTRL1_DMRPD_EN | USB2_LINECTRL1_DM_RPD;
> >       writel(val, usb2_base + USB2_LINECTRL1);
> >
> > -     if (!ch->soc_no_adp_ctrl) {
> > +     if (!ch->drvdata->no_adp_ctrl) {
> >               val = readl(usb2_base + USB2_VBCTRL);
> >               val &= ~USB2_VBCTRL_OCCLREN;
> >               writel(val | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL);
> > @@ -487,7 +486,7 @@ static int rcar_gen3_phy_usb2_init(struct phy *p)
> >       if (rphy->int_enable_bits)
> >               rcar_gen3_init_otg(channel);
> >
> > -     if (channel->utmi_ctrl) {
> > +     if (channel->drvdata->utmi_ctrl) {
> >               val = readl(usb2_base + USB2_REGEN_CG_CTRL) | USB2_REGEN_CG_CTRL_UPHY_WEN;
> >               writel(val, usb2_base + USB2_REGEN_CG_CTRL);
> >
> > @@ -778,6 +777,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
> >               ret = -EINVAL;
> >               goto error;
> >       }
> > +     channel->drvdata = phy_data;
>
> Replace the whole block with:
>
>         channel->drvdata = device_get_match_data(dev);
>         if (!channel->drvdata) {
>                 ret = -EINVAL;
>                 goto error;
>         }
>
> and drop the local phy_data.
>
Ok.

Cheers,
Prabhakar


From prabhakar.csengg at gmail.com  Wed Aug  6 13:06:42 2025
From: prabhakar.csengg at gmail.com (Lad, Prabhakar)
Date: Wed, 6 Aug 2025 21:06:42 +0100
Subject: [PATCH 4/5] phy: renesas: rcar-gen3-usb2: Add support for RZ/T2H SoC
In-Reply-To: <CAMuHMdVMKzJtomQzzZaHXbhhEJ_3u71Kj7QcMhRgCXcDWY-Kqw@mail.gmail.com>
References: <20250805122529.2566580-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <20250805122529.2566580-5-prabhakar.mahadev-lad.rj@bp.renesas.com> <CAMuHMdVMKzJtomQzzZaHXbhhEJ_3u71Kj7QcMhRgCXcDWY-Kqw@mail.gmail.com>
Message-ID: <CA+V-a8tQxJ6y-7odV-V9fZt90v4oiRwvqjcTh8-Fs7xfJAm9fg@mail.gmail.com>

Hi Geert,

Thank you for the review.

On Wed, Aug 6, 2025 at 3:59?PM Geert Uytterhoeven <geert at linux-m68k.org> wrote:
>
> Hi Prabhakar,
>
> On Tue, 5 Aug 2025 at 14:25, Prabhakar <prabhakar.csengg at gmail.com> wrote:
> > From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> >
> > Add initial support for the Renesas RZ/T2H SoC to the R-Car Gen3 USB2 PHY
> > driver. The RZ/T2H SoC requires configuration of additional
> > hardware-specific bits for proper VBUS level control and OTG operation.
> >
> > Introduce the `vblvl_ctrl` flag in the SoC-specific driver data to enable
> > handling of VBUS level selection logic using `VBCTRL.VBLVL` bits. This is
> > required for managing the VBUS status detection and drive logic based on
> > SoC-specific needs.
> >
> > Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
>
> Thanks for your patch!
>
> > --- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> > +++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
>
> > @@ -284,6 +293,21 @@ static void rcar_gen3_init_from_a_peri_to_a_host(struct rcar_gen3_chan *ch)
> >
> >  static bool rcar_gen3_check_id(struct rcar_gen3_chan *ch)
> >  {
> > +       if (ch->drvdata->vblvl_ctrl) {
> > +               bool vbus_valid = false;
> > +               bool device = false;
>
> No need to preinitialize these two variables.
>
Agreed, I will drop it.

> > +
> > +               device = !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG);
> > +               vbus_valid = !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_VBUSVALID);
> > +
> > +               if (device && vbus_valid)
> > +                       return true;
> > +               else if (!device && vbus_valid)
>
> No need for else after return, but...
>
> > +                       return false;
> > +
> > +               return !(device && !vbus_valid);
>
> ... all logic above can be simplified to
>
>     return vbus_valid ? device : !device;
>
Ahha thanks for the pointer!

Cheers,
Prabhakar


From lkp at intel.com  Wed Aug  6 13:40:15 2025
From: lkp at intel.com (kernel test robot)
Date: Thu, 7 Aug 2025 04:40:15 +0800
Subject: [PATCH 4/5] phy: renesas: rcar-gen3-usb2: Add support for RZ/T2H
 SoC
In-Reply-To: <20250805122529.2566580-5-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20250805122529.2566580-5-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <202508070430.wK3sK6kB-lkp@intel.com>

Hi Prabhakar,

kernel test robot noticed the following build errors:

[auto build test ERROR on next-20250805]
[also build test ERROR on linus/master]
[cannot apply to geert-renesas-devel/next robh/for-next v6.16 v6.16-rc7 v6.16-rc6 v6.16]
[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/Prabhakar/dt-bindings-phy-renesas-usb2-phy-Add-RZ-T2H-and-RZ-N2H-support/20250806-122832
base:   next-20250805
patch link:    https://lore.kernel.org/r/20250805122529.2566580-5-prabhakar.mahadev-lad.rj%40bp.renesas.com
patch subject: [PATCH 4/5] phy: renesas: rcar-gen3-usb2: Add support for RZ/T2H SoC
config: riscv-randconfig-002-20250807 (https://download.01.org/0day-ci/archive/20250807/202508070430.wK3sK6kB-lkp at intel.com/config)
compiler: riscv32-linux-gcc (GCC) 8.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250807/202508070430.wK3sK6kB-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/202508070430.wK3sK6kB-lkp at intel.com/

All errors (new ones prefixed by >>):

   drivers/phy/renesas/phy-rcar-gen3-usb2.c: In function 'rcar_gen3_init_otg':
>> drivers/phy/renesas/phy-rcar-gen3-usb2.c:82:31: error: implicit declaration of function 'FIELD_PREP_CONST'; did you mean 'FILE_REF_NOREF'? [-Werror=implicit-function-declaration]
    #define USB2_VBCTRL_VBLVL(m)  FIELD_PREP_CONST(USB2_VBCTRL_VBLVL_MASK, (m))
                                  ^~~~~~~~~~~~~~~~
   drivers/phy/renesas/phy-rcar-gen3-usb2.c:448:44: note: in expansion of macro 'USB2_VBCTRL_VBLVL'
       val = (val & ~USB2_VBCTRL_VBLVL_MASK) | USB2_VBCTRL_VBLVL(2);
                                               ^~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors


vim +82 drivers/phy/renesas/phy-rcar-gen3-usb2.c

    77	
    78	/* VBCTRL */
    79	#define USB2_VBCTRL_VBSTA_MASK		GENMASK(31, 28)
    80	#define USB2_VBCTRL_VBSTA_DEFAULT	2
    81	#define USB2_VBCTRL_VBLVL_MASK		GENMASK(23, 20)
  > 82	#define USB2_VBCTRL_VBLVL(m)		FIELD_PREP_CONST(USB2_VBCTRL_VBLVL_MASK, (m))
    83	#define USB2_VBCTRL_OCCLREN		BIT(16)
    84	#define USB2_VBCTRL_DRVVBUSSEL		BIT(8)
    85	#define USB2_VBCTRL_SIDDQREL		BIT(2)
    86	#define USB2_VBCTRL_VBOUT		BIT(0)
    87	

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


From robh at kernel.org  Wed Aug  6 16:42:17 2025
From: robh at kernel.org (Rob Herring)
Date: Wed, 6 Aug 2025 18:42:17 -0500
Subject: [PATCH v5 1/6] dt-bindings: phy: samsung,usb3-drd-phy: add
 ExynosAutov920 HS phy compatible
In-Reply-To: <20250805115216.3798121-2-pritam.sutar@samsung.com>
References: <20250805115216.3798121-1-pritam.sutar@samsung.com>
 <CGME20250805114306epcas5p37782c02ae0ddc6b77094786c90af247a@epcas5p3.samsung.com>
 <20250805115216.3798121-2-pritam.sutar@samsung.com>
Message-ID: <20250806234217.GA2030512-robh@kernel.org>

On Tue, Aug 05, 2025 at 05:22:11PM +0530, Pritam Manohar Sutar wrote:
> This SoC has USB2.0 phy and supports only UTMI+ interface. This phy
> requires two clocks, named as "phy" and "ref". The required supplies for
> this phy are vdd075_usb20(0.75v), vdd18_usb20(1.8v), vdd33_usb20(3.3v).
> 
> Add a dedicated compatible string for USB HS phy found in this SoC.
> 
> Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
> ---
>  .../bindings/phy/samsung,usb3-drd-phy.yaml    | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
> index e906403208c0..1932a2272ef9 100644
> --- a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
> +++ b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
> @@ -34,6 +34,7 @@ properties:
>        - samsung,exynos7870-usbdrd-phy
>        - samsung,exynos850-usbdrd-phy
>        - samsung,exynos990-usbdrd-phy
> +      - samsung,exynosautov920-usbdrd-phy
>  
>    clocks:
>      minItems: 1
> @@ -110,6 +111,12 @@ properties:
>    vddh-usbdp-supply:
>      description: VDDh power supply for the USB DP phy.
>  
> +  dvdd075-usb20-supply:
> +    description: 0.75V power supply for the USB 2.0 phy.
> +
> +  vdd18-usb20-supply:
> +    description: 1.8V power supply for the USB 2.0 phy.
> +
>  required:
>    - compatible
>    - clocks
> @@ -219,6 +226,7 @@ allOf:
>                - samsung,exynos7870-usbdrd-phy
>                - samsung,exynos850-usbdrd-phy
>                - samsung,exynos990-usbdrd-phy
> +              - samsung,exynosautov920-usbdrd-phy
>      then:
>        properties:
>          clocks:
> @@ -235,6 +243,17 @@ allOf:
>  
>          reg-names:
>            maxItems: 1
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - samsung,exynosautov920-usbdrd-phy
> +    then:
> +      required:
> +        - dvdd075-usb20-supply
> +        - vdd18-usb20-supply
> +        - vdd33-usb20-supply

Presumably the existing devices don't have these new supplies, so:

else:
  properties:
    dvdd075-usb20-supply: false
    vdd18-usb20-supply: false



From robh at kernel.org  Wed Aug  6 16:43:09 2025
From: robh at kernel.org (Rob Herring)
Date: Wed, 6 Aug 2025 18:43:09 -0500
Subject: [PATCH v5 5/6] dt-bindings: phy: samsung,usb3-drd-phy: add
 ExynosAutov920 combo ssphy
In-Reply-To: <20250805115216.3798121-6-pritam.sutar@samsung.com>
References: <20250805115216.3798121-1-pritam.sutar@samsung.com>
 <CGME20250805114320epcas5p3968288f8d01944d3d730b3094a7befe4@epcas5p3.samsung.com>
 <20250805115216.3798121-6-pritam.sutar@samsung.com>
Message-ID: <20250806234309.GA2032999-robh@kernel.org>

On Tue, Aug 05, 2025 at 05:22:15PM +0530, Pritam Manohar Sutar wrote:
> This phy supports USB3.1 SSP+(10Gbps) protocol and is backwards
> compatible to the USB3.0 SS(5Gbps). It requires two clocks, named
> "phy" and "ref". The required supplies for USB3.1 are named as
> vdd075_usb30(0.75v), vdd18_usb30(1.8v).
> 
> Add schemas for combo ssphy found on this SoC.
> 
> Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
> ---
>  .../bindings/phy/samsung,usb3-drd-phy.yaml    | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
> index 4a84b5405cd2..7a71cff10fb5 100644
> --- a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
> +++ b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
> @@ -34,6 +34,7 @@ properties:
>        - samsung,exynos7870-usbdrd-phy
>        - samsung,exynos850-usbdrd-phy
>        - samsung,exynos990-usbdrd-phy
> +      - samsung,exynosautov920-usb31drd-combo-ssphy
>        - samsung,exynosautov920-usbdrd-combo-hsphy
>        - samsung,exynosautov920-usbdrd-phy
>  
> @@ -118,6 +119,12 @@ properties:
>    vdd18-usb20-supply:
>      description: 1.8V power supply for the USB 2.0 phy.
>  
> +  dvdd075-usb30-supply:
> +    description: 0.75V power supply for the USB 3.0 phy.
> +
> +  vdd18-usb30-supply:
> +    description: 1.8V power supply for the USB 3.0 phy.
> +
>  required:
>    - compatible
>    - clocks
> @@ -227,6 +234,7 @@ allOf:
>                - samsung,exynos7870-usbdrd-phy
>                - samsung,exynos850-usbdrd-phy
>                - samsung,exynos990-usbdrd-phy
> +              - samsung,exynosautov920-usb31drd-combo-ssphy
>                - samsung,exynosautov920-usbdrd-combo-hsphy
>                - samsung,exynosautov920-usbdrd-phy
>      then:
> @@ -258,6 +266,17 @@ allOf:
>          - vdd18-usb20-supply
>          - vdd33-usb20-supply
>  
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - samsung,exynosautov920-usb31drd-combo-ssphy
> +    then:
> +      required:
> +        - dvdd075-usb30-supply
> +        - vdd18-usb30-supply

Similar issue here.


From Thinh.Nguyen at synopsys.com  Wed Aug  6 17:58:15 2025
From: Thinh.Nguyen at synopsys.com (Thinh Nguyen)
Date: Thu, 7 Aug 2025 00:58:15 +0000
Subject: [RFC/PATCH 1/2] usb: dwc3: disable for USB_ROLE_NONE
In-Reply-To: <aJOMk_PVasn-tvV6-jkeeping@inmusicbrands.com>
References: <20250710152252.2532020-1-jkeeping@inmusicbrands.com>
 <20250710152252.2532020-2-jkeeping@inmusicbrands.com>
 <20250712001131.ax3rw24h3deekxfv@synopsys.com>
 <aHUfFGnGZP4z7UgK-jkeeping@inmusicbrands.com>
 <20250729221027.jvg3bpqhc3z5j7xn@synopsys.com>
 <aJOMk_PVasn-tvV6-jkeeping@inmusicbrands.com>
Message-ID: <20250807005814.nlf7aotts5o7navl@synopsys.com>

On Wed, Aug 06, 2025, John Keeping wrote:
> On Tue, Jul 29, 2025 at 10:10:35PM +0000, Thinh Nguyen wrote:
> > On Mon, Jul 14, 2025, John Keeping wrote:
> > > On Sat, Jul 12, 2025 at 12:11:38AM +0000, Thinh Nguyen wrote:
> > > > On Thu, Jul 10, 2025, John Keeping wrote:
> > > > > When the phy is acting as a Type C mux, it may need to reset when the
> > > > > cable direction changes.  But this should not happen while DWC3 is
> > > > > trying to use the USB connection.
> > > > > 
> > > > > In this case, there must be a connection manager to notify the phy of
> > > > > the orientation change and tcpm_mux_set() ensures this happens before
> > > > > DWC3's role switch is informed of a change.
> > > > > 
> > > > > It should not be possible to go directly from device->device or
> > > > > host->host with a change in orientation without transitioning through
> > > > > the "none" role as the cable is unplugged.  So ensuring that DWC3 always
> > > > 
> > > > The controller is either host or device mode. It's odd to use "none" to
> > > > indicate connection.
> > > 
> > > There is no connection in this state.  When the type C controller
> > > indicates that the role is "none" then there cannot be a USB connection.
> > > 
> > 
> > It's not about connection. It's about the current mode of the USB
> > controller. The mode of the controller isn't "none" on disconnection
> > even if you try to role-switch to that via the typec switch.
> > 
> > > > > informs the phy of the new mode whenever a plug is detected should be
> > > > > sufficient for the phy to safely reset itself at a time that is safe for
> > > > > DWC3.
> > > > 
> > > > Couldn't the phy do this as it detects connection/disconnection.
> > > 
> > > I don't think the phy can detect a connection.  If it is configured for
> > > the wrong orientation then it will not monitor the correct data lines.
> > > The phy hardware does not signal any interrupts to the CPU for the
> > > driver to react to.
> > 
> > Ok.
> > 
> > > 
> > > > It seems what you need is a full controller initialization upon new
> > > > connection on orientation change, and you're using role_switch selecting
> > > > "none" to do so.
> > > 
> > > I'm not sure whether a complete initialization is necessary, but what I
> > > want to avoid is the phy resetting while the controller is part-way
> > > through device enumeration or setting up a gadget configuration.
> > > 
> > > It may be that simply avoiding resetting the phy if the orientation is
> > > unchanged is enough to avoid some of this problem, but I suspect there
> > > are still problems if the clocks from the phy to the controller are
> > > stopped unexpectedly.  However, I have run some tests of this change and
> > > it looks promising.
> > 
> > That sounds like the the phy reset is done after asserting the vbus
> > valid line indicating connection to the controller. Can this be fixed in
> > the phy or type-c driver?
> 
> I don't think so.  I've tried implementing this in the phy driver and it
> does not work reliably.
> 
> > > > I'm not sure if role-switch has the right interface to do so. Perhaps we
> > > > can introduce one? I don't think we should change the behavior of the
> > > > current flow and apply that to all other platforms.
> > > 
> > > I don't think it's unreasonable for the controller to be idle when there
> > > is an external type C controller notifying the connection state.
> > > 
> > > The hardware setup looks like this, with the Linux type C code notifying
> > > the phy driver of the orientation change and the DWC3 driver of the role
> > > change:
> > > 
> > >                       +------+          
> > >                       | DWC3 |<----+    
> > >                       +--^---+     |    
> > >                          |         |    
> > >                       +--v--+      |    
> > >                 +---->| PHY |      |Role
> > >                 |     +--^--+      |    
> > >     Orientation |        |         |    
> > >                 |   +----v----+    |    
> > >                 +---+ FUSB302 +----+    
> > >                     +---------+
> > > 
> > > The advantage of using the role hook is that we are guaranteed that it
> > > is called after the phy has been notified of the orientation change.
> > > 
> > > Do you have an idea of a new interface?  Or do you think it is safe to
> > > reset the phy underneath the controller when that will halt the clocks
> > > from the phy to the controller for some period of time?
> > 
> > The proper fix should be in the phy where it should only assert vbus
> > valid after processing orientation and phy reset. I'm not familiar on
> > the communication between your PHY and FUSB302. There should be some
> > indication from the phy that it's ready before you can assert vbus-valid
> > (that can be from a callback, a status register etc).
> 
> The FUSB302 is connected to the CPU via I2C, there is no direct
> communication between it and the phy, it all goes via the kernel's tcpm
> subsystem.
> 
> The problem with re-initializing the phy is that this causes dwc3 gadget
> configuration to fail with "failed to enable ep0out", and this happens
> when VBUS valid is de-asserted.  This is 100% reproducible on boot for
> me where the init scripts are setting up a gadget via configfs.
> 
> So it seems the timing of the phy setup needs to coordinate with the
> dwc3 controller.

Ok.

> 
> > What you've done is a teardown and reinit of the driver, triggering a
> > soft-reset. This can re-sync the phy. That probably takes long enough
> > that a phy-reset after orientation change will be completed before the
> > initialization complete.
> > 
> > If there's no way for you to know when the phy complete its reset, we
> > can add a quirk for your platform to always reinit on role-switch call.
> > 
> > Let me know if this is reasonable.
> 
> I'm happy to test patches.
> 

Sure. I'll need to get back on this.

BR,
Thinh

From h-shenoy at ti.com  Wed Aug  6 22:20:02 2025
From: h-shenoy at ti.com (Harikrishna Shenoy)
Date: Thu, 7 Aug 2025 10:50:02 +0530
Subject: [PATCH v3] drivers: phy: cadence: cdns-dphy: Enable lower resolutions in dphy
Message-ID: <20250807052002.717807-1-h-shenoy@ti.com>

Enable support for data lane rates between 80-160 Mbps cdns dphy
as mentioned in TRM [0] by setting the pll_opdiv field to 16.
This change enables lower resolutions like 640x480 at 60Hz.

[0]: https://www.ti.com/lit/zip/spruil1
(Table 12-552. DPHY_TX_PLL_CTRL Register Field Descriptions)

Reviewed-by: Udit Kumar <u-kumar1 at ti.com>
Reviewed-by: Devarsh Thakkar <devarsht at ti.com>
Signed-off-by: Harikrishna Shenoy <h-shenoy at ti.com>
---
Changes in v3:
- Updated commit message.
- Added Reviewed-by tags.
- Link to v2: https://lore.kernel.org/all/20250806052650.429767-1-h-shenoy at ti.com/

Changes in v2:
- Updated commit message and title.
- Added Reviewed-by tag.
- Link to v1: https://lore.kernel.org/all/1ebb82ea-4b6c-4496-b7c0-17d4168d8ddf at ti.com/

Test log: https://gist.github.com/h-shenoy/3975156baf403a0ff8dbcce5b49b2b89

 drivers/phy/cadence/cdns-dphy.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c
index ed87a3970f83..9abed2ece9b0 100644
--- a/drivers/phy/cadence/cdns-dphy.c
+++ b/drivers/phy/cadence/cdns-dphy.c
@@ -139,7 +139,7 @@ static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy,
 
 	dlane_bps = opts->hs_clk_rate;
 
-	if (dlane_bps > 2500000000UL || dlane_bps < 160000000UL)
+	if (dlane_bps > 2500000000UL || dlane_bps < 80000000UL)
 		return -EINVAL;
 	else if (dlane_bps >= 1250000000)
 		cfg->pll_opdiv = 1;
@@ -149,6 +149,8 @@ static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy,
 		cfg->pll_opdiv = 4;
 	else if (dlane_bps >= 160000000)
 		cfg->pll_opdiv = 8;
+	else if (dlane_bps >= 80000000)
+		cfg->pll_opdiv = 16;
 
 	cfg->pll_fbdiv = DIV_ROUND_UP_ULL(dlane_bps * 2 * cfg->pll_opdiv *
 					  cfg->pll_ipdiv,
-- 
2.34.1



From amadeus at jmu.edu.cn  Wed Aug  6 23:30:36 2025
From: amadeus at jmu.edu.cn (Chukun Pan)
Date: Thu,  7 Aug 2025 14:30:36 +0800
Subject: [PATCH v5 5/6] phy: rockchip: naneng-combphy: Add RK3528 support
In-Reply-To: <20250728102947.38984-7-ziyao@disroot.org>
References: <20250728102947.38984-7-ziyao@disroot.org>
Message-ID: <20250807063036.480766-1-amadeus@jmu.edu.cn>

Hi,

> Rockchip RK3528 integrates one naneng-combphy that is able to operate in
> PCIe and USB3 mode. The control logic is similar to previous variants of
> naneng-combphy but the register layout is apperantly different from the
> RK3568 one.

Is this a typo? apperantly -> apparently

Thanks,
Chukun

--
2.25.1




From amadeus at jmu.edu.cn  Thu Aug  7 00:00:35 2025
From: amadeus at jmu.edu.cn (Chukun Pan)
Date: Thu,  7 Aug 2025 15:00:35 +0800
Subject: [PATCH 07/11] arm64: dts: rockchip: Add USB nodes for RK3528
In-Reply-To: <94357eb2-d8aa-4928-8816-9f6529530170@kwiboo.se>
References: <94357eb2-d8aa-4928-8816-9f6529530170@kwiboo.se>
Message-ID: <20250807070035.486388-1-amadeus@jmu.edu.cn>

Hi,

> That is what I did for ROCK 2A testing I added the usb3-phy to the board
> dts. Mostly for two reasons, first because I did not want to make this
> series fully depend on the naneng-combphy series. And secondly because
> the ROCK 2A also have some sort of GPIO controlled mux for USB3 and PCIe
> signals that may affect how usb3 support is described in the device tree.

I tested this on a rk3528 board (usb3 only) with a usb hub:

~# lsusb -t
/:  Bus 001.Port 001: Dev 001, Class=root_hub, Driver=xhci-hcd/1p, 480M
    |__ Port 001: Dev 002, If 0, Class=[unknown], Driver=hub/4p, 480M
/:  Bus 002.Port 001: Dev 001, Class=root_hub, Driver=xhci-hcd/1p, 5000M
    |__ Port 001: Dev 002, If 0, Class=[unknown], Driver=hub/4p, 5000M
        |__ Port 002: Dev 003, If 0, Class=[unknown], Driver=usb-storage, 5000M
/:  Bus 003.Port 001: Dev 001, Class=root_hub, Driver=ehci-platform/1p, 480M
/:  Bus 004.Port 001: Dev 001, Class=root_hub, Driver=ohci-platform/1p, 12M

> I am open to ideas on how or what default phys to include in soc dtsi.

I have no problem with this, either is fine.

> > Maybe "snps,dis_u2_susphy_quirk" is needed?
>
> Maybe, it did not seem to be needed when I tested USB2.0 only or USB3.0,
> will run some more tests on my boards.
>
> Any issues you know that snps,dis_u2_susphy_quirk would help fix?

This appears to be to allow the DWC3 core to reliably detect the Vbus
status of the connected PHY. Not sure if this is really needed.

> From what I could see these nodes are named u2phy for 8 other Rockchip
> SoCs and only named usb2phy for 3. So I went with what the majority seem
> to be calling them.

The name u2phy comes from the downstream BSP, and I think it doesn't hurt
to call it usb2phy.

Thanks,
Chukun

--
2.25.1




From krzk at kernel.org  Thu Aug  7 00:42:09 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 7 Aug 2025 09:42:09 +0200
Subject: [PATCH v2 1/3] dt-bindings: phy: rockchip,pcie3-phy: add
 optional differential phy clocks
In-Reply-To: <20250806133824.525871-2-rick.wertenbroek@gmail.com>
References: <20250806133824.525871-1-rick.wertenbroek@gmail.com>
 <20250806133824.525871-2-rick.wertenbroek@gmail.com>
Message-ID: <20250807-amphibian-fanatic-muskrat-b1365b@kuoka>

On Wed, Aug 06, 2025 at 03:38:21PM +0200, Rick Wertenbroek wrote:
> Both PHYs can use an alternate reference differential clock, add the clocks

I do not see any changes in rockchip,rk3588-pcie3-phy, so your "both" is
either incorrect or ambiguous.

...

> to the DT bindings
> 
  
>    data-lanes:
>      description: which lanes (by position) should be mapped to which
> @@ -82,10 +82,15 @@ allOf:
>      then:
>        properties:
>          clocks:
> -          maxItems: 1
> +          minItems: 1
> +          maxItems: 5
>          clock-names:
>            items:
>              - const: pclk
> +            - const: phy0_ref_alt_p
> +            - const: phy0_ref_alt_m
> +            - const: phy1_ref_alt_p
> +            - const: phy1_ref_alt_m

These are different clock inputs?

>      else:
>        properties:
>          clocks:

You need to update the example as well.

> -- 
> 2.25.1
> 


From ziyao at disroot.org  Thu Aug  7 00:42:06 2025
From: ziyao at disroot.org (Yao Zi)
Date: Thu, 7 Aug 2025 07:42:06 +0000
Subject: [PATCH v5 5/6] phy: rockchip: naneng-combphy: Add RK3528 support
In-Reply-To: <20250807063036.480766-1-amadeus@jmu.edu.cn>
References: <20250728102947.38984-7-ziyao@disroot.org>
 <20250807063036.480766-1-amadeus@jmu.edu.cn>
Message-ID: <aJRYlA6jo9l-XrHt@pie>

On Thu, Aug 07, 2025 at 02:30:36PM +0800, Chukun Pan wrote:
> Hi,
> 
> > Rockchip RK3528 integrates one naneng-combphy that is able to operate in
> > PCIe and USB3 mode. The control logic is similar to previous variants of
> > naneng-combphy but the register layout is apperantly different from the
> > RK3568 one.
> 
> Is this a typo? apperantly -> apparently

Ahh, yes, thanks for catching it.

I think this series (at least the binding and driver parts) is mostly
ready for merging, so I'll be thankful if the maintainer could fix it
while picking up, or I will carry the fix in a new version if it's found
that larger changes are necessary.

> Thanks,
> Chukun

Best regards,
Yao Zi

> --
> 2.25.1
> 
> 


From krzk at kernel.org  Thu Aug  7 00:44:47 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 7 Aug 2025 09:44:47 +0200
Subject: [PATCH v2 1/3] dt-bindings: phy: rockchip,pcie3-phy: add optional
 differential phy clocks
In-Reply-To: <20250807-amphibian-fanatic-muskrat-b1365b@kuoka>
References: <20250806133824.525871-1-rick.wertenbroek@gmail.com>
 <20250806133824.525871-2-rick.wertenbroek@gmail.com>
 <20250807-amphibian-fanatic-muskrat-b1365b@kuoka>
Message-ID: <7ea03b71-d36d-49a4-b848-34eba4c1620d@kernel.org>

On 07/08/2025 09:42, Krzysztof Kozlowski wrote:
> On Wed, Aug 06, 2025 at 03:38:21PM +0200, Rick Wertenbroek wrote:
>> Both PHYs can use an alternate reference differential clock, add the clocks
> 
> I do not see any changes in rockchip,rk3588-pcie3-phy, so your "both" is

I meant 3568, the other one.

> either incorrect or ambiguous.
> 
> ...
> 
>> to the DT bindings
>>

Best regards,
Krzysztof


From krzk at kernel.org  Thu Aug  7 00:54:48 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 7 Aug 2025 09:54:48 +0200
Subject: [PATCH v2 3/3] dt-bindings: phy: rockchip,pcie3-phy: add
 rockchip,phy-ref-use-pad
In-Reply-To: <20250806133824.525871-4-rick.wertenbroek@gmail.com>
References: <20250806133824.525871-1-rick.wertenbroek@gmail.com>
 <20250806133824.525871-4-rick.wertenbroek@gmail.com>
Message-ID: <20250807-inquisitive-speedy-rooster-0a8488@kuoka>

On Wed, Aug 06, 2025 at 03:38:23PM +0200, Rick Wertenbroek wrote:
> >From the RK3588 Technical Reference Manual, Part1,
> section 6.19 PCIe3PHY_GRF Register Description: "ref_use_pad"
> 
> "Select reference clock connected to ref_pad_clk_p/ref_pad_clk_m.
> Selects the external ref_pad_clk_p and ref_pad_clk_m inputs as the
> reference clock source when asserted. When de-asserted, ref_alt_clk_p
> and ref_alt_clk_m are the sources of the reference clock."
> 
> The hardware reset value for this field is 0x1 (enabled).
> Note that this register field is only available on RK3588, not on RK3568.

Then you miss restricting it (:false) in one of if:then: blocks.

Also, binding cannot be after the user. You need to reorder patches.

...

>  
> +  rockchip,phy-ref-use-pad:
> +    description: which PHY should use the external pad as PCIe reference clock.
> +      1 means use pad (default), 0 means use internal clock (PLL_PPLL).

Can't you deduce it from the presence of clock inputs? IOW, if the
clocks are physically connected, is it even reasonable or possible to
use internal clock?

> +    $ref: /schemas/types.yaml#/definitions/uint32-array
> +    minItems: 2
> +    maxItems: 2
> +    items:
> +      minimum: 0
> +      maximum: 1

More precise:

items:
  - description: PHY0 reference clock config
  - description: PHY1 reference clock config
  enum: [ 0, 1 ]
default: [ 1, 1 ]

Anyway, default 1, 1 is pretty non-obvious, so this should be just
non-unique-string-array (and property should be like
rockchip,phy-ref-clk-source/sel).


Best regards,
Krzysztof



From krzk at kernel.org  Thu Aug  7 00:55:39 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 7 Aug 2025 09:55:39 +0200
Subject: [PATCH v2 3/3] dt-bindings: phy: rockchip,pcie3-phy: add
 rockchip,phy-ref-use-pad
In-Reply-To: <20250807-inquisitive-speedy-rooster-0a8488@kuoka>
References: <20250806133824.525871-1-rick.wertenbroek@gmail.com>
 <20250806133824.525871-4-rick.wertenbroek@gmail.com>
 <20250807-inquisitive-speedy-rooster-0a8488@kuoka>
Message-ID: <c86bcdf0-f692-4263-a597-f8e36a53e8d9@kernel.org>

On 07/08/2025 09:54, Krzysztof Kozlowski wrote:
> On Wed, Aug 06, 2025 at 03:38:23PM +0200, Rick Wertenbroek wrote:
>> >From the RK3588 Technical Reference Manual, Part1,
>> section 6.19 PCIe3PHY_GRF Register Description: "ref_use_pad"
>>
>> "Select reference clock connected to ref_pad_clk_p/ref_pad_clk_m.
>> Selects the external ref_pad_clk_p and ref_pad_clk_m inputs as the
>> reference clock source when asserted. When de-asserted, ref_alt_clk_p
>> and ref_alt_clk_m are the sources of the reference clock."
>>
>> The hardware reset value for this field is 0x1 (enabled).
>> Note that this register field is only available on RK3588, not on RK3568.
> 
> Then you miss restricting it (:false) in one of if:then: blocks.
> 
> Also, binding cannot be after the user. You need to reorder patches.
> 
> ...
> 
>>  
>> +  rockchip,phy-ref-use-pad:
>> +    description: which PHY should use the external pad as PCIe reference clock.
>> +      1 means use pad (default), 0 means use internal clock (PLL_PPLL).
> 
> Can't you deduce it from the presence of clock inputs? IOW, if the
> clocks are physically connected, is it even reasonable or possible to
> use internal clock?
> 
>> +    $ref: /schemas/types.yaml#/definitions/uint32-array
>> +    minItems: 2
>> +    maxItems: 2
>> +    items:
>> +      minimum: 0
>> +      maximum: 1
> 
> More precise:
> 
> items:
>   - description: PHY0 reference clock config
>   - description: PHY1 reference clock config
>   enum: [ 0, 1 ]

Eh, no, rather if this stays as int:

    items:
      - description: PHY0 reference clock config
        enum: [ 0, 1 ]
      - description: PHY1 reference clock config
        enum: [ 0, 1 ]
    default: [ 1, 1 ]


> default: [ 1, 1 ]
> 
> Anyway, default 1, 1 is pretty non-obvious, so this should be just
> non-unique-string-array (and property should be like
> rockchip,phy-ref-clk-source/sel).
> 
> 
> Best regards,
> Krzysztof
> 


Best regards,
Krzysztof


From rick.wertenbroek at gmail.com  Thu Aug  7 00:58:11 2025
From: rick.wertenbroek at gmail.com (Rick Wertenbroek)
Date: Thu, 7 Aug 2025 09:58:11 +0200
Subject: [PATCH v2 1/3] dt-bindings: phy: rockchip,pcie3-phy: add optional
 differential phy clocks
In-Reply-To: <7ea03b71-d36d-49a4-b848-34eba4c1620d@kernel.org>
References: <20250806133824.525871-1-rick.wertenbroek@gmail.com>
 <20250806133824.525871-2-rick.wertenbroek@gmail.com> <20250807-amphibian-fanatic-muskrat-b1365b@kuoka>
 <7ea03b71-d36d-49a4-b848-34eba4c1620d@kernel.org>
Message-ID: <CAAEEuhpZGbuGkAKRiYQouAwDwnJbP+9ppi7BtrZekKpp20iOgQ@mail.gmail.com>

On Thu, Aug 7, 2025 at 9:44?AM Krzysztof Kozlowski <krzk at kernel.org> wrote:
>
> On 07/08/2025 09:42, Krzysztof Kozlowski wrote:
> > On Wed, Aug 06, 2025 at 03:38:21PM +0200, Rick Wertenbroek wrote:
> >> Both PHYs can use an alternate reference differential clock, add the clocks
> >
> > I do not see any changes in rockchip,rk3588-pcie3-phy, so your "both" is
>
> I meant 3568, the other one.
>

By "both" I meant both PHYs of the RK3588 as the rk3588-pcie-phy is
actually a dual PHY (PHY0 and PHY1 which both can use independent
clocks).

The RK3588 PHY is a dual PHY with two independent PCIe 3.0 x2
interfaces (that can be combined into an x4 or used independently).
The RK3568 PHY is a single PHY with one PCIe 3.0 x2 interface.

The RK3568 already has the bindings for the extra differential clock
for its PHY, but the RK3588 did not, so I added them.

I should maybe rephrase this to make it clearer it applies only to the
RK3588 and that by both PHYs I mean RK3588 PHY0 and PHY1

> > either incorrect or ambiguous.
> >
> > ...
> >
> >> to the DT bindings
> >>
>
> Best regards,
> Krzysztof


From neil.armstrong at linaro.org  Thu Aug  7 01:16:24 2025
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Thu, 7 Aug 2025 10:16:24 +0200
Subject: [PATCH] phy: ti: omap-usb2: enable compile testing
In-Reply-To: <20250724131623.2662-1-johan@kernel.org>
References: <20250724131623.2662-1-johan@kernel.org>
Message-ID: <1370b493-2026-4988-a8a2-d9595c0fb02b@linaro.org>

On 24/07/2025 15:16, Johan Hovold wrote:
> Nothing seems to prevent the driver from being built on non-TI platforms
> so enable compile testing for wider build coverage.
> 
> Signed-off-by: Johan Hovold <johan at kernel.org>
> ---
>   drivers/phy/ti/Kconfig | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/phy/ti/Kconfig b/drivers/phy/ti/Kconfig
> index b905902d5750..b40f28019131 100644
> --- a/drivers/phy/ti/Kconfig
> +++ b/drivers/phy/ti/Kconfig
> @@ -62,7 +62,7 @@ config OMAP_CONTROL_PHY
>   
>   config OMAP_USB2
>   	tristate "OMAP USB2 PHY Driver"
> -	depends on ARCH_OMAP2PLUS || ARCH_K3
> +	depends on ARCH_OMAP2PLUS || ARCH_K3 || COMPILE_TEST
>   	depends on USB_SUPPORT
>   	select GENERIC_PHY
>   	select USB_PHY

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>



From neil.armstrong at linaro.org  Thu Aug  7 01:16:33 2025
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Thu, 7 Aug 2025 10:16:33 +0200
Subject: [PATCH v3 0/7] SPMI: Implement sub-devices and migrate drivers
In-Reply-To: <20250730112645.542179-1-angelogioacchino.delregno@collabora.com>
References: <20250730112645.542179-1-angelogioacchino.delregno@collabora.com>
Message-ID: <7c3d9e84-d14f-4cf0-b376-6fdde6f586f5@linaro.org>

On 30/07/2025 13:26, AngeloGioacchino Del Regno wrote:
> Changes in v3:
>   - Fixed importing "SPMI" namespace in spmi-devres.c
>   - Removed all instances of defensive programming, as pointed out by
>     jic23 and Sebastian
>   - Removed explicit casting as pointed out by jic23
>   - Moved ida_free call to spmi_subdev_release() and simplified error
>     handling in spmi_subdevice_alloc_and_add() as pointed out by jic23
> 
> Changes in v2:
>   - Fixed missing `sparent` initialization in phy-qcom-eusb2-repeater
>   - Changed val_bits to 8 in all Qualcomm drivers to ensure
>     compatibility as suggested by Casey
>   - Added struct device pointer in all conversion commits as suggested
>     by Andy
>   - Exported newly introduced functions with a new "SPMI" namespace
>     and imported the same in all converted drivers as suggested by Andy
>   - Added missing error checking for dev_set_name() call in spmi.c
>     as suggested by Andy
>   - Added comma to last entry of regmap_config as suggested by Andy
> 
> While adding support for newer MediaTek platforms, featuring complex
> SPMI PMICs, I've seen that those SPMI-connected chips are internally
> divided in various IP blocks, reachable in specific contiguous address
> ranges... more or less like a MMIO, but over a slow SPMI bus instead.
> 
> I recalled that Qualcomm had something similar... and upon checking a
> couple of devicetrees, yeah - indeed it's the same over there.
> 
> What I've seen then is a common pattern of reading the "reg" property
> from devicetree in a struct member and then either
>   A. Wrapping regmap_{read/write/etc}() calls in a function that adds
>      the register base with "base + ..register", like it's done with
>      writel()/readl() calls; or
>   B. Doing the same as A. but without wrapper functions.
> 
> Even though that works just fine, in my opinion it's wrong.
> 
> The regmap API is way more complex than MMIO-only readl()/writel()
> functions for multiple reasons (including supporting multiple busses
> like SPMI, of course) - but everyone seemed to forget that regmap
> can manage register base offsets transparently and automatically in
> its API functions by simply adding a `reg_base` to the regmap_config
> structure, which is used for initializing a `struct regmap`.
> 
> So, here we go: this series implements the software concept of an SPMI
> Sub-Device (which, well, also reflects how Qualcomm and MediaTek's
> actual hardware is laid out anyway).
> 
>                 SPMI Controller
>                       |                ______
>                       |               /       Sub-Device 1
>                       V              /
>                SPMI Device (PMIC) ----------- Sub-Device 2
>                                      \
>                                       \______ Sub-Device 3
> 
> As per this implementation, an SPMI Sub-Device can be allocated/created
> and added in any driver that implements a... well.. subdevice (!) with
> an SPMI "main" device as its parent: this allows to create and finally
> to correctly configure a regmap that is specific to the sub-device,
> operating on its specific address range and reading, and writing, to
> its registers with the regmap API taking care of adding the base address
> of a sub-device's registers as per regmap API design.
> 
> All of the SPMI Sub-Devices are therefore added as children of the SPMI
> Device (usually a PMIC), as communication depends on the PMIC's SPMI bus
> to be available (and the PMIC to be up and running, of course).
> 
> Summarizing the dependency chain (which is obvious to whoever knows what
> is going on with Qualcomm and/or MediaTek SPMI PMICs):
>      "SPMI Sub-Device x...N" are children "SPMI Device"
>      "SPMI Device" is a child of "SPMI Controller"
> 
> (that was just another way to say the same thing as the graph above anyway).
> 
> Along with the new SPMI Sub-Device registration functions, I have also
> performed a conversion of some Qualcomm SPMI drivers and only where the
> actual conversion was trivial.
> 
> I haven't included any conversion of more complex Qualcomm SPMI drivers
> because I don't have the required bandwidth to do so (and besides, I think,
> but haven't exactly verified, that some of those require SoCs that I don't
> have for testing anyway).
> 
> AngeloGioacchino Del Regno (7):
>    spmi: Implement spmi_subdevice_alloc_and_add() and devm variant
>    nvmem: qcom-spmi-sdam: Migrate to devm_spmi_subdevice_alloc_and_add()
>    power: reset: qcom-pon: Migrate to devm_spmi_subdevice_alloc_and_add()
>    phy: qualcomm: eusb2-repeater: Migrate to
>      devm_spmi_subdevice_alloc_and_add()
>    misc: qcom-coincell: Migrate to devm_spmi_subdevice_alloc_and_add()
>    iio: adc: qcom-spmi-iadc: Migrate to
>      devm_spmi_subdevice_alloc_and_add()
>    iio: adc: qcom-spmi-iadc: Remove regmap R/W wrapper functions
> 
>   drivers/iio/adc/qcom-spmi-iadc.c              | 109 ++++++++----------
>   drivers/misc/qcom-coincell.c                  |  38 ++++--
>   drivers/nvmem/qcom-spmi-sdam.c                |  37 ++++--
>   .../phy/qualcomm/phy-qcom-eusb2-repeater.c    |  51 +++++---
>   drivers/power/reset/qcom-pon.c                |  34 ++++--
>   drivers/spmi/spmi-devres.c                    |  24 ++++
>   drivers/spmi/spmi.c                           |  79 +++++++++++++
>   include/linux/spmi.h                          |  16 +++
>   8 files changed, 278 insertions(+), 110 deletions(-)
> 

Tested-by: Neil Armstrong <neil.armstrong at linaro.org> # on SM8650-QRD

Tested patch 1, 2, 3 & 4, I can see the :
/sys/kernel/debug/regmap/0-00.0.auto
/sys/kernel/debug/regmap/0-00.1.auto
/sys/kernel/debug/regmap/0-07.2.auto

And it still functional.

Neil



From neil.armstrong at linaro.org  Thu Aug  7 01:16:43 2025
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Thu, 7 Aug 2025 10:16:43 +0200
Subject: [PATCH v3 0/6] arm64: qcom: allow up to 4 lanes for the Type-C
 DisplayPort Altmode
In-Reply-To: <f21b7d52-4c3f-4e5b-bee7-f8b2945b5b02@oss.qualcomm.com>
References: <20250527-topic-4ln_dp_respin-v3-0-f9a0763ec289@oss.qualcomm.com>
 <styd5gjksbsqt7efylpfn6bgwgyvt6zexxiooihjsnmp25yigp@unq7dor6gso2>
 <447c3b13-8d6d-4bcb-83c1-9456b915a77e@oss.qualcomm.com>
 <inpfuxskvmrebxitqtqwzvpnpicibo6zakgk4ujpcrqrpef2vw@nhclj5rg7axr>
 <9037fefe-aa40-4884-97ee-b81ff8346944@oss.qualcomm.com>
 <htufwjvfgdtav2gtgrytc356py6xqhrffbwjg42sgo7k4zzxof@z4xaf35qz7kq>
 <aa17d7d4-b77d-4a0a-88c3-86255dfbc29d@oss.qualcomm.com>
 <75dde9a2-3c0d-481b-bc73-089ba89a77e0@linaro.org>
 <71196aad-6d80-4356-bbe5-3070f6b74bfe@oss.qualcomm.com>
 <fhzdhzxdwcoiuhx2eogpshwt5cxagjkrygrefqikmfbx3cfcov@awmhgrvurnfi>
 <f21b7d52-4c3f-4e5b-bee7-f8b2945b5b02@oss.qualcomm.com>
Message-ID: <c2f2ba36-1a25-450e-99b9-79aa4fd4913d@linaro.org>

On 06/08/2025 17:48, Konrad Dybcio wrote:
> On 6/3/25 3:17 PM, Dmitry Baryshkov wrote:
>> On Tue, Jun 03, 2025 at 01:03:11PM +0200, Konrad Dybcio wrote:
>>> On 6/2/25 10:55 AM, Neil Armstrong wrote:
>>>> On 28/05/2025 18:56, Konrad Dybcio wrote:
>>>>> On 5/28/25 1:22 PM, Dmitry Baryshkov wrote:
>>>>>> On Wed, May 28, 2025 at 01:13:26PM +0200, Konrad Dybcio wrote:
>>>>>>> On 5/28/25 11:00 AM, Dmitry Baryshkov wrote:
>>>>>>>> On Wed, May 28, 2025 at 12:24:02AM +0200, Konrad Dybcio wrote:
>>>>>>>>> On 5/27/25 11:10 PM, Dmitry Baryshkov wrote:
>>>>>>>>>> On Tue, May 27, 2025 at 10:40:02PM +0200, Konrad Dybcio wrote:
>>>>>>>>>>> Register a typec mux in order to change the PHY mode on the Type-C
>>>>>>>>>>> mux events depending on the mode and the svid when in Altmode setup.
>>>>>>>>>>>
>>>>>>>>>>> The DisplayPort phy should be left enabled if is still powered on
>>>>>>>>>>> by the DRM DisplayPort controller, so bail out until the DisplayPort
>>>>>>>>>>> PHY is not powered off.
>>>>>>>>>>
>>>>>>>>>> This series doesn't seem to solve the USB side of a problem. When the
>>>>>>>>>> PHY is being switch to the 4-lane mode, USB controller looses PIPE
>>>>>>>>>> clock, so it needs to be switched to the USB-2 mode.
>>>>>>>>>
>>>>>>>>> I didn't find issues with that on X13s.. Not sure if it's related, but
>>>>>>>>> on the SL7, after plugging in a 4ln DP connection, I need to plug in
>>>>>>>>> the USB thumb drive twice for the first time (only in that sequence)
>>>>>>>>
>>>>>>>> Might be.
>>>>>>>>
>>>>>>>>> But there's nothing interesting in dmesg and the phy seems to be
>>>>>>>>> programmed with the same values on both the initial and the subsequent
>>>>>>>>> working plug-in
>>>>>>>>
>>>>>>>> Please try using a DP dongle with USB 2 passthrough (there are some).
>>>>>>>> Or just emulate this by enabling DP PHY / DP chain for plugged in USB3
>>>>>>>> devices. Would you be able to see the USB device on a bus?
>>>>>>>
>>>>>>> I only have a dongle with both display and usb that does 2ln dp
>>>>>>> (I tested 4ln dp on a type-c display that I don't think has a hub)
>>>>>>>
>>>>>>> USB3 - yes, USB2 - no (but it works after a replug)
>>>>>>>
>>>>>>> Are you talking about essentially doing qcom,select-utmi-as-pipe-clk
>>>>>>> at runtime?
>>>>>>
>>>>>> I think so.
>>>>>
>>>>> So after quite some time playing with that, I noticed that the USB2
>>>>> device was never actually kicked off the bus.. and works totally fine
>>>>> after connecting the display output (2ln DP)
>>>>>
>>>>> I was looking at dmesg, checking for discovery/disconnect messages,
>>>>> but the device was simply never disconnected (which makes sense given
>>>>> repurposing USB3 TX/RX lanes doesn't affect the D+/D- of USB2)
>>>>>
>>>>> I also read some docs and learnt that what we call
>>>>> qcom,select-utmi-as-pipe-clk is suppossed to be a debug feature
>>>>> and is unnecessary to set on USB2.0-only controllers
>>>>>
>>>>> The USB controller programming guide though doesn't talk about DP,
>>>>> but I'd expect that we may need to set that override for 4lnDP+USB2
>>>>> use cases (which I don't have a dongle for)
>>>>
>>>> Yeah basically we need to:
>>>> 1) power-off the USB3 PHY
>>>> 2) switch to UTMI clock
>>>>
>>>> In the following states:
>>>> - USB safe mode (USB2 lanes may still be connected)
>>>> - 4lanes DP mode
>>>> - DP-only mode
>>>>
>>>> But for this, the dwc3 should also get USB-C events with an addition mode-switch property.
>>>> The flatten DWC3 node now allows that !
>>>
>>> Yeah, I got even more confirmation this is intended..
>>>
>>> I hacked up something that boils down to:
>>>
>>> diff --git a/drivers/usb/dwc3/drd.c b/drivers/usb/dwc3/drd.c
>>> index 7977860932b1..e5a0a8ec624d 100644
>>> --- a/drivers/usb/dwc3/drd.c
>>> +++ b/drivers/usb/dwc3/drd.c
>>> @@ -464,6 +464,11 @@ static int dwc3_usb_role_switch_set(struct usb_role_switch *sw,
>>>   		break;
>>>   	}
>>>   
>>> +	if (dwc->mode_fn)
>>> +		dwc->mode_fn(dwc, mode);
>>>
>>> diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c
>>> index 7334de85ad10..ea56f5087ecb 100644
>>> --- a/drivers/usb/dwc3/dwc3-qcom.c
>>> +++ b/drivers/usb/dwc3/dwc3-qcom.c
>>> +static void mode_fn(struct dwc3 *dwc, enum usb_role role)
>>> +{
>>> +	struct dwc3_qcom *qcom = to_dwc3_qcom(dwc);
>>> +
>>> +	if (dwc->usb3_generic_phy[0])
>>> +		dwc3_qcom_select_utmi_clk(qcom, role == USB_ROLE_NONE);
>>
>> This part is a hack for devices with no USB-2 passthrough, isn't it?
>>
>>>   }
>>>
>>>
>>> It was easy to tap into because there's already mode switch handling..
>>> But obviously it's a hack - should I register a typec_mux in there?
>>
>> I think so, we should listen to mode changes, instead of host/device
>> changes.
>>
>>> Should it go to dwc3-common or dwc3-qcom?
>>
>> I'd say, dwc3-qcom. Not all dwc3 controllers are USB 3 capable, not
>> talking about the USB-C.
> 
> I did some coding and we can't switch clock sources at runtime (not a
> huge shocker), but the bigger issue is that, paraphrasing the HPG, the
> DWC3 controller must be programmed as if it was not SS-capable (probably
> skipping starting some subcores), which is not trivial
> 
> I also came up with a sneaky workaround of simply keeping the USB PLL
> always-on, but the hardware disagrees to do so if the PHY is configured
> in the DP_ONLY mode (which I suppose makes sense)
> 
> All in all, I was not able to find people with a device that actually
> does 4ln DP + USB2 and IIUC the only drawback would be that USB2 would
> not work (and not stall the system). Not sure if/how it recovers after
> you'd plug something else into that port later on, but again, I don't
> have anyone that could test it.
> 
> With that in mind, would you be okay with me resubmitting this series
> with just a rebase & taking care of the comment to patch 5 (pertaining
> to the default mode setting if svid != DP)?

Sure please do so, and I'll retest on the SM8550 & SM8650 platforms.

Thanks for looking !
Neil

> 
> Konrad




From rick.wertenbroek at gmail.com  Thu Aug  7 01:47:18 2025
From: rick.wertenbroek at gmail.com (Rick Wertenbroek)
Date: Thu, 7 Aug 2025 10:47:18 +0200
Subject: [PATCH v2 3/3] dt-bindings: phy: rockchip,pcie3-phy: add rockchip,phy-ref-use-pad
In-Reply-To: <c86bcdf0-f692-4263-a597-f8e36a53e8d9@kernel.org>
References: <20250806133824.525871-1-rick.wertenbroek@gmail.com>
 <20250806133824.525871-4-rick.wertenbroek@gmail.com> <20250807-inquisitive-speedy-rooster-0a8488@kuoka>
 <c86bcdf0-f692-4263-a597-f8e36a53e8d9@kernel.org>
Message-ID: <CAAEEuhpHmW9hji91tbQ3MMhBZELCYc_vA+Ra3oC2W+Rf8LLC6w@mail.gmail.com>

On Thu, Aug 7, 2025 at 9:55?AM Krzysztof Kozlowski <krzk at kernel.org> wrote:
>
> On 07/08/2025 09:54, Krzysztof Kozlowski wrote:
> > On Wed, Aug 06, 2025 at 03:38:23PM +0200, Rick Wertenbroek wrote:
> >> >From the RK3588 Technical Reference Manual, Part1,
> >> section 6.19 PCIe3PHY_GRF Register Description: "ref_use_pad"
> >>
> >> "Select reference clock connected to ref_pad_clk_p/ref_pad_clk_m.
> >> Selects the external ref_pad_clk_p and ref_pad_clk_m inputs as the
> >> reference clock source when asserted. When de-asserted, ref_alt_clk_p
> >> and ref_alt_clk_m are the sources of the reference clock."
> >>
> >> The hardware reset value for this field is 0x1 (enabled).
> >> Note that this register field is only available on RK3588, not on RK3568.
> >
> > Then you miss restricting it (:false) in one of if:then: blocks.
> >
> > Also, binding cannot be after the user. You need to reorder patches.
> >
> > ...
> >
> >>
> >> +  rockchip,phy-ref-use-pad:
> >> +    description: which PHY should use the external pad as PCIe reference clock.
> >> +      1 means use pad (default), 0 means use internal clock (PLL_PPLL).
> >
> > Can't you deduce it from the presence of clock inputs? IOW, if the
> > clocks are physically connected, is it even reasonable or possible to
> > use internal clock?

Thank you Krzysztof,
But no, if there is no clock, the driver deadlocks, it needs a clock
to probe correctly.

When there is a clock physically connected on the pad, you can still
choose to use it or use the internal clock, this is no problem.
The problem is when you have no clock on the pad (as it defaults to
using the pad) and the loading the driver deadlocks the system...

> >
> >> +    $ref: /schemas/types.yaml#/definitions/uint32-array
> >> +    minItems: 2
> >> +    maxItems: 2
> >> +    items:
> >> +      minimum: 0
> >> +      maximum: 1
> >
> > More precise:
> >
> > items:
> >   - description: PHY0 reference clock config
> >   - description: PHY1 reference clock config
> >   enum: [ 0, 1 ]
>
> Eh, no, rather if this stays as int:
>
>     items:
>       - description: PHY0 reference clock config
>         enum: [ 0, 1 ]
>       - description: PHY1 reference clock config
>         enum: [ 0, 1 ]
>     default: [ 1, 1 ]
>
>
> > default: [ 1, 1 ]
> >
> > Anyway, default 1, 1 is pretty non-obvious, so this should be just
> > non-unique-string-array (and property should be like
> > rockchip,phy-ref-clk-source/sel).
> >
> >
> > Best regards,
> > Krzysztof
> >
>
>
> Best regards,
> Krzysztof

I based my patch on patch :
46492d10067660785a09db4ce9244545126a17b8
dt-bindings: phy: rockchip,pcie3-phy: add rockchip,rx-common-refclk-mode

As the option I add is extremely similar, it sets a feature in one of
the PHY registers and only applies to RK3588.
That is why I used the same style as rockchip,rx-common-refclk-mode.

Wouldn't it be confusing or at least incoherent to use enum for
rockchip,phy-ref-use-pad but not for rx-common-refclk-mode ?

As for the name, I used phy-ref-use-pad as it is the name used in the
RK3588 technical reference manual.
(Similarly done on rx-common-refclk-mode).

Best regards,
Rick


From matthias.schiffer at ew.tq-group.com  Thu Aug  7 04:48:52 2025
From: matthias.schiffer at ew.tq-group.com (Matthias Schiffer)
Date: Thu, 07 Aug 2025 13:48:52 +0200
Subject: [PATCH v2] phy: ti: gmii-sel: Force RGMII TX delay
In-Reply-To: <20250806135913.662340-1-mwalle@kernel.org>
References: <20250806135913.662340-1-mwalle@kernel.org>
Message-ID: <e659763b2535701e9061d0a19e1ce9c285d92045.camel@ew.tq-group.com>

On Wed, 2025-08-06 at 15:59 +0200, Michael Walle wrote:
> Some SoCs are just validated with the TX delay enabled. With commit
> ca13b249f291 ("net: ethernet: ti: am65-cpsw: fixup PHY mode for fixed
> RGMII TX delay"), the network driver will patch the delay setting on the
> fly assuming that the TX delay is fixed. In reality, the TX delay is
> configurable and just skipped in the documentation. There are
> bootloaders, which will disable the TX delay and this will lead to a
> transmit path which doesn't add any delays at all. Fix that by always
> forcing the TX delay to be enabled.
> 
> This is safe to do and shouldn't break any boards in mainline because
> the fixed delay is only introduced for gmii-sel compatibles which are
> used together with the am65-cpsw-nuss driver and are affected by the
> commit above.
> 
> Fixes: ca13b249f291 ("net: ethernet: ti: am65-cpsw: fixup PHY mode for fixed RGMII TX delay")
> Signed-off-by: Michael Walle <mwalle at kernel.org>
> ---
> v2:
>  - reject invalid PHY modes. Thanks Matthias.
>  - add a paragraph to the commit message that this patch shouldn't
>    break any existing boards. Thanks Andrew.
> 
>  drivers/phy/ti/phy-gmii-sel.c | 58 ++++++++++++++++++++++++++++++-----
>  1 file changed, 50 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/phy/ti/phy-gmii-sel.c b/drivers/phy/ti/phy-gmii-sel.c
> index ff5d5e29629f..ed078475c4cb 100644
> --- a/drivers/phy/ti/phy-gmii-sel.c
> +++ b/drivers/phy/ti/phy-gmii-sel.c
> @@ -34,6 +34,7 @@ enum {
>  	PHY_GMII_SEL_PORT_MODE = 0,
>  	PHY_GMII_SEL_RGMII_ID_MODE,
>  	PHY_GMII_SEL_RMII_IO_CLK_EN,
> +	PHY_GMII_SEL_FIXED_TX_DELAY,
>  	PHY_GMII_SEL_LAST,
>  };
>  
> @@ -127,6 +128,22 @@ static int phy_gmii_sel_mode(struct phy *phy, enum phy_mode mode, int submode)
>  		goto unsupported;
>  	}
>  
> +	/*
> +	 * Some SoCs only support fixed MAC side TX delays. According to the
> +	 * datasheet, they are always enabled, but that turns out not to be the
> +	 * case and the delay is configurable. But according to the vendor that
> +	 * mode is not validated and might not work. Some bootloaders disable
> +	 * this bit. To work around that, enable it again.
> +	 */
> +	if (soc_data->features & BIT(PHY_GMII_SEL_FIXED_TX_DELAY)) {
> +		/* With a fixed delay, some modes are not supported at all. */
> +		if (submode == PHY_INTERFACE_MODE_RGMII_ID ||
> +		    submode == PHY_INTERFACE_MODE_RGMII_TXID)
> +			return -EINVAL;
> +
> +		rgmii_id = 0;

Can't this just be the following? (maybe with an error message)

if (soc_data->features & BIT(PHY_GMII_SEL_FIXED_TX_DELAY)) {
	if (rgmii_id != 0)
		return -EINVAL;
}



Best,
Matthias

> +	}
> +
>  	if_phy->phy_if_mode = submode;
>  
>  	dev_dbg(dev, "%s id:%u mode:%u rgmii_id:%d rmii_clk_ext:%d\n",
> @@ -210,25 +227,46 @@ struct phy_gmii_sel_soc_data phy_gmii_sel_soc_dm814 = {
>  
>  static const
>  struct reg_field phy_gmii_sel_fields_am654[][PHY_GMII_SEL_LAST] = {
> -	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x0, 0, 2), },
> -	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x4, 0, 2), },
> -	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x8, 0, 2), },
> -	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0xC, 0, 2), },
> -	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x10, 0, 2), },
> -	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x14, 0, 2), },
> -	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x18, 0, 2), },
> -	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x1C, 0, 2), },
> +	{
> +		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x0, 0, 2),
> +		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x0, 4, 4),
> +	}, {
> +		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x4, 0, 2),
> +		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x4, 4, 4),
> +	}, {
> +		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x8, 0, 2),
> +		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x8, 4, 4),
> +	}, {
> +		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0xC, 0, 2),
> +		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0xC, 4, 4),
> +	}, {
> +		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x10, 0, 2),
> +		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x10, 4, 4),
> +	}, {
> +		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x14, 0, 2),
> +		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x14, 4, 4),
> +	}, {
> +		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x18, 0, 2),
> +		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x18, 4, 4),
> +	}, {
> +		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x1C, 0, 2),
> +		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x1C, 4, 4),
> +	},
>  };
>  
>  static const
>  struct phy_gmii_sel_soc_data phy_gmii_sel_soc_am654 = {
>  	.use_of_data = true,
> +	.features = BIT(PHY_GMII_SEL_RGMII_ID_MODE) |
> +		    BIT(PHY_GMII_SEL_FIXED_TX_DELAY),
>  	.regfields = phy_gmii_sel_fields_am654,
>  };
>  
>  static const
>  struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw5g_soc_j7200 = {
>  	.use_of_data = true,
> +	.features = BIT(PHY_GMII_SEL_RGMII_ID_MODE) |
> +		    BIT(PHY_GMII_SEL_FIXED_TX_DELAY),
>  	.regfields = phy_gmii_sel_fields_am654,
>  	.extra_modes = BIT(PHY_INTERFACE_MODE_QSGMII) | BIT(PHY_INTERFACE_MODE_SGMII) |
>  		       BIT(PHY_INTERFACE_MODE_USXGMII),
> @@ -239,6 +277,8 @@ struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw5g_soc_j7200 = {
>  static const
>  struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw9g_soc_j721e = {
>  	.use_of_data = true,
> +	.features = BIT(PHY_GMII_SEL_RGMII_ID_MODE) |
> +		    BIT(PHY_GMII_SEL_FIXED_TX_DELAY),
>  	.regfields = phy_gmii_sel_fields_am654,
>  	.extra_modes = BIT(PHY_INTERFACE_MODE_QSGMII) | BIT(PHY_INTERFACE_MODE_SGMII),
>  	.num_ports = 8,
> @@ -248,6 +288,8 @@ struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw9g_soc_j721e = {
>  static const
>  struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw9g_soc_j784s4 = {
>  	.use_of_data = true,
> +	.features = BIT(PHY_GMII_SEL_RGMII_ID_MODE) |
> +		    BIT(PHY_GMII_SEL_FIXED_TX_DELAY),
>  	.regfields = phy_gmii_sel_fields_am654,
>  	.extra_modes = BIT(PHY_INTERFACE_MODE_QSGMII) | BIT(PHY_INTERFACE_MODE_SGMII) |
>  		       BIT(PHY_INTERFACE_MODE_USXGMII),

-- 
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
https://www.tq-group.com/


From pritam.sutar at samsung.com  Thu Aug  7 05:21:02 2025
From: pritam.sutar at samsung.com (Pritam Manohar Sutar)
Date: Thu, 7 Aug 2025 17:51:02 +0530
Subject: [PATCH v5 1/6] dt-bindings: phy: samsung,usb3-drd-phy: add
 ExynosAutov920 HS phy compatible
In-Reply-To: <20250806234217.GA2030512-robh@kernel.org>
References: <20250805115216.3798121-1-pritam.sutar@samsung.com>
	<CGME20250805114306epcas5p37782c02ae0ddc6b77094786c90af247a@epcas5p3.samsung.com>
	<20250805115216.3798121-2-pritam.sutar@samsung.com>
	<20250806234217.GA2030512-robh@kernel.org>
Message-ID: <000001dc0795$c0432660$40c97320$@samsung.com>

Hi Rob, 

> -----Original Message-----
> From: Rob Herring <robh at kernel.org>
> Sent: 07 August 2025 05:12 AM
> To: Pritam Manohar Sutar <pritam.sutar at samsung.com>
> Cc: vkoul at kernel.org; kishon at kernel.org; krzk+dt at kernel.org;
> conor+dt at kernel.org; alim.akhtar at samsung.com; andre.draszik at linaro.org;
> peter.griffin at linaro.org; kauschluss at disroot.org;
> ivo.ivanov.ivanov1 at gmail.com; igor.belwon at mentallysanemainliners.org;
> m.szyprowski at samsung.com; s.nawrocki at samsung.com; linux-
> phy at lists.infradead.org; devicetree at vger.kernel.org; linux-
> kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-
> samsung-soc at vger.kernel.org; rosa.pila at samsung.com;
> dev.tailor at samsung.com; faraz.ata at samsung.com;
> muhammed.ali at samsung.com; selvarasu.g at samsung.com
> Subject: Re: [PATCH v5 1/6] dt-bindings: phy: samsung,usb3-drd-phy: add
> ExynosAutov920 HS phy compatible
> 
> On Tue, Aug 05, 2025 at 05:22:11PM +0530, Pritam Manohar Sutar wrote:
> > This SoC has USB2.0 phy and supports only UTMI+ interface. This phy
> > requires two clocks, named as "phy" and "ref". The required supplies
> > for this phy are vdd075_usb20(0.75v), vdd18_usb20(1.8v),
> vdd33_usb20(3.3v).
> >
> > Add a dedicated compatible string for USB HS phy found in this SoC.
> >
> > Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
> > ---
> >  .../bindings/phy/samsung,usb3-drd-phy.yaml    | 19
> +++++++++++++++++++
> >  1 file changed, 19 insertions(+)
> >
> > diff --git
> > a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
> > b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
> > index e906403208c0..1932a2272ef9 100644
> > --- a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-
> phy.yaml
> > +++ b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-
> phy.yaml
> > @@ -34,6 +34,7 @@ properties:
> >        - samsung,exynos7870-usbdrd-phy
> >        - samsung,exynos850-usbdrd-phy
> >        - samsung,exynos990-usbdrd-phy
> > +      - samsung,exynosautov920-usbdrd-phy
> >
> >    clocks:
> >      minItems: 1
> > @@ -110,6 +111,12 @@ properties:
> >    vddh-usbdp-supply:
> >      description: VDDh power supply for the USB DP phy.
> >
> > +  dvdd075-usb20-supply:
> > +    description: 0.75V power supply for the USB 2.0 phy.
> > +
> > +  vdd18-usb20-supply:
> > +    description: 1.8V power supply for the USB 2.0 phy.
> > +
> >  required:
> >    - compatible
> >    - clocks
> > @@ -219,6 +226,7 @@ allOf:
> >                - samsung,exynos7870-usbdrd-phy
> >                - samsung,exynos850-usbdrd-phy
> >                - samsung,exynos990-usbdrd-phy
> > +              - samsung,exynosautov920-usbdrd-phy
> >      then:
> >        properties:
> >          clocks:
> > @@ -235,6 +243,17 @@ allOf:
> >
> >          reg-names:
> >            maxItems: 1
> > +  - if:
> > +      properties:
> > +        compatible:
> > +          contains:
> > +            enum:
> > +              - samsung,exynosautov920-usbdrd-phy
> > +    then:
> > +      required:
> > +        - dvdd075-usb20-supply
> > +        - vdd18-usb20-supply
> > +        - vdd33-usb20-supply
> 
> Presumably the existing devices don't have these new supplies, so:
> 
> else:
>   properties:
>     dvdd075-usb20-supply: false
>     vdd18-usb20-supply: false

Appreciated for the suggestion. Will add this change in next version (v6) of
the patch-set. 
Snippet will look as mentioned below.

+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - samsung,exynosautov920-usbdrd-phy
+    then:
+      required:
+        - dvdd075-usb20-supply
+        - vdd18-usb20-supply
+        - vdd33-usb20-supply
+
+    else:
+      properties:
+        dvdd075-usb20-supply: false
+        vdd18-usb20-supply: false

Thank you.

Regards,
Pritam



From pritam.sutar at samsung.com  Thu Aug  7 05:32:57 2025
From: pritam.sutar at samsung.com (Pritam Manohar Sutar)
Date: Thu, 7 Aug 2025 18:02:57 +0530
Subject: [PATCH v5 5/6] dt-bindings: phy: samsung,usb3-drd-phy: add
 ExynosAutov920 combo ssphy
In-Reply-To: <20250806234309.GA2032999-robh@kernel.org>
References: <20250805115216.3798121-1-pritam.sutar@samsung.com>
	<CGME20250805114320epcas5p3968288f8d01944d3d730b3094a7befe4@epcas5p3.samsung.com>
	<20250805115216.3798121-6-pritam.sutar@samsung.com>
	<20250806234309.GA2032999-robh@kernel.org>
Message-ID: <000101dc0797$69cb0080$3d610180$@samsung.com>

Hi Rob,

> -----Original Message-----
> From: Rob Herring <robh at kernel.org>
> Sent: 07 August 2025 05:13 AM
> To: Pritam Manohar Sutar <pritam.sutar at samsung.com>
> Cc: vkoul at kernel.org; kishon at kernel.org; krzk+dt at kernel.org;
> conor+dt at kernel.org; alim.akhtar at samsung.com; andre.draszik at linaro.org;
> peter.griffin at linaro.org; kauschluss at disroot.org;
> ivo.ivanov.ivanov1 at gmail.com; igor.belwon at mentallysanemainliners.org;
> m.szyprowski at samsung.com; s.nawrocki at samsung.com; linux-
> phy at lists.infradead.org; devicetree at vger.kernel.org; linux-
> kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-
> samsung-soc at vger.kernel.org; rosa.pila at samsung.com;
> dev.tailor at samsung.com; faraz.ata at samsung.com;
> muhammed.ali at samsung.com; selvarasu.g at samsung.com
> Subject: Re: [PATCH v5 5/6] dt-bindings: phy: samsung,usb3-drd-phy: add
> ExynosAutov920 combo ssphy
> 
> On Tue, Aug 05, 2025 at 05:22:15PM +0530, Pritam Manohar Sutar wrote:
> > This phy supports USB3.1 SSP+(10Gbps) protocol and is backwards
> > compatible to the USB3.0 SS(5Gbps). It requires two clocks, named
> > "phy" and "ref". The required supplies for USB3.1 are named as
> > vdd075_usb30(0.75v), vdd18_usb30(1.8v).
> >
> > Add schemas for combo ssphy found on this SoC.
> >
> > Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
> > ---
> >  .../bindings/phy/samsung,usb3-drd-phy.yaml    | 19
> +++++++++++++++++++
> >  1 file changed, 19 insertions(+)
> >
> > diff --git
> > a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
> > b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
> > index 4a84b5405cd2..7a71cff10fb5 100644
> > --- a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-
> phy.yaml
> > +++ b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-
> phy.yaml
> > @@ -34,6 +34,7 @@ properties:
> >        - samsung,exynos7870-usbdrd-phy
> >        - samsung,exynos850-usbdrd-phy
> >        - samsung,exynos990-usbdrd-phy
> > +      - samsung,exynosautov920-usb31drd-combo-ssphy
> >        - samsung,exynosautov920-usbdrd-combo-hsphy
> >        - samsung,exynosautov920-usbdrd-phy
> >
> > @@ -118,6 +119,12 @@ properties:
> >    vdd18-usb20-supply:
> >      description: 1.8V power supply for the USB 2.0 phy.
> >
> > +  dvdd075-usb30-supply:
> > +    description: 0.75V power supply for the USB 3.0 phy.
> > +
> > +  vdd18-usb30-supply:
> > +    description: 1.8V power supply for the USB 3.0 phy.
> > +
> >  required:
> >    - compatible
> >    - clocks
> > @@ -227,6 +234,7 @@ allOf:
> >                - samsung,exynos7870-usbdrd-phy
> >                - samsung,exynos850-usbdrd-phy
> >                - samsung,exynos990-usbdrd-phy
> > +              - samsung,exynosautov920-usb31drd-combo-ssphy
> >                - samsung,exynosautov920-usbdrd-combo-hsphy
> >                - samsung,exynosautov920-usbdrd-phy
> >      then:
> > @@ -258,6 +266,17 @@ allOf:
> >          - vdd18-usb20-supply
> >          - vdd33-usb20-supply
> >
> > +  - if:
> > +      properties:
> > +        compatible:
> > +          contains:
> > +            enum:
> > +              - samsung,exynosautov920-usb31drd-combo-ssphy
> > +    then:
> > +      required:
> > +        - dvdd075-usb30-supply
> > +        - vdd18-usb30-supply
> 
> Similar issue here.

Will the suggested lines of the code in next version of the patch-set.
Snippet will look as below.

+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - samsung,exynosautov920-usb31drd-combo-ssphy
+    then:
+      required:
+        - dvdd075-usb30-supply
+        - vdd18-usb30-supply
+
+    else:
+      properties:
+        dvdd075-usb30-supply: false
+        vdd18-usb30-supply: false

Thank you.

Regards,
Pritam



From konrad.dybcio at oss.qualcomm.com  Thu Aug  7 06:06:01 2025
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Thu, 7 Aug 2025 15:06:01 +0200
Subject: [PATCH V1 4/4] phy: qcom-qmp-ufs: read max-microamp values from
 device tree
In-Reply-To: <fe2bc07c-8fe9-47fd-bcd7-c2f0ebbd596f@sirena.org.uk>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
 <20250806154340.20122-5-quic_nitirawa@quicinc.com>
 <f368b6da-1aa3-4b8e-9106-3c29d4ab5c5e@oss.qualcomm.com>
 <fe2bc07c-8fe9-47fd-bcd7-c2f0ebbd596f@sirena.org.uk>
Message-ID: <aed1de56-fafe-4ccc-b542-69400b574def@oss.qualcomm.com>

On 8/6/25 6:51 PM, Mark Brown wrote:
> On Wed, Aug 06, 2025 at 05:58:30PM +0200, Konrad Dybcio wrote:
>> On 8/6/25 5:43 PM, Nitin Rawat wrote:
> 
>>> Add support in QMP PHY driver to read optional vdda-phy-max-microamp
>>> and vdda-pll-max-microamp properties from the device tree.
> 
>>> These properties define the expected maximum current (in microamps) for
>>> each supply. The driver uses this information to configure regulators
>>> more accurately and ensure they operate in the correct mode based on
>>> client load requirements.
> 
>>> If the property is not present, the driver defaults load to
>>> `QMP_VREG_UNUSED`.
> 
>> do you think having this in regulator core would make sense?
> 
> I'm not clear why the driver is trying to do this at all, the driver is
> AFAICT making no other effort to manage the load at all.  We already
> impose any constraints that are defined for a regulator while initially
> parsing them so it's not clear to me what this is supposed to
> accomplish, and it'll be broken if the supply is ever shared since it'll
> set the load from this individual consumer to the maximum that's
> permitted for the regulator as a whole.

Qualcomm regulators feature a low- and a high-power mode. As one may
imagine, low- is preferred, and high- needs to be engaged if we go
over a current threshold.

The specific regulator instances in question are often shared between
a couple PHYs (UFS, PCIe, USB..) and we need to convey to the
framework how much each consumer requires (and consumers can of course
go on/off at runtime). The current value varies between platforms, so
we want to read from DT.
The intended use is to set the load requirement and then only en/disable
the consumer, so that the current load is updated in core (like in the
kerneldoc of _regulator_handle_consumer_enable())

My question was about moving the custom parsing of
$supplyname-max-micromap introduced in this patch into the regulator
core, as this seems like a rather common problem.

Unless you meant to object to the "QMP_VREG_UNUSED" part specifically?

Konrad


From broonie at kernel.org  Thu Aug  7 06:44:58 2025
From: broonie at kernel.org (Mark Brown)
Date: Thu, 7 Aug 2025 14:44:58 +0100
Subject: [PATCH V1 4/4] phy: qcom-qmp-ufs: read max-microamp values from
 device tree
In-Reply-To: <aed1de56-fafe-4ccc-b542-69400b574def@oss.qualcomm.com>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
 <20250806154340.20122-5-quic_nitirawa@quicinc.com>
 <f368b6da-1aa3-4b8e-9106-3c29d4ab5c5e@oss.qualcomm.com>
 <fe2bc07c-8fe9-47fd-bcd7-c2f0ebbd596f@sirena.org.uk>
 <aed1de56-fafe-4ccc-b542-69400b574def@oss.qualcomm.com>
Message-ID: <acf89420-743b-4178-ac05-d4ca492bfee3@sirena.org.uk>

On Thu, Aug 07, 2025 at 03:06:01PM +0200, Konrad Dybcio wrote:
> On 8/6/25 6:51 PM, Mark Brown wrote:

> > I'm not clear why the driver is trying to do this at all, the driver is
> > AFAICT making no other effort to manage the load at all.  We already
> > impose any constraints that are defined for a regulator while initially
> > parsing them so it's not clear to me what this is supposed to
> > accomplish, and it'll be broken if the supply is ever shared since it'll
> > set the load from this individual consumer to the maximum that's
> > permitted for the regulator as a whole.

> Qualcomm regulators feature a low- and a high-power mode. As one may
> imagine, low- is preferred, and high- needs to be engaged if we go
> over a current threshold.

Sure, but the driver is like I say doing nothing to actively manage the
current reporting.  It's just pulling a random number not specific to
the device (the max-microamp configuration is part of the constraints
which apply to the regualtor as a whole) out of the DT and throwing it
at the framework.

> The specific regulator instances in question are often shared between
> a couple PHYs (UFS, PCIe, USB..) and we need to convey to the
> framework how much each consumer requires (and consumers can of course
> go on/off at runtime). The current value varies between platforms, so
> we want to read from DT.

In that case this will definitely encounter the bug I mentioned above
where it's trying to read the maximum load permitted for the regulator
as a whole and report it as the load from this one specific device.

> The intended use is to set the load requirement and then only en/disable
> the consumer, so that the current load is updated in core (like in the
> kerneldoc of _regulator_handle_consumer_enable())

> My question was about moving the custom parsing of
> $supplyname-max-micromap introduced in this patch into the regulator
> core, as this seems like a rather common problem.

Wait, is this supposed to be some new property that you want to
standardise?  I didn't see a proposal for that, it's not something that
currently exists - the only standard properties that currently exist are
for the regulator as a whole.  

I'm not super convinced this is a particularly common issue, most
devices perform pretty much the same regardless of the board design so
the driver should just know their peak consumption and it's becoming
less and less common for regulators to need software help to adapt to
loads.  The main use case these days seems to be for safety (eg,
constraining how much can be drawn via a USB port) which seems like it'd
either be for the full supply or just known by the driver.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-phy/attachments/20250807/42f8ef2f/attachment.sig>

From paulk at sys-base.io  Thu Aug  7 08:24:41 2025
From: paulk at sys-base.io (Paul Kocialkowski)
Date: Thu, 7 Aug 2025 17:24:41 +0200
Subject: [PATCH 07/22] dt-bindings: vendor-prefixes: Shenzhen Baijie
 Technology
In-Reply-To: <20241227-a133-display-support-v1-7-13b52f71fb14@linumiz.com>
References: <20241227-a133-display-support-v1-0-13b52f71fb14@linumiz.com>
 <20241227-a133-display-support-v1-7-13b52f71fb14@linumiz.com>
Message-ID: <aJTFOV_MK4GftLWu@shepard>

Hi,

On Fri 27 Dec 24, 16:37, Parthiban Nallathambi wrote:
> Add entry for Shenzhen Baijie Technology (https://szbaijie.com)
> 
> Signed-off-by: Parthiban Nallathambi <parthiban at linumiz.com>
> ---
>  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> index da01616802c7..81cbc8b6b195 100644
> --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
> +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> @@ -1466,6 +1466,8 @@ patternProperties:
>    "^synopsys,.*":
>      description: Synopsys, Inc. (deprecated, use snps)
>      deprecated: true
> +  "^szbaijie,.*":

It's quite common for Chinese companies to have their main location as a prefix
in their name, for example Rockchip's full name is Fuzhou Rockchip Electronics
Co., Ltd.

Since the company here calls itself "Baijie Technology" I think the "sz" part
should be dropped from the vendor prefix and just be "baijie,.*".

All the best,

Paul

> +    description: Shenzhen Baijie Technology Co., Ltd.
>    "^tbs,.*":
>      description: TBS Technologies
>    "^tbs-biometrics,.*":
> 
> -- 
> 2.39.5
> 
> 

-- 
Paul Kocialkowski,

Independent contractor - sys-base - https://www.sys-base.io/
Free software developer - https://www.paulk.fr/

Expert in multimedia, graphics and embedded hardware support with Linux.
-------------- 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/20250807/bd2dfab6/attachment.sig>

From paulk at sys-base.io  Thu Aug  7 08:27:09 2025
From: paulk at sys-base.io (Paul Kocialkowski)
Date: Thu, 7 Aug 2025 17:27:09 +0200
Subject: [PATCH 01/22] dt-bindings: iommu: sun50i: remove resets from
 required property
In-Reply-To: <20241227-a133-display-support-v1-1-13b52f71fb14@linumiz.com>
References: <20241227-a133-display-support-v1-0-13b52f71fb14@linumiz.com>
 <20241227-a133-display-support-v1-1-13b52f71fb14@linumiz.com>
Message-ID: <aJTFzQP61Kt02gOj@shepard>

Hi Parthiban,

On Fri 27 Dec 24, 16:37, Parthiban Nallathambi wrote:
> iommu in a133/a100 does not have reset control. remove it
> from required property to make it optional.
> 
> Signed-off-by: Parthiban Nallathambi <parthiban at linumiz.com>
> ---
>  Documentation/devicetree/bindings/iommu/allwinner,sun50i-h6-iommu.yaml | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/iommu/allwinner,sun50i-h6-iommu.yaml b/Documentation/devicetree/bindings/iommu/allwinner,sun50i-h6-iommu.yaml
> index a8409db4a3e3..03176f68485b 100644
> --- a/Documentation/devicetree/bindings/iommu/allwinner,sun50i-h6-iommu.yaml
> +++ b/Documentation/devicetree/bindings/iommu/allwinner,sun50i-h6-iommu.yaml
> @@ -42,7 +42,6 @@ required:
>    - reg
>    - interrupts
>    - clocks
> -  - resets

Since it was previously specified that other platforms do need the reset line,
the required part should be applied conditionally based on the compatible, not
removed entirely.

Also your commit title and message would look better with uppercase first
letters at the start of a sentence :)

All the best,

Paul

>  additionalProperties: false

-- 
Paul Kocialkowski,

Independent contractor - sys-base - https://www.sys-base.io/
Free software developer - https://www.paulk.fr/

Expert in multimedia, graphics and embedded hardware support with Linux.
-------------- 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/20250807/ad8bb8da/attachment-0001.sig>

From paulk at sys-base.io  Thu Aug  7 08:29:35 2025
From: paulk at sys-base.io (Paul Kocialkowski)
Date: Thu, 7 Aug 2025 17:29:35 +0200
Subject: [PATCH 09/22] iommu: sun50i: make reset control optional
In-Reply-To: <20241227-a133-display-support-v1-9-13b52f71fb14@linumiz.com>
References: <20241227-a133-display-support-v1-0-13b52f71fb14@linumiz.com>
 <20241227-a133-display-support-v1-9-13b52f71fb14@linumiz.com>
Message-ID: <aJTGX7z5QaneVAVs@shepard>

Hi,

On Fri 27 Dec 24, 16:37, Parthiban Nallathambi wrote:
> A133/A100 SoC doesn't have reset control from the CCU. Get reset
> control line optionally.

With the dt bindings fixed, this:
Reviewed-by: Paul Kocialkowski <paulk at sys-base.io>

Although feel free to use a first uppercase later in the title after sun50i!

Cheers,

Paul

> Signed-off-by: Parthiban Nallathambi <parthiban at linumiz.com>
> ---
>  drivers/iommu/sun50i-iommu.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/iommu/sun50i-iommu.c b/drivers/iommu/sun50i-iommu.c
> index 8d8f11854676..2ba804d682dc 100644
> --- a/drivers/iommu/sun50i-iommu.c
> +++ b/drivers/iommu/sun50i-iommu.c
> @@ -1030,7 +1030,7 @@ static int sun50i_iommu_probe(struct platform_device *pdev)
>  		goto err_free_cache;
>  	}
>  
> -	iommu->reset = devm_reset_control_get(&pdev->dev, NULL);
> +	iommu->reset = devm_reset_control_get_optional(&pdev->dev, NULL);
>  	if (IS_ERR(iommu->reset)) {
>  		dev_err(&pdev->dev, "Couldn't get our reset line.\n");
>  		ret = PTR_ERR(iommu->reset);
> 
> -- 
> 2.39.5
> 
> 

-- 
Paul Kocialkowski,

Independent contractor - sys-base - https://www.sys-base.io/
Free software developer - https://www.paulk.fr/

Expert in multimedia, graphics and embedded hardware support with Linux.
-------------- 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/20250807/b4b25b1c/attachment.sig>

From quic_nitirawa at quicinc.com  Thu Aug  7 08:42:53 2025
From: quic_nitirawa at quicinc.com (Nitin Rawat)
Date: Thu, 7 Aug 2025 21:12:53 +0530
Subject: [PATCH V1 4/4] phy: qcom-qmp-ufs: read max-microamp values from
 device tree
In-Reply-To: <acf89420-743b-4178-ac05-d4ca492bfee3@sirena.org.uk>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
 <20250806154340.20122-5-quic_nitirawa@quicinc.com>
 <f368b6da-1aa3-4b8e-9106-3c29d4ab5c5e@oss.qualcomm.com>
 <fe2bc07c-8fe9-47fd-bcd7-c2f0ebbd596f@sirena.org.uk>
 <aed1de56-fafe-4ccc-b542-69400b574def@oss.qualcomm.com>
 <acf89420-743b-4178-ac05-d4ca492bfee3@sirena.org.uk>
Message-ID: <599b8a4b-324a-4543-ba27-0451f05c3dfd@quicinc.com>



On 8/7/2025 7:14 PM, Mark Brown wrote:
> On Thu, Aug 07, 2025 at 03:06:01PM +0200, Konrad Dybcio wrote:
>> On 8/6/25 6:51 PM, Mark Brown wrote:
> 
>>> I'm not clear why the driver is trying to do this at all, the driver is
>>> AFAICT making no other effort to manage the load at all.  We already
>>> impose any constraints that are defined for a regulator while initially
>>> parsing them so it's not clear to me what this is supposed to
>>> accomplish, and it'll be broken if the supply is ever shared since it'll
>>> set the load from this individual consumer to the maximum that's
>>> permitted for the regulator as a whole.
> 
>> Qualcomm regulators feature a low- and a high-power mode. As one may
>> imagine, low- is preferred, and high- needs to be engaged if we go
>> over a current threshold.
> 
> Sure, but the driver is like I say doing nothing to actively manage the
> current reporting.  It's just pulling a random number not specific to
> the device (the max-microamp configuration is part of the constraints
> which apply to the regualtor as a whole) out of the DT and throwing it
> at the framework.
> 
>> The specific regulator instances in question are often shared between
>> a couple PHYs (UFS, PCIe, USB..) and we need to convey to the
>> framework how much each consumer requires (and consumers can of course
>> go on/off at runtime). The current value varies between platforms, so
>> we want to read from DT.
> 
> In that case this will definitely encounter the bug I mentioned above
> where it's trying to read the maximum load permitted for the regulator
> as a whole and report it as the load from this one specific device.
> 
>> The intended use is to set the load requirement and then only en/disable
>> the consumer, so that the current load is updated in core (like in the
>> kerneldoc of _regulator_handle_consumer_enable())
> 
>> My question was about moving the custom parsing of
>> $supplyname-max-micromap introduced in this patch into the regulator
>> core, as this seems like a rather common problem.
> 
> Wait, is this supposed to be some new property that you want to
> standardise?  I didn't see a proposal for that, it's not something that
> currently exists - the only standard properties that currently exist are
> for the regulator as a whole.


Hi Mark,

The UFS QMP PHY driver is not the first client to use regulator_set_load 
or alternatively set load requirements and invoke enable/disable or 
alternatively

Similar to other PHY drivers (such as USB, Display, and Combo PHYs),
as well as various subsystem drivers like UFS, SDHCI, Bluetooth, and 
others, the QMP UFS PHY driver is communicating/setting its load 
requirements.

These drivers also define corresponding binding properties, as seen in 
the UFS instances documented here:

UFS Common DT Binding ((link - 
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/Documentation/devicetree/bindings/ufs/ufs-common.yaml?h=next-20250807) 


Relevant properties include:

vcc-max-microamp: Specifies the maximum load that can be drawn from the 
VCC supply
vccq-max-microamp: Specifies the maximum load that can be drawn from the 
VCCQ supply
vccq2-max-microamp: Specifies the maximum load that can be drawn from 
the VCCQ2 supply

There was a previous effort to introduce similar properties 
(vdda-phy-max-microamp and vdda-pll-max-microamp) in the device tree 
bindings.
Link - (link- 
https://patchwork.kernel.org/project/linux-arm-msm/patch/20220418205509.1102109-3-bhupesh.sharma at linaro.org/#24820481)

However, at that time, the driver-side implementation for aggregating 
load requests was not in place, which led to the patch not being merged:
Patch Reference

Currently, the regulator framework does support automatic aggregation of 
load requests from multiple client drivers. Therefore, it is reasonable 
and necessary for each client to individually communicate its expected 
runtime load to the regulator framework to put the regulators in current
operation mode.

Regards,
Nitin

> 
> I'm not super convinced this is a particularly common issue, most
> devices perform pretty much the same regardless of the board design so
> the driver should just know their peak consumption and it's becoming
> less and less common for regulators to need software help to adapt to
> loads.  The main use case these days seems to be for safety (eg,
> constraining how much can be drawn via a USB port) which seems like it'd
> either be for the full supply or just known by the driver.



From dan.carpenter at linaro.org  Thu Aug  7 08:57:32 2025
From: dan.carpenter at linaro.org (Dan Carpenter)
Date: Thu, 7 Aug 2025 18:57:32 +0300
Subject: [bug report] phy: usb: Add USB2.0 phy driver for Sunplus SP7021
Message-ID: <aJTM7MTRPQunUvzt@stanley.mountain>

Hello Vincent Shih,

Commit 99d9ccd97385 ("phy: usb: Add USB2.0 phy driver for Sunplus
SP7021") from Jul 25, 2022 (linux-next), leads to the following
Smatch static checker warning:

	drivers/phy/sunplus/phy-sunplus-usb2.c:92 update_disc_vol()
	error: 'cell' dereferencing possible ERR_PTR()

drivers/phy/sunplus/phy-sunplus-usb2.c
    78 static int update_disc_vol(struct sp_usbphy *usbphy)
    79 {
    80         struct nvmem_cell *cell;
    81         char *disc_name = "disc_vol";
    82         ssize_t otp_l = 0;
    83         char *otp_v;
    84         u32 val, set;
    85 
    86         cell = nvmem_cell_get(usbphy->dev, disc_name);
    87         if (IS_ERR_OR_NULL(cell)) {
    88                 if (PTR_ERR(cell) == -EPROBE_DEFER)
    89                         return -EPROBE_DEFER;

I don't love the if if (IS_ERR_OR_NULL(cell)) check.  The
nvmem_cell_get() function can't actually return NULL.  The normal thing
would be to make it return NULL if CONFIG_NVMEM wasn't set.  Even then
we would still only check for:

	if (IS_ERR(cell))
		return PTR_ERR(cell);

I have written a longer explanation here:
https://staticthinking.wordpress.com/2022/08/01/mixing-error-pointers-and-null/

Can PHY_SUNPLUS_USB really work without CONFIG_NVMEM?  If not then we
could just add that as a depend in the Kconfig.  The other way to fix
this would be:

	if (IS_ERR(cell) && PTR_ERR(cell) != -EOPNOTSUPP)
		return PTR_ERR(cell);

    90         }
    91 
--> 92         otp_v = nvmem_cell_read(cell, &otp_l);
                                       ^^^^
This will crash if the nvmem_cell_get() has an error.

    93         nvmem_cell_put(cell);
    94 
    95         if (!IS_ERR(otp_v)) {
    96                 set = *(otp_v + 1);
    97                 set = (set << (sizeof(char) * 8)) | *otp_v;
    98                 set = (set >> usbphy->disc_vol_addr_off) & J_DISC;
    99         }
    100 
    101         if (IS_ERR(otp_v) || set == 0)
    102                 set = OTP_DISC_LEVEL_DEFAULT;
    103 
    104         val = readl(usbphy->phy_regs + CONFIG7);
    105         val = (val & ~J_DISC) | set;
    106         writel(val, usbphy->phy_regs + CONFIG7);
    107 
    108         return 0;
    109 }

regards,
dan carpenter


From konradybcio at kernel.org  Thu Aug  7 09:33:18 2025
From: konradybcio at kernel.org (Konrad Dybcio)
Date: Thu, 07 Aug 2025 18:33:18 +0200
Subject: [PATCH v4 0/6] arm64: qcom: allow up to 4 lanes for the Type-C
 DisplayPort Altmode
Message-ID: <20250807-topic-4ln_dp_respin-v4-0-43272d6eca92@oss.qualcomm.com>

Register a typec mux in order to change the PHY mode on the Type-C
mux events depending on the mode and the svid when in Altmode setup.

The DisplayPort phy should be left enabled if is still powered on
by the DRM DisplayPort controller, so bail out until the DisplayPort
PHY is not powered off.

The Type-C Mode/SVID only changes on plug/unplug, and USB SAFE states
will be set in between of USB-Only, Combo and DisplayPort Only so
this will leave enough time to the DRM DisplayPort controller to
turn of the DisplayPort PHY.

The patchset also includes bindings changes and DT changes.

This has been successfully tested on an SM8550 board, but the
Thinkpad X13s deserved testing between non-PD USB, non-PD DisplayPort,
PD USB Hubs and PD Altmode Dongles to make sure the switch works
as expected.

The DisplayPort 4 lanes setup can be check with:
$ cat /sys/kernel/debug/dri/ae01000.display-controller/DP-1/dp_debug
	name = msm_dp
	drm_dp_link
		rate = 540000
		num_lanes = 4
...

This patchset depends on [1] to allow broadcasting the type-c mode
to the PHY, otherwise the PHY will keep the combo state while the
retimer would setup the 4 lanes in DP mode.

[1] https://lore.kernel.org/all/20240527-topic-sm8x50-upstream-retimer-broadcast-mode-v1-0-79ec91381aba at linaro.org/

Changes in v4:
- Default to USB3_ONLY if there's no DP SVID (Dmitry)
- Pick up tags, dropped T-bys due to the above change
- Add missing submitter's sign-off on some patches
- The odd 4-lane-DP + USB2 case remains unhandled for now, but it's
  not a huge deal, see:
  <c2f2ba36-1a25-450e-99b9-79aa4fd4913d at linaro.org>
- Link to v3: https://lore.kernel.org/r/20250527-topic-4ln_dp_respin-v3-0-f9a0763ec289 at oss.qualcomm.com
Changes in v3:
- Take the series from Neil
- Rebase
- Rename many variables
- Test on X1E & X13s
- Apply a number of small cosmetic/codestyle changes
- Remove some unused variables
- Some smaller bugfixes
- Link to v2: https://lore.kernel.org/lkml/20240527-topic-sm8x50-upstream-phy-combo-typec-mux-v2-0-a03e68d7b8fc at linaro.org/
Changes in v2:
- Reference usb-switch.yaml in bindings patch
- Fix switch/case indenting
- Check svid for USB_TYPEC_DP_SID
- Fix X13s patch subject
- Update SM8650 patch to enable 4 lanes on HDK aswell
- Link to v1: https://lore.kernel.org/r/20240229-topic-sm8x50-upstream-phy-combo-typec-mux-v1-0-07e24a231840 at linaro.org

Signed-off-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
---
Konrad Dybcio (1):
      phy: qcom: qmp-combo: Rename 'mode' to 'phy_mode'

Neil Armstrong (5):
      dt-bindings: phy: qcom,sc8280xp-qmp-usb43dp: Reference usb-switch.yaml to allow mode-switch
      phy: qcom: qmp-combo: store DP phy power state
      phy: qcom: qmp-combo: introduce QMPPHY_MODE
      phy: qcom: qmp-combo: register a typec mux to change the QMPPHY_MODE
      arm64: dts: qcom: sc8280xp-lenovo-thinkpad-x13: Set up 4-lane DP

 .../phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml         |   7 +-
 .../dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts     |   6 +-
 drivers/phy/qualcomm/phy-qcom-qmp-combo.c          | 179 +++++++++++++++++++--
 3 files changed, 170 insertions(+), 22 deletions(-)
---
base-commit: 442d93313caebc8ccd6d53f4572c50732a95bc48
change-id: 20250527-topic-4ln_dp_respin-c6924a8825ce

Best regards,
-- 
Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>



From konradybcio at kernel.org  Thu Aug  7 09:33:19 2025
From: konradybcio at kernel.org (Konrad Dybcio)
Date: Thu, 07 Aug 2025 18:33:19 +0200
Subject: [PATCH v4 1/6] dt-bindings: phy: qcom,sc8280xp-qmp-usb43dp:
 Reference usb-switch.yaml to allow mode-switch
In-Reply-To: <20250807-topic-4ln_dp_respin-v4-0-43272d6eca92@oss.qualcomm.com>
References: <20250807-topic-4ln_dp_respin-v4-0-43272d6eca92@oss.qualcomm.com>
Message-ID: <20250807-topic-4ln_dp_respin-v4-1-43272d6eca92@oss.qualcomm.com>

From: Neil Armstrong <neil.armstrong at linaro.org>

The QMP USB3/DP Combo PHY can work in 3 modes:
- DisplayPort Only
- USB3 Only
- USB3 + DisplayPort Combo mode

In order to switch between those modes, the PHY needs to receive
Type-C events, allow marking to the phy with the mode-switch
property in order to allow the PHY to Type-C events.

Reference usb-switch.yaml as a simpler way to allow the mode-switch
property instead of duplicating the property definition.

Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
Reviewed-by: Krzysztof Kozlowski <krzk at kernel.org>
Signed-off-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
---
 .../devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml     | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml
index 38ce04c35d945d0d8d319191c241920810ee9005..c8bc512df08b5694c8599f475de78679a4438449 100644
--- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml
@@ -73,10 +73,8 @@ properties:
     description:
       See include/dt-bindings/phy/phy-qcom-qmp.h
 
-  orientation-switch:
-    description:
-      Flag the PHY as possible handler of USB Type-C orientation switching
-    type: boolean
+  mode-switch: true
+  orientation-switch: true
 
   ports:
     $ref: /schemas/graph.yaml#/properties/ports
@@ -106,6 +104,7 @@ required:
   - "#phy-cells"
 
 allOf:
+  - $ref: /schemas/usb/usb-switch.yaml#
   - if:
       properties:
         compatible:

-- 
2.50.1



From konradybcio at kernel.org  Thu Aug  7 09:33:20 2025
From: konradybcio at kernel.org (Konrad Dybcio)
Date: Thu, 07 Aug 2025 18:33:20 +0200
Subject: [PATCH v4 2/6] phy: qcom: qmp-combo: Rename 'mode' to 'phy_mode'
In-Reply-To: <20250807-topic-4ln_dp_respin-v4-0-43272d6eca92@oss.qualcomm.com>
References: <20250807-topic-4ln_dp_respin-v4-0-43272d6eca92@oss.qualcomm.com>
Message-ID: <20250807-topic-4ln_dp_respin-v4-2-43272d6eca92@oss.qualcomm.com>

From: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>

There are a numbers of ""modes"" involved: USB mode, Type-C mode (with
its altmodes), phy_mode and QMP_PHY mode (DP/combo/USB/off).

Rename the generic sounding 'mode' to 'phy_mode' to hopefully make
the code easier to follow.

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>
Signed-off-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
index f07d097b129fb7b3fad003103b7468b16c1c4390..30749943f66280c3aa9e9673466f6f736d1adbc8 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
@@ -1846,7 +1846,7 @@ struct qmp_combo {
 	int init_count;
 
 	struct phy *usb_phy;
-	enum phy_mode mode;
+	enum phy_mode phy_mode;
 	unsigned int usb_init_count;
 
 	struct phy *dp_phy;
@@ -3282,7 +3282,7 @@ static int qmp_combo_usb_set_mode(struct phy *phy, enum phy_mode mode, int submo
 {
 	struct qmp_combo *qmp = phy_get_drvdata(phy);
 
-	qmp->mode = mode;
+	qmp->phy_mode = mode;
 
 	return 0;
 }
@@ -3311,8 +3311,8 @@ static void qmp_combo_enable_autonomous_mode(struct qmp_combo *qmp)
 	void __iomem *pcs_misc = qmp->pcs_misc;
 	u32 intr_mask;
 
-	if (qmp->mode == PHY_MODE_USB_HOST_SS ||
-	    qmp->mode == PHY_MODE_USB_DEVICE_SS)
+	if (qmp->phy_mode == PHY_MODE_USB_HOST_SS ||
+	    qmp->phy_mode == PHY_MODE_USB_DEVICE_SS)
 		intr_mask = ARCVR_DTCT_EN | ALFPS_DTCT_EN;
 	else
 		intr_mask = ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL;
@@ -3355,7 +3355,7 @@ static int __maybe_unused qmp_combo_runtime_suspend(struct device *dev)
 {
 	struct qmp_combo *qmp = dev_get_drvdata(dev);
 
-	dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->mode);
+	dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->phy_mode);
 
 	if (!qmp->init_count) {
 		dev_vdbg(dev, "PHY not initialized, bailing out\n");
@@ -3375,7 +3375,7 @@ static int __maybe_unused qmp_combo_runtime_resume(struct device *dev)
 	struct qmp_combo *qmp = dev_get_drvdata(dev);
 	int ret = 0;
 
-	dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qmp->mode);
+	dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qmp->phy_mode);
 
 	if (!qmp->init_count) {
 		dev_vdbg(dev, "PHY not initialized, bailing out\n");

-- 
2.50.1



From konradybcio at kernel.org  Thu Aug  7 09:33:21 2025
From: konradybcio at kernel.org (Konrad Dybcio)
Date: Thu, 07 Aug 2025 18:33:21 +0200
Subject: [PATCH v4 3/6] phy: qcom: qmp-combo: store DP phy power state
In-Reply-To: <20250807-topic-4ln_dp_respin-v4-0-43272d6eca92@oss.qualcomm.com>
References: <20250807-topic-4ln_dp_respin-v4-0-43272d6eca92@oss.qualcomm.com>
Message-ID: <20250807-topic-4ln_dp_respin-v4-3-43272d6eca92@oss.qualcomm.com>

From: Neil Armstrong <neil.armstrong at linaro.org>

Switching the PHY Mode requires the DisplayPort PHY to be powered off,
keep track of the DisplayPort phy power state.

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
Signed-off-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
index 30749943f66280c3aa9e9673466f6f736d1adbc8..8395035754975808ee1b5b9c48d046a719e79e60 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
@@ -1853,6 +1853,7 @@ struct qmp_combo {
 	unsigned int dp_aux_cfg;
 	struct phy_configure_opts_dp dp_opts;
 	unsigned int dp_init_count;
+	bool dp_powered_on;
 
 	struct clk_fixed_rate pipe_clk_fixed;
 	struct clk_hw dp_link_hw;
@@ -3133,6 +3134,8 @@ static int qmp_combo_dp_power_on(struct phy *phy)
 	/* Configure link rate, swing, etc. */
 	cfg->configure_dp_phy(qmp);
 
+	qmp->dp_powered_on = true;
+
 	mutex_unlock(&qmp->phy_mutex);
 
 	return 0;
@@ -3147,6 +3150,8 @@ static int qmp_combo_dp_power_off(struct phy *phy)
 	/* Assert DP PHY power down */
 	writel(DP_PHY_PD_CTL_PSR_PWRDN, qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL);
 
+	qmp->dp_powered_on = false;
+
 	mutex_unlock(&qmp->phy_mutex);
 
 	return 0;

-- 
2.50.1



From konradybcio at kernel.org  Thu Aug  7 09:33:22 2025
From: konradybcio at kernel.org (Konrad Dybcio)
Date: Thu, 07 Aug 2025 18:33:22 +0200
Subject: [PATCH v4 4/6] phy: qcom: qmp-combo: introduce QMPPHY_MODE
In-Reply-To: <20250807-topic-4ln_dp_respin-v4-0-43272d6eca92@oss.qualcomm.com>
References: <20250807-topic-4ln_dp_respin-v4-0-43272d6eca92@oss.qualcomm.com>
Message-ID: <20250807-topic-4ln_dp_respin-v4-4-43272d6eca92@oss.qualcomm.com>

From: Neil Armstrong <neil.armstrong at linaro.org>

Introduce an enum for the QMP Combo PHY modes, use it in the
QMP commmon phy init function and default to COMBO mode.

Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
[konrad: some renaming and rewording]
Signed-off-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 44 +++++++++++++++++++++++++++----
 1 file changed, 39 insertions(+), 5 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
index 8395035754975808ee1b5b9c48d046a719e79e60..c65837fc9e4c38673fc61d3ae66072ba5a265a70 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
@@ -62,6 +62,12 @@
 
 #define PHY_INIT_COMPLETE_TIMEOUT		10000
 
+enum qmpphy_mode {
+	QMPPHY_MODE_USB3DP = 0,
+	QMPPHY_MODE_DP_ONLY,
+	QMPPHY_MODE_USB3_ONLY,
+};
+
 /* set of registers with offsets different per-PHY */
 enum qphy_reg_layout {
 	/* PCS registers */
@@ -1844,6 +1850,7 @@ struct qmp_combo {
 
 	struct mutex phy_mutex;
 	int init_count;
+	enum qmpphy_mode qmpphy_mode;
 
 	struct phy *usb_phy;
 	enum phy_mode phy_mode;
@@ -3037,12 +3044,33 @@ static int qmp_combo_com_init(struct qmp_combo *qmp, bool force)
 	if (qmp->orientation == TYPEC_ORIENTATION_REVERSE)
 		val |= SW_PORTSELECT_VAL;
 	writel(val, com + QPHY_V3_DP_COM_TYPEC_CTRL);
-	writel(USB3_MODE | DP_MODE, com + QPHY_V3_DP_COM_PHY_MODE_CTRL);
 
-	/* bring both QMP USB and QMP DP PHYs PCS block out of reset */
-	qphy_clrbits(com, QPHY_V3_DP_COM_RESET_OVRD_CTRL,
-			SW_DPPHY_RESET_MUX | SW_DPPHY_RESET |
-			SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET);
+	switch (qmp->qmpphy_mode) {
+	case QMPPHY_MODE_USB3DP:
+		writel(USB3_MODE | DP_MODE, com + QPHY_V3_DP_COM_PHY_MODE_CTRL);
+
+		/* bring both QMP USB and QMP DP PHYs PCS block out of reset */
+		qphy_clrbits(com, QPHY_V3_DP_COM_RESET_OVRD_CTRL,
+				SW_DPPHY_RESET_MUX | SW_DPPHY_RESET |
+				SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET);
+		break;
+
+	case QMPPHY_MODE_DP_ONLY:
+		writel(DP_MODE, com + QPHY_V3_DP_COM_PHY_MODE_CTRL);
+
+		/* bring QMP DP PHY PCS block out of reset */
+		qphy_clrbits(com, QPHY_V3_DP_COM_RESET_OVRD_CTRL,
+				SW_DPPHY_RESET_MUX | SW_DPPHY_RESET);
+		break;
+
+	case QMPPHY_MODE_USB3_ONLY:
+		writel(USB3_MODE, com + QPHY_V3_DP_COM_PHY_MODE_CTRL);
+
+		/* bring QMP USB PHY PCS block out of reset */
+		qphy_clrbits(com, QPHY_V3_DP_COM_RESET_OVRD_CTRL,
+				SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET);
+		break;
+	}
 
 	qphy_clrbits(com, QPHY_V3_DP_COM_SWI_CTRL, 0x03);
 	qphy_clrbits(com, QPHY_V3_DP_COM_SW_RESET, SW_RESET);
@@ -4053,6 +4081,12 @@ static int qmp_combo_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_node_put;
 
+	/*
+	 * The hw default is USB3_ONLY, but USB3+DP mode lets us more easily
+	 * check both sub-blocks' init tables for blunders at probe time.
+	 */
+	qmp->qmpphy_mode = QMPPHY_MODE_USB3DP;
+
 	qmp->usb_phy = devm_phy_create(dev, usb_np, &qmp_combo_usb_phy_ops);
 	if (IS_ERR(qmp->usb_phy)) {
 		ret = PTR_ERR(qmp->usb_phy);

-- 
2.50.1



From konradybcio at kernel.org  Thu Aug  7 09:33:23 2025
From: konradybcio at kernel.org (Konrad Dybcio)
Date: Thu, 07 Aug 2025 18:33:23 +0200
Subject: [PATCH v4 5/6] phy: qcom: qmp-combo: register a typec mux to
 change the QMPPHY_MODE
In-Reply-To: <20250807-topic-4ln_dp_respin-v4-0-43272d6eca92@oss.qualcomm.com>
References: <20250807-topic-4ln_dp_respin-v4-0-43272d6eca92@oss.qualcomm.com>
Message-ID: <20250807-topic-4ln_dp_respin-v4-5-43272d6eca92@oss.qualcomm.com>

From: Neil Armstrong <neil.armstrong at linaro.org>

Register a typec mux in order to change the PHY mode on the Type-C
mux events depending on the mode and the svid when in Altmode setup.

The DisplayPort phy should be left enabled if is still powered on
by the DRM DisplayPort controller, so bail out until the DisplayPort
PHY is not powered off.

The Type-C Mode/SVID only changes on plug/unplug, and USB SAFE states
will be set in between of USB-Only, Combo and DisplayPort Only so
this will leave enough time to the DRM DisplayPort controller to
turn of the DisplayPort PHY.

Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
[konrad: renaming, rewording, bug fixes]
Signed-off-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 118 ++++++++++++++++++++++++++++--
 1 file changed, 113 insertions(+), 5 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
index c65837fc9e4c38673fc61d3ae66072ba5a265a70..7b5af30f1d028c592500e723ecd27b54ed554709 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
@@ -19,6 +19,7 @@
 #include <linux/reset.h>
 #include <linux/slab.h>
 #include <linux/usb/typec.h>
+#include <linux/usb/typec_dp.h>
 #include <linux/usb/typec_mux.h>
 
 #include <drm/bridge/aux-bridge.h>
@@ -1868,6 +1869,8 @@ struct qmp_combo {
 
 	struct typec_switch_dev *sw;
 	enum typec_orientation orientation;
+
+	struct typec_mux_dev *mux;
 };
 
 static void qmp_v3_dp_aux_init(struct qmp_combo *qmp);
@@ -3802,17 +3805,109 @@ static int qmp_combo_typec_switch_set(struct typec_switch_dev *sw,
 	return 0;
 }
 
-static void qmp_combo_typec_unregister(void *data)
+static int qmp_combo_typec_mux_set(struct typec_mux_dev *mux, struct typec_mux_state *state)
+{
+	struct qmp_combo *qmp = typec_mux_get_drvdata(mux);
+	const struct qmp_phy_cfg *cfg = qmp->cfg;
+	enum qmpphy_mode new_mode;
+	unsigned int svid;
+
+	guard(mutex)(&qmp->phy_mutex);
+
+	if (state->alt)
+		svid = state->alt->svid;
+	else
+		svid = 0;
+
+	if (svid == USB_TYPEC_DP_SID) {
+		switch (state->mode) {
+		/* DP Only */
+		case TYPEC_DP_STATE_C:
+		case TYPEC_DP_STATE_E:
+			new_mode = QMPPHY_MODE_DP_ONLY;
+			break;
+
+		/* DP + USB */
+		case TYPEC_DP_STATE_D:
+		case TYPEC_DP_STATE_F:
+
+		/* Safe fallback...*/
+		default:
+			new_mode = QMPPHY_MODE_USB3DP;
+			break;
+		}
+	} else {
+		/* No DP SVID => don't care, assume it's just USB3 */
+		new_mode = QMPPHY_MODE_USB3_ONLY;
+	}
+
+	if (new_mode == qmp->qmpphy_mode) {
+		dev_dbg(qmp->dev, "typec_mux_set: same qmpphy mode, bail out\n");
+		return 0;
+	}
+
+	if (qmp->qmpphy_mode != QMPPHY_MODE_USB3_ONLY && qmp->dp_powered_on) {
+		dev_dbg(qmp->dev, "typec_mux_set: DP PHY is still in use, delaying switch\n");
+		return 0;
+	}
+
+	dev_dbg(qmp->dev, "typec_mux_set: switching from qmpphy mode %d to %d\n",
+		qmp->qmpphy_mode, new_mode);
+
+	qmp->qmpphy_mode = new_mode;
+
+	if (qmp->init_count) {
+		if (qmp->usb_init_count)
+			qmp_combo_usb_power_off(qmp->usb_phy);
+
+		if (qmp->dp_init_count)
+			writel(DP_PHY_PD_CTL_PSR_PWRDN, qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL);
+
+		qmp_combo_com_exit(qmp, true);
+
+		/* Now everything's powered down, power up the right PHYs */
+		qmp_combo_com_init(qmp, true);
+
+		if (new_mode == QMPPHY_MODE_DP_ONLY) {
+			if (qmp->usb_init_count)
+				qmp->usb_init_count--;
+		}
+
+		if (new_mode == QMPPHY_MODE_USB3DP || new_mode == QMPPHY_MODE_USB3_ONLY) {
+			qmp_combo_usb_power_on(qmp->usb_phy);
+			if (!qmp->usb_init_count)
+				qmp->usb_init_count++;
+		}
+
+		if (new_mode == QMPPHY_MODE_DP_ONLY || new_mode == QMPPHY_MODE_USB3DP) {
+			if (qmp->dp_init_count)
+				cfg->dp_aux_init(qmp);
+		}
+	}
+
+	return 0;
+}
+
+static void qmp_combo_typec_switch_unregister(void *data)
 {
 	struct qmp_combo *qmp = data;
 
 	typec_switch_unregister(qmp->sw);
 }
 
-static int qmp_combo_typec_switch_register(struct qmp_combo *qmp)
+static void qmp_combo_typec_mux_unregister(void *data)
+{
+	struct qmp_combo *qmp = data;
+
+	typec_mux_unregister(qmp->mux);
+}
+
+static int qmp_combo_typec_register(struct qmp_combo *qmp)
 {
 	struct typec_switch_desc sw_desc = {};
+	struct typec_mux_desc mux_desc = { };
 	struct device *dev = qmp->dev;
+	int ret;
 
 	sw_desc.drvdata = qmp;
 	sw_desc.fwnode = dev->fwnode;
@@ -3823,10 +3918,23 @@ static int qmp_combo_typec_switch_register(struct qmp_combo *qmp)
 		return PTR_ERR(qmp->sw);
 	}
 
-	return devm_add_action_or_reset(dev, qmp_combo_typec_unregister, qmp);
+	ret = devm_add_action_or_reset(dev, qmp_combo_typec_switch_unregister, qmp);
+	if (ret)
+		return ret;
+
+	mux_desc.drvdata = qmp;
+	mux_desc.fwnode = dev->fwnode;
+	mux_desc.set = qmp_combo_typec_mux_set;
+	qmp->mux = typec_mux_register(dev, &mux_desc);
+	if (IS_ERR(qmp->mux)) {
+		dev_err(dev, "Unable to register typec mux: %pe\n", qmp->mux);
+		return PTR_ERR(qmp->mux);
+	}
+
+	return devm_add_action_or_reset(dev, qmp_combo_typec_mux_unregister, qmp);
 }
 #else
-static int qmp_combo_typec_switch_register(struct qmp_combo *qmp)
+static int qmp_combo_typec_register(struct qmp_combo *qmp)
 {
 	return 0;
 }
@@ -4059,7 +4167,7 @@ static int qmp_combo_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_node_put;
 
-	ret = qmp_combo_typec_switch_register(qmp);
+	ret = qmp_combo_typec_register(qmp);
 	if (ret)
 		goto err_node_put;
 

-- 
2.50.1



From konradybcio at kernel.org  Thu Aug  7 09:33:24 2025
From: konradybcio at kernel.org (Konrad Dybcio)
Date: Thu, 07 Aug 2025 18:33:24 +0200
Subject: [PATCH v4 6/6] arm64: dts: qcom: sc8280xp-lenovo-thinkpad-x13: Set
 up 4-lane DP
In-Reply-To: <20250807-topic-4ln_dp_respin-v4-0-43272d6eca92@oss.qualcomm.com>
References: <20250807-topic-4ln_dp_respin-v4-0-43272d6eca92@oss.qualcomm.com>
Message-ID: <20250807-topic-4ln_dp_respin-v4-6-43272d6eca92@oss.qualcomm.com>

From: Neil Armstrong <neil.armstrong at linaro.org>

Allow up to 4 lanes for the DisplayPort link from the PHYs to the
controllers and allow mode-switch events to reach the QMP Combo PHYs.

Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
[konrad: reword]
Signed-off-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts b/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts
index cefecb7a23cf579b1f62ef6fccf9a27a6ea92ac4..b298ec1162357f7f273cb603465dab8388d4b38c 100644
--- a/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts
+++ b/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts
@@ -726,7 +726,7 @@ &mdss0_dp0 {
 };
 
 &mdss0_dp0_out {
-	data-lanes = <0 1>;
+	data-lanes = <0 1 2 3>;
 	remote-endpoint = <&usb_0_qmpphy_dp_in>;
 };
 
@@ -735,7 +735,7 @@ &mdss0_dp1 {
 };
 
 &mdss0_dp1_out {
-	data-lanes = <0 1>;
+	data-lanes = <0 1 2 3>;
 	remote-endpoint = <&usb_1_qmpphy_dp_in>;
 };
 
@@ -1360,6 +1360,7 @@ &usb_0_qmpphy {
 	vdda-phy-supply = <&vreg_l9d>;
 	vdda-pll-supply = <&vreg_l4d>;
 
+	mode-switch;
 	orientation-switch;
 
 	status = "okay";
@@ -1397,6 +1398,7 @@ &usb_1_qmpphy {
 	vdda-phy-supply = <&vreg_l4b>;
 	vdda-pll-supply = <&vreg_l3b>;
 
+	mode-switch;
 	orientation-switch;
 
 	status = "okay";

-- 
2.50.1



From broonie at kernel.org  Thu Aug  7 10:26:25 2025
From: broonie at kernel.org (Mark Brown)
Date: Thu, 7 Aug 2025 18:26:25 +0100
Subject: [PATCH V1 4/4] phy: qcom-qmp-ufs: read max-microamp values from
 device tree
In-Reply-To: <599b8a4b-324a-4543-ba27-0451f05c3dfd@quicinc.com>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
 <20250806154340.20122-5-quic_nitirawa@quicinc.com>
 <f368b6da-1aa3-4b8e-9106-3c29d4ab5c5e@oss.qualcomm.com>
 <fe2bc07c-8fe9-47fd-bcd7-c2f0ebbd596f@sirena.org.uk>
 <aed1de56-fafe-4ccc-b542-69400b574def@oss.qualcomm.com>
 <acf89420-743b-4178-ac05-d4ca492bfee3@sirena.org.uk>
 <599b8a4b-324a-4543-ba27-0451f05c3dfd@quicinc.com>
Message-ID: <3aa82f65-4812-4bf0-9323-96f40824a004@sirena.org.uk>

On Thu, Aug 07, 2025 at 09:12:53PM +0530, Nitin Rawat wrote:
> On 8/7/2025 7:14 PM, Mark Brown wrote:

> > > The intended use is to set the load requirement and then only en/disable
> > > the consumer, so that the current load is updated in core (like in the
> > > kerneldoc of _regulator_handle_consumer_enable())

> > > My question was about moving the custom parsing of
> > > $supplyname-max-micromap introduced in this patch into the regulator
> > > core, as this seems like a rather common problem.

> > Wait, is this supposed to be some new property that you want to
> > standardise?  I didn't see a proposal for that, it's not something that
> > currently exists - the only standard properties that currently exist are
> > for the regulator as a whole.

> The UFS QMP PHY driver is not the first client to use regulator_set_load or
> alternatively set load requirements and invoke enable/disable or
> alternatively

The issue isn't using regulator_set_load(), that's perfectly fine and
expected.  The issue is either reading the value to use from the
constraint information (which is just buggy) or adding a generic
property for this (which I'm not convinced is a good idea, I'd expect a
large propoprtion of drivers should just know what their requirements
are and that a generic property would just get abused).

> These drivers also define corresponding binding properties, as seen in the
> UFS instances documented here:

> UFS Common DT Binding ((link - https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/Documentation/devicetree/bindings/ufs/ufs-common.yaml?h=next-20250807)

Note that that's specifying OPPs which is different...

> There was a previous effort to introduce similar properties
> (vdda-phy-max-microamp and vdda-pll-max-microamp) in the device tree
> bindings.
> Link - (link- https://patchwork.kernel.org/project/linux-arm-msm/patch/20220418205509.1102109-3-bhupesh.sharma at linaro.org/#24820481)

That patch also fails to supply any rationale for making this board
specific or generally putting them in the DT, AFAICT it's one of these
things just pulled out of the vendor tree without really thinking about
it.  The changelog just says the properties are in downstream DTs.

> Currently, the regulator framework does support automatic aggregation of
> load requests from multiple client drivers. Therefore, it is reasonable and
> necessary for each client to individually communicate its expected runtime
> load to the regulator framework to put the regulators in current
> operation mode.

That doesn't mean that it's a good idea to put that information in the
DT, nor if it is sensible to put in DT does it mean that it's a good
idea to define a generic property that applies to all regulator
consumers which is what I now think Konrad is proposing.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-phy/attachments/20250807/81df7875/attachment.sig>

From quic_nitirawa at quicinc.com  Thu Aug  7 10:35:08 2025
From: quic_nitirawa at quicinc.com (Nitin Rawat)
Date: Thu, 7 Aug 2025 23:05:08 +0530
Subject: [PATCH V1 4/4] phy: qcom-qmp-ufs: read max-microamp values from
 device tree
In-Reply-To: <3aa82f65-4812-4bf0-9323-96f40824a004@sirena.org.uk>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
 <20250806154340.20122-5-quic_nitirawa@quicinc.com>
 <f368b6da-1aa3-4b8e-9106-3c29d4ab5c5e@oss.qualcomm.com>
 <fe2bc07c-8fe9-47fd-bcd7-c2f0ebbd596f@sirena.org.uk>
 <aed1de56-fafe-4ccc-b542-69400b574def@oss.qualcomm.com>
 <acf89420-743b-4178-ac05-d4ca492bfee3@sirena.org.uk>
 <599b8a4b-324a-4543-ba27-0451f05c3dfd@quicinc.com>
 <3aa82f65-4812-4bf0-9323-96f40824a004@sirena.org.uk>
Message-ID: <685e3d36-c0e3-4faa-b817-aecc15976a25@quicinc.com>



On 8/7/2025 10:56 PM, Mark Brown wrote:
> On Thu, Aug 07, 2025 at 09:12:53PM +0530, Nitin Rawat wrote:
>> On 8/7/2025 7:14 PM, Mark Brown wrote:
> 
>>>> The intended use is to set the load requirement and then only en/disable
>>>> the consumer, so that the current load is updated in core (like in the
>>>> kerneldoc of _regulator_handle_consumer_enable())
> 
>>>> My question was about moving the custom parsing of
>>>> $supplyname-max-micromap introduced in this patch into the regulator
>>>> core, as this seems like a rather common problem.
> 
>>> Wait, is this supposed to be some new property that you want to
>>> standardise?  I didn't see a proposal for that, it's not something that
>>> currently exists - the only standard properties that currently exist are
>>> for the regulator as a whole.
> 
>> The UFS QMP PHY driver is not the first client to use regulator_set_load or
>> alternatively set load requirements and invoke enable/disable or
>> alternatively
> 
> The issue isn't using regulator_set_load(), that's perfectly fine and
> expected.  The issue is either reading the value to use from the
> constraint information (which is just buggy) or adding a generic
> property for this (which I'm not convinced is a good idea, I'd expect a
> large propoprtion of drivers should just know what their requirements
> are and that a generic property would just get abused).
> 
>> These drivers also define corresponding binding properties, as seen in the
>> UFS instances documented here:
> 
>> UFS Common DT Binding ((link - https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/Documentation/devicetree/bindings/ufs/ufs-common.yaml?h=next-20250807)
> 
> Note that that's specifying OPPs which is different...

Sorry for the confusion .Instead, I meant the following three properties 
defined in the link to ufs-common.yaml binding, which specify the 
maximum load that can be drawn from the respective power supplies.

   vcc-max-microamp:
     description:
       Specifies max. load that can be drawn from VCC supply.

   vccq-max-microamp:
     description:
       Specifies max. load that can be drawn from VCCQ supply.

   vccq2-max-microamp:
     description:
       Specifies max. load that can be drawn from VCCQ2 supply.


> 
>> There was a previous effort to introduce similar properties
>> (vdda-phy-max-microamp and vdda-pll-max-microamp) in the device tree
>> bindings.
>> Link - (link- https://patchwork.kernel.org/project/linux-arm-msm/patch/20220418205509.1102109-3-bhupesh.sharma at linaro.org/#24820481)
> 
> That patch also fails to supply any rationale for making this board
> specific or generally putting them in the DT, AFAICT it's one of these
> things just pulled out of the vendor tree without really thinking about
> it.  The changelog just says the properties are in downstream DTs.
> 
>> Currently, the regulator framework does support automatic aggregation of
>> load requests from multiple client drivers. Therefore, it is reasonable and
>> necessary for each client to individually communicate its expected runtime
>> load to the regulator framework to put the regulators in current
>> operation mode.
> 
> That doesn't mean that it's a good idea to put that information in the
> DT, nor if it is sensible to put in DT does it mean that it's a good
> idea to define a generic property that applies to all regulator
> consumers which is what I now think Konrad is proposing.



From konrad.dybcio at oss.qualcomm.com  Thu Aug  7 10:43:15 2025
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Thu, 7 Aug 2025 19:43:15 +0200
Subject: [PATCH V1 4/4] phy: qcom-qmp-ufs: read max-microamp values from
 device tree
In-Reply-To: <3aa82f65-4812-4bf0-9323-96f40824a004@sirena.org.uk>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
 <20250806154340.20122-5-quic_nitirawa@quicinc.com>
 <f368b6da-1aa3-4b8e-9106-3c29d4ab5c5e@oss.qualcomm.com>
 <fe2bc07c-8fe9-47fd-bcd7-c2f0ebbd596f@sirena.org.uk>
 <aed1de56-fafe-4ccc-b542-69400b574def@oss.qualcomm.com>
 <acf89420-743b-4178-ac05-d4ca492bfee3@sirena.org.uk>
 <599b8a4b-324a-4543-ba27-0451f05c3dfd@quicinc.com>
 <3aa82f65-4812-4bf0-9323-96f40824a004@sirena.org.uk>
Message-ID: <8c7f8cfc-2090-449e-b6ec-688a0021bac4@oss.qualcomm.com>

On 8/7/25 7:26 PM, Mark Brown wrote:
> On Thu, Aug 07, 2025 at 09:12:53PM +0530, Nitin Rawat wrote:
>> On 8/7/2025 7:14 PM, Mark Brown wrote:
> 
>>>> The intended use is to set the load requirement and then only en/disable
>>>> the consumer, so that the current load is updated in core (like in the
>>>> kerneldoc of _regulator_handle_consumer_enable())
> 
>>>> My question was about moving the custom parsing of
>>>> $supplyname-max-micromap introduced in this patch into the regulator
>>>> core, as this seems like a rather common problem.
> 
>>> Wait, is this supposed to be some new property that you want to
>>> standardise?  I didn't see a proposal for that, it's not something that
>>> currently exists - the only standard properties that currently exist are
>>> for the regulator as a whole.
> 
>> The UFS QMP PHY driver is not the first client to use regulator_set_load or
>> alternatively set load requirements and invoke enable/disable or
>> alternatively
> 
> The issue isn't using regulator_set_load(), that's perfectly fine and
> expected.  The issue is either reading the value to use from the
> constraint information (which is just buggy) or adding a generic
> property for this (which I'm not convinced is a good idea, I'd expect a
> large propoprtion of drivers should just know what their requirements
> are and that a generic property would just get abused).
> 
>> These drivers also define corresponding binding properties, as seen in the
>> UFS instances documented here:
> 
>> UFS Common DT Binding ((link - https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/Documentation/devicetree/bindings/ufs/ufs-common.yaml?h=next-20250807)
> 
> Note that that's specifying OPPs which is different...

The microamp properties are in the top-level, not under OPP if
that's what you meant

Or are you perhaps suggesting that any device requiring explicit
current requirement settings, should do so through an OPP table
(perhaps a degenerated one with just a single entry detailling
the single requirement most of the time)?

>> There was a previous effort to introduce similar properties
>> (vdda-phy-max-microamp and vdda-pll-max-microamp) in the device tree
>> bindings.
>> Link - (link- https://patchwork.kernel.org/project/linux-arm-msm/patch/20220418205509.1102109-3-bhupesh.sharma at linaro.org/#24820481)
> 
> That patch also fails to supply any rationale for making this board
> specific or generally putting them in the DT, AFAICT it's one of these
> things just pulled out of the vendor tree without really thinking about
> it.  The changelog just says the properties are in downstream DTs.
> 
>> Currently, the regulator framework does support automatic aggregation of
>> load requests from multiple client drivers. Therefore, it is reasonable and
>> necessary for each client to individually communicate its expected runtime
>> load to the regulator framework to put the regulators in current
>> operation mode.
> 
> That doesn't mean that it's a good idea to put that information in the
> DT, nor if it is sensible to put in DT does it mean that it's a good
> idea to define a generic property that applies to all regulator
> consumers which is what I now think Konrad is proposing.

Yeah, that's what I had in mind

I was never able to get a reliable source for those numbers myselfe
either.. At least some of them are prooooobably? chosen based on the
used regulator type, to ensure it's always in HPM..

That said, our drivers cover a wide variety of hardware, built on a
wide variety of process nodes, with different configurations, etc.,
so it's either polluting the DT, or polluting the driver with
per-compatible hardcoded data (and additional compatibles because
fallbacks wouldn't work most of the time)

Konrad 


From broonie at kernel.org  Thu Aug  7 10:43:46 2025
From: broonie at kernel.org (Mark Brown)
Date: Thu, 7 Aug 2025 18:43:46 +0100
Subject: [PATCH V1 4/4] phy: qcom-qmp-ufs: read max-microamp values from
 device tree
In-Reply-To: <685e3d36-c0e3-4faa-b817-aecc15976a25@quicinc.com>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
 <20250806154340.20122-5-quic_nitirawa@quicinc.com>
 <f368b6da-1aa3-4b8e-9106-3c29d4ab5c5e@oss.qualcomm.com>
 <fe2bc07c-8fe9-47fd-bcd7-c2f0ebbd596f@sirena.org.uk>
 <aed1de56-fafe-4ccc-b542-69400b574def@oss.qualcomm.com>
 <acf89420-743b-4178-ac05-d4ca492bfee3@sirena.org.uk>
 <599b8a4b-324a-4543-ba27-0451f05c3dfd@quicinc.com>
 <3aa82f65-4812-4bf0-9323-96f40824a004@sirena.org.uk>
 <685e3d36-c0e3-4faa-b817-aecc15976a25@quicinc.com>
Message-ID: <c1435858-6288-4525-8c92-e27ed86cb55e@sirena.org.uk>

On Thu, Aug 07, 2025 at 11:05:08PM +0530, Nitin Rawat wrote:
> On 8/7/2025 10:56 PM, Mark Brown wrote:

> > The issue isn't using regulator_set_load(), that's perfectly fine and
> > expected.  The issue is either reading the value to use from the
> > constraint information (which is just buggy) or adding a generic
> > property for this (which I'm not convinced is a good idea, I'd expect a
> > large propoprtion of drivers should just know what their requirements
> > are and that a generic property would just get abused).

> > > These drivers also define corresponding binding properties, as seen in the
> > > UFS instances documented here:

> > > UFS Common DT Binding ((link - https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/Documentation/devicetree/bindings/ufs/ufs-common.yaml?h=next-20250807)

> > Note that that's specifying OPPs which is different...

> Sorry for the confusion .Instead, I meant the following three properties
> defined in the link to ufs-common.yaml binding, which specify the maximum
> load that can be drawn from the respective power supplies.

>   vcc-max-microamp:
>     description:
>       Specifies max. load that can be drawn from VCC supply.
> 
>   vccq-max-microamp:
>     description:
>       Specifies max. load that can be drawn from VCCQ supply.
> 
>   vccq2-max-microamp:
>     description:
>       Specifies max. load that can be drawn from VCCQ2 supply.

OK, but that's still not motivating putting things in DT (the properties
are there but don't explain why) and having this for some devices
doesn't really address the why make it a generic rather than device
specific part of things like Konrad was suggesting.  Perhaps there's
enough board specific variation that it does make sense to put something
specific to this consumer in DT, but it'd be another step to make it a
generic thing that applies to all regulators.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-phy/attachments/20250807/650a531c/attachment.sig>

From quic_nitirawa at quicinc.com  Thu Aug  7 10:56:17 2025
From: quic_nitirawa at quicinc.com (Nitin Rawat)
Date: Thu, 7 Aug 2025 23:26:17 +0530
Subject: [PATCH V1 4/4] phy: qcom-qmp-ufs: read max-microamp values from
 device tree
In-Reply-To: <c1435858-6288-4525-8c92-e27ed86cb55e@sirena.org.uk>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
 <20250806154340.20122-5-quic_nitirawa@quicinc.com>
 <f368b6da-1aa3-4b8e-9106-3c29d4ab5c5e@oss.qualcomm.com>
 <fe2bc07c-8fe9-47fd-bcd7-c2f0ebbd596f@sirena.org.uk>
 <aed1de56-fafe-4ccc-b542-69400b574def@oss.qualcomm.com>
 <acf89420-743b-4178-ac05-d4ca492bfee3@sirena.org.uk>
 <599b8a4b-324a-4543-ba27-0451f05c3dfd@quicinc.com>
 <3aa82f65-4812-4bf0-9323-96f40824a004@sirena.org.uk>
 <685e3d36-c0e3-4faa-b817-aecc15976a25@quicinc.com>
 <c1435858-6288-4525-8c92-e27ed86cb55e@sirena.org.uk>
Message-ID: <31461227-3f3a-4316-9c8a-c851209d0278@quicinc.com>



On 8/7/2025 11:13 PM, Mark Brown wrote:
> On Thu, Aug 07, 2025 at 11:05:08PM +0530, Nitin Rawat wrote:
>> On 8/7/2025 10:56 PM, Mark Brown wrote:
> 
>>> The issue isn't using regulator_set_load(), that's perfectly fine and
>>> expected.  The issue is either reading the value to use from the
>>> constraint information (which is just buggy) or adding a generic
>>> property for this (which I'm not convinced is a good idea, I'd expect a
>>> large propoprtion of drivers should just know what their requirements
>>> are and that a generic property would just get abused).
> 
>>>> These drivers also define corresponding binding properties, as seen in the
>>>> UFS instances documented here:
> 
>>>> UFS Common DT Binding ((link - https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/Documentation/devicetree/bindings/ufs/ufs-common.yaml?h=next-20250807)
> 
>>> Note that that's specifying OPPs which is different...
> 
>> Sorry for the confusion .Instead, I meant the following three properties
>> defined in the link to ufs-common.yaml binding, which specify the maximum
>> load that can be drawn from the respective power supplies.
> 
>>    vcc-max-microamp:
>>      description:
>>        Specifies max. load that can be drawn from VCC supply.
>>
>>    vccq-max-microamp:
>>      description:
>>        Specifies max. load that can be drawn from VCCQ supply.
>>
>>    vccq2-max-microamp:
>>      description:
>>        Specifies max. load that can be drawn from VCCQ2 supply.
> 
> OK, but that's still not motivating putting things in DT (the properties
> are there but don't explain why) and having this for some devices
> doesn't really address the why make it a generic rather than device
> specific part of things like Konrad was suggesting.  Perhaps there's
> enough board specific variation that it does make sense to put something
> specific to this consumer in DT, but it'd be another step to make it a
> generic thing that applies to all regulators.

Hi Mark,

Thanks for your review and feedback.
To address your question about why these properties should be included 
in the device tree:

1. Regulator and PMIC configurations are board-specific, meaning they 
can vary significantly across different platforms. For example, some 
boards may use different generations of UFS devices ? such as UFS 2.x ? 
which come with distinct power and load requirements and some with 
UFS3.x which has it own power/load requirement.

2. UFS PHY load and PMIC requirements also varies across targets, 
depending on the underlying technology node and the specific PHY 
capabilities. These differences can be influenced by the MIPI version or 
other implementation details.

Given this variability, expressing these requirements in the device tree 
allows for a flexible and accurate way to describe board-specific 
constraints without hardcoding them into the driver.

Thanks,
Nitin


From quic_nitirawa at quicinc.com  Thu Aug  7 11:09:29 2025
From: quic_nitirawa at quicinc.com (Nitin Rawat)
Date: Thu, 7 Aug 2025 23:39:29 +0530
Subject: [PATCH V1 4/4] phy: qcom-qmp-ufs: read max-microamp values from
 device tree
In-Reply-To: <8c7f8cfc-2090-449e-b6ec-688a0021bac4@oss.qualcomm.com>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
 <20250806154340.20122-5-quic_nitirawa@quicinc.com>
 <f368b6da-1aa3-4b8e-9106-3c29d4ab5c5e@oss.qualcomm.com>
 <fe2bc07c-8fe9-47fd-bcd7-c2f0ebbd596f@sirena.org.uk>
 <aed1de56-fafe-4ccc-b542-69400b574def@oss.qualcomm.com>
 <acf89420-743b-4178-ac05-d4ca492bfee3@sirena.org.uk>
 <599b8a4b-324a-4543-ba27-0451f05c3dfd@quicinc.com>
 <3aa82f65-4812-4bf0-9323-96f40824a004@sirena.org.uk>
 <8c7f8cfc-2090-449e-b6ec-688a0021bac4@oss.qualcomm.com>
Message-ID: <faadad49-9fa6-4f76-9162-d6f19974ad49@quicinc.com>



On 8/7/2025 11:13 PM, Konrad Dybcio wrote:
> On 8/7/25 7:26 PM, Mark Brown wrote:
>> On Thu, Aug 07, 2025 at 09:12:53PM +0530, Nitin Rawat wrote:
>>> On 8/7/2025 7:14 PM, Mark Brown wrote:
>>
>>>>> The intended use is to set the load requirement and then only en/disable
>>>>> the consumer, so that the current load is updated in core (like in the
>>>>> kerneldoc of _regulator_handle_consumer_enable())
>>
>>>>> My question was about moving the custom parsing of
>>>>> $supplyname-max-micromap introduced in this patch into the regulator
>>>>> core, as this seems like a rather common problem.
>>
>>>> Wait, is this supposed to be some new property that you want to
>>>> standardise?  I didn't see a proposal for that, it's not something that
>>>> currently exists - the only standard properties that currently exist are
>>>> for the regulator as a whole.
>>
>>> The UFS QMP PHY driver is not the first client to use regulator_set_load or
>>> alternatively set load requirements and invoke enable/disable or
>>> alternatively
>>
>> The issue isn't using regulator_set_load(), that's perfectly fine and
>> expected.  The issue is either reading the value to use from the
>> constraint information (which is just buggy) or adding a generic
>> property for this (which I'm not convinced is a good idea, I'd expect a
>> large propoprtion of drivers should just know what their requirements
>> are and that a generic property would just get abused).
>>
>>> These drivers also define corresponding binding properties, as seen in the
>>> UFS instances documented here:
>>
>>> UFS Common DT Binding ((link - https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/Documentation/devicetree/bindings/ufs/ufs-common.yaml?h=next-20250807)
>>
>> Note that that's specifying OPPs which is different...
> 
> The microamp properties are in the top-level, not under OPP if
> that's what you meant

Thanks for pointing that out, Konrad


> 
> Or are you perhaps suggesting that any device requiring explicit
> current requirement settings, should do so through an OPP table
> (perhaps a degenerated one with just a single entry detailling
> the single requirement most of the time)?
> 
>>> There was a previous effort to introduce similar properties
>>> (vdda-phy-max-microamp and vdda-pll-max-microamp) in the device tree
>>> bindings.
>>> Link - (link- https://patchwork.kernel.org/project/linux-arm-msm/patch/20220418205509.1102109-3-bhupesh.sharma at linaro.org/#24820481)
>>
>> That patch also fails to supply any rationale for making this board
>> specific or generally putting them in the DT, AFAICT it's one of these
>> things just pulled out of the vendor tree without really thinking about
>> it.  The changelog just says the properties are in downstream DTs.
>>
>>> Currently, the regulator framework does support automatic aggregation of
>>> load requests from multiple client drivers. Therefore, it is reasonable and
>>> necessary for each client to individually communicate its expected runtime
>>> load to the regulator framework to put the regulators in current
>>> operation mode.
>>
>> That doesn't mean that it's a good idea to put that information in the
>> DT, nor if it is sensible to put in DT does it mean that it's a good
>> idea to define a generic property that applies to all regulator
>> consumers which is what I now think Konrad is proposing.
> 
> Yeah, that's what I had in mind
> 
> I was never able to get a reliable source for those numbers myselfe
> either.. At least some of them are prooooobably? chosen based on the
> used regulator type, to ensure it's always in HPM..
> 
> That said, our drivers cover a wide variety of hardware, built on a
> wide variety of process nodes, with different configurations, etc.,
> so it's either polluting the DT, or polluting the driver with
> per-compatible hardcoded data (and additional compatibles because
> fallbacks wouldn't work most of the time)

I missed to read this before replying to my last reply.
Thanks for the explaining this. I too had mention similar thing in reply 
to mark's query in my last reply.



> 
> Konrad



From broonie at kernel.org  Thu Aug  7 11:45:19 2025
From: broonie at kernel.org (Mark Brown)
Date: Thu, 7 Aug 2025 19:45:19 +0100
Subject: [PATCH V1 4/4] phy: qcom-qmp-ufs: read max-microamp values from
 device tree
In-Reply-To: <31461227-3f3a-4316-9c8a-c851209d0278@quicinc.com>
References: <20250806154340.20122-5-quic_nitirawa@quicinc.com>
 <f368b6da-1aa3-4b8e-9106-3c29d4ab5c5e@oss.qualcomm.com>
 <fe2bc07c-8fe9-47fd-bcd7-c2f0ebbd596f@sirena.org.uk>
 <aed1de56-fafe-4ccc-b542-69400b574def@oss.qualcomm.com>
 <acf89420-743b-4178-ac05-d4ca492bfee3@sirena.org.uk>
 <599b8a4b-324a-4543-ba27-0451f05c3dfd@quicinc.com>
 <3aa82f65-4812-4bf0-9323-96f40824a004@sirena.org.uk>
 <685e3d36-c0e3-4faa-b817-aecc15976a25@quicinc.com>
 <c1435858-6288-4525-8c92-e27ed86cb55e@sirena.org.uk>
 <31461227-3f3a-4316-9c8a-c851209d0278@quicinc.com>
Message-ID: <4efc8a3a-ceb6-40dc-b877-328b86348e0b@sirena.org.uk>

On Thu, Aug 07, 2025 at 11:26:17PM +0530, Nitin Rawat wrote:

> 1. Regulator and PMIC configurations are board-specific, meaning they can
> vary significantly across different platforms. For example, some boards may
> use different generations of UFS devices ? such as UFS 2.x ? which come with
> distinct power and load requirements and some with UFS3.x which has it own
> power/load requirement.

Requirements from generations of UFS devices presumably come from the
UFS spec and should just be known though?

> 2. UFS PHY load and PMIC requirements also varies across targets, depending
> on the underlying technology node and the specific PHY capabilities. These
> differences can be influenced by the MIPI version or other implementation
> details.

If you've got non-enumerable PHYs that have a big impact that's a much
clearer use case for putting things in DT.

> Given this variability, expressing these requirements in the device tree
> allows for a flexible and accurate way to describe board-specific
> constraints without hardcoding them into the driver.

There's still the issue with making this a thing for all regulators, not
just for this specific device.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-phy/attachments/20250807/bce87247/attachment.sig>

From broonie at kernel.org  Thu Aug  7 12:09:56 2025
From: broonie at kernel.org (Mark Brown)
Date: Thu, 7 Aug 2025 20:09:56 +0100
Subject: [PATCH V1 4/4] phy: qcom-qmp-ufs: read max-microamp values from
 device tree
In-Reply-To: <8c7f8cfc-2090-449e-b6ec-688a0021bac4@oss.qualcomm.com>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
 <20250806154340.20122-5-quic_nitirawa@quicinc.com>
 <f368b6da-1aa3-4b8e-9106-3c29d4ab5c5e@oss.qualcomm.com>
 <fe2bc07c-8fe9-47fd-bcd7-c2f0ebbd596f@sirena.org.uk>
 <aed1de56-fafe-4ccc-b542-69400b574def@oss.qualcomm.com>
 <acf89420-743b-4178-ac05-d4ca492bfee3@sirena.org.uk>
 <599b8a4b-324a-4543-ba27-0451f05c3dfd@quicinc.com>
 <3aa82f65-4812-4bf0-9323-96f40824a004@sirena.org.uk>
 <8c7f8cfc-2090-449e-b6ec-688a0021bac4@oss.qualcomm.com>
Message-ID: <14566f49-7f7b-4583-98b7-8a473054f7c3@sirena.org.uk>

On Thu, Aug 07, 2025 at 07:43:15PM +0200, Konrad Dybcio wrote:
> On 8/7/25 7:26 PM, Mark Brown wrote:

> > Note that that's specifying OPPs which is different...

> The microamp properties are in the top-level, not under OPP if
> that's what you meant

I mean the OPPs use case is an existing well known one for dumping stuff
into DT.

> > That doesn't mean that it's a good idea to put that information in the
> > DT, nor if it is sensible to put in DT does it mean that it's a good
> > idea to define a generic property that applies to all regulator
> > consumers which is what I now think Konrad is proposing.

> Yeah, that's what I had in mind

> I was never able to get a reliable source for those numbers myselfe
> either.. At least some of them are prooooobably? chosen based on the
> used regulator type, to ensure it's always in HPM..

That's what set_mode() is for.  Like I say it's becoming less and less
relevant though.

> That said, our drivers cover a wide variety of hardware, built on a
> wide variety of process nodes, with different configurations, etc.,
> so it's either polluting the DT, or polluting the driver with
> per-compatible hardcoded data (and additional compatibles because
> fallbacks wouldn't work most of the time)

That's really not a persuasive argument for adding a genric property
that applies to all regulator consumers...

My instinct with this stuff is generally to avoid putting it in the DT,
we see far too many instances where someone's typed some numbers in
wrongly or discovers the ability to drive the hardware harder and needs
to tune the numbers - once something is ABI you're stuck just trusting
the numbers.  That said I'm not going to stop you putting something
specific to this driver in there, I just don't think this is a good idea
as a generic property.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-phy/attachments/20250807/bed8bbf8/attachment.sig>

From quic_nitirawa at quicinc.com  Thu Aug  7 13:45:31 2025
From: quic_nitirawa at quicinc.com (Nitin Rawat)
Date: Fri, 8 Aug 2025 02:15:31 +0530
Subject: [PATCH V1 4/4] phy: qcom-qmp-ufs: read max-microamp values from
 device tree
In-Reply-To: <4efc8a3a-ceb6-40dc-b877-328b86348e0b@sirena.org.uk>
References: <20250806154340.20122-5-quic_nitirawa@quicinc.com>
 <f368b6da-1aa3-4b8e-9106-3c29d4ab5c5e@oss.qualcomm.com>
 <fe2bc07c-8fe9-47fd-bcd7-c2f0ebbd596f@sirena.org.uk>
 <aed1de56-fafe-4ccc-b542-69400b574def@oss.qualcomm.com>
 <acf89420-743b-4178-ac05-d4ca492bfee3@sirena.org.uk>
 <599b8a4b-324a-4543-ba27-0451f05c3dfd@quicinc.com>
 <3aa82f65-4812-4bf0-9323-96f40824a004@sirena.org.uk>
 <685e3d36-c0e3-4faa-b817-aecc15976a25@quicinc.com>
 <c1435858-6288-4525-8c92-e27ed86cb55e@sirena.org.uk>
 <31461227-3f3a-4316-9c8a-c851209d0278@quicinc.com>
 <4efc8a3a-ceb6-40dc-b877-328b86348e0b@sirena.org.uk>
Message-ID: <52625e59-c7d0-45d1-8af3-d9958c5ef01a@quicinc.com>



On 8/8/2025 12:15 AM, Mark Brown wrote:
> On Thu, Aug 07, 2025 at 11:26:17PM +0530, Nitin Rawat wrote:
> 
>> 1. Regulator and PMIC configurations are board-specific, meaning they can
>> vary significantly across different platforms. For example, some boards may
>> use different generations of UFS devices ? such as UFS 2.x ? which come with
>> distinct power and load requirements and some with UFS3.x which has it own
>> power/load requirement.
> 
> Requirements from generations of UFS devices presumably come from the
> UFS spec and should just be known though?
> 
>> 2. UFS PHY load and PMIC requirements also varies across targets, depending
>> on the underlying technology node and the specific PHY capabilities. These
>> differences can be influenced by the MIPI version or other implementation
>> details.
> 
> If you've got non-enumerable PHYs that have a big impact that's a much
> clearer use case for putting things in DT.

What I meant is that different boards may use different UFS parts, and 
the associated PHY load requirements are not governed by the UFS 
specification itself. Instead, these requirements depend on our specific 
PHY design and MIPI, which can vary across platforms.

Because these characteristics ? such as load requirements ? are not 
enumerable or automatically detectable, it makes sense to describe them 
explicitly in the device tree. This approach ensures that board-specific 
variations are accurately captured without hardcoding them into the driver.

> 
>> Given this variability, expressing these requirements in the device tree
>> allows for a flexible and accurate way to describe board-specific
>> constraints without hardcoding them into the driver.
> 
> There's still the issue with making this a thing for all regulators, not
> just for this specific device.


I see your point. Just to clarify ? my patch is specifically scoped to 
UFS PHY and PLL regulators. The device tree binding defines these 
properties as optional, and they are only enabled for targets where load 
voting is required.

So, this isn?t intended to be a generic change for all regulators, but 
rather a targeted solution for specific consumers that need it.

That?s why I?ve chosen to keep the regulator parsing logic and 
corresponding load voting support within the UFS PHY driver, rather than 
extending it to the core regulator framework.


Thanks,
Nitin



From robh at kernel.org  Thu Aug  7 19:49:30 2025
From: robh at kernel.org (Rob Herring (Arm))
Date: Thu, 07 Aug 2025 21:49:30 -0500
Subject: [PATCH v4 0/6] arm64: qcom: allow up to 4 lanes for the Type-C
 DisplayPort Altmode
In-Reply-To: <20250807-topic-4ln_dp_respin-v4-0-43272d6eca92@oss.qualcomm.com>
References: <20250807-topic-4ln_dp_respin-v4-0-43272d6eca92@oss.qualcomm.com>
Message-ID: <175462129176.394940.16810637795278334342.robh@kernel.org>


On Thu, 07 Aug 2025 18:33:18 +0200, Konrad Dybcio wrote:
> Register a typec mux in order to change the PHY mode on the Type-C
> mux events depending on the mode and the svid when in Altmode setup.
> 
> The DisplayPort phy should be left enabled if is still powered on
> by the DRM DisplayPort controller, so bail out until the DisplayPort
> PHY is not powered off.
> 
> The Type-C Mode/SVID only changes on plug/unplug, and USB SAFE states
> will be set in between of USB-Only, Combo and DisplayPort Only so
> this will leave enough time to the DRM DisplayPort controller to
> turn of the DisplayPort PHY.
> 
> The patchset also includes bindings changes and DT changes.
> 
> This has been successfully tested on an SM8550 board, but the
> Thinkpad X13s deserved testing between non-PD USB, non-PD DisplayPort,
> PD USB Hubs and PD Altmode Dongles to make sure the switch works
> as expected.
> 
> The DisplayPort 4 lanes setup can be check with:
> $ cat /sys/kernel/debug/dri/ae01000.display-controller/DP-1/dp_debug
> 	name = msm_dp
> 	drm_dp_link
> 		rate = 540000
> 		num_lanes = 4
> ...
> 
> This patchset depends on [1] to allow broadcasting the type-c mode
> to the PHY, otherwise the PHY will keep the combo state while the
> retimer would setup the 4 lanes in DP mode.
> 
> [1] https://lore.kernel.org/all/20240527-topic-sm8x50-upstream-retimer-broadcast-mode-v1-0-79ec91381aba at linaro.org/
> 
> Changes in v4:
> - Default to USB3_ONLY if there's no DP SVID (Dmitry)
> - Pick up tags, dropped T-bys due to the above change
> - Add missing submitter's sign-off on some patches
> - The odd 4-lane-DP + USB2 case remains unhandled for now, but it's
>   not a huge deal, see:
>   <c2f2ba36-1a25-450e-99b9-79aa4fd4913d at linaro.org>
> - Link to v3: https://lore.kernel.org/r/20250527-topic-4ln_dp_respin-v3-0-f9a0763ec289 at oss.qualcomm.com
> Changes in v3:
> - Take the series from Neil
> - Rebase
> - Rename many variables
> - Test on X1E & X13s
> - Apply a number of small cosmetic/codestyle changes
> - Remove some unused variables
> - Some smaller bugfixes
> - Link to v2: https://lore.kernel.org/lkml/20240527-topic-sm8x50-upstream-phy-combo-typec-mux-v2-0-a03e68d7b8fc at linaro.org/
> Changes in v2:
> - Reference usb-switch.yaml in bindings patch
> - Fix switch/case indenting
> - Check svid for USB_TYPEC_DP_SID
> - Fix X13s patch subject
> - Update SM8650 patch to enable 4 lanes on HDK aswell
> - Link to v1: https://lore.kernel.org/r/20240229-topic-sm8x50-upstream-phy-combo-typec-mux-v1-0-07e24a231840 at linaro.org
> 
> Signed-off-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
> ---
> Konrad Dybcio (1):
>       phy: qcom: qmp-combo: Rename 'mode' to 'phy_mode'
> 
> Neil Armstrong (5):
>       dt-bindings: phy: qcom,sc8280xp-qmp-usb43dp: Reference usb-switch.yaml to allow mode-switch
>       phy: qcom: qmp-combo: store DP phy power state
>       phy: qcom: qmp-combo: introduce QMPPHY_MODE
>       phy: qcom: qmp-combo: register a typec mux to change the QMPPHY_MODE
>       arm64: dts: qcom: sc8280xp-lenovo-thinkpad-x13: Set up 4-lane DP
> 
>  .../phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml         |   7 +-
>  .../dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts     |   6 +-
>  drivers/phy/qualcomm/phy-qcom-qmp-combo.c          | 179 +++++++++++++++++++--
>  3 files changed, 170 insertions(+), 22 deletions(-)
> ---
> base-commit: 442d93313caebc8ccd6d53f4572c50732a95bc48
> change-id: 20250527-topic-4ln_dp_respin-c6924a8825ce
> 
> Best regards,
> --
> Konrad Dybcio <konrad.dybcio at oss.qualcomm.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


This patch series was applied (using b4) to base:
 Base: using specified base-commit 442d93313caebc8ccd6d53f4572c50732a95bc48

If this is not the correct base, please add 'base-commit' tag
(or use b4 which does this automatically)

New warnings running 'make CHECK_DTBS=y for arch/arm64/boot/dts/qcom/' for 20250807-topic-4ln_dp_respin-v4-0-43272d6eca92 at oss.qualcomm.com:

arch/arm64/boot/dts/qcom/sm7125-xiaomi-curtana.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3-lte.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-r4.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-quackingstick-r0.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz-r1-lte.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel360-wifi.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler-rev1-inx.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz-r1.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-nots-r4.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r10.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-nots-r9.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3-kb.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar-r4.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-r1.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-acer-aspire1.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-kingoftown.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom-r2-lte.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-r9.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel360-lte.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1-kb.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar-r3.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r10-lte.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-idp.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-r10.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler-rev1-boe-rt5682s.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler-rev1-boe.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r9-kb.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel-parade.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel-ti.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz-r3-lte.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom-r1-lte.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r9.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz-r3.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-r1-lte.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r9-lte.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel-lte-ti.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom-r3.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1-lte.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom-r2.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler-rev1-inx-rt5682s.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel-lte-parade.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar-r2.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-nots-r5.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r10-kb.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom-r3-lte.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom-r1.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sm7125-xiaomi-joyeuse.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-nots-r10.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
arch/arm64/boot/dts/qcom/sc7180-trogdor-quackingstick-r0-lte.dtb: phy at 88e8000 (qcom,sc7180-qmp-usb3-dp-phy): 'oneOf' conditional failed, one must be fixed:
	'port' is a required property
	'ports' is a required property
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#







From claudiu.beznea at tuxon.dev  Thu Aug  7 23:17:59 2025
From: claudiu.beznea at tuxon.dev (Claudiu)
Date: Fri,  8 Aug 2025 09:17:59 +0300
Subject: [PATCH v4 1/8] soc: renesas: rz-sysc: Add syscon/regmap support
In-Reply-To: <20250808061806.2729274-1-claudiu.beznea.uj@bp.renesas.com>
References: <20250808061806.2729274-1-claudiu.beznea.uj@bp.renesas.com>
Message-ID: <20250808061806.2729274-2-claudiu.beznea.uj@bp.renesas.com>

From: John Madieu <john.madieu.xa at bp.renesas.com>

The RZ/G3E system controller has various registers that control or report
some properties specific to individual IPs. The regmap is registered as a
syscon device to allow these IP drivers to access the registers through the
regmap API.

As other RZ SoCs might have custom read/write callbacks or max-offsets,
register a custom regmap configuration.

Signed-off-by: John Madieu <john.madieu.xa at bp.renesas.com>
[claudiu.beznea:
 - do not check the match->data validity in rz_sysc_probe() as it is
   always valid
 - dinamically allocate regmap_cfg]
Signed-off-by: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
---

Changes in v4:
- adjusted the patch description by dropping "add" from
  "add register a custom regmap configuration"
- updated the list of changes from Claudiu Beznea
- dynamically allocate the regmap_config as proposed at [2]
- this patch is needed for proper function of USB (as proposed in this
  series) that being the reason it is introduced here, as well

[2] https://lore.kernel.org/all/CAMuHMdVyf3Xtpw=LWHrnD2CVQX4xYm=FBHvY_dx9OesHDz5zNg at mail.gmail.com/

Changes in v3:
- none, this patch is new, it was picked from John after he addressed
  the review comments received at [1];
- I adjusted as specified in the SoB area, and included it here as it
  is the base for the signal support presented in the next commits

[1] https://lore.kernel.org/all/20250330214945.185725-2-john.madieu.xa at bp.renesas.com/

 drivers/soc/renesas/Kconfig          |  1 +
 drivers/soc/renesas/r9a08g045-sysc.c |  1 +
 drivers/soc/renesas/r9a09g047-sys.c  |  1 +
 drivers/soc/renesas/r9a09g057-sys.c  |  1 +
 drivers/soc/renesas/rz-sysc.c        | 29 +++++++++++++++++++++++++++-
 drivers/soc/renesas/rz-sysc.h        |  2 ++
 6 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/renesas/Kconfig b/drivers/soc/renesas/Kconfig
index 719b7f4f376f..c97e2a183388 100644
--- a/drivers/soc/renesas/Kconfig
+++ b/drivers/soc/renesas/Kconfig
@@ -449,6 +449,7 @@ config RST_RCAR
 
 config SYSC_RZ
 	bool "System controller for RZ SoCs" if COMPILE_TEST
+	select MFD_SYSCON
 
 config SYSC_R9A08G045
 	bool "Renesas System controller support for R9A08G045 (RZ/G3S)" if COMPILE_TEST
diff --git a/drivers/soc/renesas/r9a08g045-sysc.c b/drivers/soc/renesas/r9a08g045-sysc.c
index f4db1431e036..0504d4e68761 100644
--- a/drivers/soc/renesas/r9a08g045-sysc.c
+++ b/drivers/soc/renesas/r9a08g045-sysc.c
@@ -20,4 +20,5 @@ static const struct rz_sysc_soc_id_init_data rzg3s_sysc_soc_id_init_data __initc
 
 const struct rz_sysc_init_data rzg3s_sysc_init_data __initconst = {
 	.soc_id_init_data = &rzg3s_sysc_soc_id_init_data,
+	.max_register = 0xe20,
 };
diff --git a/drivers/soc/renesas/r9a09g047-sys.c b/drivers/soc/renesas/r9a09g047-sys.c
index cd2eb7782cfe..2e8426c03050 100644
--- a/drivers/soc/renesas/r9a09g047-sys.c
+++ b/drivers/soc/renesas/r9a09g047-sys.c
@@ -64,4 +64,5 @@ static const struct rz_sysc_soc_id_init_data rzg3e_sys_soc_id_init_data __initco
 
 const struct rz_sysc_init_data rzg3e_sys_init_data = {
 	.soc_id_init_data = &rzg3e_sys_soc_id_init_data,
+	.max_register = 0x170c,
 };
diff --git a/drivers/soc/renesas/r9a09g057-sys.c b/drivers/soc/renesas/r9a09g057-sys.c
index 4c21cc29edbc..e3390e7c7fe5 100644
--- a/drivers/soc/renesas/r9a09g057-sys.c
+++ b/drivers/soc/renesas/r9a09g057-sys.c
@@ -64,4 +64,5 @@ static const struct rz_sysc_soc_id_init_data rzv2h_sys_soc_id_init_data __initco
 
 const struct rz_sysc_init_data rzv2h_sys_init_data = {
 	.soc_id_init_data = &rzv2h_sys_soc_id_init_data,
+	.max_register = 0x170c,
 };
diff --git a/drivers/soc/renesas/rz-sysc.c b/drivers/soc/renesas/rz-sysc.c
index ffa65fb4dade..66cc8d01f096 100644
--- a/drivers/soc/renesas/rz-sysc.c
+++ b/drivers/soc/renesas/rz-sysc.c
@@ -6,8 +6,10 @@
  */
 
 #include <linux/io.h>
+#include <linux/mfd/syscon.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
+#include <linux/regmap.h>
 #include <linux/sys_soc.h>
 
 #include "rz-sysc.h"
@@ -100,14 +102,20 @@ MODULE_DEVICE_TABLE(of, rz_sysc_match);
 
 static int rz_sysc_probe(struct platform_device *pdev)
 {
+	const struct rz_sysc_init_data *data;
 	const struct of_device_id *match;
+	struct regmap_config *regmap_cfg;
 	struct device *dev = &pdev->dev;
+	struct regmap *regmap;
 	struct rz_sysc *sysc;
+	int ret;
 
 	match = of_match_node(rz_sysc_match, dev->of_node);
 	if (!match)
 		return -ENODEV;
 
+	data = match->data;
+
 	sysc = devm_kzalloc(dev, sizeof(*sysc), GFP_KERNEL);
 	if (!sysc)
 		return -ENOMEM;
@@ -117,7 +125,26 @@ static int rz_sysc_probe(struct platform_device *pdev)
 		return PTR_ERR(sysc->base);
 
 	sysc->dev = dev;
-	return rz_sysc_soc_init(sysc, match);
+	ret = rz_sysc_soc_init(sysc, match);
+	if (ret)
+		return ret;
+
+	regmap_cfg = devm_kzalloc(dev, sizeof(*regmap_cfg), GFP_KERNEL);
+	if (!regmap_cfg)
+		return -ENOMEM;
+
+	regmap_cfg->name = "rz_sysc_regs";
+	regmap_cfg->reg_bits = 32;
+	regmap_cfg->reg_stride = 4;
+	regmap_cfg->val_bits = 32;
+	regmap_cfg->fast_io = true;
+	regmap_cfg->max_register = data->max_register;
+
+	regmap = devm_regmap_init_mmio(dev, sysc->base, regmap_cfg);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	return of_syscon_register_regmap(dev->of_node, regmap);
 }
 
 static struct platform_driver rz_sysc_driver = {
diff --git a/drivers/soc/renesas/rz-sysc.h b/drivers/soc/renesas/rz-sysc.h
index 56bc047a1bff..8eec355d5d56 100644
--- a/drivers/soc/renesas/rz-sysc.h
+++ b/drivers/soc/renesas/rz-sysc.h
@@ -34,9 +34,11 @@ struct rz_sysc_soc_id_init_data {
 /**
  * struct rz_sysc_init_data - RZ SYSC initialization data
  * @soc_id_init_data: RZ SYSC SoC ID initialization data
+ * @max_register: Maximum SYSC register offset to be used by the regmap config
  */
 struct rz_sysc_init_data {
 	const struct rz_sysc_soc_id_init_data *soc_id_init_data;
+	u32 max_register;
 };
 
 extern const struct rz_sysc_init_data rzg3e_sys_init_data;
-- 
2.43.0



From claudiu.beznea at tuxon.dev  Thu Aug  7 23:17:58 2025
From: claudiu.beznea at tuxon.dev (Claudiu)
Date: Fri,  8 Aug 2025 09:17:58 +0300
Subject: [PATCH v4 0/8] Add initial USB support for the Renesas RZ/G3S SoC
Message-ID: <20250808061806.2729274-1-claudiu.beznea.uj@bp.renesas.com>

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:
- patches 1/8		- add syscon regmap support to SYSC driver support; this
			  is necessary for the USB PHY CTRL driver to
			  set the PWRRDY in the SYSC address space
- patches 2-3/8		- fixes on bindings and driver for USB PHY
- patches 4-6/8		- updates the rzg2l-usbphy-ctrl driver and documentation
			  with support for setting PWRRDY though SYSC
- patches 7-8/12	- add device tree support

Merge strategy, if any:
- patches 1,7-8/8 can go through Renesas tree
- patches 2-3/8 can go through the PHY tree
- patches 4-6/8 can go through the reset tree

Thank you,
Claudiu Beznea

Changes in v4:
- replaced "renesas,sysc-signals" DT property with "renesas,sysc-pwrrdy"
- dropped the "renesas,sysc-signals" property from USB PHY (as proposed
  in v3) and let only the USB PHY CTRL driver to handle it as on RZ/G3S
  the USB PHY CTRL driver needs to be probed before any other USB driver
- dropped the signal abstraction from SYSC driver as there is no need
  for reference counting it now
- adjusted the "soc: renesas: rz-sysc: Add syscon/regmap support" to
  comply with the latest review comments

Changes in v3:
- as the basics of the SYSC driver was integrated, only the signal support
  was preserved in this series, in a separate patch; patch 01/12 was
  adjusted (by addressing the review comments received at [1]) as it is
  necessary to build the signal support on top of it
- after long discussions with the internal HW team it has been confirmed
  that the relation b/w individual USB specific HW blocks and signals
  is like:

                                   ????????????????????????????????
                                   ?                              ???? CPG_CLKON_USB.CLK0_ON
                                   ?     USB CH0                  ?
    ????????????????????????????   ?????????????????????????????? ???? CPG_CLKON_USB.CLK2_ON
    ?                 ??????????   ??host controller registers  ? ?
    ?                 ?        ?   ??function controller registers?
    ?                 ? PHY0   ?????????????????????????????????? ?
    ?     USB PHY     ?        ?   ????????????????????????????????
    ?                 ??????????                ?
    ?                          ?    CPG_BUS_PERI_COM_MSTOP.MSTOP{6, 5}_ON
    ????????????????? ??????????
    ??USBPHY control? ?        ?
    ??  registers   ? ? PHY1   ?   ????????????????????????????????
    ????????????????? ?        ?????     USB CH1                  ?
    ?                 ??????????   ?????????????????????????????? ???? CPG_CLKON_USB.CLK1_ON
    ????????????????????????????   ?? host controller registers ? ?
      ?       ?         ?          ?????????????????????????????? ?
      ?       ?         ?          ????????????????????????????????
      ?       ?         ?                       ?
      ?       ?         ?           CPG_BUS_PERI_COM_MSTOP.MSTOP7_ON
      ?PWRRDY ?         ?
      ?       ?   CPG_CLK_ON_USB.CLK3_ON
      ?       ?
      ?  CPG_BUS_PERI_COM_MSTOP.MSTOP4_ON
      ?
    ??????
    ?SYSC?
    ??????

  where:
  - CPG_CLKON_USB.CLK.CLKX_ON is the register bit controlling the clock X
      of different USB blocks, X in {0, 1, 2, 3}
  - CPG_BUS_PERI_COM_MSTOP.MSTOPX_ON is the register bit controlling the
    MSTOP of different USB blocks, X in {4, 5, 6, 7}
  - USB PHY is the USB PHY block exposing 2 ports, port0 and port1, used
    by the USB CH0, USB CH1
  - SYSC is the system controller block controlling the PWRRDY signal
  - USB CHx are individual USB block with host and function capabilities
    (USB CH0 have both host and function capabilities, USB CH1 has only
    host capabilities)

  Due to this, the PWRRDY signal was also passed to the reset-rzg2l-usbphy-ctrl
  reset driver (as it controls the USBPHY control registers) and these
  are in the USB PHY block controlled by PWRRDY signal.

  The PWRRDY signal need to be de-asserted on probe before enabling the module
  clocks and the module MSTOP. To avoid any violation of this configuration
  sequence, the PWRRDY signal is now controlled by USB PHY driver and the
  reset-rzg2l-usbphy-ctrl driver.

  As the PHYs gets reset signals from the USB reset controller driver, the
  reset-rzg2l-usbphy-ctrl is probed before the USB PHY driver and thus,
  in theory, we can drop the signal support (reference counting of the
  USB PWRRDY) and configure the USB PWRRDY just in the reset-rzg2l-usbphy-ctrl.

  However, to have a proper description of the diagram described above in 
  device tree and ensure the configuration sequence b/w PRWRDY, CLK and MSTOP
  is preserved, the PWRRDY signal is controlled in this series in all the
  drivers that work with registers from the USB PHY block.

  Please provide your feedback on this solution.

Thank you,
Claudiu

[1] https://lore.kernel.org/all/20250330214945.185725-2-john.madieu.xa at bp.renesas.com/

Changes in v2:
- dropped v1 patches already applied
- added fixes patches (07/14 and 09/14)
- dropped the approach of handling the USB PWRRDY though a reset controller
  driver and introduced the signal concept for the SYSC driver; because
  of this, most of the work done in v1 was dropped
- per patch changes are listed in individual patches, if any

Christophe JAILLET (1):
  phy: renesas: rcar-gen3-usb2: Fix an error handling path in
    rcar_gen3_phy_usb2_probe()

Claudiu Beznea (6):
  dt-bindings: phy: renesas,usb2-phy: Mark resets as required for RZ/G3S
  dt-bindings: reset: renesas,rzg2l-usbphy-ctrl: Document RZ/G3S support
  reset: rzg2l-usbphy-ctrl: Add support for USB PWRRDY
  reset: rzg2l-usbphy-ctrl: Add support for RZ/G3S SoC
  arm64: dts: renesas: r9a08g045: Add USB support
  arm64: dts: renesas: rzg3s-smarc: Enable USB support

John Madieu (1):
  soc: renesas: rz-sysc: Add syscon/regmap support

 .../bindings/phy/renesas,usb2-phy.yaml        |   1 +
 .../reset/renesas,rzg2l-usbphy-ctrl.yaml      |  40 +++++-
 arch/arm64/boot/dts/renesas/r9a08g045.dtsi    | 118 ++++++++++++++++++
 arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi  |  57 +++++++++
 drivers/phy/renesas/phy-rcar-gen3-usb2.c      |  11 +-
 drivers/reset/Kconfig                         |   1 +
 drivers/reset/reset-rzg2l-usbphy-ctrl.c       |  70 +++++++++++
 drivers/soc/renesas/Kconfig                   |   1 +
 drivers/soc/renesas/r9a08g045-sysc.c          |   1 +
 drivers/soc/renesas/r9a09g047-sys.c           |   1 +
 drivers/soc/renesas/r9a09g057-sys.c           |   1 +
 drivers/soc/renesas/rz-sysc.c                 |  29 ++++-
 drivers/soc/renesas/rz-sysc.h                 |   2 +
 13 files changed, 325 insertions(+), 8 deletions(-)

-- 
2.43.0



From claudiu.beznea at tuxon.dev  Thu Aug  7 23:18:00 2025
From: claudiu.beznea at tuxon.dev (Claudiu)
Date: Fri,  8 Aug 2025 09:18:00 +0300
Subject: [PATCH v4 2/8] dt-bindings: phy: renesas,usb2-phy: Mark resets as required for RZ/G3S
In-Reply-To: <20250808061806.2729274-1-claudiu.beznea.uj@bp.renesas.com>
References: <20250808061806.2729274-1-claudiu.beznea.uj@bp.renesas.com>
Message-ID: <20250808061806.2729274-3-claudiu.beznea.uj@bp.renesas.com>

From: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>

The reset lines are mandatory for the Renesas RZ/G3S platform and must be
explicitly defined in device tree.

Fixes: f3c849855114 ("dt-bindings: phy: renesas,usb2-phy: Document RZ/G3S phy bindings")
Reviewed-by: Geert Uytterhoeven <geert+renesas at glider.be>
Acked-by: Conor Dooley <conor.dooley at microchip.com>
Signed-off-by: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
---

Changes in v4:
- none

Changes in v3:
- collected tags
- rebased on top of latest version of renesas,usb2-phy.yaml;
  Conor, Geert: I kept your tags; please let me know if you consider it
  otherwise

Changes in v2:
- none; this patch is new

 Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml b/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml
index f45c5f039ae8..52d777057281 100644
--- a/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml
@@ -112,6 +112,7 @@ allOf:
           contains:
             enum:
               - renesas,usb2-phy-r9a09g057
+              - renesas,usb2-phy-r9a08g045
               - renesas,rzg2l-usb2-phy
     then:
       properties:
-- 
2.43.0



From claudiu.beznea at tuxon.dev  Thu Aug  7 23:18:02 2025
From: claudiu.beznea at tuxon.dev (Claudiu)
Date: Fri,  8 Aug 2025 09:18:02 +0300
Subject: [PATCH v4 4/8] dt-bindings: reset: renesas,rzg2l-usbphy-ctrl: Document RZ/G3S support
In-Reply-To: <20250808061806.2729274-1-claudiu.beznea.uj@bp.renesas.com>
References: <20250808061806.2729274-1-claudiu.beznea.uj@bp.renesas.com>
Message-ID: <20250808061806.2729274-5-claudiu.beznea.uj@bp.renesas.com>

From: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>

The Renesas USB PHY hardware block needs to have the PWRRDY bit in the
system controller set before applying any other settings. The PWRRDY bit
must be controlled during power-on, power-off, and system suspend/resume
sequences as follows:
- during power-on/resume, it must be set to zero before enabling clocks and
  modules
- during power-off/suspend, it must be set to one after disabling clocks
  and modules

Add the renesas,sysc-pwrrdy device tree property, which allows the
reset-rzg2l-usbphy-ctrl driver to parse, map, and control the system
controller PWRRDY bit at the appropriate time. Along with it add a new
compatible for the RZ/G3S SoC.

Signed-off-by: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
---

Changes in v4:
- dropped blank line from compatible section
- s/renesas,sysc-signals/renesas,sysc-pwrrdy/g
- dropped description from renesas,sysc-pwrrdy
- updated description of renesas,sysc-pwrrdy items
- updated patch description

Changes in v3:
- none; this patch is new

 .../reset/renesas,rzg2l-usbphy-ctrl.yaml      | 40 ++++++++++++++++---
 1 file changed, 34 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml b/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml
index b0b20af15313..c1d5f3228aa9 100644
--- a/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml
+++ b/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml
@@ -15,12 +15,14 @@ description:
 
 properties:
   compatible:
-    items:
-      - enum:
-          - renesas,r9a07g043-usbphy-ctrl # RZ/G2UL and RZ/Five
-          - renesas,r9a07g044-usbphy-ctrl # RZ/G2{L,LC}
-          - renesas,r9a07g054-usbphy-ctrl # RZ/V2L
-      - const: renesas,rzg2l-usbphy-ctrl
+    oneOf:
+      - items:
+          - enum:
+              - renesas,r9a07g043-usbphy-ctrl # RZ/G2UL and RZ/Five
+              - renesas,r9a07g044-usbphy-ctrl # RZ/G2{L,LC}
+              - renesas,r9a07g054-usbphy-ctrl # RZ/V2L
+          - const: renesas,rzg2l-usbphy-ctrl
+      - const: renesas,r9a08g045-usbphy-ctrl # RZ/G3S
 
   reg:
     maxItems: 1
@@ -48,6 +50,19 @@ properties:
     $ref: /schemas/regulator/regulator.yaml#
     unevaluatedProperties: false
 
+  renesas,sysc-pwrrdy:
+    description: The system controller PWRRDY indicates to the USB PHY if the
+                 power supply is ready. PWRRDY needs to be set during power-on
+                 before applying any other settings. It also needs to
+                 be set before powering off the USB.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    items:
+      - items:
+          - description: System controller phandle required by USB PHY CTRL
+                         driver to set PWRRDY
+          - description: Register offset associated with PWRRDY
+          - description: Register bitmask associated with PWRRDY
+
 required:
   - compatible
   - reg
@@ -57,6 +72,19 @@ required:
   - '#reset-cells'
   - regulator-vbus
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: renesas,r9a08g045-usbphy-ctrl
+    then:
+      required:
+        - renesas,sysc-pwrrdy
+    else:
+      properties:
+        renesas,sysc-pwrrdy: false
+
 additionalProperties: false
 
 examples:
-- 
2.43.0



From claudiu.beznea at tuxon.dev  Thu Aug  7 23:18:01 2025
From: claudiu.beznea at tuxon.dev (Claudiu)
Date: Fri,  8 Aug 2025 09:18:01 +0300
Subject: [PATCH v4 3/8] phy: renesas: rcar-gen3-usb2: Fix an error handling path in rcar_gen3_phy_usb2_probe()
In-Reply-To: <20250808061806.2729274-1-claudiu.beznea.uj@bp.renesas.com>
References: <20250808061806.2729274-1-claudiu.beznea.uj@bp.renesas.com>
Message-ID: <20250808061806.2729274-4-claudiu.beznea.uj@bp.renesas.com>

From: Christophe JAILLET <christophe.jaillet at 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>
Reviewed-by: Biju Das <biju.das.jz at bp.renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas at glider.be>
[claudiu.beznea: removed "struct reset_control *rstc = data;" from
 rcar_gen3_reset_assert()]
Signed-off-by: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
---

Changes in v4:
- none

Changes in v3:
- collected tags

Changes in v2:
- none; this patch is new; re-spinned the Christophe's work at
  https://lore.kernel.org/all/TYCPR01MB113329930BA5E2149C9BE2A1986672 at TYCPR01MB11332.jpnprd01.prod.outlook.com/


 drivers/phy/renesas/phy-rcar-gen3-usb2.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index 47beb94cd424..d61c171d454f 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -699,6 +699,11 @@ static enum usb_dr_mode rcar_gen3_get_dr_mode(struct device_node *np)
 	return candidate;
 }
 
+static void rcar_gen3_reset_assert(void *data)
+{
+	reset_control_assert(data);
+}
+
 static int rcar_gen3_phy_usb2_init_bus(struct rcar_gen3_chan *channel)
 {
 	struct device *dev = channel->dev;
@@ -717,6 +722,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;
@@ -860,7 +870,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.43.0



From claudiu.beznea at tuxon.dev  Thu Aug  7 23:18:03 2025
From: claudiu.beznea at tuxon.dev (Claudiu)
Date: Fri,  8 Aug 2025 09:18:03 +0300
Subject: [PATCH v4 5/8] reset: rzg2l-usbphy-ctrl: Add support for USB PWRRDY
In-Reply-To: <20250808061806.2729274-1-claudiu.beznea.uj@bp.renesas.com>
References: <20250808061806.2729274-1-claudiu.beznea.uj@bp.renesas.com>
Message-ID: <20250808061806.2729274-6-claudiu.beznea.uj@bp.renesas.com>

From: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>

On the Renesas RZ/G3S SoC, the USB PHY block has an input signal called
PWRRDY. This signal is managed by the system controller and must be
de-asserted after powering on the area where USB PHY resides and asserted
before powering it off.

On power-on the USB PWRRDY signal need to be de-asserted before enabling
clock and switching the module to normal state (through MSTOP support). The
power-on configuration sequence must be:

1/ PWRRDY=0
2/ CLK_ON=1
3/ MSTOP=0

On power-off the configuration sequence should be:

1/ MSTOP=1
2/ CLK_ON=0
3/ PWRRDY=1

The CLK_ON and MSTOP functionalities are controlled by clock drivers.

After long discussions with the internal HW team, it has been confirmed
that the HW connection b/w USB PHY block, the USB channels, the system
controller, clock, MSTOP, PWRRDY signal is as follows:

                               ????????????????????????????????
                               ?                              ???? CPG_CLKON_USB.CLK0_ON
                               ?     USB CH0                  ?
????????????????????????????   ?????????????????????????????? ???? CPG_CLKON_USB.CLK2_ON
?                 ??????????   ??host controller registers  ? ?
?                 ?        ?   ??function controller registers?
?                 ? PHY0   ?????????????????????????????????? ?
?     USB PHY     ?        ?   ????????????????????????????????
?                 ??????????                ?
?                          ?    CPG_BUS_PERI_COM_MSTOP.MSTOP{6, 5}_ON
????????????????? ??????????
??USHPHY control? ?        ?
??  registers   ? ? PHY1   ?   ????????????????????????????????
????????????????? ?        ?????     USB CH1                  ?
?                 ??????????   ?????????????????????????????? ???? CPG_CLKON_USB.CLK1_ON
????????????????????????????   ?? host controller registers ? ?
  ?       ?         ?          ?????????????????????????????? ?
  ?       ?         ?          ????????????????????????????????
  ?       ?         ?                       ?
  ?       ?         ?           CPG_BUS_PERI_COM_MSTOP.MSTOP7_ON
  ?PWRRDY ?         ?
  ?       ?   CPG_CLK_ON_USB.CLK3_ON
  ?       ?
  ?  CPG_BUS_PERI_COM_MSTOP.MSTOP4_ON
  ?
??????
?SYSC?
??????

where:
- CPG_CLKON_USB.CLK.CLKX_ON is the register bit controlling the clock X
  of different USB blocks, X in {0, 1, 2, 3}
- CPG_BUS_PERI_COM_MSTOP.MSTOPX_ON is the register bit controlling the
  MSTOP of different USB blocks, X in {4, 5, 6, 7}
- USB PHY is the USB PHY block exposing 2 ports, port0 and port1, used
  by the USB CH0, USB CH1
- SYSC is the system controller block controlling the PWRRDY signal
- USB CHx are individual USB block with host and function capabilities
  (USB CH0 have both host and function capabilities, USB CH1 has only
  host capabilities)

The USBPHY control registers are controlled though the
reset-rzg2l-usbphy-ctrl driver. The USB PHY ports are controlled by
phy_rcar_gen3_usb2 (drivers/phy/renesas/phy-rcar-gen3-usb2.c file). The
USB PHY ports request resets from the reset-rzg2l-usbphy-ctrl driver.

The connection b/w the system controller and the USB PHY CTRL driver is
implemented through the renesas,sysc-pwrrdy device tree property
proposed in this patch. This property specifies the register offset and the
bitmask required to control the PWRRDY signal.

Since the USB PHY CTRL driver needs to be probed before any other
USB-specific driver on RZ/G3S, control of PWRRDY is passed exclusively
to it. This guarantees the correct configuration sequence between clocks,
MSTOP bits, and the PWRRDY bit. At the same time, changes are kept minimal
by avoiding modifications to the USB PHY driver to also handle the PWRRDY
itself.

Signed-off-by: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
---

Changes in v4:
- updated patch description
- updated rzg2l_usbphy_ctrl_pwrrdy_init() to map directly the
  "renesas,sysc-pwrrdy" as the SYSC signal abstraction was dropped
  in this version, along with rz_sysc_get_signal_map()
- dropped priv member of rzg2l_usbphy_ctrl_pwrrdy_init() as it is
  not needed in this version
- shift left !power_on with pwrrdy->mask as this is how the
  regmap_update_bits() needs the last member to be
- selected MFD_SYSCON

Changes in v3:
- none; this patch is new

 drivers/reset/Kconfig                   |  1 +
 drivers/reset/reset-rzg2l-usbphy-ctrl.c | 66 +++++++++++++++++++++++++
 2 files changed, 67 insertions(+)

diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 635eef469ab7..3524b760dc1b 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -230,6 +230,7 @@ config RESET_RASPBERRYPI
 config RESET_RZG2L_USBPHY_CTRL
 	tristate "Renesas RZ/G2L USBPHY control driver"
 	depends on ARCH_RZG2L || COMPILE_TEST
+	select MFD_SYSCON
 	help
 	  Support for USBPHY Control found on RZ/G2L family. It mainly
 	  controls reset and power down of the USB/PHY.
diff --git a/drivers/reset/reset-rzg2l-usbphy-ctrl.c b/drivers/reset/reset-rzg2l-usbphy-ctrl.c
index 8a7f167e405e..fc14c41f5572 100644
--- a/drivers/reset/reset-rzg2l-usbphy-ctrl.c
+++ b/drivers/reset/reset-rzg2l-usbphy-ctrl.c
@@ -13,6 +13,7 @@
 #include <linux/regmap.h>
 #include <linux/reset.h>
 #include <linux/reset-controller.h>
+#include <linux/mfd/syscon.h>
 
 #define RESET			0x000
 #define VBENCTL			0x03c
@@ -41,6 +42,18 @@ struct rzg2l_usbphy_ctrl_priv {
 
 #define rcdev_to_priv(x)	container_of(x, struct rzg2l_usbphy_ctrl_priv, rcdev)
 
+/**
+ * struct rzg2l_usbphy_ctrl_pwrrdy - SYSC PWRRDY signal descriptor
+ * @regmap: SYSC regmap
+ * @offset: offset into the SYSC address space for accessing PWRRDY
+ * @mask: mask into the register at offset for accessing PWRRDY
+ */
+struct rzg2l_usbphy_ctrl_pwrrdy {
+	struct regmap *regmap;
+	u32 offset;
+	u32 mask;
+};
+
 static int rzg2l_usbphy_ctrl_assert(struct reset_controller_dev *rcdev,
 				    unsigned long id)
 {
@@ -91,6 +104,8 @@ static int rzg2l_usbphy_ctrl_status(struct reset_controller_dev *rcdev,
 	return !!(readl(priv->base + RESET) & port_mask);
 }
 
+#define RZG2L_USBPHY_CTRL_PWRRDY	1
+
 static const struct of_device_id rzg2l_usbphy_ctrl_match_table[] = {
 	{ .compatible = "renesas,rzg2l-usbphy-ctrl" },
 	{ /* Sentinel */ }
@@ -110,6 +125,53 @@ static const struct regmap_config rzg2l_usb_regconf = {
 	.max_register = 1,
 };
 
+static void rzg2l_usbphy_ctrl_set_pwrrdy(struct rzg2l_usbphy_ctrl_pwrrdy *pwrrdy,
+					 bool power_on)
+{
+	regmap_update_bits(pwrrdy->regmap, pwrrdy->offset, pwrrdy->mask,
+			   !power_on << pwrrdy->mask);
+}
+
+static void rzg2l_usbphy_ctrl_pwrrdy_off(void *data)
+{
+	rzg2l_usbphy_ctrl_set_pwrrdy(data, false);
+}
+
+static int rzg2l_usbphy_ctrl_pwrrdy_init(struct device *dev)
+{
+	struct rzg2l_usbphy_ctrl_pwrrdy *pwrrdy;
+	struct of_phandle_args args;
+	struct regmap *regmap;
+	const int *data;
+	int ret;
+
+	data = device_get_match_data(dev);
+	if (data != (int *)RZG2L_USBPHY_CTRL_PWRRDY)
+		return 0;
+
+	ret = of_parse_phandle_with_fixed_args(dev->of_node, "renesas,sysc-pwrrdy", 2,
+					       0, &args);
+	if (ret)
+		return ret;
+
+	regmap = syscon_node_to_regmap(args.np);
+	of_node_put(args.np);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	pwrrdy = devm_kzalloc(dev, sizeof(*pwrrdy), GFP_KERNEL);
+	if (!pwrrdy)
+		return -ENOMEM;
+
+	pwrrdy->regmap = regmap;
+	pwrrdy->offset = args.args[0];
+	pwrrdy->mask = args.args[1];
+
+	rzg2l_usbphy_ctrl_set_pwrrdy(pwrrdy, true);
+
+	return devm_add_action_or_reset(dev, rzg2l_usbphy_ctrl_pwrrdy_off, pwrrdy);
+}
+
 static int rzg2l_usbphy_ctrl_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -132,6 +194,10 @@ static int rzg2l_usbphy_ctrl_probe(struct platform_device *pdev)
 	if (IS_ERR(regmap))
 		return PTR_ERR(regmap);
 
+	error = rzg2l_usbphy_ctrl_pwrrdy_init(dev);
+	if (error)
+		return error;
+
 	priv->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
 	if (IS_ERR(priv->rstc))
 		return dev_err_probe(dev, PTR_ERR(priv->rstc),
-- 
2.43.0



From claudiu.beznea at tuxon.dev  Thu Aug  7 23:18:04 2025
From: claudiu.beznea at tuxon.dev (Claudiu)
Date: Fri,  8 Aug 2025 09:18:04 +0300
Subject: [PATCH v4 6/8] reset: rzg2l-usbphy-ctrl: Add support for RZ/G3S SoC
In-Reply-To: <20250808061806.2729274-1-claudiu.beznea.uj@bp.renesas.com>
References: <20250808061806.2729274-1-claudiu.beznea.uj@bp.renesas.com>
Message-ID: <20250808061806.2729274-7-claudiu.beznea.uj@bp.renesas.com>

From: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>

The Renesas RZ/G3S SoC USB PHY HW block receives as input the USB PWRRDY
signal from the system controller. Add support for the Renesas RZ/G3S SoC.

Signed-off-by: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
---

Changes in v4:
- none

Changes in v3:
- none; this patch is new

 drivers/reset/reset-rzg2l-usbphy-ctrl.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/reset/reset-rzg2l-usbphy-ctrl.c b/drivers/reset/reset-rzg2l-usbphy-ctrl.c
index fc14c41f5572..8aa2a5833c2e 100644
--- a/drivers/reset/reset-rzg2l-usbphy-ctrl.c
+++ b/drivers/reset/reset-rzg2l-usbphy-ctrl.c
@@ -108,6 +108,10 @@ static int rzg2l_usbphy_ctrl_status(struct reset_controller_dev *rcdev,
 
 static const struct of_device_id rzg2l_usbphy_ctrl_match_table[] = {
 	{ .compatible = "renesas,rzg2l-usbphy-ctrl" },
+	{
+		.compatible = "renesas,r9a08g045-usbphy-ctrl",
+		.data = (void *)RZG2L_USBPHY_CTRL_PWRRDY
+	},
 	{ /* Sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, rzg2l_usbphy_ctrl_match_table);
-- 
2.43.0



From claudiu.beznea at tuxon.dev  Thu Aug  7 23:18:05 2025
From: claudiu.beznea at tuxon.dev (Claudiu)
Date: Fri,  8 Aug 2025 09:18:05 +0300
Subject: [PATCH v4 7/8] arm64: dts: renesas: r9a08g045: Add USB support
In-Reply-To: <20250808061806.2729274-1-claudiu.beznea.uj@bp.renesas.com>
References: <20250808061806.2729274-1-claudiu.beznea.uj@bp.renesas.com>
Message-ID: <20250808061806.2729274-8-claudiu.beznea.uj@bp.renesas.com>

From: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>

Add USB nodes for the Renesas RZ/G3S SoC. This consists of PHY reset,
host and device support.

Signed-off-by: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
---

Changes in v4:
- dropped renesas,sysc-signals from usb2_phy0, usb2_phy1 nodes
- s/renesas,sysc-signals/renesas,sysc-pwrrdy/g

Changes in v3:
- changed the nodes order to keep similar nodes toghether

Changes in v2:
- this was patch 14/16 in v1
- added renesas,sysc-signal properties to USB PHYs
- collected tags
- Geert: I kept your tag; please let me know if you consider otherwise 

 arch/arm64/boot/dts/renesas/r9a08g045.dtsi | 118 +++++++++++++++++++++
 1 file changed, 118 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r9a08g045.dtsi b/arch/arm64/boot/dts/renesas/r9a08g045.dtsi
index 0364f89776e6..b7ad6db0174b 100644
--- a/arch/arm64/boot/dts/renesas/r9a08g045.dtsi
+++ b/arch/arm64/boot/dts/renesas/r9a08g045.dtsi
@@ -681,6 +681,124 @@ eth1: ethernet at 11c40000 {
 			status = "disabled";
 		};
 
+		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-domains = <&cpg>;
+			#reset-cells = <1>;
+			renesas,sysc-pwrrdy = <&sysc 0xd70 0x1>;
+			status = "disabled";
+
+			usb0_vbus_otg: regulator-vbus {
+				regulator-name = "vbus";
+			};
+		};
+
+		ohci0: usb at 11e10000 {
+			compatible = "generic-ohci";
+			reg = <0 0x11e10000 0 0x100>;
+			interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A08G045_USB_PCLK>,
+				 <&cpg CPG_MOD R9A08G045_USB_U2H0_HCLK>;
+			resets = <&phyrst 0>,
+				 <&cpg R9A08G045_USB_U2H0_HRESETN>;
+			phys = <&usb2_phy0 1>;
+			phy-names = "usb";
+			power-domains = <&cpg>;
+			status = "disabled";
+		};
+
+		ohci1: usb at 11e30000 {
+			compatible = "generic-ohci";
+			reg = <0 0x11e30000 0 0x100>;
+			interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A08G045_USB_PCLK>,
+				 <&cpg CPG_MOD R9A08G045_USB_U2H1_HCLK>;
+			resets = <&phyrst 1>,
+				 <&cpg R9A08G045_USB_U2H1_HRESETN>;
+			phys = <&usb2_phy1 1>;
+			phy-names = "usb";
+			power-domains = <&cpg>;
+			status = "disabled";
+		};
+
+		ehci0: usb at 11e10100 {
+			compatible = "generic-ehci";
+			reg = <0 0x11e10100 0 0x100>;
+			interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A08G045_USB_PCLK>,
+				 <&cpg CPG_MOD R9A08G045_USB_U2H0_HCLK>;
+			resets = <&phyrst 0>,
+				 <&cpg R9A08G045_USB_U2H0_HRESETN>;
+			phys = <&usb2_phy0 2>;
+			phy-names = "usb";
+			companion = <&ohci0>;
+			power-domains = <&cpg>;
+			status = "disabled";
+		};
+
+		ehci1: usb at 11e30100 {
+			compatible = "generic-ehci";
+			reg = <0 0x11e30100 0 0x100>;
+			interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A08G045_USB_PCLK>,
+				 <&cpg CPG_MOD R9A08G045_USB_U2H1_HCLK>;
+			resets = <&phyrst 1>,
+				 <&cpg R9A08G045_USB_U2H1_HRESETN>;
+			phys = <&usb2_phy1 2>;
+			phy-names = "usb";
+			companion = <&ohci1>;
+			power-domains = <&cpg>;
+			status = "disabled";
+		};
+
+		usb2_phy0: usb-phy at 11e10200 {
+			compatible = "renesas,usb2-phy-r9a08g045";
+			reg = <0 0x11e10200 0 0x700>;
+			interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A08G045_USB_PCLK>,
+				 <&cpg CPG_MOD R9A08G045_USB_U2H0_HCLK>;
+			resets = <&phyrst 0>,
+				 <&cpg R9A08G045_USB_U2H0_HRESETN>;
+			#phy-cells = <1>;
+			power-domains = <&cpg>;
+			status = "disabled";
+		};
+
+		usb2_phy1: usb-phy at 11e30200 {
+			compatible = "renesas,usb2-phy-r9a08g045";
+			reg = <0 0x11e30200 0 0x700>;
+			interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A08G045_USB_PCLK>,
+				 <&cpg CPG_MOD R9A08G045_USB_U2H1_HCLK>;
+			resets = <&phyrst 1>,
+				 <&cpg R9A08G045_USB_U2H1_HRESETN>;
+			#phy-cells = <1>;
+			power-domains = <&cpg>;
+			status = "disabled";
+		};
+
+		hsusb: usb at 11e20000 {
+			compatible = "renesas,usbhs-r9a08g045",
+				     "renesas,rzg2l-usbhs";
+			reg = <0 0x11e20000 0 0x10000>;
+			interrupts = <GIC_SPI 85 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A08G045_USB_PCLK>,
+				 <&cpg CPG_MOD R9A08G045_USB_U2P_EXR_CPUCLK>;
+			resets = <&phyrst 0>,
+				 <&cpg R9A08G045_USB_U2P_EXL_SYSRST>;
+			renesas,buswait = <7>;
+			phys = <&usb2_phy0 3>;
+			phy-names = "usb";
+			power-domains = <&cpg>;
+			status = "disabled";
+		};
+
 		gic: interrupt-controller at 12400000 {
 			compatible = "arm,gic-v3";
 			#interrupt-cells = <3>;
-- 
2.43.0



From claudiu.beznea at tuxon.dev  Thu Aug  7 23:18:06 2025
From: claudiu.beznea at tuxon.dev (Claudiu)
Date: Fri,  8 Aug 2025 09:18:06 +0300
Subject: [PATCH v4 8/8] arm64: dts: renesas: rzg3s-smarc: Enable USB support
In-Reply-To: <20250808061806.2729274-1-claudiu.beznea.uj@bp.renesas.com>
References: <20250808061806.2729274-1-claudiu.beznea.uj@bp.renesas.com>
Message-ID: <20250808061806.2729274-9-claudiu.beznea.uj@bp.renesas.com>

From: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>

Enable USB support (host, device, USB PHYs).

Reviewed-by: Geert Uytterhoeven <geert+renesas at glider.be>
Signed-off-by: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
---

Changes in v4:
- none

Changes in v3:
- collected tags

Changes in v2:
- this was patch 15/16 in v1:
- dropped sysc enablement as it is now done in SoC dtsi file

 arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi | 57 ++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi b/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi
index 5e044a4d0234..5586dd43c4d5 100644
--- a/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi
+++ b/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi
@@ -92,6 +92,20 @@ &audio_clk2 {
 	clock-frequency = <12288000>;
 };
 
+&ehci0 {
+	dr_mode = "otg";
+	status = "okay";
+};
+
+&ehci1 {
+	status = "okay";
+};
+
+&hsusb {
+	dr_mode = "otg";
+	status = "okay";
+};
+
 &i2c0 {
 	status = "okay";
 
@@ -132,6 +146,15 @@ power-monitor at 44 {
 	};
 };
 
+&ohci0 {
+	dr_mode = "otg";
+	status = "okay";
+};
+
+&ohci1 {
+	status = "okay";
+};
+
 &pinctrl {
 	audio_clock_pins: audio-clock {
 		pins = "AUDIO_CLK1", "AUDIO_CLK2";
@@ -207,6 +230,27 @@ ssi3_pins: ssi3 {
 			 <RZG2L_PORT_PINMUX(18, 4, 8)>, /* TXD */
 			 <RZG2L_PORT_PINMUX(18, 5, 8)>; /* RXD */
 	};
+
+	usb0_pins: usb0 {
+		peri {
+			pinmux = <RZG2L_PORT_PINMUX(5, 0, 1)>, /* VBUS */
+				 <RZG2L_PORT_PINMUX(5, 2, 1)>; /* OVC */
+		};
+
+		otg {
+			pinmux = <RZG2L_PORT_PINMUX(5, 3, 1)>; /* OTG_ID */
+			bias-pull-up;
+		};
+	};
+
+	usb1_pins: usb1 {
+		pinmux = <RZG2L_PORT_PINMUX(5, 4, 5)>, /* OVC */
+			 <RZG2L_PORT_PINMUX(6, 0, 1)>; /* VBUS */
+	};
+};
+
+&phyrst {
+	status = "okay";
 };
 
 &scif0 {
@@ -242,3 +286,16 @@ &ssi3 {
 	pinctrl-0 = <&ssi3_pins>, <&audio_clock_pins>;
 	status = "okay";
 };
+
+&usb2_phy0 {
+	pinctrl-0 = <&usb0_pins>;
+	pinctrl-names = "default";
+	vbus-supply = <&usb0_vbus_otg>;
+	status = "okay";
+};
+
+&usb2_phy1 {
+	pinctrl-0 = <&usb1_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+};
-- 
2.43.0



From krzk at kernel.org  Thu Aug  7 23:47:48 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 8 Aug 2025 08:47:48 +0200
Subject: [PATCH v2 3/3] dt-bindings: phy: rockchip,pcie3-phy: add
 rockchip,phy-ref-use-pad
In-Reply-To: <CAAEEuhpHmW9hji91tbQ3MMhBZELCYc_vA+Ra3oC2W+Rf8LLC6w@mail.gmail.com>
References: <20250806133824.525871-1-rick.wertenbroek@gmail.com>
 <20250806133824.525871-4-rick.wertenbroek@gmail.com>
 <20250807-inquisitive-speedy-rooster-0a8488@kuoka>
 <c86bcdf0-f692-4263-a597-f8e36a53e8d9@kernel.org>
 <CAAEEuhpHmW9hji91tbQ3MMhBZELCYc_vA+Ra3oC2W+Rf8LLC6w@mail.gmail.com>
Message-ID: <20250808-ubiquitous-persimmon-llama-ff350e@kuoka>

On Thu, Aug 07, 2025 at 10:47:18AM +0200, Rick Wertenbroek wrote:
> On Thu, Aug 7, 2025 at 9:55?AM Krzysztof Kozlowski <krzk at kernel.org> wrote:
> >
> > On 07/08/2025 09:54, Krzysztof Kozlowski wrote:
> > > On Wed, Aug 06, 2025 at 03:38:23PM +0200, Rick Wertenbroek wrote:
> > >> >From the RK3588 Technical Reference Manual, Part1,
> > >> section 6.19 PCIe3PHY_GRF Register Description: "ref_use_pad"
> > >>
> > >> "Select reference clock connected to ref_pad_clk_p/ref_pad_clk_m.
> > >> Selects the external ref_pad_clk_p and ref_pad_clk_m inputs as the
> > >> reference clock source when asserted. When de-asserted, ref_alt_clk_p
> > >> and ref_alt_clk_m are the sources of the reference clock."
> > >>
> > >> The hardware reset value for this field is 0x1 (enabled).
> > >> Note that this register field is only available on RK3588, not on RK3568.
> > >
> > > Then you miss restricting it (:false) in one of if:then: blocks.
> > >
> > > Also, binding cannot be after the user. You need to reorder patches.
> > >
> > > ...
> > >
> > >>
> > >> +  rockchip,phy-ref-use-pad:
> > >> +    description: which PHY should use the external pad as PCIe reference clock.
> > >> +      1 means use pad (default), 0 means use internal clock (PLL_PPLL).
> > >
> > > Can't you deduce it from the presence of clock inputs? IOW, if the
> > > clocks are physically connected, is it even reasonable or possible to
> > > use internal clock?
> 
> Thank you Krzysztof,
> But no, if there is no clock, the driver deadlocks, it needs a clock
> to probe correctly.
> 
> When there is a clock physically connected on the pad, you can still
> choose to use it or use the internal clock, this is no problem.

Why would use internal clock for such case? In few other cases this
appeared we usualyl were using the presence of the clock as determining
factor.

> The problem is when you have no clock on the pad (as it defaults to
> using the pad) and the loading the driver deadlocks the system...

This sounds like a driver, not a binding, problem.

> 
> > >
> > >> +    $ref: /schemas/types.yaml#/definitions/uint32-array
> > >> +    minItems: 2
> > >> +    maxItems: 2
> > >> +    items:
> > >> +      minimum: 0
> > >> +      maximum: 1
> > >
> > > More precise:
> > >
> > > items:
> > >   - description: PHY0 reference clock config
> > >   - description: PHY1 reference clock config
> > >   enum: [ 0, 1 ]
> >
> > Eh, no, rather if this stays as int:
> >
> >     items:
> >       - description: PHY0 reference clock config
> >         enum: [ 0, 1 ]
> >       - description: PHY1 reference clock config
> >         enum: [ 0, 1 ]
> >     default: [ 1, 1 ]
> >
> >
> > > default: [ 1, 1 ]
> > >
> > > Anyway, default 1, 1 is pretty non-obvious, so this should be just
> > > non-unique-string-array (and property should be like
> > > rockchip,phy-ref-clk-source/sel).
> > >
> > >
> > > Best regards,
> > > Krzysztof
> > >
> >
> >
> > Best regards,
> > Krzysztof
> 
> I based my patch on patch :
> 46492d10067660785a09db4ce9244545126a17b8
> dt-bindings: phy: rockchip,pcie3-phy: add rockchip,rx-common-refclk-mode
> 
> As the option I add is extremely similar, it sets a feature in one of
> the PHY registers and only applies to RK3588.
> That is why I used the same style as rockchip,rx-common-refclk-mode.

So you should have used for example same property.

> 
> Wouldn't it be confusing or at least incoherent to use enum for
> rockchip,phy-ref-use-pad but not for rx-common-refclk-mode ?

Same hardware properties should have same properties - type, name and
meaning - but you did not re-use existing one. Maybe it is too specific?

We do not write properties for registers, but for hardware (like SoC or
board) characteristics.

Best regards,
Krzysztof



From krzk at kernel.org  Fri Aug  8 00:25:49 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 8 Aug 2025 09:25:49 +0200
Subject: [PATCH V1 4/4] phy: qcom-qmp-ufs: read max-microamp values from
 device tree
In-Reply-To: <52625e59-c7d0-45d1-8af3-d9958c5ef01a@quicinc.com>
References: <fe2bc07c-8fe9-47fd-bcd7-c2f0ebbd596f@sirena.org.uk>
 <aed1de56-fafe-4ccc-b542-69400b574def@oss.qualcomm.com>
 <acf89420-743b-4178-ac05-d4ca492bfee3@sirena.org.uk>
 <599b8a4b-324a-4543-ba27-0451f05c3dfd@quicinc.com>
 <3aa82f65-4812-4bf0-9323-96f40824a004@sirena.org.uk>
 <685e3d36-c0e3-4faa-b817-aecc15976a25@quicinc.com>
 <c1435858-6288-4525-8c92-e27ed86cb55e@sirena.org.uk>
 <31461227-3f3a-4316-9c8a-c851209d0278@quicinc.com>
 <4efc8a3a-ceb6-40dc-b877-328b86348e0b@sirena.org.uk>
 <52625e59-c7d0-45d1-8af3-d9958c5ef01a@quicinc.com>
Message-ID: <20250808-unbiased-classy-heron-cd7f3f@kuoka>

On Fri, Aug 08, 2025 at 02:15:31AM +0530, Nitin Rawat wrote:
> 
> 
> On 8/8/2025 12:15 AM, Mark Brown wrote:
> > On Thu, Aug 07, 2025 at 11:26:17PM +0530, Nitin Rawat wrote:
> > 
> > > 1. Regulator and PMIC configurations are board-specific, meaning they can
> > > vary significantly across different platforms. For example, some boards may
> > > use different generations of UFS devices ? such as UFS 2.x ? which come with
> > > distinct power and load requirements and some with UFS3.x which has it own
> > > power/load requirement.
> > 
> > Requirements from generations of UFS devices presumably come from the
> > UFS spec and should just be known though?
> > 
> > > 2. UFS PHY load and PMIC requirements also varies across targets, depending
> > > on the underlying technology node and the specific PHY capabilities. These
> > > differences can be influenced by the MIPI version or other implementation
> > > details.
> > 
> > If you've got non-enumerable PHYs that have a big impact that's a much
> > clearer use case for putting things in DT.
> 
> What I meant is that different boards may use different UFS parts, and the
> associated PHY load requirements are not governed by the UFS specification
> itself. Instead, these requirements depend on our specific PHY design and
> MIPI, which can vary across platforms.

The UFS controller knows which device it has attached - 2.x or 3.x - so
power considerations are known to the driver.

> 
> Because these characteristics ? such as load requirements ? are not
> enumerable or automatically detectable, it makes sense to describe them
> explicitly in the device tree. This approach ensures that board-specific
> variations are accurately captured without hardcoding them into the driver.

But you never came with rationale why given board has that value.

All this is done ONLY because downstream has it.

Best regards,
Krzysztof



From krzk at kernel.org  Fri Aug  8 00:28:04 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 8 Aug 2025 09:28:04 +0200
Subject: [PATCH V1 1/4] dt-bindings: phy: Add max-microamp properties for
 PHY and PLL supplies
In-Reply-To: <20250806154340.20122-2-quic_nitirawa@quicinc.com>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
 <20250806154340.20122-2-quic_nitirawa@quicinc.com>
Message-ID: <20250808-spiffy-vegan-boa-c24dd4@kuoka>

On Wed, Aug 06, 2025 at 09:13:37PM +0530, Nitin Rawat wrote:
> Add two new optional properties to the SC8280XP QMP UFS PHY
> device tree binding:
> 
> - `vdda-phy-max-microamp`: Specifies the maximum current (in microamps)
> 			   that can be drawn from the PHY supply.
> - `vdda-pll-max-microamp`: Specifies the maximum current (in microamps)
> 			   that can be drawn from the PLL supply.

How much you can draw from some supply is not a property of the device,
but that supply, so to me this is really oddly named.

Anyway, discussion is going in driver patch.

Best regards,
Krzysztof



From krzk at kernel.org  Fri Aug  8 00:29:16 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 8 Aug 2025 09:29:16 +0200
Subject: [PATCH V1 2/4] arm64: dts: qcom: sm8750: add max-microamp for
 UFS PHY and PLL supplies
In-Reply-To: <20250806154340.20122-3-quic_nitirawa@quicinc.com>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
 <20250806154340.20122-3-quic_nitirawa@quicinc.com>
Message-ID: <20250808-calm-boa-of-swiftness-a4a7ce@kuoka>

On Wed, Aug 06, 2025 at 09:13:38PM +0530, Nitin Rawat wrote:
> Add `vdda-phy-max-microamp` and `vdda-pll-max-microamp` properties to
> the UFS PHY node in the device tree.
> 
> These properties define the maximum current (in microamps) expected
> from the PHY and PLL regulators. This allows the PHY driver to
> configure regulator load accurately and ensure proper regulator
> mode based on load requirements.

That's not the property of phy, but regulator.

Also reasoning is here incomplete - you just post downstream code. :/

Best regards,
Krzysztof



From konrad.dybcio at oss.qualcomm.com  Fri Aug  8 01:58:20 2025
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Fri, 8 Aug 2025 10:58:20 +0200
Subject: [PATCH V1 2/4] arm64: dts: qcom: sm8750: add max-microamp for UFS
 PHY and PLL supplies
In-Reply-To: <20250808-calm-boa-of-swiftness-a4a7ce@kuoka>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
 <20250806154340.20122-3-quic_nitirawa@quicinc.com>
 <20250808-calm-boa-of-swiftness-a4a7ce@kuoka>
Message-ID: <9af71063-0629-4ccc-bc76-3fb588677bf4@oss.qualcomm.com>

On 8/8/25 9:29 AM, Krzysztof Kozlowski wrote:
> On Wed, Aug 06, 2025 at 09:13:38PM +0530, Nitin Rawat wrote:
>> Add `vdda-phy-max-microamp` and `vdda-pll-max-microamp` properties to
>> the UFS PHY node in the device tree.
>>
>> These properties define the maximum current (in microamps) expected
>> from the PHY and PLL regulators. This allows the PHY driver to
>> configure regulator load accurately and ensure proper regulator
>> mode based on load requirements.
> 
> That's not the property of phy, but regulator.
> 
> Also reasoning is here incomplete - you just post downstream code. :/

The reason for this change is good, but perhaps not explained clearly

All of these values refer to the maximum current draw that needs to be
allocated on a shared voltage supply for this peripheral (because the
supply's capabilities change depending on the maximum potential load
at any given time, which the regulator driver must be aware of)

This is a property of a regulator *consumer*, i.e. if we had a chain
of LEDs hanging off of this supply, we'd need to specify NUM_LEDS * 
MAX_CURR under the "led chain" device, to make sure that if the
aggregated current requirements go over a certain threshold (which is
unknown to Linux and hidden in RPMh fw), the regulator can be
reconfigured to allow for a higher current draw (likely at some
downgrade to efficiency)

Konrad


From geert at linux-m68k.org  Fri Aug  8 02:29:06 2025
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Fri, 8 Aug 2025 11:29:06 +0200
Subject: [PATCH v4 1/8] soc: renesas: rz-sysc: Add syscon/regmap support
In-Reply-To: <20250808061806.2729274-2-claudiu.beznea.uj@bp.renesas.com>
References: <20250808061806.2729274-1-claudiu.beznea.uj@bp.renesas.com> <20250808061806.2729274-2-claudiu.beznea.uj@bp.renesas.com>
Message-ID: <CAMuHMdUsFFd+orb17oQqoEidzYWMRjPoqMyzpgrdnicc=MRSYQ@mail.gmail.com>

Hi Claudiu,

On Fri, 8 Aug 2025 at 08:18, Claudiu <claudiu.beznea at tuxon.dev> wrote:
> From: John Madieu <john.madieu.xa at bp.renesas.com>
>
> The RZ/G3E system controller has various registers that control or report
> some properties specific to individual IPs. The regmap is registered as a
> syscon device to allow these IP drivers to access the registers through the
> regmap API.
>
> As other RZ SoCs might have custom read/write callbacks or max-offsets,
> register a custom regmap configuration.
>
> Signed-off-by: John Madieu <john.madieu.xa at bp.renesas.com>
> [claudiu.beznea:
>  - do not check the match->data validity in rz_sysc_probe() as it is
>    always valid
>  - dinamically allocate regmap_cfg]
> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
> ---
>
> Changes in v4:
> - adjusted the patch description by dropping "add" from
>   "add register a custom regmap configuration"
> - updated the list of changes from Claudiu Beznea
> - dynamically allocate the regmap_config as proposed at [2]
> - this patch is needed for proper function of USB (as proposed in this
>   series) that being the reason it is introduced here, as well
>
> [2] https://lore.kernel.org/all/CAMuHMdVyf3Xtpw=LWHrnD2CVQX4xYm=FBHvY_dx9OesHDz5zNg at mail.gmail.com/

Thanks for the update!

> --- a/drivers/soc/renesas/rz-sysc.c
> +++ b/drivers/soc/renesas/rz-sysc.c
=
> @@ -117,7 +125,26 @@ static int rz_sysc_probe(struct platform_device *pdev)
>                 return PTR_ERR(sysc->base);
>
>         sysc->dev = dev;
> -       return rz_sysc_soc_init(sysc, match);
> +       ret = rz_sysc_soc_init(sysc, match);
> +       if (ret)
> +               return ret;
> +
> +       regmap_cfg = devm_kzalloc(dev, sizeof(*regmap_cfg), GFP_KERNEL);
> +       if (!regmap_cfg)
> +               return -ENOMEM;

Is there any specific reason you decided to allocate regmap_cfg
separately, instead of embedding it into struct rz_sysc?

The rest LGTM.

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 krzk at kernel.org  Fri Aug  8 02:39:20 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 8 Aug 2025 11:39:20 +0200
Subject: [PATCH V1 2/4] arm64: dts: qcom: sm8750: add max-microamp for UFS
 PHY and PLL supplies
In-Reply-To: <9af71063-0629-4ccc-bc76-3fb588677bf4@oss.qualcomm.com>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
 <20250806154340.20122-3-quic_nitirawa@quicinc.com>
 <20250808-calm-boa-of-swiftness-a4a7ce@kuoka>
 <9af71063-0629-4ccc-bc76-3fb588677bf4@oss.qualcomm.com>
Message-ID: <292907f3-25d6-40d9-be6e-b6b83e646d73@kernel.org>

On 08/08/2025 10:58, Konrad Dybcio wrote:
> On 8/8/25 9:29 AM, Krzysztof Kozlowski wrote:
>> On Wed, Aug 06, 2025 at 09:13:38PM +0530, Nitin Rawat wrote:
>>> Add `vdda-phy-max-microamp` and `vdda-pll-max-microamp` properties to
>>> the UFS PHY node in the device tree.
>>>
>>> These properties define the maximum current (in microamps) expected
>>> from the PHY and PLL regulators. This allows the PHY driver to
>>> configure regulator load accurately and ensure proper regulator
>>> mode based on load requirements.
>>
>> That's not the property of phy, but regulator.
>>
>> Also reasoning is here incomplete - you just post downstream code. :/
> 
> The reason for this change is good, but perhaps not explained clearly
> 
> All of these values refer to the maximum current draw that needs to be
> allocated on a shared voltage supply for this peripheral (because the


It sounds very different than how much it can be drawn. How much can be
drawn is the property of the regulator. The regulator knows how much
current it can support.


> supply's capabilities change depending on the maximum potential load
> at any given time, which the regulator driver must be aware of)
> 
> This is a property of a regulator *consumer*, i.e. if we had a chain
> of LEDs hanging off of this supply, we'd need to specify NUM_LEDS * 
> MAX_CURR under the "led chain" device, to make sure that if the
> aggregated current requirements go over a certain threshold (which is
> unknown to Linux and hidden in RPMh fw), the regulator can be
> reconfigured to allow for a higher current draw (likely at some
> downgrade to efficiency)


The problem is that rationale is downstream. Instead I want to see some
reason: e.g. datasheets, spec, type of UFS device (that was the argument
in the driver patch discussion).

The only argument here for given value is: downstream has it.

Best regards,
Krzysztof


From claudiu.beznea at tuxon.dev  Fri Aug  8 03:32:03 2025
From: claudiu.beznea at tuxon.dev (Claudiu Beznea)
Date: Fri, 8 Aug 2025 13:32:03 +0300
Subject: [PATCH v4 1/8] soc: renesas: rz-sysc: Add syscon/regmap support
In-Reply-To: <CAMuHMdUsFFd+orb17oQqoEidzYWMRjPoqMyzpgrdnicc=MRSYQ@mail.gmail.com>
References: <20250808061806.2729274-1-claudiu.beznea.uj@bp.renesas.com>
 <20250808061806.2729274-2-claudiu.beznea.uj@bp.renesas.com>
 <CAMuHMdUsFFd+orb17oQqoEidzYWMRjPoqMyzpgrdnicc=MRSYQ@mail.gmail.com>
Message-ID: <cbdfa6fd-e65b-45d7-a21f-3bfdd46af332@tuxon.dev>

Hi, Geert,

On 08.08.2025 12:29, Geert Uytterhoeven wrote:
> Hi Claudiu,
> 
> On Fri, 8 Aug 2025 at 08:18, Claudiu <claudiu.beznea at tuxon.dev> wrote:
>> From: John Madieu <john.madieu.xa at bp.renesas.com>
>>
>> The RZ/G3E system controller has various registers that control or report
>> some properties specific to individual IPs. The regmap is registered as a
>> syscon device to allow these IP drivers to access the registers through the
>> regmap API.
>>
>> As other RZ SoCs might have custom read/write callbacks or max-offsets,
>> register a custom regmap configuration.
>>
>> Signed-off-by: John Madieu <john.madieu.xa at bp.renesas.com>
>> [claudiu.beznea:
>>  - do not check the match->data validity in rz_sysc_probe() as it is
>>    always valid
>>  - dinamically allocate regmap_cfg]
>> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
>> ---
>>
>> Changes in v4:
>> - adjusted the patch description by dropping "add" from
>>   "add register a custom regmap configuration"
>> - updated the list of changes from Claudiu Beznea
>> - dynamically allocate the regmap_config as proposed at [2]
>> - this patch is needed for proper function of USB (as proposed in this
>>   series) that being the reason it is introduced here, as well
>>
>> [2] https://lore.kernel.org/all/CAMuHMdVyf3Xtpw=LWHrnD2CVQX4xYm=FBHvY_dx9OesHDz5zNg at mail.gmail.com/
> 
> Thanks for the update!
> 
>> --- a/drivers/soc/renesas/rz-sysc.c
>> +++ b/drivers/soc/renesas/rz-sysc.c
> =
>> @@ -117,7 +125,26 @@ static int rz_sysc_probe(struct platform_device *pdev)
>>                 return PTR_ERR(sysc->base);
>>
>>         sysc->dev = dev;
>> -       return rz_sysc_soc_init(sysc, match);
>> +       ret = rz_sysc_soc_init(sysc, match);
>> +       if (ret)
>> +               return ret;
>> +
>> +       regmap_cfg = devm_kzalloc(dev, sizeof(*regmap_cfg), GFP_KERNEL);
>> +       if (!regmap_cfg)
>> +               return -ENOMEM;
> 
> Is there any specific reason you decided to allocate regmap_cfg
> separately, instead of embedding it into struct rz_sysc?

Sorry, I missed to mention.

I chose to have it like this as the regmap_cfg is not used anywhere else
(through rz_sysc) except in probe.

Thank you for your review,
Claudiu

> 
> The rest LGTM.
> 
> Gr{oetje,eeting}s,
> 
>                         Geert
> 



From miquel.raynal at bootlin.com  Fri Aug  8 03:43:59 2025
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Fri, 08 Aug 2025 12:43:59 +0200
Subject: [PATCH] dt-bindings: phy: marvell,comphy-cp110: Fix clock and
 child node constraints
In-Reply-To: <20250806200138.1366189-1-robh@kernel.org> (Rob Herring's message
	of "Wed, 6 Aug 2025 15:01:37 -0500")
References: <20250806200138.1366189-1-robh@kernel.org>
Message-ID: <87qzxm9jps.fsf@bootlin.com>

On 06/08/2025 at 15:01:37 -05, "Rob Herring (Arm)" <robh at kernel.org> wrote:

> In converting marvell,comphy-cp110 to schema, the constraints for clocks on
> marvell,comphy-a3700 are wrong, the maximum number of child nodes are wrong,
> and the phy nodes may have a 'connector' child node:
>
> phy at 18300 (marvell,comphy-a3700): clock-names: False schema does not allow ['xtal']
> phy at 120000 (marvell,comphy-cp110): 'phy at 3', 'phy at 4', 'phy at 5' do not match any of the regexes: '^phy@[0-2]$', '^pinctrl-[0-9]+$'
> phy at 120000 (marvell,comphy-cp110): phy at 2: 'connector' does not match any of the regexes: '^pinctrl-[0-9]+$'
>
> Fixes: 50355ac70d4f ("dt-bindings: phy: Convert marvell,comphy-cp110 to DT schema")
> Signed-off-by: Rob Herring (Arm) <robh at kernel.org>
> ---

Reviewed-by: Miquel Raynal <miquel.raynal at bootlin.com>

Thanks,
Miqu?l


From geert at linux-m68k.org  Fri Aug  8 04:36:46 2025
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Fri, 8 Aug 2025 13:36:46 +0200
Subject: [PATCH v4 1/8] soc: renesas: rz-sysc: Add syscon/regmap support
In-Reply-To: <cbdfa6fd-e65b-45d7-a21f-3bfdd46af332@tuxon.dev>
References: <20250808061806.2729274-1-claudiu.beznea.uj@bp.renesas.com>
 <20250808061806.2729274-2-claudiu.beznea.uj@bp.renesas.com>
 <CAMuHMdUsFFd+orb17oQqoEidzYWMRjPoqMyzpgrdnicc=MRSYQ@mail.gmail.com> <cbdfa6fd-e65b-45d7-a21f-3bfdd46af332@tuxon.dev>
Message-ID: <CAMuHMdXM=Mu+vJ6n3spj7Dd+8boLXEpcSn0M1KB8OwPijqq4aw@mail.gmail.com>

Hi Claudiu,

On Fri, 8 Aug 2025 at 12:32, Claudiu Beznea <claudiu.beznea at tuxon.dev> wrote:
> On 08.08.2025 12:29, Geert Uytterhoeven wrote:
> > On Fri, 8 Aug 2025 at 08:18, Claudiu <claudiu.beznea at tuxon.dev> wrote:
> >> From: John Madieu <john.madieu.xa at bp.renesas.com>
> >>
> >> The RZ/G3E system controller has various registers that control or report
> >> some properties specific to individual IPs. The regmap is registered as a
> >> syscon device to allow these IP drivers to access the registers through the
> >> regmap API.
> >>
> >> As other RZ SoCs might have custom read/write callbacks or max-offsets,
> >> register a custom regmap configuration.
> >>
> >> Signed-off-by: John Madieu <john.madieu.xa at bp.renesas.com>
> >> [claudiu.beznea:
> >>  - do not check the match->data validity in rz_sysc_probe() as it is
> >>    always valid
> >>  - dinamically allocate regmap_cfg]
> >> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
> >> ---
> >>
> >> Changes in v4:
> >> - adjusted the patch description by dropping "add" from
> >>   "add register a custom regmap configuration"
> >> - updated the list of changes from Claudiu Beznea
> >> - dynamically allocate the regmap_config as proposed at [2]
> >> - this patch is needed for proper function of USB (as proposed in this
> >>   series) that being the reason it is introduced here, as well
> >>
> >> [2] https://lore.kernel.org/all/CAMuHMdVyf3Xtpw=LWHrnD2CVQX4xYm=FBHvY_dx9OesHDz5zNg at mail.gmail.com/
> >
> >> --- a/drivers/soc/renesas/rz-sysc.c
> >> +++ b/drivers/soc/renesas/rz-sysc.c
> > =
> >> @@ -117,7 +125,26 @@ static int rz_sysc_probe(struct platform_device *pdev)
> >>                 return PTR_ERR(sysc->base);
> >>
> >>         sysc->dev = dev;
> >> -       return rz_sysc_soc_init(sysc, match);
> >> +       ret = rz_sysc_soc_init(sysc, match);
> >> +       if (ret)
> >> +               return ret;
> >> +
> >> +       regmap_cfg = devm_kzalloc(dev, sizeof(*regmap_cfg), GFP_KERNEL);
> >> +       if (!regmap_cfg)
> >> +               return -ENOMEM;
> >
> > Is there any specific reason you decided to allocate regmap_cfg
> > separately, instead of embedding it into struct rz_sysc?
>
> Sorry, I missed to mention.
>
> I chose to have it like this as the regmap_cfg is not used anywhere else
> (through rz_sysc) except in probe.

OK.  Upon closer look, devm_regmap_init_mmio() does not save the
regmap_cfg pointer for later use, so it can be allocated using kzalloc()
instead, and freed immediately after calling devm_regmap_init_mmio().

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 claudiu.beznea at tuxon.dev  Fri Aug  8 05:11:01 2025
From: claudiu.beznea at tuxon.dev (Claudiu Beznea)
Date: Fri, 8 Aug 2025 15:11:01 +0300
Subject: [PATCH v4 1/8] soc: renesas: rz-sysc: Add syscon/regmap support
In-Reply-To: <CAMuHMdXM=Mu+vJ6n3spj7Dd+8boLXEpcSn0M1KB8OwPijqq4aw@mail.gmail.com>
References: <20250808061806.2729274-1-claudiu.beznea.uj@bp.renesas.com>
 <20250808061806.2729274-2-claudiu.beznea.uj@bp.renesas.com>
 <CAMuHMdUsFFd+orb17oQqoEidzYWMRjPoqMyzpgrdnicc=MRSYQ@mail.gmail.com>
 <cbdfa6fd-e65b-45d7-a21f-3bfdd46af332@tuxon.dev>
 <CAMuHMdXM=Mu+vJ6n3spj7Dd+8boLXEpcSn0M1KB8OwPijqq4aw@mail.gmail.com>
Message-ID: <277ca37d-e304-4d78-bfd9-b1fa222fd0f3@tuxon.dev>

Hi, Geert,

On 08.08.2025 14:36, Geert Uytterhoeven wrote:
> Hi Claudiu,
> 
> On Fri, 8 Aug 2025 at 12:32, Claudiu Beznea <claudiu.beznea at tuxon.dev> wrote:
>> On 08.08.2025 12:29, Geert Uytterhoeven wrote:
>>> On Fri, 8 Aug 2025 at 08:18, Claudiu <claudiu.beznea at tuxon.dev> wrote:
>>>> From: John Madieu <john.madieu.xa at bp.renesas.com>
>>>>
>>>> The RZ/G3E system controller has various registers that control or report
>>>> some properties specific to individual IPs. The regmap is registered as a
>>>> syscon device to allow these IP drivers to access the registers through the
>>>> regmap API.
>>>>
>>>> As other RZ SoCs might have custom read/write callbacks or max-offsets,
>>>> register a custom regmap configuration.
>>>>
>>>> Signed-off-by: John Madieu <john.madieu.xa at bp.renesas.com>
>>>> [claudiu.beznea:
>>>>  - do not check the match->data validity in rz_sysc_probe() as it is
>>>>    always valid
>>>>  - dinamically allocate regmap_cfg]
>>>> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
>>>> ---
>>>>
>>>> Changes in v4:
>>>> - adjusted the patch description by dropping "add" from
>>>>   "add register a custom regmap configuration"
>>>> - updated the list of changes from Claudiu Beznea
>>>> - dynamically allocate the regmap_config as proposed at [2]
>>>> - this patch is needed for proper function of USB (as proposed in this
>>>>   series) that being the reason it is introduced here, as well
>>>>
>>>> [2] https://lore.kernel.org/all/CAMuHMdVyf3Xtpw=LWHrnD2CVQX4xYm=FBHvY_dx9OesHDz5zNg at mail.gmail.com/
>>>
>>>> --- a/drivers/soc/renesas/rz-sysc.c
>>>> +++ b/drivers/soc/renesas/rz-sysc.c
>>> =
>>>> @@ -117,7 +125,26 @@ static int rz_sysc_probe(struct platform_device *pdev)
>>>>                 return PTR_ERR(sysc->base);
>>>>
>>>>         sysc->dev = dev;
>>>> -       return rz_sysc_soc_init(sysc, match);
>>>> +       ret = rz_sysc_soc_init(sysc, match);
>>>> +       if (ret)
>>>> +               return ret;
>>>> +
>>>> +       regmap_cfg = devm_kzalloc(dev, sizeof(*regmap_cfg), GFP_KERNEL);
>>>> +       if (!regmap_cfg)
>>>> +               return -ENOMEM;
>>>
>>> Is there any specific reason you decided to allocate regmap_cfg
>>> separately, instead of embedding it into struct rz_sysc?
>>
>> Sorry, I missed to mention.
>>
>> I chose to have it like this as the regmap_cfg is not used anywhere else
>> (through rz_sysc) except in probe.
> 
> OK.  Upon closer look, devm_regmap_init_mmio() does not save the
> regmap_cfg pointer for later use, so it can be allocated using kzalloc()
> instead, and freed immediately after calling devm_regmap_init_mmio().

You're right, I forgot this. I'll update it this way.

Thank you,
Claudiu

> 
> Gr{oetje,eeting}s,
> 
>                         Geert
> 



From mani at kernel.org  Fri Aug  8 05:33:46 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Fri, 8 Aug 2025 18:03:46 +0530
Subject: [PATCH V1 4/4] phy: qcom-qmp-ufs: read max-microamp values from
 device tree
In-Reply-To: <20250806154340.20122-5-quic_nitirawa@quicinc.com>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
 <20250806154340.20122-5-quic_nitirawa@quicinc.com>
Message-ID: <xrarnbg2qmhuivqgl7vzhmvfi6sc4zp6wa6zvpv4r4nufllc3p@u4wed2orm2cq>

On Wed, Aug 06, 2025 at 09:13:40PM GMT, Nitin Rawat wrote:
> Add support in QMP PHY driver to read optional vdda-phy-max-microamp
> and vdda-pll-max-microamp properties from the device tree.
> 
> These properties define the expected maximum current (in microamps) for
> each supply. The driver uses this information to configure regulators
> more accurately and ensure they operate in the correct mode based on
> client load requirements.
> 
> If the property is not present, the driver defaults load to
> `QMP_VREG_UNUSED`.
> 
> Signed-off-by: Nitin Rawat <quic_nitirawa at quicinc.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 22 +++++++++++++++++++---
>  1 file changed, 19 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> index 9c69c77d10c8..6e116f7370c3 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> @@ -39,6 +39,8 @@
>  #define PHY_INIT_COMPLETE_TIMEOUT		10000
>  
>  #define NUM_OVERLAY				2
> +#define QMP_VREG_UNUSED				-1
> +#define MAX_PROP_NAME				32
>  
>  /* set of registers with offsets different per-PHY */
>  enum qphy_reg_layout {
> @@ -1894,15 +1896,29 @@ static int qmp_ufs_vreg_init(struct qmp_ufs *qmp)
>  {
>  	const struct qmp_phy_cfg *cfg = qmp->cfg;
>  	struct device *dev = qmp->dev;
> +	struct device_node *np = dev->of_node;
> +	char prop_name[MAX_PROP_NAME];
>  	int num = cfg->num_vregs;
> -	int i;
> +	const char *supply;
> +	int i, ret;
>  
>  	qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL);
>  	if (!qmp->vregs)
>  		return -ENOMEM;
>  
> -	for (i = 0; i < num; i++)
> -		qmp->vregs[i].supply = cfg->vreg_list[i];
> +	for (i = 0; i < num; i++) {
> +		supply = cfg->vreg_list[i];
> +		qmp->vregs[i].supply = supply;
> +
> +		/* Defaults to unused */
> +		qmp->vregs[i].init_load_uA = QMP_VREG_UNUSED;

You don't need to initialize the load. It will be zero initialized at this point
and if the property parsing fails below, it's value still be zero. And the
regulator core will apply the load only if it is > 0.

> +
> +		snprintf(prop_name, sizeof(prop_name), "%s-max-microamp", supply);
> +		ret = of_property_read_u32(np, prop_name, &qmp->vregs[i].init_load_uA);
> +		if (ret)
> +			dev_dbg(qmp->dev, "No max microamp for %s, using default %d\n",
> +				supply, QMP_VREG_UNUSED);

This print doesn't make sense as it will print the default value of -1. Please
drop it.

- Mani

-- 
????????? ????????


From quic_nitirawa at quicinc.com  Fri Aug  8 08:19:45 2025
From: quic_nitirawa at quicinc.com (Nitin Rawat)
Date: Fri, 8 Aug 2025 20:49:45 +0530
Subject: [PATCH V1 2/4] arm64: dts: qcom: sm8750: add max-microamp for UFS
 PHY and PLL supplies
In-Reply-To: <292907f3-25d6-40d9-be6e-b6b83e646d73@kernel.org>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
 <20250806154340.20122-3-quic_nitirawa@quicinc.com>
 <20250808-calm-boa-of-swiftness-a4a7ce@kuoka>
 <9af71063-0629-4ccc-bc76-3fb588677bf4@oss.qualcomm.com>
 <292907f3-25d6-40d9-be6e-b6b83e646d73@kernel.org>
Message-ID: <5e32be05-0dbd-4d6f-879d-8ce97fb430ba@quicinc.com>



On 8/8/2025 3:09 PM, Krzysztof Kozlowski wrote:
> On 08/08/2025 10:58, Konrad Dybcio wrote:
>> On 8/8/25 9:29 AM, Krzysztof Kozlowski wrote:
>>> On Wed, Aug 06, 2025 at 09:13:38PM +0530, Nitin Rawat wrote:
>>>> Add `vdda-phy-max-microamp` and `vdda-pll-max-microamp` properties to
>>>> the UFS PHY node in the device tree.
>>>>
>>>> These properties define the maximum current (in microamps) expected
>>>> from the PHY and PLL regulators. This allows the PHY driver to
>>>> configure regulator load accurately and ensure proper regulator
>>>> mode based on load requirements.
>>>
>>> That's not the property of phy, but regulator.
>>>
>>> Also reasoning is here incomplete - you just post downstream code. :/
>>
>> The reason for this change is good, but perhaps not explained clearly
>>
>> All of these values refer to the maximum current draw that needs to be
>> allocated on a shared voltage supply for this peripheral (because the
> 
> 
> It sounds very different than how much it can be drawn. How much can be
> drawn is the property of the regulator. The regulator knows how much
> current it can support.

Consumers are aware of their dynamic load requirements, which can vary 
at runtime?this awareness is not reciprocal. The power grid is designed 
based on the collective load requirements of all clients sharing the 
same power rail.

Since regulators can operate in multiple modes for power optimization, 
each consumer is expected to vote for its runtime power needs. These 
votes help the regulator framework maintain the regulator in the 
appropriate mode, ensuring stable and efficient operation across all 
clients.


Stability issues can arise if each consumer does not vote for its own 
load requirement.
For example, consider a scenario where a single regulator is shared by 
two consumers.

If the first client requests low-power mode by voting for zero or a 
minimal load to regulator framework during its driver's LPM sequence, 
and the second client (e.g., UFS PHY) has not voted for its own load 
requirement through the regulator framework, the regulator may 
transition to low-power mode. This can lead to issues for the second 
client, which expects a higher power state to operate correctly.


> 
> 
>> supply's capabilities change depending on the maximum potential load
>> at any given time, which the regulator driver must be aware of)
>>
>> This is a property of a regulator *consumer*, i.e. if we had a chain
>> of LEDs hanging off of this supply, we'd need to specify NUM_LEDS *
>> MAX_CURR under the "led chain" device, to make sure that if the
>> aggregated current requirements go over a certain threshold (which is
>> unknown to Linux and hidden in RPMh fw), the regulator can be
>> reconfigured to allow for a higher current draw (likely at some
>> downgrade to efficiency)
> 
> 
> The problem is that rationale is downstream. Instead I want to see some
> reason: e.g. datasheets, spec, type of UFS device (that was the argument
> in the driver patch discussion).


The PHY load requirements for consumers such as UFS, USB, PCIe are 
defined by Qualcomm?s PHY IP and are well-documented in Qualcomm?s 
datasheets and power grid documentation. These values can depending on 
the process or technology node, board design, and even the chip foundry 
used.

As a result, the load values can differ across SoCs or may be even 
board(unlikely though) due to variations in any of these parameters.


Regards,
Nitin



> 
> The only argument here for given value is: downstream has it.
> 
> Best regards,
> Krzysztof



From prabhakar.csengg at gmail.com  Fri Aug  8 14:52:04 2025
From: prabhakar.csengg at gmail.com (Prabhakar)
Date: Fri,  8 Aug 2025 22:52:04 +0100
Subject: [PATCH v2 0/5] Add USB2 PHY support for RZ/T2H and RZ/N2H SoCs
Message-ID: <20250808215209.3692744-1-prabhakar.mahadev-lad.rj@bp.renesas.com>

From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>

Hi All,

This patch series adds support for the USB2 PHY on the Renesas RZ/T2H
and RZ/N2H SoCs. The USB2 PHY driver has been updated to handle
differences in clocking, reset handling, and register configurations
specific to these SoCs.

v1->v2:
- Added Acked-by from Conor for the DT bindings.
- Renamed drvdata to phy_data.
- Updated commit message to clarify the change.
- Dropped local phy_data variable in probe, using channel->phy_data
  directly.
- Included the necessary header files.
- Simplified device/host detection in rcar_gen3_check_id() as suggested
  by Geert.
- Added Reviewed-by from Neil.

Cheers,
Prabhakar

Lad Prabhakar (5):
  dt-bindings: phy: renesas,usb2-phy: Add RZ/T2H and RZ/N2H support
  phy: renesas: rcar-gen3-usb2: store drvdata pointer in channel
  phy: renesas: rcar-gen3-usb2: Allow SoC-specific OBINT bits via
    phy_data
  phy: renesas: rcar-gen3-usb2: Add support for RZ/T2H SoC
  phy: renesas: rcar-gen3-usb2: Move debug print after register value is
    updated

 .../bindings/phy/renesas,usb2-phy.yaml        |  17 +++
 drivers/phy/renesas/phy-rcar-gen3-usb2.c      | 132 +++++++++++++-----
 2 files changed, 115 insertions(+), 34 deletions(-)

-- 
2.50.1



From prabhakar.csengg at gmail.com  Fri Aug  8 14:52:05 2025
From: prabhakar.csengg at gmail.com (Prabhakar)
Date: Fri,  8 Aug 2025 22:52:05 +0100
Subject: [PATCH v2 1/5] dt-bindings: phy: renesas,usb2-phy: Add RZ/T2H and RZ/N2H support
In-Reply-To: <20250808215209.3692744-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20250808215209.3692744-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <20250808215209.3692744-2-prabhakar.mahadev-lad.rj@bp.renesas.com>

From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>

Document the USB2 PHY controller for the Renesas RZ/T2H (r9a09g077) and
RZ/N2H (r9a09g087) SoCs. These SoCs share the same PHY block, which is
similar to the one on RZ/G2L but differs in clocks, resets, and register
bits. To account for these differences, a new compatible string
`renesas,usb2-phy-r9a09g077` is introduced.

The RZ/N2H SoC uses the same PHY as RZ/T2H, so it reuses the RZ/T2H
compatible string as a fallback.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
Acked-by: Conor Dooley <conor.dooley at microchip.com>
---
v1->v2:
- Added Acked-by from Conor.
---
 .../bindings/phy/renesas,usb2-phy.yaml          | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml b/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml
index f45c5f039ae8..179cb4bfc424 100644
--- a/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml
@@ -44,6 +44,12 @@ properties:
           - const: renesas,usb2-phy-r9a09g056 # RZ/V2N
           - const: renesas,usb2-phy-r9a09g057
 
+      - const: renesas,usb2-phy-r9a09g077 # RZ/T2H
+
+      - items:
+          - const: renesas,usb2-phy-r9a09g087 # RZ/N2H
+          - const: renesas,usb2-phy-r9a09g077
+
   reg:
     maxItems: 1
 
@@ -120,6 +126,17 @@ allOf:
       required:
         - resets
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: renesas,usb2-phy-r9a09g077
+    then:
+      properties:
+        clocks:
+          minItems: 2
+        resets: false
+
 additionalProperties: false
 
 examples:
-- 
2.50.1



From prabhakar.csengg at gmail.com  Fri Aug  8 14:52:06 2025
From: prabhakar.csengg at gmail.com (Prabhakar)
Date: Fri,  8 Aug 2025 22:52:06 +0100
Subject: [PATCH v2 2/5] phy: renesas: rcar-gen3-usb2: store drvdata pointer in channel
In-Reply-To: <20250808215209.3692744-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20250808215209.3692744-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <20250808215209.3692744-3-prabhakar.mahadev-lad.rj@bp.renesas.com>

From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>

Store the SoC-specific driver data pointer (struct rcar_gen3_phy_drv_data)
directly in struct rcar_gen3_chan instead of copying individual flags into
separate channel members.

Obtain the drvdata with of_device_get_match_data() in probe and assign it
to channel->phy_data. Update all call sites to reference
`channel->phy_data->*` for SoC-specific behaviour (for example no_adp_ctrl
and utmi_ctrl). Remove the redundant soc_no_adp_ctrl and utmi_ctrl fields
from struct rcar_gen3_chan.

This simplifies the probe path, reduces duplication, and makes it easier
to extend the driver with additional platform-specific fields in the
future.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
---
v1->v2:
- Renamed drvdata to phy_data.
- Updated commit message to clarify the change.
- Dropped local phy_data variable in probe, using channel->phy_data
  directly.
---
 drivers/phy/renesas/phy-rcar-gen3-usb2.c | 27 ++++++++++--------------
 1 file changed, 11 insertions(+), 16 deletions(-)

diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index 47beb94cd424..7ac56102aed0 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -122,6 +122,7 @@ struct rcar_gen3_phy {
 struct rcar_gen3_chan {
 	void __iomem *base;
 	struct device *dev;	/* platform_device's device */
+	const struct rcar_gen3_phy_drv_data *phy_data;
 	struct extcon_dev *extcon;
 	struct rcar_gen3_phy rphys[NUM_OF_PHYS];
 	struct regulator *vbus;
@@ -133,8 +134,6 @@ struct rcar_gen3_chan {
 	bool extcon_host;
 	bool is_otg_channel;
 	bool uses_otg_pins;
-	bool soc_no_adp_ctrl;
-	bool utmi_ctrl;
 };
 
 struct rcar_gen3_phy_drv_data {
@@ -204,7 +203,7 @@ static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus)
 	u32 val;
 
 	dev_vdbg(ch->dev, "%s: %08x, %d\n", __func__, val, vbus);
-	if (ch->soc_no_adp_ctrl) {
+	if (ch->phy_data->no_adp_ctrl) {
 		if (ch->vbus)
 			regulator_hardware_enable(ch->vbus, vbus);
 
@@ -290,7 +289,7 @@ static bool rcar_gen3_check_id(struct rcar_gen3_chan *ch)
 	if (!ch->uses_otg_pins)
 		return (ch->dr_mode == USB_DR_MODE_HOST) ? false : true;
 
-	if (ch->soc_no_adp_ctrl)
+	if (ch->phy_data->no_adp_ctrl)
 		return !!(readl(ch->base + USB2_LINECTRL1) & USB2_LINECTRL1_USB2_IDMON);
 
 	return !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG);
@@ -421,7 +420,7 @@ static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch)
 	      USB2_LINECTRL1_DMRPD_EN | USB2_LINECTRL1_DM_RPD;
 	writel(val, usb2_base + USB2_LINECTRL1);
 
-	if (!ch->soc_no_adp_ctrl) {
+	if (!ch->phy_data->no_adp_ctrl) {
 		val = readl(usb2_base + USB2_VBCTRL);
 		val &= ~USB2_VBCTRL_OCCLREN;
 		writel(val | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL);
@@ -487,7 +486,7 @@ static int rcar_gen3_phy_usb2_init(struct phy *p)
 	if (rphy->int_enable_bits)
 		rcar_gen3_init_otg(channel);
 
-	if (channel->utmi_ctrl) {
+	if (channel->phy_data->utmi_ctrl) {
 		val = readl(usb2_base + USB2_REGEN_CG_CTRL) | USB2_REGEN_CG_CTRL_UPHY_WEN;
 		writel(val, usb2_base + USB2_REGEN_CG_CTRL);
 
@@ -730,7 +729,6 @@ static int rcar_gen3_phy_usb2_init_bus(struct rcar_gen3_chan *channel)
 
 static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
 {
-	const struct rcar_gen3_phy_drv_data *phy_data;
 	struct device *dev = &pdev->dev;
 	struct rcar_gen3_chan *channel;
 	struct phy_provider *provider;
@@ -773,8 +771,8 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
 	 */
 	pm_runtime_enable(dev);
 
-	phy_data = of_device_get_match_data(dev);
-	if (!phy_data) {
+	channel->phy_data = of_device_get_match_data(dev);
+	if (!channel->phy_data) {
 		ret = -EINVAL;
 		goto error;
 	}
@@ -782,22 +780,19 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, channel);
 	channel->dev = dev;
 
-	if (phy_data->init_bus) {
+	if (channel->phy_data->init_bus) {
 		ret = rcar_gen3_phy_usb2_init_bus(channel);
 		if (ret)
 			goto error;
 	}
 
-	channel->soc_no_adp_ctrl = phy_data->no_adp_ctrl;
-	if (phy_data->no_adp_ctrl)
+	if (channel->phy_data->no_adp_ctrl)
 		channel->obint_enable_bits = USB2_OBINT_IDCHG_EN;
 
-	channel->utmi_ctrl = phy_data->utmi_ctrl;
-
 	spin_lock_init(&channel->lock);
 	for (i = 0; i < NUM_OF_PHYS; i++) {
 		channel->rphys[i].phy = devm_phy_create(dev, NULL,
-							phy_data->phy_usb2_ops);
+							channel->phy_data->phy_usb2_ops);
 		if (IS_ERR(channel->rphys[i].phy)) {
 			dev_err(dev, "Failed to create USB2 PHY\n");
 			ret = PTR_ERR(channel->rphys[i].phy);
@@ -808,7 +803,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
 		phy_set_drvdata(channel->rphys[i].phy, &channel->rphys[i]);
 	}
 
-	if (channel->soc_no_adp_ctrl && channel->is_otg_channel)
+	if (channel->phy_data->no_adp_ctrl && channel->is_otg_channel)
 		channel->vbus = devm_regulator_get_exclusive(dev, "vbus");
 	else
 		channel->vbus = devm_regulator_get_optional(dev, "vbus");
-- 
2.50.1



From prabhakar.csengg at gmail.com  Fri Aug  8 14:52:07 2025
From: prabhakar.csengg at gmail.com (Prabhakar)
Date: Fri,  8 Aug 2025 22:52:07 +0100
Subject: [PATCH v2 3/5] phy: renesas: rcar-gen3-usb2: Allow SoC-specific OBINT bits via phy_data
In-Reply-To: <20250808215209.3692744-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20250808215209.3692744-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <20250808215209.3692744-4-prabhakar.mahadev-lad.rj@bp.renesas.com>

From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>

Update the PHY driver to support SoC-specific OBINT enable bits by
introducing the `obint_enable_bits` field in the `rcar_gen3_phy_drv_data`
structure. This allows each SoC to specify bits required.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>
---
v1->v2:
- Added Reviewed-by from Neil.
---
 drivers/phy/renesas/phy-rcar-gen3-usb2.c | 27 ++++++++++++------------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index 7ac56102aed0..a37af7d8f2f4 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -71,8 +71,7 @@
 /* OBINTSTA and OBINTEN */
 #define USB2_OBINT_SESSVLDCHG		BIT(12)
 #define USB2_OBINT_IDDIGCHG		BIT(11)
-#define USB2_OBINT_BITS			(USB2_OBINT_SESSVLDCHG | \
-					 USB2_OBINT_IDDIGCHG)
+#define USB2_OBINT_IDCHG_EN		BIT(0) /*  RZ/G2L specific */
 
 /* VBCTRL */
 #define USB2_VBCTRL_OCCLREN		BIT(16)
@@ -93,7 +92,6 @@
 #define USB2_ADPCTRL_DRVVBUS		BIT(4)
 
 /*  RZ/G2L specific */
-#define USB2_OBINT_IDCHG_EN		BIT(0)
 #define USB2_LINECTRL1_USB2_IDMON	BIT(0)
 
 #define NUM_OF_PHYS			4
@@ -130,7 +128,6 @@ struct rcar_gen3_chan {
 	struct work_struct work;
 	spinlock_t lock;	/* protects access to hardware and driver data structure. */
 	enum usb_dr_mode dr_mode;
-	u32 obint_enable_bits;
 	bool extcon_host;
 	bool is_otg_channel;
 	bool uses_otg_pins;
@@ -141,6 +138,7 @@ struct rcar_gen3_phy_drv_data {
 	bool no_adp_ctrl;
 	bool init_bus;
 	bool utmi_ctrl;
+	u32 obint_enable_bits;
 };
 
 /*
@@ -225,9 +223,9 @@ static void rcar_gen3_control_otg_irq(struct rcar_gen3_chan *ch, int enable)
 	u32 val = readl(usb2_base + USB2_OBINTEN);
 
 	if (ch->uses_otg_pins && enable)
-		val |= ch->obint_enable_bits;
+		val |= ch->phy_data->obint_enable_bits;
 	else
-		val &= ~ch->obint_enable_bits;
+		val &= ~ch->phy_data->obint_enable_bits;
 	writel(val, usb2_base + USB2_OBINTEN);
 }
 
@@ -430,7 +428,7 @@ static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch)
 	mdelay(20);
 
 	writel(0xffffffff, usb2_base + USB2_OBINTSTA);
-	writel(ch->obint_enable_bits, usb2_base + USB2_OBINTEN);
+	writel(ch->phy_data->obint_enable_bits, usb2_base + USB2_OBINTEN);
 
 	rcar_gen3_device_recognition(ch);
 }
@@ -450,9 +448,9 @@ static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch)
 
 	scoped_guard(spinlock, &ch->lock) {
 		status = readl(usb2_base + USB2_OBINTSTA);
-		if (status & ch->obint_enable_bits) {
+		if (status & ch->phy_data->obint_enable_bits) {
 			dev_vdbg(dev, "%s: %08x\n", __func__, status);
-			writel(ch->obint_enable_bits, usb2_base + USB2_OBINTSTA);
+			writel(ch->phy_data->obint_enable_bits, usb2_base + USB2_OBINTSTA);
 			rcar_gen3_device_recognition(ch);
 			ret = IRQ_HANDLED;
 		}
@@ -591,28 +589,35 @@ static const struct phy_ops rz_g1c_phy_usb2_ops = {
 static const struct rcar_gen3_phy_drv_data rcar_gen3_phy_usb2_data = {
 	.phy_usb2_ops = &rcar_gen3_phy_usb2_ops,
 	.no_adp_ctrl = false,
+	.obint_enable_bits = USB2_OBINT_SESSVLDCHG |
+			     USB2_OBINT_IDDIGCHG,
 };
 
 static const struct rcar_gen3_phy_drv_data rz_g1c_phy_usb2_data = {
 	.phy_usb2_ops = &rz_g1c_phy_usb2_ops,
 	.no_adp_ctrl = false,
+	.obint_enable_bits = USB2_OBINT_SESSVLDCHG |
+			     USB2_OBINT_IDDIGCHG,
 };
 
 static const struct rcar_gen3_phy_drv_data rz_g2l_phy_usb2_data = {
 	.phy_usb2_ops = &rcar_gen3_phy_usb2_ops,
 	.no_adp_ctrl = true,
+	.obint_enable_bits = USB2_OBINT_IDCHG_EN,
 };
 
 static const struct rcar_gen3_phy_drv_data rz_g3s_phy_usb2_data = {
 	.phy_usb2_ops = &rcar_gen3_phy_usb2_ops,
 	.no_adp_ctrl = true,
 	.init_bus = true,
+	.obint_enable_bits = USB2_OBINT_IDCHG_EN,
 };
 
 static const struct rcar_gen3_phy_drv_data rz_v2h_phy_usb2_data = {
 	.phy_usb2_ops = &rcar_gen3_phy_usb2_ops,
 	.no_adp_ctrl = true,
 	.utmi_ctrl = true,
+	.obint_enable_bits = USB2_OBINT_IDCHG_EN,
 };
 
 static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = {
@@ -747,7 +752,6 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
 	if (IS_ERR(channel->base))
 		return PTR_ERR(channel->base);
 
-	channel->obint_enable_bits = USB2_OBINT_BITS;
 	channel->dr_mode = rcar_gen3_get_dr_mode(dev->of_node);
 	if (channel->dr_mode != USB_DR_MODE_UNKNOWN) {
 		channel->is_otg_channel = true;
@@ -786,9 +790,6 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
 			goto error;
 	}
 
-	if (channel->phy_data->no_adp_ctrl)
-		channel->obint_enable_bits = USB2_OBINT_IDCHG_EN;
-
 	spin_lock_init(&channel->lock);
 	for (i = 0; i < NUM_OF_PHYS; i++) {
 		channel->rphys[i].phy = devm_phy_create(dev, NULL,
-- 
2.50.1



From prabhakar.csengg at gmail.com  Fri Aug  8 14:52:08 2025
From: prabhakar.csengg at gmail.com (Prabhakar)
Date: Fri,  8 Aug 2025 22:52:08 +0100
Subject: [PATCH v2 4/5] phy: renesas: rcar-gen3-usb2: Add support for RZ/T2H SoC
In-Reply-To: <20250808215209.3692744-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20250808215209.3692744-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <20250808215209.3692744-5-prabhakar.mahadev-lad.rj@bp.renesas.com>

From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>

Add initial support for the Renesas RZ/T2H SoC to the R-Car Gen3 USB2 PHY
driver. The RZ/T2H SoC requires configuration of additional
hardware-specific bits for proper VBUS level control and OTG operation.

Introduce the `vblvl_ctrl` flag in the SoC-specific driver data to enable
handling of VBUS level selection logic using `VBCTRL.VBLVL` bits. This is
required for managing the VBUS status detection and drive logic based on
SoC-specific needs.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>
---
v1->v2:
- Included the necessary header files.
- Simplified device/host detection in rcar_gen3_check_id() as suggested
  by Geert.
- Added Reviewed-by from Neil.
---
 drivers/phy/renesas/phy-rcar-gen3-usb2.c | 82 ++++++++++++++++++++++--
 1 file changed, 75 insertions(+), 7 deletions(-)

diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index a37af7d8f2f4..8caef9cb228c 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -9,6 +9,8 @@
  * Copyright (C) 2014 Cogent Embedded, Inc.
  */
 
+#include <linux/bitfield.h>
+#include <linux/bits.h>
 #include <linux/cleanup.h>
 #include <linux/extcon-provider.h>
 #include <linux/interrupt.h>
@@ -69,13 +71,20 @@
 #define USB2_COMMCTRL_OTG_PERI		BIT(31)	/* 1 = Peripheral mode */
 
 /* OBINTSTA and OBINTEN */
+#define USB2_OBINTSTA_CLEAR		GENMASK(31, 0)
 #define USB2_OBINT_SESSVLDCHG		BIT(12)
 #define USB2_OBINT_IDDIGCHG		BIT(11)
+#define USB2_OBINT_VBSTAINT		BIT(3)
 #define USB2_OBINT_IDCHG_EN		BIT(0) /*  RZ/G2L specific */
 
 /* VBCTRL */
+#define USB2_VBCTRL_VBSTA_MASK		GENMASK(31, 28)
+#define USB2_VBCTRL_VBSTA_DEFAULT	2
+#define USB2_VBCTRL_VBLVL_MASK		GENMASK(23, 20)
+#define USB2_VBCTRL_VBLVL(m)		FIELD_PREP_CONST(USB2_VBCTRL_VBLVL_MASK, (m))
 #define USB2_VBCTRL_OCCLREN		BIT(16)
 #define USB2_VBCTRL_DRVVBUSSEL		BIT(8)
+#define USB2_VBCTRL_SIDDQREL		BIT(2)
 #define USB2_VBCTRL_VBOUT		BIT(0)
 
 /* LINECTRL1 */
@@ -88,6 +97,7 @@
 /* ADPCTRL */
 #define USB2_ADPCTRL_OTGSESSVLD		BIT(20)
 #define USB2_ADPCTRL_IDDIG		BIT(19)
+#define USB2_ADPCTRL_VBUSVALID		BIT(18)
 #define USB2_ADPCTRL_IDPULLUP		BIT(5)	/* 1 = ID sampling is enabled */
 #define USB2_ADPCTRL_DRVVBUS		BIT(4)
 
@@ -138,6 +148,7 @@ struct rcar_gen3_phy_drv_data {
 	bool no_adp_ctrl;
 	bool init_bus;
 	bool utmi_ctrl;
+	bool vblvl_ctrl;
 	u32 obint_enable_bits;
 };
 
@@ -201,7 +212,7 @@ static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus)
 	u32 val;
 
 	dev_vdbg(ch->dev, "%s: %08x, %d\n", __func__, val, vbus);
-	if (ch->phy_data->no_adp_ctrl) {
+	if (ch->phy_data->no_adp_ctrl || ch->phy_data->vblvl_ctrl) {
 		if (ch->vbus)
 			regulator_hardware_enable(ch->vbus, vbus);
 
@@ -284,6 +295,16 @@ static void rcar_gen3_init_from_a_peri_to_a_host(struct rcar_gen3_chan *ch)
 
 static bool rcar_gen3_check_id(struct rcar_gen3_chan *ch)
 {
+	if (ch->phy_data->vblvl_ctrl) {
+		bool vbus_valid;
+		bool device;
+
+		device = !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG);
+		vbus_valid = !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_VBUSVALID);
+
+		return !(device && !vbus_valid);
+	}
+
 	if (!ch->uses_otg_pins)
 		return (ch->dr_mode == USB_DR_MODE_HOST) ? false : true;
 
@@ -419,11 +440,20 @@ static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch)
 	writel(val, usb2_base + USB2_LINECTRL1);
 
 	if (!ch->phy_data->no_adp_ctrl) {
-		val = readl(usb2_base + USB2_VBCTRL);
-		val &= ~USB2_VBCTRL_OCCLREN;
-		writel(val | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL);
-		val = readl(usb2_base + USB2_ADPCTRL);
-		writel(val | USB2_ADPCTRL_IDPULLUP, usb2_base + USB2_ADPCTRL);
+		if (ch->phy_data->vblvl_ctrl) {
+			val = readl(usb2_base + USB2_VBCTRL);
+			val = (val & ~USB2_VBCTRL_VBLVL_MASK) | USB2_VBCTRL_VBLVL(2);
+			writel(val, usb2_base + USB2_VBCTRL);
+			val = readl(usb2_base + USB2_ADPCTRL);
+			writel(val | USB2_ADPCTRL_IDPULLUP | USB2_ADPCTRL_DRVVBUS,
+			       usb2_base + USB2_ADPCTRL);
+		} else {
+			val = readl(usb2_base + USB2_VBCTRL);
+			val &= ~USB2_VBCTRL_OCCLREN;
+			writel(val | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL);
+			val = readl(usb2_base + USB2_ADPCTRL);
+			writel(val | USB2_ADPCTRL_IDPULLUP, usb2_base + USB2_ADPCTRL);
+		}
 	}
 	mdelay(20);
 
@@ -433,6 +463,23 @@ static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch)
 	rcar_gen3_device_recognition(ch);
 }
 
+static void rcar_gen3_configure_vblvl_ctrl(struct rcar_gen3_chan *ch)
+{
+	void __iomem *usb2_base = ch->base;
+	u32 val;
+
+	if (!ch->phy_data->vblvl_ctrl)
+		return;
+
+	val = readl(usb2_base + USB2_VBCTRL);
+	if ((val & USB2_VBCTRL_VBSTA_MASK) ==
+	    FIELD_PREP_CONST(USB2_VBCTRL_VBSTA_MASK, USB2_VBCTRL_VBSTA_DEFAULT))
+		val &= ~USB2_VBCTRL_VBLVL_MASK;
+	else
+		val |= USB2_VBCTRL_VBLVL(USB2_VBCTRL_VBSTA_DEFAULT);
+	writel(val, usb2_base + USB2_VBCTRL);
+}
+
 static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch)
 {
 	struct rcar_gen3_chan *ch = _ch;
@@ -450,8 +497,12 @@ static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch)
 		status = readl(usb2_base + USB2_OBINTSTA);
 		if (status & ch->phy_data->obint_enable_bits) {
 			dev_vdbg(dev, "%s: %08x\n", __func__, status);
-			writel(ch->phy_data->obint_enable_bits, usb2_base + USB2_OBINTSTA);
+			if (ch->phy_data->vblvl_ctrl)
+				writel(USB2_OBINTSTA_CLEAR, usb2_base + USB2_OBINTSTA);
+			else
+				writel(ch->phy_data->obint_enable_bits, usb2_base + USB2_OBINTSTA);
 			rcar_gen3_device_recognition(ch);
+			rcar_gen3_configure_vblvl_ctrl(ch);
 			ret = IRQ_HANDLED;
 		}
 	}
@@ -484,6 +535,13 @@ static int rcar_gen3_phy_usb2_init(struct phy *p)
 	if (rphy->int_enable_bits)
 		rcar_gen3_init_otg(channel);
 
+	if (channel->phy_data->vblvl_ctrl) {
+		/* SIDDQ mode release */
+		writel(readl(usb2_base + USB2_VBCTRL) | USB2_VBCTRL_SIDDQREL,
+		       usb2_base + USB2_VBCTRL);
+		udelay(250);
+	}
+
 	if (channel->phy_data->utmi_ctrl) {
 		val = readl(usb2_base + USB2_REGEN_CG_CTRL) | USB2_REGEN_CG_CTRL_UPHY_WEN;
 		writel(val, usb2_base + USB2_REGEN_CG_CTRL);
@@ -613,6 +671,12 @@ static const struct rcar_gen3_phy_drv_data rz_g3s_phy_usb2_data = {
 	.obint_enable_bits = USB2_OBINT_IDCHG_EN,
 };
 
+static const struct rcar_gen3_phy_drv_data rz_t2h_phy_usb2_data = {
+	.phy_usb2_ops = &rcar_gen3_phy_usb2_ops,
+	.vblvl_ctrl = true,
+	.obint_enable_bits = USB2_OBINT_IDCHG_EN | USB2_OBINT_VBSTAINT,
+};
+
 static const struct rcar_gen3_phy_drv_data rz_v2h_phy_usb2_data = {
 	.phy_usb2_ops = &rcar_gen3_phy_usb2_ops,
 	.no_adp_ctrl = true,
@@ -645,6 +709,10 @@ static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = {
 		.compatible = "renesas,usb2-phy-r9a09g057",
 		.data = &rz_v2h_phy_usb2_data,
 	},
+	{
+		.compatible = "renesas,usb2-phy-r9a09g077",
+		.data = &rz_t2h_phy_usb2_data,
+	},
 	{
 		.compatible = "renesas,rzg2l-usb2-phy",
 		.data = &rz_g2l_phy_usb2_data,
-- 
2.50.1



From prabhakar.csengg at gmail.com  Fri Aug  8 14:52:09 2025
From: prabhakar.csengg at gmail.com (Prabhakar)
Date: Fri,  8 Aug 2025 22:52:09 +0100
Subject: [PATCH v2 5/5] phy: renesas: rcar-gen3-usb2: Move debug print after register value is updated
In-Reply-To: <20250808215209.3692744-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20250808215209.3692744-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <20250808215209.3692744-6-prabhakar.mahadev-lad.rj@bp.renesas.com>

From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>

Relocate the debug print in rcar_gen3_enable_vbus_ctrl() to appear after
the `val` variable is assigned and updated based on the VBUS state. This
ensures that the debug log reflects the actual register value being
written, improving debugging accuracy.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>
---
v1->v2:
- Added Reviewed-by from Neil.
---
 drivers/phy/renesas/phy-rcar-gen3-usb2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index 8caef9cb228c..7b4a6e8b7508 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -211,7 +211,6 @@ static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus)
 	u32 vbus_ctrl_val = USB2_ADPCTRL_DRVVBUS;
 	u32 val;
 
-	dev_vdbg(ch->dev, "%s: %08x, %d\n", __func__, val, vbus);
 	if (ch->phy_data->no_adp_ctrl || ch->phy_data->vblvl_ctrl) {
 		if (ch->vbus)
 			regulator_hardware_enable(ch->vbus, vbus);
@@ -225,6 +224,7 @@ static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus)
 		val |= vbus_ctrl_val;
 	else
 		val &= ~vbus_ctrl_val;
+	dev_vdbg(ch->dev, "%s: %08x, %d\n", __func__, val, vbus);
 	writel(val, usb2_base + vbus_ctrl_reg);
 }
 
-- 
2.50.1



From Frank.Li at nxp.com  Fri Aug  8 15:39:03 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:03 -0400
Subject: [PATCH v2 00/32] media: add imx93 mipi/controller csi support
Message-ID: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>

Totally rewrite CSI part driver compared to V1.

This only includes CSI related patches.

DTS part: see https://lore.kernel.org/imx/20250701-95_cam-v1-6-c5172bab387b at nxp.com/
PHY part: see https://lore.kernel.org/imx/20250701-95_cam-v1-4-c5172bab387b at nxp.com/
AP1302 part: see https://lore.kernel.org/imx/20250701-95_cam-v1-7-c5172bab387b at nxp.com/
	upstream: https://lore.kernel.org/imx/20250623-ap1302-v3-0-c9ca5b791494 at nxp.com/

First 3 patches add some common helper function to simple code and remove
duplicated code in difference CSI2 drivers.

Clean up stage imx6 old version csi2 driver, and prepare create common
dw csi2 library for difference IP version.

Move stage driver under driver/media/synosis.

Create simple platform driver for common dw csi2 use case.

TODO:
	1. create bus, to probe phy driver under "test_if" interface for
specific phys under CSI2.
	2. support to combine phy, (which connect to both dw CSI and DSI's
test_if). Need use DSI's test_if to config combo phy to switch to RX mode.
and also need config RX part's phy register by use CSI's testif.
	3. move other vendor's csi driver to use this common DWC CSI
library.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Changes in v2:
- totally rewrite, see above section
- Link to v1: https://lore.kernel.org/r/20250701-95_cam-v1-0-c5172bab387b at nxp.com

---
Eugen Hristev (1):
      dt-bindings: media: add DW MIPI CSI-2 Host support

Frank Li (31):
      media: v4l2-common: Add helper function v4l_get_required_align_by_bpp()
      media: v4l2-common: Add helper function media_bus_fmt_to_csi2_bpp()
      media: v4l2-common: Add helper function media_bus_fmt_to_csi2_dt()
      media: staging: media: imx6-mipi-csi2: replace space with tab for alignment
      media: staging: media: imx6-mipi-csi2: use devm_add_action_or_reset() to simplify code
      media: staging: media: imx6-mipi-csi2: use devm_clk_bulk_get_all() to fetch clocks
      media: staging: media: imx6-mipi-csi2: use devm_mutex_init() to simplify code
      media: staging: media: imx6-mipi-csi2: use guard() to simplify code
      media: staging: media: imx6-mipi-csi2: use register structure to match hardware
      media: staging: media: imx6-mipi-csi2: use devm_platform_ioremap_resource() simplify code
      media: staging: media: imx6-mipi-csi2: move probe part to imx6-csi2.c
      media: staging: media: imx6-mipi-csi2: move sd imx6's specific initialization into imx6-sci2.c
      media: staging: media: imx6-mipi-csi2: move csi2ipu_gasket_init() to imx6-csi2.c
      media: staging: media: imx6-mipi-csi2: move number pad macro define into imx6-csi2.c
      media: staging: media: imx6-mipi-csi2: move dphy init part to imx6-csi2.c
      media: staging: media: imx6-mipi-csi2: use runtime_pm frame to control clks
      media: synopsys: move imx6-mipi-csi2.c to synopsys/mipi-csi2.c
      media: synopsys: csi2: Remove deprecated s_stream and use v4l2_subdev_pad_ops
      media: synopsys: csi2: Add phy interface support
      media: synopsys: csi2: Add basic v150* version register
      media: synopsys: csi2: Add irq support to record error count
      media: synopsys: csi2: Handle alignment requirement for width
      media: synopsys: csi2: Add register prefix to register field definitions
      media: synopsys: csi2: Add need_dphy_reset in config
      media: synopsys: csi2: Add default simple dw_csi2_subdev_init_state
      media: synopsys: csi2: Add v150 lane stop state register bit define
      media: synopsys: csi2: use standard v4l2_subdev_get_fmt() function
      media: synopsys: csi2: Add customize get_frame_desc() callback
      media: synopsys: csi2: Add Image Pixel Interface (IPI) support for v150
      media: synopsys: csi2: Remove source pad connected check at dw_csi2_enable_streams()
      media: synopsys: csi2: Add simple synopsys platform driver

 .../bindings/media/snps,dw-mipi-csi2-v150.yaml     |  158 +++
 MAINTAINERS                                        |    1 +
 drivers/media/platform/synopsys/Kconfig            |   20 +
 drivers/media/platform/synopsys/Makefile           |    3 +
 drivers/media/platform/synopsys/mipi-csi2-simple.c |   75 ++
 drivers/media/platform/synopsys/mipi-csi2.c        | 1258 ++++++++++++++++++++
 drivers/media/v4l2-core/v4l2-common.c              |  220 ++++
 drivers/staging/media/imx/Kconfig                  |    1 +
 drivers/staging/media/imx/Makefile                 |    2 +-
 drivers/staging/media/imx/imx6-csi2.c              |  181 +++
 drivers/staging/media/imx/imx6-mipi-csi2.c         |  846 -------------
 include/media/dw-mipi-csi2.h                       |  120 ++
 include/media/mipi-csi2.h                          |    5 +
 include/media/v4l2-common.h                        |   30 +
 14 files changed, 2073 insertions(+), 847 deletions(-)
---
base-commit: 33652d58b64e92d2598205fd992989bd93cd61f4
change-id: 20250606-95_cam-b74c094ad1fb

Best regards,
--
Frank Li <Frank.Li at nxp.com>



From Frank.Li at nxp.com  Fri Aug  8 15:39:04 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:04 -0400
Subject: [PATCH v2 01/32] dt-bindings: media: add DW MIPI CSI-2 Host
 support
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <20250808-95_cam-v2-1-4b29fa6919a7@nxp.com>

From: Eugen Hristev <eugen.hristev at linaro.org>

Add bindings for Synopsys DesignWare MIPI CSI-2 host, which used at i.MX93
and i.MX95 platform.

Signed-off-by: Luis Oliveira <lolivei at synopsys.com>
Signed-off-by: Eugen Hristev <eugen.hristev at linaro.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change in v2
- remove Eugen Hristev <eugen.hristev at microchip.com> from mantainer.
- update ugen Hristev's s-o-b tag to align original author's email address
- remove single snps,dw-mipi-csi2-v150 compatible string
- move additionalProperties after required
---
 .../bindings/media/snps,dw-mipi-csi2-v150.yaml     | 158 +++++++++++++++++++++
 MAINTAINERS                                        |   1 +
 2 files changed, 159 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/snps,dw-mipi-csi2-v150.yaml b/Documentation/devicetree/bindings/media/snps,dw-mipi-csi2-v150.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..fc1b167d6d3b142a01e2ea7f04230934260a05e6
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/snps,dw-mipi-csi2-v150.yaml
@@ -0,0 +1,158 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/snps,dw-mipi-csi2-v150.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Synopsys DesignWare CSI-2 Host controller (csi2host)
+
+maintainers:
+  - Frank Li <Frank.Li at nxp.com>
+
+description:
+  CSI2HOST is used to receive image coming from an MIPI CSI-2 compatible
+  camera. It will convert the incoming CSI-2 stream into a dedicated
+  interface called the Synopsys IDI (Image Data Interface).
+  This interface is a 32-bit SoC internal only, and can be assimilated
+  with a CSI-2 interface.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - fsl,imx93-mipi-csi2
+      - const: snps,dw-mipi-csi2-v150
+
+  reg:
+    items:
+      - description: MIPI CSI-2 core register
+
+  reg-names:
+    items:
+      - const: core
+
+  clocks:
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: per
+      - const: pixel
+
+  phys:
+    maxItems: 1
+    description: MIPI D-PHY
+
+  phy-names:
+    items:
+      - const: rx
+
+  resets:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port at 0:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description:
+          Input port node, single endpoint describing the input port.
+
+        properties:
+          endpoint:
+            $ref: video-interfaces.yaml#
+            unevaluatedProperties: false
+            description: Endpoint connected to input device
+
+            properties:
+              bus-type:
+                const: 4
+
+              data-lanes:
+                minItems: 1
+                maxItems: 4
+                items:
+                  maximum: 4
+
+              clock-lanes:
+                maxItems: 1
+
+              remote-endpoint: true
+
+      port at 1:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description:
+          Output port node, single endpoint describing the output port.
+
+        properties:
+          endpoint:
+            unevaluatedProperties: false
+            $ref: video-interfaces.yaml#
+            description: Endpoint connected to output device
+
+            properties:
+              bus-type:
+                const: 4
+
+              remote-endpoint: true
+
+    required:
+      - port at 0
+      - port at 1
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - interrupts
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+    csi at 3000 {
+        compatible = "fsl,imx93-mipi-csi2", "snps,dw-mipi-csi2-v150";
+        reg = <0x03000 0x1000>;
+        reg-names = "core";
+        phys = <&mipi_dphy_rx 0>;
+        phy-names = "rx";
+        resets = <&dw_rst 1>;
+        interrupts = <2>;
+
+        ports {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            port at 0 {
+                reg = <0>;
+
+                endpoint {
+                    bus-type = <4>; /* MIPI CSI2 D-PHY */
+                    remote-endpoint = <&camera_1>;
+                    data-lanes = <1 2>;
+                    clock-lanes = <0>;
+                };
+            };
+
+            port at 1 {
+                reg = <1>;
+
+                endpoint {
+                    remote-endpoint = <&idi_receiver>;
+                    bus-type = <4>;
+                };
+            };
+        };
+    };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index edfcee622f74054f519336f0ea963e7c8f2f6add..385b797c1e29c71fb89a908d543cc60806aaa978 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15193,6 +15193,7 @@ F:	Documentation/devicetree/bindings/media/fsl,imx93-parallel-csi.yaml
 F:	Documentation/devicetree/bindings/media/nxp,imx-mipi-csi2.yaml
 F:	Documentation/devicetree/bindings/media/nxp,imx7-csi.yaml
 F:	Documentation/devicetree/bindings/media/nxp,imx8mq-mipi-csi2.yaml
+F:	Documentation/devicetree/bindings/media/snps,dw-mipi-csi2-v150.yaml
 F:	drivers/media/platform/nxp/imx-mipi-csis.c
 F:	drivers/media/platform/nxp/imx-parallel-csi.c
 F:	drivers/media/platform/nxp/imx7-media-csi.c

-- 
2.34.1



From Frank.Li at nxp.com  Fri Aug  8 15:39:05 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:05 -0400
Subject: [PATCH v2 02/32] media: v4l2-common: Add helper function
 v4l_get_required_align_by_bpp()
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <20250808-95_cam-v2-2-4b29fa6919a7@nxp.com>

Add helper v4l_get_required_align_by_bpp() to help get width alignment
requirement. Basic replace below logic and enhance to any 2^[0..31] in
drivers/media/platform/nxp/imx-mipi-csis.c

mipi_csis_set_fmt(
{
        ...

        switch (csis_fmt->width % 8) {
        case 0:
                align = 0;
                break;
        case 4:
                align = 1;
                break;
        case 2:
        case 6:
                align = 2;
                break;
        default:
                /* 1, 3, 5, 7 */
                align = 3;
                break;
        }
	...
}

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
The same patch will be see at https://lore.kernel.org/imx/20250729-imx8qxp_pcam-v4-2-4dfca4ed2f87 at nxp.com/
dw csi2 patch also this
---
 include/media/v4l2-common.h | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index 0a43f56578bce1896cf63e29dd19f58ec0c46bed..a861d83bcd835dc854476b25919383415e5d434f 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -669,4 +669,34 @@ static inline bool v4l2_is_quant_valid(__u8 quantization)
 	       quantization == V4L2_QUANTIZATION_LIM_RANGE;
 }
 
+/**
+ * v4l_get_required_align_by_bpp - get align requirement for
+ *	v4l_bound_align_image(). (bpp * width) % (1 << align) have to be 0.
+ *	given number bpp, get width's alignment requirement. For example,
+ *	if align is 3, means require bpp * width must be multiples of 8.
+ *	    bpp     return  width's requirememnt
+ *	    0       0       none
+ *	    1       3       8 (need 3 zero bits)
+ *	    2       2       4
+ *	    3       3       8
+ *	    4       1       2
+ *	    5       3       8
+ *	    6       2       4
+ *	    7       3       8
+ * @bpp: input bpp
+ * @align: expected alignment, 2^(align).
+ *
+ * return: required alignment.
+ */
+static inline u32 v4l_get_required_align_by_bpp(u32 bpp, u32 align)
+{
+	int pos;
+
+	if (bpp == 0)
+		return 0;
+
+	pos = ffs(bpp) - 1;
+	return pos > align ? 0 : align - pos;
+}
+
 #endif /* V4L2_COMMON_H_ */

-- 
2.34.1



From Frank.Li at nxp.com  Fri Aug  8 15:39:06 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:06 -0400
Subject: [PATCH v2 03/32] media: v4l2-common: Add helper function
 media_bus_fmt_to_csi2_bpp()
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <20250808-95_cam-v2-3-4b29fa6919a7@nxp.com>

Add helper function media_bus_fmt_to_csi2_bpp() to get media bus fmt's bpp
to reduce codes such as

	static const struct imx7_csi_pixfmt pixel_formats[] = {
        {
                .fourcc = V4L2_PIX_FMT_UYVY,
                .codes  = IMX_BUS_FMTS(
                        MEDIA_BUS_FMT_UYVY8_2X8,
                        MEDIA_BUS_FMT_UYVY8_1X16
                ),
                .yuv    = true,
                .bpp    = 16,
        },
	....

.bpp can be removed from pixel_formats with this helper function.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/media/v4l2-core/v4l2-common.c | 176 ++++++++++++++++++++++++++++++++++
 include/media/mipi-csi2.h             |   2 +
 2 files changed, 178 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
index a9bd3ca0f281d557cb80de5e1200c82b5282a70e..3a48b6a55c6e322696b910dd519def4f0b4a58fb 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -43,6 +43,7 @@
 #include <linux/uaccess.h>
 #include <asm/io.h>
 #include <asm/div64.h>
+#include <media/mipi-csi2.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ctrls.h>
@@ -699,3 +700,178 @@ int v4l2_link_freq_to_bitmap(struct device *dev, const u64 *fw_link_freqs,
 	return 0;
 }
 EXPORT_SYMBOL_GPL(v4l2_link_freq_to_bitmap);
+
+int media_bus_fmt_to_csi2_bpp(int bus_fmt)
+{
+	switch (bus_fmt) {
+	case MEDIA_BUS_FMT_SBGGR8_1X8:
+	case MEDIA_BUS_FMT_SGBRG8_1X8:
+	case MEDIA_BUS_FMT_SGRBG8_1X8:
+	case MEDIA_BUS_FMT_SRGGB8_1X8:
+	case MEDIA_BUS_FMT_Y8_1X8:
+	case MEDIA_BUS_FMT_UV8_1X8:
+	case MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8:
+	case MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8:
+	case MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8:
+	case MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8:
+	case MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8:
+	case MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8:
+	case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8:
+	case MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8:
+	case MEDIA_BUS_FMT_META_8:
+	case MEDIA_BUS_FMT_JPEG_1X8:
+		return 8;
+
+	case MEDIA_BUS_FMT_Y10_1X10:
+	case MEDIA_BUS_FMT_SBGGR10_1X10:
+	case MEDIA_BUS_FMT_SGBRG10_1X10:
+	case MEDIA_BUS_FMT_SGRBG10_1X10:
+	case MEDIA_BUS_FMT_SRGGB10_1X10:
+	case MEDIA_BUS_FMT_META_10:
+		return 10;
+
+	case MEDIA_BUS_FMT_RGB444_1X12:
+	case MEDIA_BUS_FMT_Y12_1X12:
+	case MEDIA_BUS_FMT_SBGGR12_1X12:
+	case MEDIA_BUS_FMT_SGBRG12_1X12:
+	case MEDIA_BUS_FMT_SGRBG12_1X12:
+	case MEDIA_BUS_FMT_SRGGB12_1X12:
+	case MEDIA_BUS_FMT_META_12:
+		return 12;
+
+	case MEDIA_BUS_FMT_Y14_1X14:
+	case MEDIA_BUS_FMT_SBGGR14_1X14:
+	case MEDIA_BUS_FMT_SGBRG14_1X14:
+	case MEDIA_BUS_FMT_SGRBG14_1X14:
+	case MEDIA_BUS_FMT_SRGGB14_1X14:
+	case MEDIA_BUS_FMT_META_14:
+		return 14;
+
+	case MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE:
+	case MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE:
+	case MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE:
+	case MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE:
+	case MEDIA_BUS_FMT_RGB565_1X16:
+	case MEDIA_BUS_FMT_BGR565_2X8_BE:
+	case MEDIA_BUS_FMT_BGR565_2X8_LE:
+	case MEDIA_BUS_FMT_RGB565_2X8_BE:
+	case MEDIA_BUS_FMT_RGB565_2X8_LE:
+
+	case MEDIA_BUS_FMT_UYVY8_2X8:
+	case MEDIA_BUS_FMT_VYUY8_2X8:
+	case MEDIA_BUS_FMT_YUYV8_2X8:
+	case MEDIA_BUS_FMT_YVYU8_2X8:
+	case MEDIA_BUS_FMT_Y10_2X8_PADHI_LE:
+	case MEDIA_BUS_FMT_Y16_1X16:
+	case MEDIA_BUS_FMT_UYVY8_1X16:
+	case MEDIA_BUS_FMT_VYUY8_1X16:
+	case MEDIA_BUS_FMT_YUYV8_1X16:
+	case MEDIA_BUS_FMT_YVYU8_1X16:
+	case MEDIA_BUS_FMT_YDYUYDYV8_1X16:
+
+	case MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE:
+	case MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE:
+	case MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE:
+	case MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE:
+	case MEDIA_BUS_FMT_SBGGR16_1X16:
+	case MEDIA_BUS_FMT_SGBRG16_1X16:
+	case MEDIA_BUS_FMT_SRGGB16_1X16:
+	case MEDIA_BUS_FMT_META_16:
+		return 16;
+
+	case MEDIA_BUS_FMT_RGB666_1X18:
+	case MEDIA_BUS_FMT_RGB666_2X9_BE:
+	case MEDIA_BUS_FMT_BGR666_1X18:
+		return 18;
+
+	case MEDIA_BUS_FMT_UYVY10_2X10:
+	case MEDIA_BUS_FMT_VYUY10_2X10:
+	case MEDIA_BUS_FMT_YUYV10_2X10:
+	case MEDIA_BUS_FMT_YVYU10_2X10:
+	case MEDIA_BUS_FMT_UYVY10_1X20:
+	case MEDIA_BUS_FMT_VYUY10_1X20:
+	case MEDIA_BUS_FMT_YUYV10_1X20:
+	case MEDIA_BUS_FMT_YVYU10_1X20:
+	case MEDIA_BUS_FMT_META_20:
+		return 20;
+
+	case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
+		return 21;
+
+	case MEDIA_BUS_FMT_RBG888_1X24:
+	case MEDIA_BUS_FMT_BGR888_3X8:
+	case MEDIA_BUS_FMT_GBR888_1X24:
+	case MEDIA_BUS_FMT_RGB888_1X24:
+	case MEDIA_BUS_FMT_RGB888_2X12_BE:
+	case MEDIA_BUS_FMT_RGB888_2X12_LE:
+	case MEDIA_BUS_FMT_RGB888_3X8:
+	case MEDIA_BUS_FMT_RGB888_3X8_DELTA:
+	case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
+	case MEDIA_BUS_FMT_BGR666_1X24_CPADHI:
+	case MEDIA_BUS_FMT_RGB565_1X24_CPADHI:
+	case MEDIA_BUS_FMT_UYVY12_2X12:
+	case MEDIA_BUS_FMT_VYUY12_2X12:
+	case MEDIA_BUS_FMT_YUYV12_2X12:
+	case MEDIA_BUS_FMT_YVYU12_2X12:
+	case MEDIA_BUS_FMT_VUY8_1X24:
+	case MEDIA_BUS_FMT_YUV8_1X24:
+	case MEDIA_BUS_FMT_UYVY12_1X24:
+	case MEDIA_BUS_FMT_VYUY12_1X24:
+	case MEDIA_BUS_FMT_YUYV12_1X24:
+	case MEDIA_BUS_FMT_YVYU12_1X24:
+	case MEDIA_BUS_FMT_META_24:
+		return 24;
+
+	case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
+	case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
+		return 28;
+
+	case MEDIA_BUS_FMT_RGB666_1X30_CPADLO:
+	case MEDIA_BUS_FMT_RGB888_1X30_CPADLO:
+	case MEDIA_BUS_FMT_RGB101010_1X30:
+	case MEDIA_BUS_FMT_YUV10_1X30:
+		return 30;
+
+	case MEDIA_BUS_FMT_ARGB8888_1X32:
+	case MEDIA_BUS_FMT_RGB888_1X32_PADHI:
+	case MEDIA_BUS_FMT_AYUV8_1X32:
+	case MEDIA_BUS_FMT_AHSV8888_1X32:
+		return 32;
+
+	case MEDIA_BUS_FMT_RGB101010_1X7X5_SPWG:
+	case MEDIA_BUS_FMT_RGB101010_1X7X5_JEIDA:
+		return 35;
+
+	case MEDIA_BUS_FMT_RGB666_1X36_CPADLO:
+	case MEDIA_BUS_FMT_RGB888_1X36_CPADLO:
+	case MEDIA_BUS_FMT_RGB121212_1X36:
+	case MEDIA_BUS_FMT_YUV12_1X36:
+		return 36;
+
+	case MEDIA_BUS_FMT_UYVY8_1_5X8:
+	case MEDIA_BUS_FMT_VYUY8_1_5X8:
+	case MEDIA_BUS_FMT_YUYV8_1_5X8:
+	case MEDIA_BUS_FMT_YVYU8_1_5X8:
+		return 40;
+
+	case MEDIA_BUS_FMT_RGB161616_1X48:
+	case MEDIA_BUS_FMT_YUV16_1X48:
+		return 48;
+
+	case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
+		return 120;
+
+	case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
+		return 150;
+
+	case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
+		return 180;
+
+	case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
+		return 240;
+
+	};
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(media_bus_fmt_to_csi2_bpp);
diff --git a/include/media/mipi-csi2.h b/include/media/mipi-csi2.h
index 40fc0264250d779ab5dfa7d2fe16e6f1382c07d4..c5b4e8e1ca93803568b1eee85f7f99c3a45a0b6e 100644
--- a/include/media/mipi-csi2.h
+++ b/include/media/mipi-csi2.h
@@ -44,4 +44,6 @@
 #define MIPI_CSI2_DT_RAW20		0x2f
 #define MIPI_CSI2_DT_USER_DEFINED(n)	(0x30 + (n))	/* 0..7 */
 
+int media_bus_fmt_to_csi2_bpp(int bus_fmt);
+
 #endif /* _MEDIA_MIPI_CSI2_H */

-- 
2.34.1



From Frank.Li at nxp.com  Fri Aug  8 15:39:07 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:07 -0400
Subject: [PATCH v2 04/32] media: v4l2-common: Add helper function
 media_bus_fmt_to_csi2_dt()
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <20250808-95_cam-v2-4-4b29fa6919a7@nxp.com>

CSI2 data type is defined by MIPI Camera Serial Interface 2 Spec Ver4.1.
See section 9.4.

Add helper function media_bus_fmt_to_csi2_dt() to convert media bus fmt to
MIPI defined data type and avoid below duplicated static array in each CSI2
drivers.

	{
		.code = MEDIA_BUS_FMT_UYVY8_1X16,
		.data_type = MIPI_CSI2_DT_YUV422_8B,
	}

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/media/v4l2-core/v4l2-common.c | 44 +++++++++++++++++++++++++++++++++++
 include/media/mipi-csi2.h             |  3 +++
 2 files changed, 47 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
index 3a48b6a55c6e322696b910dd519def4f0b4a58fb..fcc01030beb347499da2a3c8539793d20f6f512c 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -701,6 +701,50 @@ int v4l2_link_freq_to_bitmap(struct device *dev, const u64 *fw_link_freqs,
 }
 EXPORT_SYMBOL_GPL(v4l2_link_freq_to_bitmap);
 
+int media_bus_fmt_to_csi2_dt(int bus_fmt)
+{
+	switch (bus_fmt) {
+	case MEDIA_BUS_FMT_UYVY8_1X16:
+		return MIPI_CSI2_DT_YUV422_8B;
+	case MEDIA_BUS_FMT_RGB565_1X16:
+		return MIPI_CSI2_DT_RGB565;
+	case MEDIA_BUS_FMT_BGR888_1X24:
+		return MIPI_CSI2_DT_RGB888;
+	case MEDIA_BUS_FMT_SBGGR8_1X8:
+	case MEDIA_BUS_FMT_SGBRG8_1X8:
+	case MEDIA_BUS_FMT_SGRBG8_1X8:
+	case MEDIA_BUS_FMT_SRGGB8_1X8:
+	case MEDIA_BUS_FMT_Y8_1X8:
+		return MIPI_CSI2_DT_RAW8;
+	case MEDIA_BUS_FMT_SBGGR10_1X10:
+	case MEDIA_BUS_FMT_SGBRG10_1X10:
+	case MEDIA_BUS_FMT_SGRBG10_1X10:
+	case MEDIA_BUS_FMT_SRGGB10_1X10:
+	case MEDIA_BUS_FMT_Y10_1X10:
+		return MIPI_CSI2_DT_RAW10;
+	case MEDIA_BUS_FMT_SBGGR12_1X12:
+	case MEDIA_BUS_FMT_SGBRG12_1X12:
+	case MEDIA_BUS_FMT_SGRBG12_1X12:
+	case MEDIA_BUS_FMT_SRGGB12_1X12:
+	case MEDIA_BUS_FMT_Y12_1X12:
+		return MIPI_CSI2_DT_RAW12;
+	case MEDIA_BUS_FMT_SBGGR14_1X14:
+	case MEDIA_BUS_FMT_SGBRG14_1X14:
+	case MEDIA_BUS_FMT_SGRBG14_1X14:
+	case MEDIA_BUS_FMT_SRGGB14_1X14:
+		return MIPI_CSI2_DT_RAW14;
+	case MEDIA_BUS_FMT_SBGGR16_1X16:
+	case MEDIA_BUS_FMT_SGBRG16_1X16:
+	case MEDIA_BUS_FMT_SGRBG16_1X16:
+	case MEDIA_BUS_FMT_SRGGB16_1X16:
+		return MIPI_CSI2_DT_RAW16;
+
+	default:
+		return MIPI_CSI2_DT_NULL;
+	}
+}
+EXPORT_SYMBOL_GPL(media_bus_fmt_to_csi2_dt);
+
 int media_bus_fmt_to_csi2_bpp(int bus_fmt)
 {
 	switch (bus_fmt) {
diff --git a/include/media/mipi-csi2.h b/include/media/mipi-csi2.h
index c5b4e8e1ca93803568b1eee85f7f99c3a45a0b6e..35de536b9b65b49ad9e2914437d26d0e4240cf38 100644
--- a/include/media/mipi-csi2.h
+++ b/include/media/mipi-csi2.h
@@ -8,6 +8,8 @@
 #ifndef _MEDIA_MIPI_CSI2_H
 #define _MEDIA_MIPI_CSI2_H
 
+/* DT value ref to MIPI Camera Serial Interface 2 Spec Ver4.1 section 9.4 */
+
 /* Short packet data types */
 #define MIPI_CSI2_DT_FS			0x00
 #define MIPI_CSI2_DT_FE			0x01
@@ -44,6 +46,7 @@
 #define MIPI_CSI2_DT_RAW20		0x2f
 #define MIPI_CSI2_DT_USER_DEFINED(n)	(0x30 + (n))	/* 0..7 */
 
+int media_bus_fmt_to_csi2_dt(int buf_fmt);
 int media_bus_fmt_to_csi2_bpp(int bus_fmt);
 
 #endif /* _MEDIA_MIPI_CSI2_H */

-- 
2.34.1



From Frank.Li at nxp.com  Fri Aug  8 15:39:08 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:08 -0400
Subject: [PATCH v2 05/32] media: staging: media: imx6-mipi-csi2: replace
 space with tab for alignment
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <20250808-95_cam-v2-5-4b29fa6919a7@nxp.com>

Replace space with tab to follow coding convention. No functional change.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/staging/media/imx/imx6-mipi-csi2.c | 92 +++++++++++++++---------------
 1 file changed, 46 insertions(+), 46 deletions(-)

diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index dd8c7b3233bccfc34b59e0f0ff813b36752e1526..42256441b881d9f132ad7ff899d6f1e35643b4ac 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -23,65 +23,65 @@
  * there must be 5 pads: 1 input pad from sensor, and
  * the 4 virtual channel output pads
  */
-#define CSI2_SINK_PAD       0
-#define CSI2_NUM_SINK_PADS  1
-#define CSI2_NUM_SRC_PADS   4
-#define CSI2_NUM_PADS       5
+#define CSI2_SINK_PAD		0
+#define CSI2_NUM_SINK_PADS	1
+#define CSI2_NUM_SRC_PADS	4
+#define CSI2_NUM_PADS		5
 
 /*
  * The default maximum bit-rate per lane in Mbps, if the
  * source subdev does not provide V4L2_CID_LINK_FREQ.
  */
-#define CSI2_DEFAULT_MAX_MBPS 849
+#define CSI2_DEFAULT_MAX_MBPS	849
 
 struct csi2_dev {
-	struct device          *dev;
-	struct v4l2_subdev      sd;
-	struct v4l2_async_notifier notifier;
-	struct media_pad       pad[CSI2_NUM_PADS];
-	struct clk             *dphy_clk;
-	struct clk             *pllref_clk;
-	struct clk             *pix_clk; /* what is this? */
-	void __iomem           *base;
-
-	struct v4l2_subdev	*remote;
-	unsigned int		remote_pad;
-	unsigned short		data_lanes;
+	struct device			*dev;
+	struct v4l2_subdev		sd;
+	struct v4l2_async_notifier	notifier;
+	struct media_pad		pad[CSI2_NUM_PADS];
+	struct clk			*dphy_clk;
+	struct clk			*pllref_clk;
+	struct clk			*pix_clk; /* what is this? */
+	void __iomem			*base;
+
+	struct v4l2_subdev		*remote;
+	unsigned int			remote_pad;
+	unsigned short			data_lanes;
 
 	/* lock to protect all members below */
-	struct mutex lock;
+	struct mutex			lock;
 
-	struct v4l2_mbus_framefmt format_mbus;
+	struct v4l2_mbus_framefmt	format_mbus;
 
-	int                     stream_count;
-	struct v4l2_subdev      *src_sd;
-	bool                    sink_linked[CSI2_NUM_SRC_PADS];
+	int				stream_count;
+	struct v4l2_subdev		*src_sd;
+	bool				sink_linked[CSI2_NUM_SRC_PADS];
 };
 
 #define DEVICE_NAME "imx6-mipi-csi2"
 
 /* Register offsets */
-#define CSI2_VERSION            0x000
-#define CSI2_N_LANES            0x004
-#define CSI2_PHY_SHUTDOWNZ      0x008
-#define CSI2_DPHY_RSTZ          0x00c
-#define CSI2_RESETN             0x010
-#define CSI2_PHY_STATE          0x014
-#define PHY_STOPSTATEDATA_BIT   4
-#define PHY_STOPSTATEDATA(n)    BIT(PHY_STOPSTATEDATA_BIT + (n))
-#define PHY_RXCLKACTIVEHS       BIT(8)
-#define PHY_RXULPSCLKNOT        BIT(9)
-#define PHY_STOPSTATECLK        BIT(10)
-#define CSI2_DATA_IDS_1         0x018
-#define CSI2_DATA_IDS_2         0x01c
-#define CSI2_ERR1               0x020
-#define CSI2_ERR2               0x024
-#define CSI2_MSK1               0x028
-#define CSI2_MSK2               0x02c
-#define CSI2_PHY_TST_CTRL0      0x030
+#define CSI2_VERSION		0x000
+#define CSI2_N_LANES		0x004
+#define CSI2_PHY_SHUTDOWNZ	0x008
+#define CSI2_DPHY_RSTZ		0x00c
+#define CSI2_RESETN		0x010
+#define CSI2_PHY_STATE		0x014
+#define PHY_STOPSTATEDATA_BIT	4
+#define PHY_STOPSTATEDATA(n)	BIT(PHY_STOPSTATEDATA_BIT + (n))
+#define PHY_RXCLKACTIVEHS	BIT(8)
+#define PHY_RXULPSCLKNOT	BIT(9)
+#define PHY_STOPSTATECLK	BIT(10)
+#define CSI2_DATA_IDS_1		0x018
+#define CSI2_DATA_IDS_2		0x01c
+#define CSI2_ERR1		0x020
+#define CSI2_ERR2		0x024
+#define CSI2_MSK1		0x028
+#define CSI2_MSK2		0x02c
+#define CSI2_PHY_TST_CTRL0	0x030
 #define PHY_TESTCLR		BIT(0)
 #define PHY_TESTCLK		BIT(1)
-#define CSI2_PHY_TST_CTRL1      0x034
+#define CSI2_PHY_TST_CTRL1	0x034
 #define PHY_TESTEN		BIT(16)
 /*
  * i.MX CSI2IPU Gasket registers follow. The CSI2IPU gasket is
@@ -106,13 +106,13 @@ static inline struct csi2_dev *notifier_to_dev(struct v4l2_async_notifier *n)
  * reference manual is as follows:
  *
  * 1. Deassert presetn signal (global reset).
- *        It's not clear what this "global reset" signal is (maybe APB
- *        global reset), but in any case this step would be probably
- *        be carried out during driver load in csi2_probe().
+ *	It's not clear what this "global reset" signal is (maybe APB
+ *	global reset), but in any case this step would be probably
+ *	be carried out during driver load in csi2_probe().
  *
  * 2. Configure MIPI Camera Sensor to put all Tx lanes in LP-11 state.
- *        This must be carried out by the MIPI sensor's s_power(ON) subdev
- *        op.
+ *	This must be carried out by the MIPI sensor's s_power(ON) subdev
+ *	op.
  *
  * 3. D-PHY initialization.
  * 4. CSI2 Controller programming (Set N_LANES, deassert PHY_SHUTDOWNZ,

-- 
2.34.1



From Frank.Li at nxp.com  Fri Aug  8 15:39:09 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:09 -0400
Subject: [PATCH v2 06/32] media: staging: media: imx6-mipi-csi2: use
 devm_add_action_or_reset() to simplify code
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <20250808-95_cam-v2-6-4b29fa6919a7@nxp.com>

Use devm_add_action_or_reset() to simplify the code. No functional change.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/staging/media/imx/imx6-mipi-csi2.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index 42256441b881d9f132ad7ff899d6f1e35643b4ac..eba9a650030f5e380aa900b94728ad375171c6a5 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -716,6 +716,14 @@ static int csi2_async_register(struct csi2_dev *csi2)
 	return ret;
 }
 
+static void csi2_nf_cleanup(void *data)
+{
+	struct csi2_dev *csi2 = data;
+
+	v4l2_async_nf_unregister(&csi2->notifier);
+	v4l2_async_nf_cleanup(&csi2->notifier);
+}
+
 static int csi2_probe(struct platform_device *pdev)
 {
 	struct csi2_dev *csi2;
@@ -749,6 +757,10 @@ static int csi2_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	ret = devm_add_action_or_reset(&pdev->dev, csi2_nf_cleanup, csi2);
+	if (ret)
+		return ret;
+
 	csi2->pllref_clk = devm_clk_get(&pdev->dev, "ref");
 	if (IS_ERR(csi2->pllref_clk)) {
 		v4l2_err(&csi2->sd, "failed to get pll reference clock\n");
@@ -800,8 +812,6 @@ static int csi2_probe(struct platform_device *pdev)
 	return 0;
 
 clean_notifier:
-	v4l2_async_nf_unregister(&csi2->notifier);
-	v4l2_async_nf_cleanup(&csi2->notifier);
 	clk_disable_unprepare(csi2->dphy_clk);
 pllref_off:
 	clk_disable_unprepare(csi2->pllref_clk);
@@ -815,8 +825,6 @@ static void csi2_remove(struct platform_device *pdev)
 	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
 	struct csi2_dev *csi2 = sd_to_dev(sd);
 
-	v4l2_async_nf_unregister(&csi2->notifier);
-	v4l2_async_nf_cleanup(&csi2->notifier);
 	v4l2_async_unregister_subdev(sd);
 	clk_disable_unprepare(csi2->dphy_clk);
 	clk_disable_unprepare(csi2->pllref_clk);

-- 
2.34.1



From Frank.Li at nxp.com  Fri Aug  8 15:39:10 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:10 -0400
Subject: [PATCH v2 07/32] media: staging: media: imx6-mipi-csi2: use
 devm_clk_bulk_get_all() to fetch clocks
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <20250808-95_cam-v2-7-4b29fa6919a7@nxp.com>

Use devm_clk_bulk_get_all_enabled() helper to simplify clock handling.

Defer all clock prepare and enable to csi2_start(), which previous only
enable pix clock here.

We can safely do that because there are not register access before
csi2_start().

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/staging/media/imx/imx6-mipi-csi2.c | 52 ++++++------------------------
 1 file changed, 9 insertions(+), 43 deletions(-)

diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index eba9a650030f5e380aa900b94728ad375171c6a5..32ddcef7ec8535a44e121754bb621c0d2e226369 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -39,11 +39,11 @@ struct csi2_dev {
 	struct v4l2_subdev		sd;
 	struct v4l2_async_notifier	notifier;
 	struct media_pad		pad[CSI2_NUM_PADS];
-	struct clk			*dphy_clk;
-	struct clk			*pllref_clk;
-	struct clk			*pix_clk; /* what is this? */
 	void __iomem			*base;
 
+	struct clk_bulk_data		*clks;
+	int				num_clks;
+
 	struct v4l2_subdev		*remote;
 	unsigned int			remote_pad;
 	unsigned short			data_lanes;
@@ -343,7 +343,7 @@ static int csi2_start(struct csi2_dev *csi2)
 	unsigned int lanes;
 	int ret;
 
-	ret = clk_prepare_enable(csi2->pix_clk);
+	ret = clk_bulk_prepare_enable(csi2->num_clks, csi2->clks);
 	if (ret)
 		return ret;
 
@@ -390,7 +390,7 @@ static int csi2_start(struct csi2_dev *csi2)
 err_assert_reset:
 	csi2_enable(csi2, false);
 err_disable_clk:
-	clk_disable_unprepare(csi2->pix_clk);
+	clk_bulk_disable_unprepare(csi2->num_clks, csi2->clks);
 	return ret;
 }
 
@@ -401,7 +401,7 @@ static void csi2_stop(struct csi2_dev *csi2)
 	v4l2_subdev_call(csi2->src_sd, video, post_streamoff);
 
 	csi2_enable(csi2, false);
-	clk_disable_unprepare(csi2->pix_clk);
+	clk_bulk_disable_unprepare(csi2->num_clks, csi2->clks);
 }
 
 /*
@@ -761,24 +761,6 @@ static int csi2_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	csi2->pllref_clk = devm_clk_get(&pdev->dev, "ref");
-	if (IS_ERR(csi2->pllref_clk)) {
-		v4l2_err(&csi2->sd, "failed to get pll reference clock\n");
-		return PTR_ERR(csi2->pllref_clk);
-	}
-
-	csi2->dphy_clk = devm_clk_get(&pdev->dev, "dphy");
-	if (IS_ERR(csi2->dphy_clk)) {
-		v4l2_err(&csi2->sd, "failed to get dphy clock\n");
-		return PTR_ERR(csi2->dphy_clk);
-	}
-
-	csi2->pix_clk = devm_clk_get(&pdev->dev, "pix");
-	if (IS_ERR(csi2->pix_clk)) {
-		v4l2_err(&csi2->sd, "failed to get pixel clock\n");
-		return PTR_ERR(csi2->pix_clk);
-	}
-
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
 		v4l2_err(&csi2->sd, "failed to get platform resources\n");
@@ -791,19 +773,9 @@ static int csi2_probe(struct platform_device *pdev)
 
 	mutex_init(&csi2->lock);
 
-	ret = clk_prepare_enable(csi2->pllref_clk);
-	if (ret) {
-		v4l2_err(&csi2->sd, "failed to enable pllref_clk\n");
-		goto rmmutex;
-	}
-
-	ret = clk_prepare_enable(csi2->dphy_clk);
-	if (ret) {
-		v4l2_err(&csi2->sd, "failed to enable dphy_clk\n");
-		goto pllref_off;
-	}
-
-	platform_set_drvdata(pdev, &csi2->sd);
+	csi2->num_clks = devm_clk_bulk_get_all(&pdev->dev, &csi2->clks);
+	if (csi2->num_clks < 0)
+		return dev_err_probe(&pdev->dev, csi2->num_clks, "Failed to get clocks\n");
 
 	ret = csi2_async_register(csi2);
 	if (ret)
@@ -812,10 +784,6 @@ static int csi2_probe(struct platform_device *pdev)
 	return 0;
 
 clean_notifier:
-	clk_disable_unprepare(csi2->dphy_clk);
-pllref_off:
-	clk_disable_unprepare(csi2->pllref_clk);
-rmmutex:
 	mutex_destroy(&csi2->lock);
 	return ret;
 }
@@ -826,8 +794,6 @@ static void csi2_remove(struct platform_device *pdev)
 	struct csi2_dev *csi2 = sd_to_dev(sd);
 
 	v4l2_async_unregister_subdev(sd);
-	clk_disable_unprepare(csi2->dphy_clk);
-	clk_disable_unprepare(csi2->pllref_clk);
 	mutex_destroy(&csi2->lock);
 	media_entity_cleanup(&sd->entity);
 }

-- 
2.34.1



From Frank.Li at nxp.com  Fri Aug  8 15:39:11 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:11 -0400
Subject: [PATCH v2 08/32] media: staging: media: imx6-mipi-csi2: use
 devm_mutex_init() to simplify code
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <20250808-95_cam-v2-8-4b29fa6919a7@nxp.com>

Use devm_mutex_init() to simplify the code. No functional change.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/staging/media/imx/imx6-mipi-csi2.c | 13 ++-----------
 1 file changed, 2 insertions(+), 11 deletions(-)

diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index 32ddcef7ec8535a44e121754bb621c0d2e226369..72ede5ebf4d4c426e62cf288225a2b2dd7cfe1bd 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -771,30 +771,21 @@ static int csi2_probe(struct platform_device *pdev)
 	if (!csi2->base)
 		return -ENOMEM;
 
-	mutex_init(&csi2->lock);
+	devm_mutex_init(&pdev->dev, &csi2->lock);
 
 	csi2->num_clks = devm_clk_bulk_get_all(&pdev->dev, &csi2->clks);
 	if (csi2->num_clks < 0)
 		return dev_err_probe(&pdev->dev, csi2->num_clks, "Failed to get clocks\n");
 
-	ret = csi2_async_register(csi2);
-	if (ret)
-		goto clean_notifier;
-
-	return 0;
+	return csi2_async_register(csi2);
 
-clean_notifier:
-	mutex_destroy(&csi2->lock);
-	return ret;
 }
 
 static void csi2_remove(struct platform_device *pdev)
 {
 	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
-	struct csi2_dev *csi2 = sd_to_dev(sd);
 
 	v4l2_async_unregister_subdev(sd);
-	mutex_destroy(&csi2->lock);
 	media_entity_cleanup(&sd->entity);
 }
 

-- 
2.34.1



From Frank.Li at nxp.com  Fri Aug  8 15:39:12 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:12 -0400
Subject: [PATCH v2 09/32] media: staging: media: imx6-mipi-csi2: use
 guard() to simplify code
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <20250808-95_cam-v2-9-4b29fa6919a7@nxp.com>

Use guard() to simplify mutex locking. No functional change.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/staging/media/imx/imx6-mipi-csi2.c | 54 +++++++++++-------------------
 1 file changed, 19 insertions(+), 35 deletions(-)

diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index 72ede5ebf4d4c426e62cf288225a2b2dd7cfe1bd..73278d9ec2d66afa33b2bea17f2d56bb1391108b 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -413,21 +413,17 @@ static int csi2_s_stream(struct v4l2_subdev *sd, int enable)
 	struct csi2_dev *csi2 = sd_to_dev(sd);
 	int i, ret = 0;
 
-	mutex_lock(&csi2->lock);
+	guard(mutex)(&csi2->lock);
 
-	if (!csi2->src_sd) {
-		ret = -EPIPE;
-		goto out;
-	}
+	if (!csi2->src_sd)
+		return -EPIPE;
 
 	for (i = 0; i < CSI2_NUM_SRC_PADS; i++) {
 		if (csi2->sink_linked[i])
 			break;
 	}
-	if (i >= CSI2_NUM_SRC_PADS) {
-		ret = -EPIPE;
-		goto out;
-	}
+	if (i >= CSI2_NUM_SRC_PADS)
+		return -EPIPE;
 
 	/*
 	 * enable/disable streaming only if stream_count is
@@ -442,14 +438,12 @@ static int csi2_s_stream(struct v4l2_subdev *sd, int enable)
 	else
 		csi2_stop(csi2);
 	if (ret)
-		goto out;
+		return ret;
 
 update_count:
 	csi2->stream_count += enable ? 1 : -1;
 	if (csi2->stream_count < 0)
 		csi2->stream_count = 0;
-out:
-	mutex_unlock(&csi2->lock);
 	return ret;
 }
 
@@ -467,32 +461,28 @@ static int csi2_link_setup(struct media_entity *entity,
 
 	remote_sd = media_entity_to_v4l2_subdev(remote->entity);
 
-	mutex_lock(&csi2->lock);
+	guard(mutex)(&csi2->lock);
 
 	if (local->flags & MEDIA_PAD_FL_SOURCE) {
 		if (flags & MEDIA_LNK_FL_ENABLED) {
-			if (csi2->sink_linked[local->index - 1]) {
-				ret = -EBUSY;
-				goto out;
-			}
+			if (csi2->sink_linked[local->index - 1])
+				return -EBUSY;
+
 			csi2->sink_linked[local->index - 1] = true;
 		} else {
 			csi2->sink_linked[local->index - 1] = false;
 		}
 	} else {
 		if (flags & MEDIA_LNK_FL_ENABLED) {
-			if (csi2->src_sd) {
-				ret = -EBUSY;
-				goto out;
-			}
+			if (csi2->src_sd)
+				return -EBUSY;
+
 			csi2->src_sd = remote_sd;
 		} else {
 			csi2->src_sd = NULL;
 		}
 	}
 
-out:
-	mutex_unlock(&csi2->lock);
 	return ret;
 }
 
@@ -513,14 +503,12 @@ static int csi2_get_fmt(struct v4l2_subdev *sd,
 	struct csi2_dev *csi2 = sd_to_dev(sd);
 	struct v4l2_mbus_framefmt *fmt;
 
-	mutex_lock(&csi2->lock);
+	guard(mutex)(&csi2->lock);
 
 	fmt = __csi2_get_fmt(csi2, sd_state, sdformat->pad, sdformat->which);
 
 	sdformat->format = *fmt;
 
-	mutex_unlock(&csi2->lock);
-
 	return 0;
 }
 
@@ -530,17 +518,14 @@ static int csi2_set_fmt(struct v4l2_subdev *sd,
 {
 	struct csi2_dev *csi2 = sd_to_dev(sd);
 	struct v4l2_mbus_framefmt *fmt;
-	int ret = 0;
 
 	if (sdformat->pad >= CSI2_NUM_PADS)
 		return -EINVAL;
 
-	mutex_lock(&csi2->lock);
+	guard(mutex)(&csi2->lock);
 
-	if (csi2->stream_count > 0) {
-		ret = -EBUSY;
-		goto out;
-	}
+	if (csi2->stream_count > 0)
+		return -EBUSY;
 
 	/* Output pads mirror active input pad, no limits on input pads */
 	if (sdformat->pad != CSI2_SINK_PAD)
@@ -549,9 +534,8 @@ static int csi2_set_fmt(struct v4l2_subdev *sd,
 	fmt = __csi2_get_fmt(csi2, sd_state, sdformat->pad, sdformat->which);
 
 	*fmt = sdformat->format;
-out:
-	mutex_unlock(&csi2->lock);
-	return ret;
+
+	return 0;
 }
 
 static int csi2_registered(struct v4l2_subdev *sd)

-- 
2.34.1



From Frank.Li at nxp.com  Fri Aug  8 15:39:13 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:13 -0400
Subject: [PATCH v2 10/32] media: staging: media: imx6-mipi-csi2: use
 register structure to match hardware
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <20250808-95_cam-v2-10-4b29fa6919a7@nxp.com>

Use register structure to handle different versions of the DesignWare CSI2
controller, as register offsets slightly differ between versions. Add
register existence bits to detect invalid register access when using
different versions of the CSI2 controller.

No functional change.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/staging/media/imx/imx6-mipi-csi2.c | 165 +++++++++++++++++------------
 1 file changed, 96 insertions(+), 69 deletions(-)

diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index 73278d9ec2d66afa33b2bea17f2d56bb1391108b..cef9a5dbca40c94a36d5d8473d3b7d9806381bf9 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -34,12 +34,30 @@
  */
 #define CSI2_DEFAULT_MAX_MBPS	849
 
+struct dw_csi2_regs {
+	u32	version;
+	u32	n_lanes;
+	u32	phy_shutdownz;
+	u32	dphy_rstz;
+	u32	resetn;
+	u32	phy_state;
+	u32	data_ids_1;
+	u32	data_ids_2;
+	u32	err1;
+	u32	err2;
+	u32	msk1;
+	u32	msk2;
+	u32	phy_tst_ctrl0;
+	u32	phy_tst_ctrl1;
+};
+
 struct csi2_dev {
 	struct device			*dev;
 	struct v4l2_subdev		sd;
 	struct v4l2_async_notifier	notifier;
 	struct media_pad		pad[CSI2_NUM_PADS];
 	void __iomem			*base;
+	const struct dw_csi2_regs	*regs;
 
 	struct clk_bulk_data		*clks;
 	int				num_clks;
@@ -60,28 +78,53 @@ struct csi2_dev {
 
 #define DEVICE_NAME "imx6-mipi-csi2"
 
-/* Register offsets */
-#define CSI2_VERSION		0x000
-#define CSI2_N_LANES		0x004
-#define CSI2_PHY_SHUTDOWNZ	0x008
-#define CSI2_DPHY_RSTZ		0x00c
-#define CSI2_RESETN		0x010
-#define CSI2_PHY_STATE		0x014
+/* Help check wrong access unexisted register at difference IP version */
+#define DW_REG_EXIST		0x80000000
+#define DW_REG(x)		(DW_REG_EXIST | (x))
+
+/* Register offsets for v0 */
+static const struct dw_csi2_regs dw_csi2_v0 = {
+	.version = DW_REG(0x0),
+	.n_lanes = DW_REG(0x4),
+	.phy_shutdownz = DW_REG(0x8),
+	.dphy_rstz = DW_REG(0xc),
+	.resetn = DW_REG(0x10),
+	.phy_state = DW_REG(0x14),
+	.data_ids_1 = DW_REG(0x18),
+	.data_ids_2 = DW_REG(0x1c),
+	.err1 = DW_REG(0x20),
+	.err2 = DW_REG(0x24),
+	.msk1 = DW_REG(0x28),
+	.msk2 = DW_REG(0x2c),
+	.phy_tst_ctrl0 = DW_REG(0x30),
+	.phy_tst_ctrl1 = DW_REG(0x34),
+};
+
+static int dw_csi2_reg_err(struct csi2_dev *csi2, const char *name)
+{
+	dev_err_once(csi2->dev, "access to unexisted register: %s", name);
+	return 0;
+}
+
+#define dw_reg_exist(csi2, __name) ((csi2)->regs->__name & DW_REG_EXIST)
+
+#define dw_writel(csi2, value, __name) (dw_reg_exist((csi2), __name) ? \
+writel(value, (csi2)->base + (csi2->regs->__name & ~DW_REG_EXIST)) : \
+dw_csi2_reg_err((csi2), #__name))
+
+#define dw_readl(csi2, __name) (dw_reg_exist((csi2), __name) ? \
+readl((csi2)->base + ((csi2)->regs->__name & ~DW_REG_EXIST)) : \
+dw_csi2_reg_err(csi2, #__name))
+
 #define PHY_STOPSTATEDATA_BIT	4
 #define PHY_STOPSTATEDATA(n)	BIT(PHY_STOPSTATEDATA_BIT + (n))
 #define PHY_RXCLKACTIVEHS	BIT(8)
 #define PHY_RXULPSCLKNOT	BIT(9)
 #define PHY_STOPSTATECLK	BIT(10)
-#define CSI2_DATA_IDS_1		0x018
-#define CSI2_DATA_IDS_2		0x01c
-#define CSI2_ERR1		0x020
-#define CSI2_ERR2		0x024
-#define CSI2_MSK1		0x028
-#define CSI2_MSK2		0x02c
-#define CSI2_PHY_TST_CTRL0	0x030
+
 #define PHY_TESTCLR		BIT(0)
 #define PHY_TESTCLK		BIT(1)
-#define CSI2_PHY_TST_CTRL1	0x034
+
 #define PHY_TESTEN		BIT(16)
 /*
  * i.MX CSI2IPU Gasket registers follow. The CSI2IPU gasket is
@@ -132,42 +175,42 @@ static inline struct csi2_dev *notifier_to_dev(struct v4l2_async_notifier *n)
 static void csi2_enable(struct csi2_dev *csi2, bool enable)
 {
 	if (enable) {
-		writel(0x1, csi2->base + CSI2_PHY_SHUTDOWNZ);
-		writel(0x1, csi2->base + CSI2_DPHY_RSTZ);
-		writel(0x1, csi2->base + CSI2_RESETN);
+		dw_writel(csi2, 0x1, phy_shutdownz);
+		dw_writel(csi2, 0x1, dphy_rstz);
+		dw_writel(csi2, 0x1, resetn);
 	} else {
-		writel(0x0, csi2->base + CSI2_PHY_SHUTDOWNZ);
-		writel(0x0, csi2->base + CSI2_DPHY_RSTZ);
-		writel(0x0, csi2->base + CSI2_RESETN);
+		dw_writel(csi2, 0x0, phy_shutdownz);
+		dw_writel(csi2, 0x0, dphy_rstz);
+		dw_writel(csi2, 0x0, resetn);
 	}
 }
 
 static void csi2_set_lanes(struct csi2_dev *csi2, unsigned int lanes)
 {
-	writel(lanes - 1, csi2->base + CSI2_N_LANES);
+	dw_writel(csi2, lanes - 1, n_lanes);
 }
 
 static void dw_mipi_csi2_phy_write(struct csi2_dev *csi2,
 				   u32 test_code, u32 test_data)
 {
 	/* Clear PHY test interface */
-	writel(PHY_TESTCLR, csi2->base + CSI2_PHY_TST_CTRL0);
-	writel(0x0, csi2->base + CSI2_PHY_TST_CTRL1);
-	writel(0x0, csi2->base + CSI2_PHY_TST_CTRL0);
+	dw_writel(csi2, PHY_TESTCLR, phy_tst_ctrl0);
+	dw_writel(csi2, 0x0, phy_tst_ctrl1);
+	dw_writel(csi2, 0x0, phy_tst_ctrl0);
 
 	/* Raise test interface strobe signal */
-	writel(PHY_TESTCLK, csi2->base + CSI2_PHY_TST_CTRL0);
+	dw_writel(csi2, PHY_TESTCLK, phy_tst_ctrl0);
 
 	/* Configure address write on falling edge and lower strobe signal */
-	writel(PHY_TESTEN | test_code, csi2->base + CSI2_PHY_TST_CTRL1);
-	writel(0x0, csi2->base + CSI2_PHY_TST_CTRL0);
+	dw_writel(csi2, PHY_TESTEN | test_code, phy_tst_ctrl1);
+	dw_writel(csi2, 0x0, phy_tst_ctrl0);
 
 	/* Configure data write on rising edge and raise strobe signal */
-	writel(test_data, csi2->base + CSI2_PHY_TST_CTRL1);
-	writel(PHY_TESTCLK, csi2->base + CSI2_PHY_TST_CTRL0);
+	dw_writel(csi2, test_data, phy_tst_ctrl1);
+	dw_writel(csi2, PHY_TESTCLK, phy_tst_ctrl0);
 
 	/* Clear strobe signal */
-	writel(0x0, csi2->base + CSI2_PHY_TST_CTRL0);
+	dw_writel(csi2, 0x0, phy_tst_ctrl0);
 }
 
 /*
@@ -233,16 +276,15 @@ static int __maybe_unused csi2_dphy_wait_ulp(struct csi2_dev *csi2)
 	int ret;
 
 	/* wait for ULP on clock lane */
-	ret = readl_poll_timeout(csi2->base + CSI2_PHY_STATE, reg,
-				 !(reg & PHY_RXULPSCLKNOT), 0, 500000);
+	ret = read_poll_timeout(dw_readl, reg, !(reg & PHY_RXULPSCLKNOT),
+				0, 500000, 0, csi2, phy_state);
 	if (ret) {
 		v4l2_err(&csi2->sd, "ULP timeout, phy_state = 0x%08x\n", reg);
 		return ret;
 	}
 
 	/* wait until no errors on bus */
-	ret = readl_poll_timeout(csi2->base + CSI2_ERR1, reg,
-				 reg == 0x0, 0, 500000);
+	ret = read_poll_timeout(dw_readl, reg, reg == 0x0, 0, 500000, 0, csi2, err1);
 	if (ret) {
 		v4l2_err(&csi2->sd, "stable bus timeout, err1 = 0x%08x\n", reg);
 		return ret;
@@ -259,8 +301,7 @@ static void csi2_dphy_wait_stopstate(struct csi2_dev *csi2, unsigned int lanes)
 
 	mask = PHY_STOPSTATECLK | (((1 << lanes) - 1) << PHY_STOPSTATEDATA_BIT);
 
-	ret = readl_poll_timeout(csi2->base + CSI2_PHY_STATE, reg,
-				 (reg & mask) == mask, 0, 500000);
+	ret = read_poll_timeout(dw_readl, reg, (reg & mask) == mask, 0, 500000, 0, csi2, phy_state);
 	if (ret) {
 		v4l2_warn(&csi2->sd, "LP-11 wait timeout, likely a sensor driver bug, expect capture failures.\n");
 		v4l2_warn(&csi2->sd, "phy_state = 0x%08x\n", reg);
@@ -273,8 +314,8 @@ static int csi2_dphy_wait_clock_lane(struct csi2_dev *csi2)
 	u32 reg;
 	int ret;
 
-	ret = readl_poll_timeout(csi2->base + CSI2_PHY_STATE, reg,
-				 (reg & PHY_RXCLKACTIVEHS), 0, 500000);
+	ret = read_poll_timeout(dw_readl, reg, (reg & PHY_RXCLKACTIVEHS),
+				0, 500000, 0, csi2, phy_state);
 	if (ret) {
 		v4l2_err(&csi2->sd, "clock lane timeout, phy_state = 0x%08x\n",
 			 reg);
@@ -556,34 +597,20 @@ static int csi2_log_status(struct v4l2_subdev *sd)
 	struct csi2_dev *csi2 = sd_to_dev(sd);
 
 	v4l2_info(sd, "-----MIPI CSI status-----\n");
-	v4l2_info(sd, "VERSION: 0x%x\n",
-		  readl(csi2->base + CSI2_VERSION));
-	v4l2_info(sd, "N_LANES: 0x%x\n",
-		  readl(csi2->base + CSI2_N_LANES));
-	v4l2_info(sd, "PHY_SHUTDOWNZ: 0x%x\n",
-		  readl(csi2->base + CSI2_PHY_SHUTDOWNZ));
-	v4l2_info(sd, "DPHY_RSTZ: 0x%x\n",
-		  readl(csi2->base + CSI2_DPHY_RSTZ));
-	v4l2_info(sd, "RESETN: 0x%x\n",
-		  readl(csi2->base + CSI2_RESETN));
-	v4l2_info(sd, "PHY_STATE: 0x%x\n",
-		  readl(csi2->base + CSI2_PHY_STATE));
-	v4l2_info(sd, "DATA_IDS_1: 0x%x\n",
-		  readl(csi2->base + CSI2_DATA_IDS_1));
-	v4l2_info(sd, "DATA_IDS_2: 0x%x\n",
-		  readl(csi2->base + CSI2_DATA_IDS_2));
-	v4l2_info(sd, "ERR1: 0x%x\n",
-		  readl(csi2->base + CSI2_ERR1));
-	v4l2_info(sd, "ERR2: 0x%x\n",
-		  readl(csi2->base + CSI2_ERR2));
-	v4l2_info(sd, "MSK1: 0x%x\n",
-		  readl(csi2->base + CSI2_MSK1));
-	v4l2_info(sd, "MSK2: 0x%x\n",
-		  readl(csi2->base + CSI2_MSK2));
-	v4l2_info(sd, "PHY_TST_CTRL0: 0x%x\n",
-		  readl(csi2->base + CSI2_PHY_TST_CTRL0));
-	v4l2_info(sd, "PHY_TST_CTRL1: 0x%x\n",
-		  readl(csi2->base + CSI2_PHY_TST_CTRL1));
+	v4l2_info(sd, "VERSION: 0x%x\n", dw_readl(csi2, version));
+	v4l2_info(sd, "N_LANES: 0x%x\n", dw_readl(csi2, n_lanes));
+	v4l2_info(sd, "PHY_SHUTDOWNZ: 0x%x\n", dw_readl(csi2, phy_shutdownz));
+	v4l2_info(sd, "DPHY_RSTZ: 0x%x\n", dw_readl(csi2, dphy_rstz));
+	v4l2_info(sd, "RESETN: 0x%x\n", dw_readl(csi2, resetn));
+	v4l2_info(sd, "PHY_STATE: 0x%x\n", dw_readl(csi2, phy_state));
+	v4l2_info(sd, "DATA_IDS_1: 0x%x\n", dw_readl(csi2, data_ids_1));
+	v4l2_info(sd, "DATA_IDS_2: 0x%x\n", dw_readl(csi2, data_ids_2));
+	v4l2_info(sd, "ERR1: 0x%x\n", dw_readl(csi2, err1));
+	v4l2_info(sd, "ERR2: 0x%x\n", dw_readl(csi2, err2));
+	v4l2_info(sd, "MSK1: 0x%x\n", dw_readl(csi2, msk1));
+	v4l2_info(sd, "MSK2: 0x%x\n", dw_readl(csi2, msk2));
+	v4l2_info(sd, "PHY_TST_CTRL0: 0x%x\n", dw_readl(csi2, phy_tst_ctrl0));
+	v4l2_info(sd, "PHY_TST_CTRL1: 0x%x\n", dw_readl(csi2, phy_tst_ctrl1));
 
 	return 0;
 }
@@ -719,7 +746,7 @@ static int csi2_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	csi2->dev = &pdev->dev;
-
+	csi2->regs = &dw_csi2_v0;
 	v4l2_subdev_init(&csi2->sd, &csi2_subdev_ops);
 	v4l2_set_subdevdata(&csi2->sd, &pdev->dev);
 	csi2->sd.internal_ops = &csi2_internal_ops;
@@ -774,7 +801,7 @@ static void csi2_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id csi2_dt_ids[] = {
-	{ .compatible = "fsl,imx6-mipi-csi2", },
+	{ .compatible = "fsl,imx6-mipi-csi2"},
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, csi2_dt_ids);

-- 
2.34.1



From Frank.Li at nxp.com  Fri Aug  8 15:39:14 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:14 -0400
Subject: [PATCH v2 11/32] media: staging: media: imx6-mipi-csi2: use
 devm_platform_ioremap_resource() simplify code
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <20250808-95_cam-v2-11-4b29fa6919a7@nxp.com>

Use devm_platform_ioremap_resource() simplify code. No functional change.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/staging/media/imx/imx6-mipi-csi2.c | 14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index cef9a5dbca40c94a36d5d8473d3b7d9806381bf9..3956c352a27ae6d962e74a4ce7733946574668ef 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -738,7 +738,6 @@ static void csi2_nf_cleanup(void *data)
 static int csi2_probe(struct platform_device *pdev)
 {
 	struct csi2_dev *csi2;
-	struct resource *res;
 	int i, ret;
 
 	csi2 = devm_kzalloc(&pdev->dev, sizeof(*csi2), GFP_KERNEL);
@@ -772,15 +771,10 @@ static int csi2_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		v4l2_err(&csi2->sd, "failed to get platform resources\n");
-		return -ENODEV;
-	}
-
-	csi2->base = devm_ioremap(&pdev->dev, res->start, PAGE_SIZE);
-	if (!csi2->base)
-		return -ENOMEM;
+	csi2->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(csi2->base))
+		return dev_err_probe(&pdev->dev, -ENOMEM,
+				     "failed to get platform resources");
 
 	devm_mutex_init(&pdev->dev, &csi2->lock);
 

-- 
2.34.1



From Frank.Li at nxp.com  Fri Aug  8 15:39:15 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:15 -0400
Subject: [PATCH v2 12/32] media: staging: media: imx6-mipi-csi2: move probe
 part to imx6-csi2.c
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <20250808-95_cam-v2-12-4b29fa6919a7@nxp.com>

Prepare create common dw mipi csi2 library from imx6-mipi-csi2.c.

Move probe part to imx6-csi.c.

Rename struct csi2_dev to struct dw_mipi_csi2_dev and move it
include/media/dw-mipi-csi2.h.

Create two API dw_mipi_csi2_init() and dw_mipi_csi2_deinit().

No functional change.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/staging/media/imx/Makefile         |   2 +-
 drivers/staging/media/imx/imx6-csi2.c      |  61 ++++++++++++++
 drivers/staging/media/imx/imx6-mipi-csi2.c | 130 ++++++++---------------------
 include/media/dw-mipi-csi2.h               |  62 ++++++++++++++
 4 files changed, 159 insertions(+), 96 deletions(-)

diff --git a/drivers/staging/media/imx/Makefile b/drivers/staging/media/imx/Makefile
index 330e0825f506bd98d6a8093a58d3b7d06a94a626..064a6c6c069aa440c72a483080cbedf89d370193 100644
--- a/drivers/staging/media/imx/Makefile
+++ b/drivers/staging/media/imx/Makefile
@@ -11,4 +11,4 @@ imx6-media-csi-objs := imx-media-csi.o imx-media-fim.o
 obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx-media-common.o
 obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx6-media.o
 obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx6-media-csi.o
-obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx6-mipi-csi2.o
+obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx6-mipi-csi2.o imx6-csi2.o
diff --git a/drivers/staging/media/imx/imx6-csi2.c b/drivers/staging/media/imx/imx6-csi2.c
new file mode 100644
index 0000000000000000000000000000000000000000..72eff685fad99b3def46cf2866565191b7de9a8b
--- /dev/null
+++ b/drivers/staging/media/imx/imx6-csi2.c
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * MIPI CSI-2 Receiver Subdev for Freescale i.MX6 SOC.
+ *
+ * Copyright (c) 2012-2017 Mentor Graphics Inc.
+ */
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+#include <media/dw-mipi-csi2.h>
+#include "imx-media.h"
+
+struct imx6_csi2 {
+	struct dw_mipi_csi2_dev dw;
+};
+
+static int csi2_probe(struct platform_device *pdev)
+{
+	struct imx6_csi2 *csi2;
+
+	csi2 = devm_kzalloc(&pdev->dev, sizeof(*csi2), GFP_KERNEL);
+	if (!csi2)
+		return -ENOMEM;
+
+	return dw_mipi_csi2_init(pdev, &csi2->dw, NULL);
+}
+
+static void csi2_remove(struct platform_device *pdev)
+{
+	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
+	struct dw_mipi_csi2_dev *csi2 = sd_to_dw_mipi_csi2_dev(sd);
+
+	dw_mipi_csi2_deinit(csi2);
+}
+
+static const struct of_device_id csi2_dt_ids[] = {
+	{ .compatible = "fsl,imx6-mipi-csi2"},
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, csi2_dt_ids);
+
+static struct platform_driver csi2_driver = {
+	.driver = {
+		.name = "imx6-mipi-csi2",
+		.of_match_table = csi2_dt_ids,
+	},
+	.probe = csi2_probe,
+	.remove = csi2_remove,
+};
+
+module_platform_driver(csi2_driver);
+
+MODULE_DESCRIPTION("i.MX5/6 MIPI CSI-2 Receiver driver");
+MODULE_AUTHOR("Steve Longerbeam <steve_longerbeam at mentor.com>");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index 3956c352a27ae6d962e74a4ce7733946574668ef..29b27a58d9bcaf882d7f434605ee7b424b2588bd 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -4,6 +4,7 @@
  *
  * Copyright (c) 2012-2017 Mentor Graphics Inc.
  */
+#include <linux/export.h>
 #include <linux/clk.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -12,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/of_graph.h>
 #include <linux/platform_device.h>
+#include <media/dw-mipi-csi2.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-fwnode.h>
@@ -19,15 +21,6 @@
 #include <media/v4l2-subdev.h>
 #include "imx-media.h"
 
-/*
- * there must be 5 pads: 1 input pad from sensor, and
- * the 4 virtual channel output pads
- */
-#define CSI2_SINK_PAD		0
-#define CSI2_NUM_SINK_PADS	1
-#define CSI2_NUM_SRC_PADS	4
-#define CSI2_NUM_PADS		5
-
 /*
  * The default maximum bit-rate per lane in Mbps, if the
  * source subdev does not provide V4L2_CID_LINK_FREQ.
@@ -51,31 +44,6 @@ struct dw_csi2_regs {
 	u32	phy_tst_ctrl1;
 };
 
-struct csi2_dev {
-	struct device			*dev;
-	struct v4l2_subdev		sd;
-	struct v4l2_async_notifier	notifier;
-	struct media_pad		pad[CSI2_NUM_PADS];
-	void __iomem			*base;
-	const struct dw_csi2_regs	*regs;
-
-	struct clk_bulk_data		*clks;
-	int				num_clks;
-
-	struct v4l2_subdev		*remote;
-	unsigned int			remote_pad;
-	unsigned short			data_lanes;
-
-	/* lock to protect all members below */
-	struct mutex			lock;
-
-	struct v4l2_mbus_framefmt	format_mbus;
-
-	int				stream_count;
-	struct v4l2_subdev		*src_sd;
-	bool				sink_linked[CSI2_NUM_SRC_PADS];
-};
-
 #define DEVICE_NAME "imx6-mipi-csi2"
 
 /* Help check wrong access unexisted register at difference IP version */
@@ -100,7 +68,7 @@ static const struct dw_csi2_regs dw_csi2_v0 = {
 	.phy_tst_ctrl1 = DW_REG(0x34),
 };
 
-static int dw_csi2_reg_err(struct csi2_dev *csi2, const char *name)
+static int dw_csi2_reg_err(struct dw_mipi_csi2_dev *csi2, const char *name)
 {
 	dev_err_once(csi2->dev, "access to unexisted register: %s", name);
 	return 0;
@@ -134,14 +102,11 @@ dw_csi2_reg_err(csi2, #__name))
 #define CSI2IPU_GASKET		0xf00
 #define CSI2IPU_YUV422_YUYV	BIT(2)
 
-static inline struct csi2_dev *sd_to_dev(struct v4l2_subdev *sdev)
-{
-	return container_of(sdev, struct csi2_dev, sd);
-}
+#define sd_to_dev sd_to_dw_mipi_csi2_dev
 
-static inline struct csi2_dev *notifier_to_dev(struct v4l2_async_notifier *n)
+static inline struct dw_mipi_csi2_dev *notifier_to_dev(struct v4l2_async_notifier *n)
 {
-	return container_of(n, struct csi2_dev, notifier);
+	return container_of(n, struct dw_mipi_csi2_dev, notifier);
 }
 
 /*
@@ -172,7 +137,7 @@ static inline struct csi2_dev *notifier_to_dev(struct v4l2_async_notifier *n)
  * steps 5 and 7.
  */
 
-static void csi2_enable(struct csi2_dev *csi2, bool enable)
+static void csi2_enable(struct dw_mipi_csi2_dev *csi2, bool enable)
 {
 	if (enable) {
 		dw_writel(csi2, 0x1, phy_shutdownz);
@@ -185,12 +150,12 @@ static void csi2_enable(struct csi2_dev *csi2, bool enable)
 	}
 }
 
-static void csi2_set_lanes(struct csi2_dev *csi2, unsigned int lanes)
+static void csi2_set_lanes(struct dw_mipi_csi2_dev *csi2, unsigned int lanes)
 {
 	dw_writel(csi2, lanes - 1, n_lanes);
 }
 
-static void dw_mipi_csi2_phy_write(struct csi2_dev *csi2,
+static void dw_mipi_csi2_phy_write(struct dw_mipi_csi2_dev *csi2,
 				   u32 test_code, u32 test_data)
 {
 	/* Clear PHY test interface */
@@ -243,7 +208,7 @@ static int max_mbps_to_hsfreqrange_sel(u32 max_mbps)
 	return -EINVAL;
 }
 
-static int csi2_dphy_init(struct csi2_dev *csi2)
+static int csi2_dphy_init(struct dw_mipi_csi2_dev *csi2)
 {
 	struct v4l2_ctrl *ctrl;
 	u32 mbps_per_lane;
@@ -270,7 +235,7 @@ static int csi2_dphy_init(struct csi2_dev *csi2)
  * Waits for ultra-low-power state on D-PHY clock lane. This is currently
  * unused and may not be needed at all, but keep around just in case.
  */
-static int __maybe_unused csi2_dphy_wait_ulp(struct csi2_dev *csi2)
+static int __maybe_unused csi2_dphy_wait_ulp(struct dw_mipi_csi2_dev *csi2)
 {
 	u32 reg;
 	int ret;
@@ -294,7 +259,7 @@ static int __maybe_unused csi2_dphy_wait_ulp(struct csi2_dev *csi2)
 }
 
 /* Waits for low-power LP-11 state on data and clock lanes. */
-static void csi2_dphy_wait_stopstate(struct csi2_dev *csi2, unsigned int lanes)
+static void csi2_dphy_wait_stopstate(struct dw_mipi_csi2_dev *csi2, unsigned int lanes)
 {
 	u32 mask, reg;
 	int ret;
@@ -309,7 +274,7 @@ static void csi2_dphy_wait_stopstate(struct csi2_dev *csi2, unsigned int lanes)
 }
 
 /* Wait for active clock on the clock lane. */
-static int csi2_dphy_wait_clock_lane(struct csi2_dev *csi2)
+static int csi2_dphy_wait_clock_lane(struct dw_mipi_csi2_dev *csi2)
 {
 	u32 reg;
 	int ret;
@@ -326,7 +291,7 @@ static int csi2_dphy_wait_clock_lane(struct csi2_dev *csi2)
 }
 
 /* Setup the i.MX CSI2IPU Gasket */
-static void csi2ipu_gasket_init(struct csi2_dev *csi2)
+static void csi2ipu_gasket_init(struct dw_mipi_csi2_dev *csi2)
 {
 	u32 reg = 0;
 
@@ -342,7 +307,7 @@ static void csi2ipu_gasket_init(struct csi2_dev *csi2)
 	writel(reg, csi2->base + CSI2IPU_GASKET);
 }
 
-static int csi2_get_active_lanes(struct csi2_dev *csi2, unsigned int *lanes)
+static int csi2_get_active_lanes(struct dw_mipi_csi2_dev *csi2, unsigned int *lanes)
 {
 	struct v4l2_mbus_config mbus_config = { 0 };
 	int ret;
@@ -379,7 +344,7 @@ static int csi2_get_active_lanes(struct csi2_dev *csi2, unsigned int *lanes)
 	return 0;
 }
 
-static int csi2_start(struct csi2_dev *csi2)
+static int csi2_start(struct dw_mipi_csi2_dev *csi2)
 {
 	unsigned int lanes;
 	int ret;
@@ -435,7 +400,7 @@ static int csi2_start(struct csi2_dev *csi2)
 	return ret;
 }
 
-static void csi2_stop(struct csi2_dev *csi2)
+static void csi2_stop(struct dw_mipi_csi2_dev *csi2)
 {
 	/* stop upstream */
 	v4l2_subdev_call(csi2->src_sd, video, s_stream, 0);
@@ -451,7 +416,7 @@ static void csi2_stop(struct csi2_dev *csi2)
 
 static int csi2_s_stream(struct v4l2_subdev *sd, int enable)
 {
-	struct csi2_dev *csi2 = sd_to_dev(sd);
+	struct dw_mipi_csi2_dev *csi2 = sd_to_dev(sd);
 	int i, ret = 0;
 
 	guard(mutex)(&csi2->lock);
@@ -493,7 +458,7 @@ static int csi2_link_setup(struct media_entity *entity,
 			   const struct media_pad *remote, u32 flags)
 {
 	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
-	struct csi2_dev *csi2 = sd_to_dev(sd);
+	struct dw_mipi_csi2_dev *csi2 = sd_to_dev(sd);
 	struct v4l2_subdev *remote_sd;
 	int ret = 0;
 
@@ -528,7 +493,7 @@ static int csi2_link_setup(struct media_entity *entity,
 }
 
 static struct v4l2_mbus_framefmt *
-__csi2_get_fmt(struct csi2_dev *csi2, struct v4l2_subdev_state *sd_state,
+__csi2_get_fmt(struct dw_mipi_csi2_dev *csi2, struct v4l2_subdev_state *sd_state,
 	       unsigned int pad, enum v4l2_subdev_format_whence which)
 {
 	if (which == V4L2_SUBDEV_FORMAT_TRY)
@@ -541,7 +506,7 @@ static int csi2_get_fmt(struct v4l2_subdev *sd,
 			struct v4l2_subdev_state *sd_state,
 			struct v4l2_subdev_format *sdformat)
 {
-	struct csi2_dev *csi2 = sd_to_dev(sd);
+	struct dw_mipi_csi2_dev *csi2 = sd_to_dev(sd);
 	struct v4l2_mbus_framefmt *fmt;
 
 	guard(mutex)(&csi2->lock);
@@ -557,7 +522,7 @@ static int csi2_set_fmt(struct v4l2_subdev *sd,
 			struct v4l2_subdev_state *sd_state,
 			struct v4l2_subdev_format *sdformat)
 {
-	struct csi2_dev *csi2 = sd_to_dev(sd);
+	struct dw_mipi_csi2_dev *csi2 = sd_to_dev(sd);
 	struct v4l2_mbus_framefmt *fmt;
 
 	if (sdformat->pad >= CSI2_NUM_PADS)
@@ -581,7 +546,7 @@ static int csi2_set_fmt(struct v4l2_subdev *sd,
 
 static int csi2_registered(struct v4l2_subdev *sd)
 {
-	struct csi2_dev *csi2 = sd_to_dev(sd);
+	struct dw_mipi_csi2_dev *csi2 = sd_to_dev(sd);
 
 	/* set a default mbus format  */
 	return imx_media_init_mbus_fmt(&csi2->format_mbus,
@@ -594,7 +559,7 @@ static int csi2_registered(struct v4l2_subdev *sd)
 
 static int csi2_log_status(struct v4l2_subdev *sd)
 {
-	struct csi2_dev *csi2 = sd_to_dev(sd);
+	struct dw_mipi_csi2_dev *csi2 = sd_to_dev(sd);
 
 	v4l2_info(sd, "-----MIPI CSI status-----\n");
 	v4l2_info(sd, "VERSION: 0x%x\n", dw_readl(csi2, version));
@@ -649,7 +614,7 @@ static int csi2_notify_bound(struct v4l2_async_notifier *notifier,
 			     struct v4l2_subdev *sd,
 			     struct v4l2_async_connection *asd)
 {
-	struct csi2_dev *csi2 = notifier_to_dev(notifier);
+	struct dw_mipi_csi2_dev *csi2 = notifier_to_dev(notifier);
 	struct media_pad *sink = &csi2->sd.entity.pads[CSI2_SINK_PAD];
 	int pad;
 
@@ -672,7 +637,7 @@ static void csi2_notify_unbind(struct v4l2_async_notifier *notifier,
 			       struct v4l2_subdev *sd,
 			       struct v4l2_async_connection *asd)
 {
-	struct csi2_dev *csi2 = notifier_to_dev(notifier);
+	struct dw_mipi_csi2_dev *csi2 = notifier_to_dev(notifier);
 
 	csi2->remote = NULL;
 }
@@ -682,7 +647,7 @@ static const struct v4l2_async_notifier_operations csi2_notify_ops = {
 	.unbind = csi2_notify_unbind,
 };
 
-static int csi2_async_register(struct csi2_dev *csi2)
+static int csi2_async_register(struct dw_mipi_csi2_dev *csi2)
 {
 	struct v4l2_fwnode_endpoint vep = {
 		.bus_type = V4L2_MBUS_CSI2_DPHY,
@@ -729,21 +694,17 @@ static int csi2_async_register(struct csi2_dev *csi2)
 
 static void csi2_nf_cleanup(void *data)
 {
-	struct csi2_dev *csi2 = data;
+	struct dw_mipi_csi2_dev *csi2 = data;
 
 	v4l2_async_nf_unregister(&csi2->notifier);
 	v4l2_async_nf_cleanup(&csi2->notifier);
 }
 
-static int csi2_probe(struct platform_device *pdev)
+int dw_mipi_csi2_init(struct platform_device *pdev, struct dw_mipi_csi2_dev *csi2,
+		      const struct dw_mipi_csi2_config *config)
 {
-	struct csi2_dev *csi2;
 	int i, ret;
 
-	csi2 = devm_kzalloc(&pdev->dev, sizeof(*csi2), GFP_KERNEL);
-	if (!csi2)
-		return -ENOMEM;
-
 	csi2->dev = &pdev->dev;
 	csi2->regs = &dw_csi2_v0;
 	v4l2_subdev_init(&csi2->sd, &csi2_subdev_ops);
@@ -785,32 +746,11 @@ static int csi2_probe(struct platform_device *pdev)
 	return csi2_async_register(csi2);
 
 }
+EXPORT_SYMBOL_GPL(dw_mipi_csi2_init);
 
-static void csi2_remove(struct platform_device *pdev)
+void dw_mipi_csi2_deinit(struct dw_mipi_csi2_dev *csi2)
 {
-	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
-
-	v4l2_async_unregister_subdev(sd);
-	media_entity_cleanup(&sd->entity);
+	v4l2_async_unregister_subdev(&csi2->sd);
+	media_entity_cleanup(&csi2->sd.entity);
 }
-
-static const struct of_device_id csi2_dt_ids[] = {
-	{ .compatible = "fsl,imx6-mipi-csi2"},
-	{ /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, csi2_dt_ids);
-
-static struct platform_driver csi2_driver = {
-	.driver = {
-		.name = DEVICE_NAME,
-		.of_match_table = csi2_dt_ids,
-	},
-	.probe = csi2_probe,
-	.remove = csi2_remove,
-};
-
-module_platform_driver(csi2_driver);
-
-MODULE_DESCRIPTION("i.MX5/6 MIPI CSI-2 Receiver driver");
-MODULE_AUTHOR("Steve Longerbeam <steve_longerbeam at mentor.com>");
-MODULE_LICENSE("GPL");
+EXPORT_SYMBOL_GPL(dw_mipi_csi2_deinit);
diff --git a/include/media/dw-mipi-csi2.h b/include/media/dw-mipi-csi2.h
new file mode 100644
index 0000000000000000000000000000000000000000..4e656f09c81db9dc9f232ed061f70803a5478c85
--- /dev/null
+++ b/include/media/dw-mipi-csi2.h
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef __DW_MIPI_CSI2_COMMON_
+#define __DW_MIPI_CSI2_COMMON_
+
+#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-mc.h>
+#include <media/v4l2-subdev.h>
+
+struct dw_mipi_csi2_config {
+};
+
+/*
+ * there must be 5 pads: 1 input pad from sensor, and
+ * the 4 virtual channel output pads
+ */
+#define CSI2_SINK_PAD		0
+#define CSI2_NUM_SINK_PADS	1
+#define CSI2_NUM_SRC_PADS	4
+#define CSI2_NUM_PADS		5
+
+struct dw_mipi_csi2_dev {
+	struct device			*dev;
+	struct v4l2_subdev		sd;
+	struct v4l2_async_notifier	notifier;
+	struct media_pad		pad[CSI2_NUM_PADS];
+	void __iomem			*base;
+	const struct dw_csi2_regs	*regs;
+
+	struct clk_bulk_data		*clks;
+	int				num_clks;
+
+	struct v4l2_subdev		*remote;
+	unsigned int			remote_pad;
+	unsigned short			data_lanes;
+
+	/* lock to protect all members below */
+	struct mutex			lock;
+
+	struct v4l2_mbus_framefmt	format_mbus;
+
+	int				stream_count;
+	struct v4l2_subdev		*src_sd;
+	bool				sink_linked[CSI2_NUM_SRC_PADS];
+};
+
+static inline struct dw_mipi_csi2_dev *
+sd_to_dw_mipi_csi2_dev(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct dw_mipi_csi2_dev, sd);
+}
+
+int dw_mipi_csi2_init(struct platform_device *pdev,
+		      struct dw_mipi_csi2_dev *csi2,
+		      const struct dw_mipi_csi2_config *config);
+
+void dw_mipi_csi2_deinit(struct dw_mipi_csi2_dev *csi2);
+
+#endif
+

-- 
2.34.1



From Frank.Li at nxp.com  Fri Aug  8 15:39:16 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:16 -0400
Subject: [PATCH v2 13/32] media: staging: media: imx6-mipi-csi2: move sd
 imx6's specific initialization into imx6-sci2.c
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <20250808-95_cam-v2-13-4b29fa6919a7@nxp.com>

Move imx6's specific sd's owner, name, csi2_internal_ops, grp_id into
imx6-sci2.c.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/staging/media/imx/imx6-csi2.c      | 23 +++++++++++++++++++++++
 drivers/staging/media/imx/imx6-mipi-csi2.c | 29 ++++++-----------------------
 include/media/dw-mipi-csi2.h               |  4 ++++
 3 files changed, 33 insertions(+), 23 deletions(-)

diff --git a/drivers/staging/media/imx/imx6-csi2.c b/drivers/staging/media/imx/imx6-csi2.c
index 72eff685fad99b3def46cf2866565191b7de9a8b..66274d8d73b67b35682bb82a9eb745bb24da7ae4 100644
--- a/drivers/staging/media/imx/imx6-csi2.c
+++ b/drivers/staging/media/imx/imx6-csi2.c
@@ -19,6 +19,29 @@ struct imx6_csi2 {
 	struct dw_mipi_csi2_dev dw;
 };
 
+static int csi2_registered(struct v4l2_subdev *sd)
+{
+	struct dw_mipi_csi2_dev *csi2 = sd_to_dw_mipi_csi2_dev(sd);
+
+	/* set a default mbus format  */
+	return imx_media_init_mbus_fmt(&csi2->format_mbus,
+				      IMX_MEDIA_DEF_PIX_WIDTH,
+				      IMX_MEDIA_DEF_PIX_HEIGHT, 0,
+				      V4L2_FIELD_NONE, NULL);
+}
+
+static const struct v4l2_subdev_internal_ops csi2_internal_ops = {
+	.init_state = imx_media_init_state,
+	.registered = csi2_registered,
+};
+
+static const struct dw_mipi_csi2_config imx6_config = {
+	.module = THIS_MODULE,
+	.name = "imx6-mipi-csi2",
+	.internal_ops = &csi2_internal_ops,
+	.grp_id = IMX_MEDIA_GRP_ID_CSI2,
+};
+
 static int csi2_probe(struct platform_device *pdev)
 {
 	struct imx6_csi2 *csi2;
diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index 29b27a58d9bcaf882d7f434605ee7b424b2588bd..40a146faaa9c79304b1e1f16e608b3b10eae6c80 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -15,11 +15,11 @@
 #include <linux/platform_device.h>
 #include <media/dw-mipi-csi2.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-fwnode.h>
 #include <media/v4l2-mc.h>
 #include <media/v4l2-subdev.h>
-#include "imx-media.h"
 
 /*
  * The default maximum bit-rate per lane in Mbps, if the
@@ -44,8 +44,6 @@ struct dw_csi2_regs {
 	u32	phy_tst_ctrl1;
 };
 
-#define DEVICE_NAME "imx6-mipi-csi2"
-
 /* Help check wrong access unexisted register at difference IP version */
 #define DW_REG_EXIST		0x80000000
 #define DW_REG(x)		(DW_REG_EXIST | (x))
@@ -544,17 +542,6 @@ static int csi2_set_fmt(struct v4l2_subdev *sd,
 	return 0;
 }
 
-static int csi2_registered(struct v4l2_subdev *sd)
-{
-	struct dw_mipi_csi2_dev *csi2 = sd_to_dev(sd);
-
-	/* set a default mbus format  */
-	return imx_media_init_mbus_fmt(&csi2->format_mbus,
-				      IMX_MEDIA_DEF_PIX_WIDTH,
-				      IMX_MEDIA_DEF_PIX_HEIGHT, 0,
-				      V4L2_FIELD_NONE, NULL);
-}
-
 /* --------------- CORE OPS --------------- */
 
 static int csi2_log_status(struct v4l2_subdev *sd)
@@ -605,11 +592,6 @@ static const struct v4l2_subdev_ops csi2_subdev_ops = {
 	.pad = &csi2_pad_ops,
 };
 
-static const struct v4l2_subdev_internal_ops csi2_internal_ops = {
-	.init_state = imx_media_init_state,
-	.registered = csi2_registered,
-};
-
 static int csi2_notify_bound(struct v4l2_async_notifier *notifier,
 			     struct v4l2_subdev *sd,
 			     struct v4l2_async_connection *asd)
@@ -709,14 +691,15 @@ int dw_mipi_csi2_init(struct platform_device *pdev, struct dw_mipi_csi2_dev *csi
 	csi2->regs = &dw_csi2_v0;
 	v4l2_subdev_init(&csi2->sd, &csi2_subdev_ops);
 	v4l2_set_subdevdata(&csi2->sd, &pdev->dev);
-	csi2->sd.internal_ops = &csi2_internal_ops;
 	csi2->sd.entity.ops = &csi2_entity_ops;
 	csi2->sd.dev = &pdev->dev;
-	csi2->sd.owner = THIS_MODULE;
 	csi2->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
-	strscpy(csi2->sd.name, DEVICE_NAME, sizeof(csi2->sd.name));
 	csi2->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
-	csi2->sd.grp_id = IMX_MEDIA_GRP_ID_CSI2;
+
+	csi2->sd.owner = config->module;
+	strscpy(csi2->sd.name, config->name, sizeof(csi2->sd.name));
+	csi2->sd.internal_ops = config->internal_ops;
+	csi2->sd.grp_id = config->grp_id;
 
 	for (i = 0; i < CSI2_NUM_PADS; i++) {
 		csi2->pad[i].flags = (i == CSI2_SINK_PAD) ?
diff --git a/include/media/dw-mipi-csi2.h b/include/media/dw-mipi-csi2.h
index 4e656f09c81db9dc9f232ed061f70803a5478c85..dfd25e23ea93fd53b064471b6a9557ef9c070fe7 100644
--- a/include/media/dw-mipi-csi2.h
+++ b/include/media/dw-mipi-csi2.h
@@ -10,6 +10,10 @@
 #include <media/v4l2-subdev.h>
 
 struct dw_mipi_csi2_config {
+	struct module *module;
+	const char *name;
+	int grp_id;
+	const struct v4l2_subdev_internal_ops *internal_ops;
 };
 
 /*

-- 
2.34.1



From Frank.Li at nxp.com  Fri Aug  8 15:39:17 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:17 -0400
Subject: [PATCH v2 14/32] media: staging: media: imx6-mipi-csi2: move
 csi2ipu_gasket_init() to imx6-csi2.c
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <20250808-95_cam-v2-14-4b29fa6919a7@nxp.com>

Move platform specific csi2ipu_gasket_init() to imx6-csi2.c.

Create callback function in struct dw_mipi_csi2_config.

Prepare create common library for dw MIPI CSI2.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/staging/media/imx/imx6-csi2.c      | 28 +++++++++++++++++++++++++++-
 drivers/staging/media/imx/imx6-mipi-csi2.c | 28 +++-------------------------
 include/media/dw-mipi-csi2.h               |  6 ++++++
 3 files changed, 36 insertions(+), 26 deletions(-)

diff --git a/drivers/staging/media/imx/imx6-csi2.c b/drivers/staging/media/imx/imx6-csi2.c
index 66274d8d73b67b35682bb82a9eb745bb24da7ae4..b7ea710df07cba33465d79ef57be4792c503958a 100644
--- a/drivers/staging/media/imx/imx6-csi2.c
+++ b/drivers/staging/media/imx/imx6-csi2.c
@@ -15,10 +15,35 @@
 #include <media/dw-mipi-csi2.h>
 #include "imx-media.h"
 
+/*
+ * i.MX CSI2IPU Gasket registers follow. The CSI2IPU gasket is
+ * not part of the MIPI CSI-2 core, but its registers fall in the
+ * same register map range.
+ */
+#define CSI2IPU_GASKET		0xf00
+#define CSI2IPU_YUV422_YUYV	BIT(2)
+
 struct imx6_csi2 {
 	struct dw_mipi_csi2_dev dw;
 };
 
+/* Setup the i.MX CSI2IPU Gasket */
+static void csi2ipu_gasket_init(struct dw_mipi_csi2_dev *csi2)
+{
+	u32 reg = 0;
+
+	switch (csi2->format_mbus.code) {
+	case MEDIA_BUS_FMT_YUYV8_2X8:
+	case MEDIA_BUS_FMT_YUYV8_1X16:
+		reg = CSI2IPU_YUV422_YUYV;
+		break;
+	default:
+		break;
+	}
+
+	writel(reg, csi2->base + CSI2IPU_GASKET);
+}
+
 static int csi2_registered(struct v4l2_subdev *sd)
 {
 	struct dw_mipi_csi2_dev *csi2 = sd_to_dw_mipi_csi2_dev(sd);
@@ -40,6 +65,7 @@ static const struct dw_mipi_csi2_config imx6_config = {
 	.name = "imx6-mipi-csi2",
 	.internal_ops = &csi2_internal_ops,
 	.grp_id = IMX_MEDIA_GRP_ID_CSI2,
+	.gasket_init = csi2ipu_gasket_init,
 };
 
 static int csi2_probe(struct platform_device *pdev)
@@ -50,7 +76,7 @@ static int csi2_probe(struct platform_device *pdev)
 	if (!csi2)
 		return -ENOMEM;
 
-	return dw_mipi_csi2_init(pdev, &csi2->dw, NULL);
+	return dw_mipi_csi2_init(pdev, &csi2->dw, &imx6_config);
 }
 
 static void csi2_remove(struct platform_device *pdev)
diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index 40a146faaa9c79304b1e1f16e608b3b10eae6c80..4127b927a73aaf2eada1636fcc6101155f41b334 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -92,13 +92,6 @@ dw_csi2_reg_err(csi2, #__name))
 #define PHY_TESTCLK		BIT(1)
 
 #define PHY_TESTEN		BIT(16)
-/*
- * i.MX CSI2IPU Gasket registers follow. The CSI2IPU gasket is
- * not part of the MIPI CSI-2 core, but its registers fall in the
- * same register map range.
- */
-#define CSI2IPU_GASKET		0xf00
-#define CSI2IPU_YUV422_YUYV	BIT(2)
 
 #define sd_to_dev sd_to_dw_mipi_csi2_dev
 
@@ -288,23 +281,6 @@ static int csi2_dphy_wait_clock_lane(struct dw_mipi_csi2_dev *csi2)
 	return 0;
 }
 
-/* Setup the i.MX CSI2IPU Gasket */
-static void csi2ipu_gasket_init(struct dw_mipi_csi2_dev *csi2)
-{
-	u32 reg = 0;
-
-	switch (csi2->format_mbus.code) {
-	case MEDIA_BUS_FMT_YUYV8_2X8:
-	case MEDIA_BUS_FMT_YUYV8_1X16:
-		reg = CSI2IPU_YUV422_YUYV;
-		break;
-	default:
-		break;
-	}
-
-	writel(reg, csi2->base + CSI2IPU_GASKET);
-}
-
 static int csi2_get_active_lanes(struct dw_mipi_csi2_dev *csi2, unsigned int *lanes)
 {
 	struct v4l2_mbus_config mbus_config = { 0 };
@@ -352,7 +328,8 @@ static int csi2_start(struct dw_mipi_csi2_dev *csi2)
 		return ret;
 
 	/* setup the gasket */
-	csi2ipu_gasket_init(csi2);
+	if (csi2->config && csi2->config->gasket_init)
+		csi2->config->gasket_init(csi2);
 
 	/* Step 3 */
 	ret = csi2_dphy_init(csi2);
@@ -700,6 +677,7 @@ int dw_mipi_csi2_init(struct platform_device *pdev, struct dw_mipi_csi2_dev *csi
 	strscpy(csi2->sd.name, config->name, sizeof(csi2->sd.name));
 	csi2->sd.internal_ops = config->internal_ops;
 	csi2->sd.grp_id = config->grp_id;
+	csi2->config = config;
 
 	for (i = 0; i < CSI2_NUM_PADS; i++) {
 		csi2->pad[i].flags = (i == CSI2_SINK_PAD) ?
diff --git a/include/media/dw-mipi-csi2.h b/include/media/dw-mipi-csi2.h
index dfd25e23ea93fd53b064471b6a9557ef9c070fe7..d3e1c334df692c5dff10b467d759fe4da45b7b5f 100644
--- a/include/media/dw-mipi-csi2.h
+++ b/include/media/dw-mipi-csi2.h
@@ -9,11 +9,15 @@
 #include <media/v4l2-mc.h>
 #include <media/v4l2-subdev.h>
 
+struct dw_mipi_csi2_dev;
+
 struct dw_mipi_csi2_config {
 	struct module *module;
 	const char *name;
 	int grp_id;
 	const struct v4l2_subdev_internal_ops *internal_ops;
+	/* Deprecated, should go through phy interface */
+	void (*gasket_init)(struct dw_mipi_csi2_dev *dev);
 };
 
 /*
@@ -48,6 +52,8 @@ struct dw_mipi_csi2_dev {
 	int				stream_count;
 	struct v4l2_subdev		*src_sd;
 	bool				sink_linked[CSI2_NUM_SRC_PADS];
+
+	const struct dw_mipi_csi2_config *config;
 };
 
 static inline struct dw_mipi_csi2_dev *

-- 
2.34.1



From Frank.Li at nxp.com  Fri Aug  8 15:39:18 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:18 -0400
Subject: [PATCH v2 15/32] media: staging: media: imx6-mipi-csi2: move
 number pad macro define into imx6-csi2.c
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <20250808-95_cam-v2-15-4b29fa6919a7@nxp.com>

Move number of pad macro to imx6-csi2.c. The number of pads is platform
related feature.

This version just support maximum 32 pads.

Prepare to create common library for dw MIPI CSI2 controller.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/staging/media/imx/imx6-csi2.c      | 12 ++++++++++++
 drivers/staging/media/imx/imx6-mipi-csi2.c | 27 ++++++++++++++++++---------
 include/media/dw-mipi-csi2.h               | 21 +++++++++------------
 3 files changed, 39 insertions(+), 21 deletions(-)

diff --git a/drivers/staging/media/imx/imx6-csi2.c b/drivers/staging/media/imx/imx6-csi2.c
index b7ea710df07cba33465d79ef57be4792c503958a..062db72a36ef294566272d9f39d82e9414640e9a 100644
--- a/drivers/staging/media/imx/imx6-csi2.c
+++ b/drivers/staging/media/imx/imx6-csi2.c
@@ -4,6 +4,7 @@
  *
  * Copyright (c) 2012-2017 Mentor Graphics Inc.
  */
+#include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -60,12 +61,23 @@ static const struct v4l2_subdev_internal_ops csi2_internal_ops = {
 	.registered = csi2_registered,
 };
 
+/*
+ * there must be 5 pads: 1 input pad from sensor, and
+ * the 4 virtual channel output pads
+ */
+#define CSI2_SINK_PAD		0
+#define CSI2_NUM_SINK_PADS	1
+#define CSI2_NUM_SRC_PADS	4
+#define CSI2_NUM_PADS		5
+
 static const struct dw_mipi_csi2_config imx6_config = {
 	.module = THIS_MODULE,
 	.name = "imx6-mipi-csi2",
 	.internal_ops = &csi2_internal_ops,
 	.grp_id = IMX_MEDIA_GRP_ID_CSI2,
 	.gasket_init = csi2ipu_gasket_init,
+	.num_pads = CSI2_NUM_PADS,
+	.sink_pad_mask = BIT(CSI2_NUM_SINK_PADS),
 };
 
 static int csi2_probe(struct platform_device *pdev)
diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index 4127b927a73aaf2eada1636fcc6101155f41b334..546c6e7c5d13f3be618fc3eeca780695ead6bfe5 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -399,11 +399,11 @@ static int csi2_s_stream(struct v4l2_subdev *sd, int enable)
 	if (!csi2->src_sd)
 		return -EPIPE;
 
-	for (i = 0; i < CSI2_NUM_SRC_PADS; i++) {
+	for (i = 0; i < csi2->num_sink_pads; i++) {
 		if (csi2->sink_linked[i])
 			break;
 	}
-	if (i >= CSI2_NUM_SRC_PADS)
+	if (i >= csi2->num_sink_pads)
 		return -EPIPE;
 
 	/*
@@ -500,7 +500,7 @@ static int csi2_set_fmt(struct v4l2_subdev *sd,
 	struct dw_mipi_csi2_dev *csi2 = sd_to_dev(sd);
 	struct v4l2_mbus_framefmt *fmt;
 
-	if (sdformat->pad >= CSI2_NUM_PADS)
+	if (sdformat->pad >= (csi2->num_src_pads + csi2->num_sink_pads))
 		return -EINVAL;
 
 	guard(mutex)(&csi2->lock);
@@ -509,7 +509,7 @@ static int csi2_set_fmt(struct v4l2_subdev *sd,
 		return -EBUSY;
 
 	/* Output pads mirror active input pad, no limits on input pads */
-	if (sdformat->pad != CSI2_SINK_PAD)
+	if (!(csi2->config->sink_pad_mask & BIT(sdformat->pad)))
 		sdformat->format = csi2->format_mbus;
 
 	fmt = __csi2_get_fmt(csi2, sd_state, sdformat->pad, sdformat->which);
@@ -574,7 +574,8 @@ static int csi2_notify_bound(struct v4l2_async_notifier *notifier,
 			     struct v4l2_async_connection *asd)
 {
 	struct dw_mipi_csi2_dev *csi2 = notifier_to_dev(notifier);
-	struct media_pad *sink = &csi2->sd.entity.pads[CSI2_SINK_PAD];
+	int sink_index = ffs(csi2->config->sink_pad_mask) - 1;
+	struct media_pad *sink = &csi2->sd.entity.pads[sink_index];
 	int pad;
 
 	pad = media_entity_get_fwnode_pad(&sd->entity, asd->match.fwnode,
@@ -679,12 +680,20 @@ int dw_mipi_csi2_init(struct platform_device *pdev, struct dw_mipi_csi2_dev *csi
 	csi2->sd.grp_id = config->grp_id;
 	csi2->config = config;
 
-	for (i = 0; i < CSI2_NUM_PADS; i++) {
-		csi2->pad[i].flags = (i == CSI2_SINK_PAD) ?
-		MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
+	if (!config)
+		return -EINVAL;
+
+	for (i = 0; i < config->num_pads; i++) {
+		if (config->sink_pad_mask & BIT(i)) {
+			csi2->pad[i].flags = MEDIA_PAD_FL_SINK;
+			csi2->num_sink_pads++;
+		} else {
+			csi2->pad[i].flags = MEDIA_PAD_FL_SOURCE;
+			csi2->num_src_pads++;
+		}
 	}
 
-	ret = media_entity_pads_init(&csi2->sd.entity, CSI2_NUM_PADS,
+	ret = media_entity_pads_init(&csi2->sd.entity, config->num_pads,
 				     csi2->pad);
 	if (ret)
 		return ret;
diff --git a/include/media/dw-mipi-csi2.h b/include/media/dw-mipi-csi2.h
index d3e1c334df692c5dff10b467d759fe4da45b7b5f..12e1db1d149513fcd0db8c191c801cb144d18143 100644
--- a/include/media/dw-mipi-csi2.h
+++ b/include/media/dw-mipi-csi2.h
@@ -11,6 +11,8 @@
 
 struct dw_mipi_csi2_dev;
 
+#define DW_MAX_PAD_NUM		32
+
 struct dw_mipi_csi2_config {
 	struct module *module;
 	const char *name;
@@ -18,22 +20,18 @@ struct dw_mipi_csi2_config {
 	const struct v4l2_subdev_internal_ops *internal_ops;
 	/* Deprecated, should go through phy interface */
 	void (*gasket_init)(struct dw_mipi_csi2_dev *dev);
+	u32	num_pads;	/* Max 64 pad now */
+	u32	sink_pad_mask;
 };
 
-/*
- * there must be 5 pads: 1 input pad from sensor, and
- * the 4 virtual channel output pads
- */
-#define CSI2_SINK_PAD		0
-#define CSI2_NUM_SINK_PADS	1
-#define CSI2_NUM_SRC_PADS	4
-#define CSI2_NUM_PADS		5
-
 struct dw_mipi_csi2_dev {
 	struct device			*dev;
 	struct v4l2_subdev		sd;
 	struct v4l2_async_notifier	notifier;
-	struct media_pad		pad[CSI2_NUM_PADS];
+	struct media_pad		pad[DW_MAX_PAD_NUM];
+	int				num_src_pads;
+	int				num_sink_pads;
+
 	void __iomem			*base;
 	const struct dw_csi2_regs	*regs;
 
@@ -51,8 +49,7 @@ struct dw_mipi_csi2_dev {
 
 	int				stream_count;
 	struct v4l2_subdev		*src_sd;
-	bool				sink_linked[CSI2_NUM_SRC_PADS];
-
+	bool				sink_linked[DW_MAX_PAD_NUM];
 	const struct dw_mipi_csi2_config *config;
 };
 

-- 
2.34.1



From Frank.Li at nxp.com  Fri Aug  8 15:39:19 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:19 -0400
Subject: [PATCH v2 16/32] media: staging: media: imx6-mipi-csi2: move dphy
 init part to imx6-csi2.c
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <20250808-95_cam-v2-16-4b29fa6919a7@nxp.com>

Move dphy init part to imx6-csi.c.

Prepare create common library for dw MIPI CSI2 controller.

Add callback for dphy_init in struct dw_mipi_csi2_config. New driver should
use phy interface.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/staging/media/imx/imx6-csi2.c      | 55 +++++++++++++++++++++++
 drivers/staging/media/imx/imx6-mipi-csi2.c | 72 ++++++------------------------
 include/media/dw-mipi-csi2.h               | 21 +++++++++
 3 files changed, 89 insertions(+), 59 deletions(-)

diff --git a/drivers/staging/media/imx/imx6-csi2.c b/drivers/staging/media/imx/imx6-csi2.c
index 062db72a36ef294566272d9f39d82e9414640e9a..696644aa04c83b1f2877b2b2315202627d927e96 100644
--- a/drivers/staging/media/imx/imx6-csi2.c
+++ b/drivers/staging/media/imx/imx6-csi2.c
@@ -16,6 +16,12 @@
 #include <media/dw-mipi-csi2.h>
 #include "imx-media.h"
 
+/*
+ * The default maximum bit-rate per lane in Mbps, if the
+ * source subdev does not provide V4L2_CID_LINK_FREQ.
+ */
+#define CSI2_DEFAULT_MAX_MBPS	849
+
 /*
  * i.MX CSI2IPU Gasket registers follow. The CSI2IPU gasket is
  * not part of the MIPI CSI-2 core, but its registers fall in the
@@ -28,6 +34,54 @@ struct imx6_csi2 {
 	struct dw_mipi_csi2_dev dw;
 };
 
+static const struct {
+	u32 max_mbps;
+	u32 hsfreqrange_sel;
+} hsfreq_map[] = {
+	{ 90, 0x00}, {100, 0x20}, {110, 0x40}, {125, 0x02},
+	{140, 0x22}, {150, 0x42}, {160, 0x04}, {180, 0x24},
+	{200, 0x44}, {210, 0x06}, {240, 0x26}, {250, 0x46},
+	{270, 0x08}, {300, 0x28}, {330, 0x48}, {360, 0x2a},
+	{400, 0x4a}, {450, 0x0c}, {500, 0x2c}, {550, 0x0e},
+	{600, 0x2e}, {650, 0x10}, {700, 0x30}, {750, 0x12},
+	{800, 0x32}, {850, 0x14}, {900, 0x34}, {950, 0x54},
+	{1000, 0x74},
+};
+
+static int max_mbps_to_hsfreqrange_sel(u32 max_mbps)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(hsfreq_map); i++)
+		if (hsfreq_map[i].max_mbps > max_mbps)
+			return hsfreq_map[i].hsfreqrange_sel;
+
+	return -EINVAL;
+}
+
+static int csi2_dphy_init(struct dw_mipi_csi2_dev *csi2)
+{
+	struct v4l2_ctrl *ctrl;
+	u32 mbps_per_lane;
+	int sel;
+
+	ctrl = v4l2_ctrl_find(csi2->src_sd->ctrl_handler,
+			      V4L2_CID_LINK_FREQ);
+	if (!ctrl)
+		mbps_per_lane = CSI2_DEFAULT_MAX_MBPS;
+	else
+		mbps_per_lane = DIV_ROUND_UP_ULL(2 * ctrl->qmenu_int[ctrl->val],
+						 USEC_PER_SEC);
+
+	sel = max_mbps_to_hsfreqrange_sel(mbps_per_lane);
+	if (sel < 0)
+		return sel;
+
+	dw_mipi_csi2_tstif_write(csi2, 0x44, sel);
+
+	return 0;
+}
+
 /* Setup the i.MX CSI2IPU Gasket */
 static void csi2ipu_gasket_init(struct dw_mipi_csi2_dev *csi2)
 {
@@ -74,6 +128,7 @@ static const struct dw_mipi_csi2_config imx6_config = {
 	.module = THIS_MODULE,
 	.name = "imx6-mipi-csi2",
 	.internal_ops = &csi2_internal_ops,
+	.dphy_init = csi2_dphy_init,
 	.grp_id = IMX_MEDIA_GRP_ID_CSI2,
 	.gasket_init = csi2ipu_gasket_init,
 	.num_pads = CSI2_NUM_PADS,
diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index 546c6e7c5d13f3be618fc3eeca780695ead6bfe5..23656291d808ccdfc47f36d1f7f5104698812eba 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -21,12 +21,6 @@
 #include <media/v4l2-mc.h>
 #include <media/v4l2-subdev.h>
 
-/*
- * The default maximum bit-rate per lane in Mbps, if the
- * source subdev does not provide V4L2_CID_LINK_FREQ.
- */
-#define CSI2_DEFAULT_MAX_MBPS	849
-
 struct dw_csi2_regs {
 	u32	version;
 	u32	n_lanes;
@@ -146,9 +140,11 @@ static void csi2_set_lanes(struct dw_mipi_csi2_dev *csi2, unsigned int lanes)
 	dw_writel(csi2, lanes - 1, n_lanes);
 }
 
-static void dw_mipi_csi2_phy_write(struct dw_mipi_csi2_dev *csi2,
-				   u32 test_code, u32 test_data)
+static int dw_mipi_csi2_phy_write(struct dw_mipi_tstif *tstif,
+				  u32 test_code, u32 test_data)
 {
+	struct dw_mipi_csi2_dev *csi2 = container_of(tstif, struct dw_mipi_csi2_dev, tstif);
+
 	/* Clear PHY test interface */
 	dw_writel(csi2, PHY_TESTCLR, phy_tst_ctrl0);
 	dw_writel(csi2, 0x0, phy_tst_ctrl1);
@@ -167,6 +163,8 @@ static void dw_mipi_csi2_phy_write(struct dw_mipi_csi2_dev *csi2,
 
 	/* Clear strobe signal */
 	dw_writel(csi2, 0x0, phy_tst_ctrl0);
+
+	return 0;
 }
 
 /*
@@ -174,54 +172,6 @@ static void dw_mipi_csi2_phy_write(struct dw_mipi_csi2_dev *csi2,
  * https://community.nxp.com/docs/DOC-94312. It assumes
  * a 27MHz D-PHY pll reference clock.
  */
-static const struct {
-	u32 max_mbps;
-	u32 hsfreqrange_sel;
-} hsfreq_map[] = {
-	{ 90, 0x00}, {100, 0x20}, {110, 0x40}, {125, 0x02},
-	{140, 0x22}, {150, 0x42}, {160, 0x04}, {180, 0x24},
-	{200, 0x44}, {210, 0x06}, {240, 0x26}, {250, 0x46},
-	{270, 0x08}, {300, 0x28}, {330, 0x48}, {360, 0x2a},
-	{400, 0x4a}, {450, 0x0c}, {500, 0x2c}, {550, 0x0e},
-	{600, 0x2e}, {650, 0x10}, {700, 0x30}, {750, 0x12},
-	{800, 0x32}, {850, 0x14}, {900, 0x34}, {950, 0x54},
-	{1000, 0x74},
-};
-
-static int max_mbps_to_hsfreqrange_sel(u32 max_mbps)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(hsfreq_map); i++)
-		if (hsfreq_map[i].max_mbps > max_mbps)
-			return hsfreq_map[i].hsfreqrange_sel;
-
-	return -EINVAL;
-}
-
-static int csi2_dphy_init(struct dw_mipi_csi2_dev *csi2)
-{
-	struct v4l2_ctrl *ctrl;
-	u32 mbps_per_lane;
-	int sel;
-
-	ctrl = v4l2_ctrl_find(csi2->src_sd->ctrl_handler,
-			      V4L2_CID_LINK_FREQ);
-	if (!ctrl)
-		mbps_per_lane = CSI2_DEFAULT_MAX_MBPS;
-	else
-		mbps_per_lane = DIV_ROUND_UP_ULL(2 * ctrl->qmenu_int[ctrl->val],
-						 USEC_PER_SEC);
-
-	sel = max_mbps_to_hsfreqrange_sel(mbps_per_lane);
-	if (sel < 0)
-		return sel;
-
-	dw_mipi_csi2_phy_write(csi2, 0x44, sel);
-
-	return 0;
-}
-
 /*
  * Waits for ultra-low-power state on D-PHY clock lane. This is currently
  * unused and may not be needed at all, but keep around just in case.
@@ -332,9 +282,11 @@ static int csi2_start(struct dw_mipi_csi2_dev *csi2)
 		csi2->config->gasket_init(csi2);
 
 	/* Step 3 */
-	ret = csi2_dphy_init(csi2);
-	if (ret)
-		goto err_disable_clk;
+	if (csi2->config && csi2->config->dphy_init) {
+		ret = csi2->config->dphy_init(csi2);
+		if (ret)
+			goto err_disable_clk;
+	}
 
 	ret = csi2_get_active_lanes(csi2, &lanes);
 	if (ret)
@@ -680,6 +632,8 @@ int dw_mipi_csi2_init(struct platform_device *pdev, struct dw_mipi_csi2_dev *csi
 	csi2->sd.grp_id = config->grp_id;
 	csi2->config = config;
 
+	csi2->tstif.write = dw_mipi_csi2_phy_write;
+
 	if (!config)
 		return -EINVAL;
 
diff --git a/include/media/dw-mipi-csi2.h b/include/media/dw-mipi-csi2.h
index 12e1db1d149513fcd0db8c191c801cb144d18143..935c664440aae82d69f0253a551b91ec4ff2724e 100644
--- a/include/media/dw-mipi-csi2.h
+++ b/include/media/dw-mipi-csi2.h
@@ -20,10 +20,26 @@ struct dw_mipi_csi2_config {
 	const struct v4l2_subdev_internal_ops *internal_ops;
 	/* Deprecated, should go through phy interface */
 	void (*gasket_init)(struct dw_mipi_csi2_dev *dev);
+	int (*dphy_init)(struct dw_mipi_csi2_dev *dev);
 	u32	num_pads;	/* Max 64 pad now */
 	u32	sink_pad_mask;
 };
 
+struct dw_mipi_tstif {
+	int (*write)(struct dw_mipi_tstif *tstif, u32 indice, u32 data);
+};
+
+static inline int dw_mipi_tstif_write(struct dw_mipi_tstif *tstif, u32 indice, u32 data)
+{
+	if (!tstif)
+		return -EINVAL;
+
+	if (!tstif->write)
+		return -EINVAL;
+
+	return  tstif->write(tstif, indice, data);
+}
+
 struct dw_mipi_csi2_dev {
 	struct device			*dev;
 	struct v4l2_subdev		sd;
@@ -51,8 +67,13 @@ struct dw_mipi_csi2_dev {
 	struct v4l2_subdev		*src_sd;
 	bool				sink_linked[DW_MAX_PAD_NUM];
 	const struct dw_mipi_csi2_config *config;
+
+	struct dw_mipi_tstif		tstif;
 };
 
+#define dw_mipi_csi2_tstif_write(csi2, indice, data)		\
+dw_mipi_tstif_write(&(csi2)->tstif, indice, data)
+
 static inline struct dw_mipi_csi2_dev *
 sd_to_dw_mipi_csi2_dev(struct v4l2_subdev *sd)
 {

-- 
2.34.1



From Frank.Li at nxp.com  Fri Aug  8 15:39:20 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:20 -0400
Subject: [PATCH v2 17/32] media: staging: media: imx6-mipi-csi2: use
 runtime_pm frame to control clks
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <20250808-95_cam-v2-17-4b29fa6919a7@nxp.com>

Enable runtime pm and use runtime pm API to control clocks.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/staging/media/imx/imx6-csi2.c      |  4 ++++
 drivers/staging/media/imx/imx6-mipi-csi2.c | 11 ++++++++---
 include/media/dw-mipi-csi2.h               | 18 ++++++++++++++++++
 3 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/media/imx/imx6-csi2.c b/drivers/staging/media/imx/imx6-csi2.c
index 696644aa04c83b1f2877b2b2315202627d927e96..e5192bcd886958a27f4255fca1055ae0a94866ef 100644
--- a/drivers/staging/media/imx/imx6-csi2.c
+++ b/drivers/staging/media/imx/imx6-csi2.c
@@ -154,6 +154,9 @@ static void csi2_remove(struct platform_device *pdev)
 	dw_mipi_csi2_deinit(csi2);
 }
 
+static DEFINE_RUNTIME_DEV_PM_OPS(imx6_csi2_pm_ops, dw_mipi_csi2_runtime_suspend,
+				 dw_mipi_csi2_runtime_resume, NULL);
+
 static const struct of_device_id csi2_dt_ids[] = {
 	{ .compatible = "fsl,imx6-mipi-csi2"},
 	{ /* sentinel */ }
@@ -164,6 +167,7 @@ static struct platform_driver csi2_driver = {
 	.driver = {
 		.name = "imx6-mipi-csi2",
 		.of_match_table = csi2_dt_ids,
+		.pm = pm_ptr(&imx6_csi2_pm_ops),
 	},
 	.probe = csi2_probe,
 	.remove = csi2_remove,
diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index 23656291d808ccdfc47f36d1f7f5104698812eba..0c8022ecdc18d42fa038c721e0c0953e8eb9cd6c 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -273,7 +273,7 @@ static int csi2_start(struct dw_mipi_csi2_dev *csi2)
 	unsigned int lanes;
 	int ret;
 
-	ret = clk_bulk_prepare_enable(csi2->num_clks, csi2->clks);
+	ret = pm_runtime_resume_and_get(csi2->dev);
 	if (ret)
 		return ret;
 
@@ -323,7 +323,7 @@ static int csi2_start(struct dw_mipi_csi2_dev *csi2)
 err_assert_reset:
 	csi2_enable(csi2, false);
 err_disable_clk:
-	clk_bulk_disable_unprepare(csi2->num_clks, csi2->clks);
+	pm_runtime_put(csi2->dev);
 	return ret;
 }
 
@@ -334,7 +334,8 @@ static void csi2_stop(struct dw_mipi_csi2_dev *csi2)
 	v4l2_subdev_call(csi2->src_sd, video, post_streamoff);
 
 	csi2_enable(csi2, false);
-	clk_bulk_disable_unprepare(csi2->num_clks, csi2->clks);
+
+	pm_runtime_put(csi2->dev);
 }
 
 /*
@@ -634,6 +635,8 @@ int dw_mipi_csi2_init(struct platform_device *pdev, struct dw_mipi_csi2_dev *csi
 
 	csi2->tstif.write = dw_mipi_csi2_phy_write;
 
+	platform_set_drvdata(pdev, csi2);
+
 	if (!config)
 		return -EINVAL;
 
@@ -667,6 +670,8 @@ int dw_mipi_csi2_init(struct platform_device *pdev, struct dw_mipi_csi2_dev *csi
 	if (csi2->num_clks < 0)
 		return dev_err_probe(&pdev->dev, csi2->num_clks, "Failed to get clocks\n");
 
+	devm_pm_runtime_enable(&pdev->dev);
+
 	return csi2_async_register(csi2);
 
 }
diff --git a/include/media/dw-mipi-csi2.h b/include/media/dw-mipi-csi2.h
index 935c664440aae82d69f0253a551b91ec4ff2724e..3d70c1f4f38e7d663f9b043d8903ce57d630d1b1 100644
--- a/include/media/dw-mipi-csi2.h
+++ b/include/media/dw-mipi-csi2.h
@@ -3,6 +3,8 @@
 #ifndef __DW_MIPI_CSI2_COMMON_
 #define __DW_MIPI_CSI2_COMMON_
 
+#include <linux/pm_runtime.h>
+
 #include <media/v4l2-common.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-fwnode.h>
@@ -86,5 +88,21 @@ int dw_mipi_csi2_init(struct platform_device *pdev,
 
 void dw_mipi_csi2_deinit(struct dw_mipi_csi2_dev *csi2);
 
+static inline int dw_mipi_csi2_runtime_suspend(struct device *dev)
+{
+	struct dw_mipi_csi2_dev *csi2 = dev_get_drvdata(dev);
+
+	clk_bulk_disable_unprepare(csi2->num_clks, csi2->clks);
+
+	return 0;
+}
+
+static inline int dw_mipi_csi2_runtime_resume(struct device *dev)
+{
+	struct dw_mipi_csi2_dev *csi2 = dev_get_drvdata(dev);
+
+	return clk_bulk_prepare_enable(csi2->num_clks, csi2->clks);
+}
+
 #endif
 

-- 
2.34.1



From Frank.Li at nxp.com  Fri Aug  8 15:39:21 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:21 -0400
Subject: [PATCH v2 18/32] media: synopsys: move imx6-mipi-csi2.c to
 synopsys/mipi-csi2.c
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <20250808-95_cam-v2-18-4b29fa6919a7@nxp.com>

Move dw MIPI CSI2 common part drivers/staging/media/imx/imx6-mipi-csi2.c
under synopsys to let more SoC can reuse it.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/media/platform/synopsys/Kconfig                      | 12 ++++++++++++
 drivers/media/platform/synopsys/Makefile                     |  2 ++
 .../imx6-mipi-csi2.c => media/platform/synopsys/mipi-csi2.c} |  0
 drivers/staging/media/imx/Kconfig                            |  1 +
 drivers/staging/media/imx/Makefile                           |  2 +-
 5 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/synopsys/Kconfig b/drivers/media/platform/synopsys/Kconfig
index 4fd521f78425a96985fa3b6b017deef36631d1a9..e54dad835349d420dead6d5313c0623567c28c0b 100644
--- a/drivers/media/platform/synopsys/Kconfig
+++ b/drivers/media/platform/synopsys/Kconfig
@@ -1,3 +1,15 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
+config VIDEO_SYNOPSYS_MIPI_CSI2
+        tristate "Synopsys DesignWare MIPI CSI2 Receiver common library"
+        depends on VIDEO_DEV
+        select MEDIA_CONTROLLER
+        select VIDEO_V4L2_SUBDEV_API
+        select VIDEOBUF2_DMA_CONTIG
+        help
+          Common library for MIPI CSI2 Controller.
+
+          To compile this driver as a module, choose M here. The module
+          will be called synopsys_hdmirx
+
 source "drivers/media/platform/synopsys/hdmirx/Kconfig"
diff --git a/drivers/media/platform/synopsys/Makefile b/drivers/media/platform/synopsys/Makefile
index 3b12c574dd67c072901108d88cad64ca3a723938..045ed3177738e6d28aa223804b79e6774e141dc8 100644
--- a/drivers/media/platform/synopsys/Makefile
+++ b/drivers/media/platform/synopsys/Makefile
@@ -1,2 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-y += hdmirx/
+
+obj-$(CONFIG_VIDEO_SYNOPSYS_MIPI_CSI2) += mipi-csi2.o
diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/media/platform/synopsys/mipi-csi2.c
similarity index 100%
rename from drivers/staging/media/imx/imx6-mipi-csi2.c
rename to drivers/media/platform/synopsys/mipi-csi2.c
diff --git a/drivers/staging/media/imx/Kconfig b/drivers/staging/media/imx/Kconfig
index 1cd48028b6416ae16ed69c68186281b6c6bcbec8..53e5c1546ac53e4942974a9acdcf078de1cb6073 100644
--- a/drivers/staging/media/imx/Kconfig
+++ b/drivers/staging/media/imx/Kconfig
@@ -10,6 +10,7 @@ config VIDEO_IMX_MEDIA
 	select V4L2_MEM2MEM_DEV
 	select VIDEOBUF2_DMA_CONTIG
 	select VIDEO_V4L2_SUBDEV_API
+	select VIDEO_SYNOPSYS_MIPI_CSI2
 	help
 	  Say yes here to enable support for video4linux media controller
 	  drivers for the i.MX5/6 SOC.
diff --git a/drivers/staging/media/imx/Makefile b/drivers/staging/media/imx/Makefile
index 064a6c6c069aa440c72a483080cbedf89d370193..1978b82fd1876566acbb952a4d14cf9aca35e996 100644
--- a/drivers/staging/media/imx/Makefile
+++ b/drivers/staging/media/imx/Makefile
@@ -11,4 +11,4 @@ imx6-media-csi-objs := imx-media-csi.o imx-media-fim.o
 obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx-media-common.o
 obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx6-media.o
 obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx6-media-csi.o
-obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx6-mipi-csi2.o imx6-csi2.o
+obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx6-csi2.o

-- 
2.34.1



From Frank.Li at nxp.com  Fri Aug  8 15:39:22 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:22 -0400
Subject: [PATCH v2 19/32] media: synopsys: csi2: Remove deprecated s_stream
 and use v4l2_subdev_pad_ops
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <20250808-95_cam-v2-19-4b29fa6919a7@nxp.com>

Use new v4l2_subdev_pad_ops.enable_streams(disalbe_stream) replace
deprecated s_stream interface.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/media/platform/synopsys/mipi-csi2.c | 52 +++++++++++++++++------------
 1 file changed, 31 insertions(+), 21 deletions(-)

diff --git a/drivers/media/platform/synopsys/mipi-csi2.c b/drivers/media/platform/synopsys/mipi-csi2.c
index 0c8022ecdc18d42fa038c721e0c0953e8eb9cd6c..9ea3ae22fecfbb66abc460c40cbbcf15e1a97494 100644
--- a/drivers/media/platform/synopsys/mipi-csi2.c
+++ b/drivers/media/platform/synopsys/mipi-csi2.c
@@ -342,7 +342,9 @@ static void csi2_stop(struct dw_mipi_csi2_dev *csi2)
  * V4L2 subdev operations.
  */
 
-static int csi2_s_stream(struct v4l2_subdev *sd, int enable)
+static int dw_csi2_enable_streams(struct v4l2_subdev *sd,
+				  struct v4l2_subdev_state *state, u32 pad,
+				  u64 streams_mask)
 {
 	struct dw_mipi_csi2_dev *csi2 = sd_to_dev(sd);
 	int i, ret = 0;
@@ -359,28 +361,39 @@ static int csi2_s_stream(struct v4l2_subdev *sd, int enable)
 	if (i >= csi2->num_sink_pads)
 		return -EPIPE;
 
-	/*
-	 * enable/disable streaming only if stream_count is
-	 * going from 0 to 1 / 1 to 0.
-	 */
-	if (csi2->stream_count != !enable)
-		goto update_count;
+	if (csi2->stream_count)
+		return 0;
 
-	dev_dbg(csi2->dev, "stream %s\n", enable ? "ON" : "OFF");
-	if (enable)
-		ret = csi2_start(csi2);
-	else
-		csi2_stop(csi2);
+	ret = csi2_start(csi2);
 	if (ret)
 		return ret;
 
-update_count:
-	csi2->stream_count += enable ? 1 : -1;
-	if (csi2->stream_count < 0)
-		csi2->stream_count = 0;
+	csi2->stream_count++;
+
 	return ret;
 }
 
+static int dw_csi2_disable_streams(struct v4l2_subdev *sd,
+				   struct v4l2_subdev_state *state, u32 pad,
+				   u64 streams_mask)
+{
+	struct dw_mipi_csi2_dev *csi2 = sd_to_dev(sd);
+
+	guard(mutex)(&csi2->lock);
+
+	if (!csi2->stream_count) {
+		dev_err(csi2->dev, "Error: csi2 enable count already be 0\n");
+		return 0;
+	}
+
+	csi2->stream_count--;
+
+	if (!csi2->stream_count)
+		csi2_stop(csi2);
+
+	return 0;
+}
+
 static int csi2_link_setup(struct media_entity *entity,
 			   const struct media_pad *local,
 			   const struct media_pad *remote, u32 flags)
@@ -507,18 +520,15 @@ static const struct media_entity_operations csi2_entity_ops = {
 	.get_fwnode_pad = v4l2_subdev_get_fwnode_pad_1_to_1,
 };
 
-static const struct v4l2_subdev_video_ops csi2_video_ops = {
-	.s_stream = csi2_s_stream,
-};
-
 static const struct v4l2_subdev_pad_ops csi2_pad_ops = {
 	.get_fmt = csi2_get_fmt,
 	.set_fmt = csi2_set_fmt,
+	.enable_streams = dw_csi2_enable_streams,
+	.disable_streams = dw_csi2_disable_streams,
 };
 
 static const struct v4l2_subdev_ops csi2_subdev_ops = {
 	.core = &csi2_core_ops,
-	.video = &csi2_video_ops,
 	.pad = &csi2_pad_ops,
 };
 

-- 
2.34.1



From Frank.Li at nxp.com  Fri Aug  8 15:39:23 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:23 -0400
Subject: [PATCH v2 20/32] media: synopsys: csi2: Add phy interface support
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <20250808-95_cam-v2-20-4b29fa6919a7@nxp.com>

Add standard phy interface support.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/media/platform/synopsys/mipi-csi2.c | 91 +++++++++++++++++++++++++++--
 include/media/dw-mipi-csi2.h                |  4 ++
 2 files changed, 90 insertions(+), 5 deletions(-)

diff --git a/drivers/media/platform/synopsys/mipi-csi2.c b/drivers/media/platform/synopsys/mipi-csi2.c
index 9ea3ae22fecfbb66abc460c40cbbcf15e1a97494..610f2debbf08f571a47f5372853d5ef10a6add52 100644
--- a/drivers/media/platform/synopsys/mipi-csi2.c
+++ b/drivers/media/platform/synopsys/mipi-csi2.c
@@ -14,6 +14,7 @@
 #include <linux/of_graph.h>
 #include <linux/platform_device.h>
 #include <media/dw-mipi-csi2.h>
+#include <media/mipi-csi2.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
@@ -268,7 +269,63 @@ static int csi2_get_active_lanes(struct dw_mipi_csi2_dev *csi2, unsigned int *la
 	return 0;
 }
 
-static int csi2_start(struct dw_mipi_csi2_dev *csi2)
+static int dw_csi2_get_dphy_configuration(struct dw_mipi_csi2_dev *csi2,
+					  union phy_configure_opts *opts,
+					  int bpp)
+{
+	struct phy_configure_opts_mipi_dphy *cfg = &opts->mipi_dphy;
+	struct v4l2_subdev *source = csi2->src_sd;
+	s64 link_freq;
+
+	link_freq = v4l2_get_link_freq(source->ctrl_handler,
+				       bpp,
+				       csi2->data_lanes * 2);
+	if (link_freq < 0) {
+		dev_err(csi2->dev, "Unable to obtain link frequency: %d\n",
+			(int)link_freq);
+		return link_freq;
+	}
+
+	memset(cfg, 0x0, sizeof(*cfg));
+	cfg->hs_clk_rate = link_freq * 2;
+	cfg->lanes = csi2->data_lanes;
+
+	return 0;
+}
+
+static int dw_mipi_csi2_phy_prep(struct dw_mipi_csi2_dev *csi2, int bpp)
+{
+	union phy_configure_opts opts;
+	int ret;
+
+	ret = dw_csi2_get_dphy_configuration(csi2, &opts, bpp);
+	if (ret)
+		return ret;
+
+	ret = phy_init(csi2->phy);
+	if (ret)
+		return ret;
+
+	ret = phy_reset(csi2->phy);
+	if (ret)
+		goto exit;
+
+	ret = phy_set_mode(csi2->phy, PHY_MODE_MIPI_DPHY);
+	if (ret)
+		goto exit;
+
+	ret = phy_configure(csi2->phy, &opts);
+	if (ret)
+		goto exit;
+
+	return 0;
+
+exit:
+	phy_exit(csi2->phy);
+	return ret;
+}
+
+static int csi2_start(struct dw_mipi_csi2_dev *csi2, int bpp)
 {
 	unsigned int lanes;
 	int ret;
@@ -277,6 +334,10 @@ static int csi2_start(struct dw_mipi_csi2_dev *csi2)
 	if (ret)
 		return ret;
 
+	ret = dw_mipi_csi2_phy_prep(csi2, bpp);
+	if (ret)
+		goto err_phy_prep;
+
 	/* setup the gasket */
 	if (csi2->config && csi2->config->gasket_init)
 		csi2->config->gasket_init(csi2);
@@ -285,15 +346,20 @@ static int csi2_start(struct dw_mipi_csi2_dev *csi2)
 	if (csi2->config && csi2->config->dphy_init) {
 		ret = csi2->config->dphy_init(csi2);
 		if (ret)
-			goto err_disable_clk;
+			goto err_dphy_init;
 	}
 
 	ret = csi2_get_active_lanes(csi2, &lanes);
 	if (ret)
-		goto err_disable_clk;
+		goto err_active_lanes;
 
 	/* Step 4 */
 	csi2_set_lanes(csi2, lanes);
+
+	ret = phy_power_on(csi2->phy);
+	if (ret)
+		goto err_phy_power_on;
+
 	csi2_enable(csi2, true);
 
 	/* Step 5 */
@@ -322,13 +388,21 @@ static int csi2_start(struct dw_mipi_csi2_dev *csi2)
 	v4l2_subdev_call(csi2->src_sd, video, post_streamoff);
 err_assert_reset:
 	csi2_enable(csi2, false);
-err_disable_clk:
+err_phy_power_on:
+	phy_power_off(csi2->phy);
+err_active_lanes:
+err_dphy_init:
+	phy_exit(csi2->phy);
+err_phy_prep:
 	pm_runtime_put(csi2->dev);
 	return ret;
 }
 
 static void csi2_stop(struct dw_mipi_csi2_dev *csi2)
 {
+	phy_power_off(csi2->phy);
+	phy_exit(csi2->phy);
+
 	/* stop upstream */
 	v4l2_subdev_call(csi2->src_sd, video, s_stream, 0);
 	v4l2_subdev_call(csi2->src_sd, video, post_streamoff);
@@ -364,7 +438,7 @@ static int dw_csi2_enable_streams(struct v4l2_subdev *sd,
 	if (csi2->stream_count)
 		return 0;
 
-	ret = csi2_start(csi2);
+	ret = csi2_start(csi2, media_bus_fmt_to_csi2_bpp(csi2->format_mbus.code));
 	if (ret)
 		return ret;
 
@@ -680,6 +754,13 @@ int dw_mipi_csi2_init(struct platform_device *pdev, struct dw_mipi_csi2_dev *csi
 	if (csi2->num_clks < 0)
 		return dev_err_probe(&pdev->dev, csi2->num_clks, "Failed to get clocks\n");
 
+	if (config->has_phy) {
+		csi2->phy = devm_phy_get(&pdev->dev, "rx");
+		if (IS_ERR(csi2->phy))
+			return dev_err_probe(&pdev->dev, PTR_ERR(csi2->phy),
+					     "Failed to get DPHY Rx\n");
+	}
+
 	devm_pm_runtime_enable(&pdev->dev);
 
 	return csi2_async_register(csi2);
diff --git a/include/media/dw-mipi-csi2.h b/include/media/dw-mipi-csi2.h
index 3d70c1f4f38e7d663f9b043d8903ce57d630d1b1..14a80c09fd273c334f91ea70d955dcf92b6646ce 100644
--- a/include/media/dw-mipi-csi2.h
+++ b/include/media/dw-mipi-csi2.h
@@ -3,6 +3,7 @@
 #ifndef __DW_MIPI_CSI2_COMMON_
 #define __DW_MIPI_CSI2_COMMON_
 
+#include <linux/phy/phy.h>
 #include <linux/pm_runtime.h>
 
 #include <media/v4l2-common.h>
@@ -25,6 +26,7 @@ struct dw_mipi_csi2_config {
 	int (*dphy_init)(struct dw_mipi_csi2_dev *dev);
 	u32	num_pads;	/* Max 64 pad now */
 	u32	sink_pad_mask;
+	bool	has_phy: 1;
 };
 
 struct dw_mipi_tstif {
@@ -56,6 +58,8 @@ struct dw_mipi_csi2_dev {
 	struct clk_bulk_data		*clks;
 	int				num_clks;
 
+	struct phy			*phy;
+
 	struct v4l2_subdev		*remote;
 	unsigned int			remote_pad;
 	unsigned short			data_lanes;

-- 
2.34.1



From Frank.Li at nxp.com  Fri Aug  8 15:39:24 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:24 -0400
Subject: [PATCH v2 21/32] media: synopsys: csi2: Add basic v150* version
 register
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <20250808-95_cam-v2-21-4b29fa6919a7@nxp.com>

Add basic v150* version register and auto detect IP version by read version
register, which located position 0 for both version.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/media/platform/synopsys/mipi-csi2.c | 37 ++++++++++++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/synopsys/mipi-csi2.c b/drivers/media/platform/synopsys/mipi-csi2.c
index 610f2debbf08f571a47f5372853d5ef10a6add52..0386d91522ec7b41694ac9c36ad0c3c37b1e68b3 100644
--- a/drivers/media/platform/synopsys/mipi-csi2.c
+++ b/drivers/media/platform/synopsys/mipi-csi2.c
@@ -61,6 +61,19 @@ static const struct dw_csi2_regs dw_csi2_v0 = {
 	.phy_tst_ctrl1 = DW_REG(0x34),
 };
 
+static const struct dw_csi2_regs dw_csi2_v150 = {
+	.version = DW_REG(0x0),
+	.n_lanes = DW_REG(0x4),
+	.resetn = DW_REG(0x8),
+	.data_ids_1 = DW_REG(0x10),
+	.data_ids_2 = DW_REG(0x14),
+	.phy_shutdownz = DW_REG(0x40),
+	.dphy_rstz = DW_REG(0x44),
+	.phy_state = DW_REG(0x48),
+	.phy_tst_ctrl0 = DW_REG(0x50),
+	.phy_tst_ctrl1 = DW_REG(0x54),
+};
+
 static int dw_csi2_reg_err(struct dw_mipi_csi2_dev *csi2, const char *name)
 {
 	dev_err_once(csi2->dev, "access to unexisted register: %s", name);
@@ -697,13 +710,31 @@ static void csi2_nf_cleanup(void *data)
 	v4l2_async_nf_cleanup(&csi2->notifier);
 }
 
+static int dw_detect_version(struct dw_mipi_csi2_dev *csi2)
+{
+	int ret;
+	int ver;
+
+	ret = pm_runtime_resume_and_get(csi2->dev);
+	if (ret)
+		return ret;
+
+	/* version is first register for known chips */
+	ver = readl(csi2->base);
+	if (ver >= 0x3135302a) /* ASCII "150*" */
+		csi2->regs = &dw_csi2_v150;
+	else
+		csi2->regs = &dw_csi2_v0;
+
+	return 0;
+}
+
 int dw_mipi_csi2_init(struct platform_device *pdev, struct dw_mipi_csi2_dev *csi2,
 		      const struct dw_mipi_csi2_config *config)
 {
 	int i, ret;
 
 	csi2->dev = &pdev->dev;
-	csi2->regs = &dw_csi2_v0;
 	v4l2_subdev_init(&csi2->sd, &csi2_subdev_ops);
 	v4l2_set_subdevdata(&csi2->sd, &pdev->dev);
 	csi2->sd.entity.ops = &csi2_entity_ops;
@@ -763,6 +794,10 @@ int dw_mipi_csi2_init(struct platform_device *pdev, struct dw_mipi_csi2_dev *csi
 
 	devm_pm_runtime_enable(&pdev->dev);
 
+	ret = dw_detect_version(csi2);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "Failed to detect IP version");
+
 	return csi2_async_register(csi2);
 
 }

-- 
2.34.1



From Frank.Li at nxp.com  Fri Aug  8 15:39:25 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:25 -0400
Subject: [PATCH v2 22/32] media: synopsys: csi2: Add irq support to record
 error count
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <20250808-95_cam-v2-22-4b29fa6919a7@nxp.com>

Add irq support to record error count. Use debugfs to show such error
count.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/media/platform/synopsys/mipi-csi2.c | 171 ++++++++++++++++++++++++++++
 include/media/dw-mipi-csi2.h                |   8 ++
 2 files changed, 179 insertions(+)

diff --git a/drivers/media/platform/synopsys/mipi-csi2.c b/drivers/media/platform/synopsys/mipi-csi2.c
index 0386d91522ec7b41694ac9c36ad0c3c37b1e68b3..dcad69cea99f3172786156699513f8cc8771ad2a 100644
--- a/drivers/media/platform/synopsys/mipi-csi2.c
+++ b/drivers/media/platform/synopsys/mipi-csi2.c
@@ -4,6 +4,7 @@
  *
  * Copyright (c) 2012-2017 Mentor Graphics Inc.
  */
+#include <linux/debugfs.h>
 #include <linux/export.h>
 #include <linux/clk.h>
 #include <linux/interrupt.h>
@@ -37,6 +38,19 @@ struct dw_csi2_regs {
 	u32	msk2;
 	u32	phy_tst_ctrl0;
 	u32	phy_tst_ctrl1;
+	u32	int_st_main;
+	u32	int_st_dphy_fatal;
+	u32	int_msk_dphy_fatal;
+	u32	int_force_dphy_fatal;
+	u32	int_st_pkt_fatal;
+	u32	int_msk_pkt_fatal;
+	u32	int_force_pkt_fatal;
+	u32	int_st_dphy;
+	u32	int_msk_dphy;
+	u32	int_force_dphy;
+	u32	int_st_ipi_fatal;
+	u32	int_msk_ipi_fatal;
+	u32	int_force_ipi_fatal;
 };
 
 /* Help check wrong access unexisted register at difference IP version */
@@ -65,6 +79,7 @@ static const struct dw_csi2_regs dw_csi2_v150 = {
 	.version = DW_REG(0x0),
 	.n_lanes = DW_REG(0x4),
 	.resetn = DW_REG(0x8),
+	.int_st_main = DW_REG(0xc),
 	.data_ids_1 = DW_REG(0x10),
 	.data_ids_2 = DW_REG(0x14),
 	.phy_shutdownz = DW_REG(0x40),
@@ -72,8 +87,48 @@ static const struct dw_csi2_regs dw_csi2_v150 = {
 	.phy_state = DW_REG(0x48),
 	.phy_tst_ctrl0 = DW_REG(0x50),
 	.phy_tst_ctrl1 = DW_REG(0x54),
+	.int_st_dphy_fatal = DW_REG(0xe0),
+	.int_msk_dphy_fatal = DW_REG(0xe4),
+	.int_force_dphy_fatal = DW_REG(0xe8),
+	.int_st_pkt_fatal = DW_REG(0xf0),
+	.int_msk_pkt_fatal = DW_REG(0xf4),
+	.int_force_pkt_fatal = DW_REG(0xf8),
+	.int_st_dphy = DW_REG(0x110),
+	.int_msk_dphy = DW_REG(0x114),
+	.int_force_dphy = DW_REG(0x118),
+	.int_st_ipi_fatal = DW_REG(0x140),
+	.int_msk_ipi_fatal = DW_REG(0x144),
+	.int_force_ipi_fatal = DW_REG(0x148),
 };
 
+#define INT_ST_MAIN_FATAL_ERR_PHY		BIT(0)
+#define INT_ST_MAIN_FATAL_ERR_PKT		BIT(1)
+#define INT_ST_MAIN_FATAL_ERR_BNDRY_FRAMEL	BIT(2)
+#define INT_ST_MAIN_FATAL_ERR_SEQ_FRAME		BIT(3)
+#define INT_ST_MAIN_FATAL_ERR_CRC_FRAME		BIT(4)
+#define INT_ST_MAIN_FATAL_ERR_PLD_CRC		BIT(5)
+#define INT_ST_MAIN_ERR_DID			BIT(6)
+#define INT_ST_MAIN_ERR_ECC			BIT(7)
+#define INT_ST_MAIN_ERR_PHY			BIT(16)
+#define INT_ST_MAIN_FATAL_ERR_IPI		BIT(18)
+
+#define INT_MSK_DPHY_FATAL_ERR_SOT_LANE0	BIT(0)
+#define INT_MSK_DPHY_FATAL_ERR_SOT_LANE1	BIT(1)
+
+#define INT_ST_PKT_FATAL_ERR_ECC		BIT(0)
+#define INT_ST_PKT_FATAL_ERR_PAYLOAD	BIT(1)
+
+#define INT_MSK_PKT_FATAL_ERR_ECC		BIT(0)
+#define INT_MSK_PKT_FATAL_ERR_PAYLOAD		BIT(1)
+
+#define INT_ST_IPI_FATAL_ERR_IFFIFO_UNDERFLOW	BIT(0)
+#define INT_ST_IPI_FATAL_ERR_IFFIFO_OVERFLOW	BIT(1)
+#define INT_ST_IPI_FATAL_ERR_FRAME_SYNC		BIT(2)
+#define INT_ST_IPI_FATAL_ERR_FIFO_NOT_EMPTY	BIT(3)
+#define INT_ST_IPI_FATAL_ERR_HLINE_TIME		BIT(4)
+#define INT_ST_IPI_FATAL_ERR_FIFO_OVERFLOW	BIT(5)
+#define INT_ST_IPI_FATAL_ERR_PD_FIFO_OVERFLOW	BIT(6)
+
 static int dw_csi2_reg_err(struct dw_mipi_csi2_dev *csi2, const char *name)
 {
 	dev_err_once(csi2->dev, "access to unexisted register: %s", name);
@@ -108,6 +163,25 @@ static inline struct dw_mipi_csi2_dev *notifier_to_dev(struct v4l2_async_notifie
 	return container_of(n, struct dw_mipi_csi2_dev, notifier);
 }
 
+struct dw_csi2_event {
+	u32 mask;
+	const char * const name;
+	u32 counter;
+};
+
+static const struct dw_csi2_event dw_events[] = {
+	{ INT_ST_MAIN_FATAL_ERR_IPI, "IPI Interface Fatal Error" },
+	{ INT_ST_MAIN_ERR_PHY, "PHY Error" },
+	{ INT_ST_MAIN_ERR_ECC, "Header Single Bit Error" },
+	{ INT_ST_MAIN_ERR_DID, "Data ID Error" },
+	{ INT_ST_MAIN_FATAL_ERR_PLD_CRC, "Payload CRC Fatal Error" },
+	{ INT_ST_MAIN_FATAL_ERR_CRC_FRAME, "Frame CRC Fatal Error" },
+	{ INT_ST_MAIN_FATAL_ERR_SEQ_FRAME, "Frame Sequence Fatal Error" },
+	{ INT_ST_MAIN_FATAL_ERR_BNDRY_FRAMEL, "Frame Boundaries Fatal Error" },
+	{ INT_ST_MAIN_FATAL_ERR_PKT, "Packet Construction Fatal Error" },
+	{ INT_ST_MAIN_FATAL_ERR_PHY, "PHY Fatal Error" },
+};
+
 /*
  * The required sequence of MIPI CSI-2 startup as specified in the i.MX6
  * reference manual is as follows:
@@ -338,6 +412,40 @@ static int dw_mipi_csi2_phy_prep(struct dw_mipi_csi2_dev *csi2, int bpp)
 	return ret;
 }
 
+static void dw_csi2_enable_irq(struct dw_mipi_csi2_dev *csi2)
+{
+	u32 val;
+
+	/* Define errors to be enabled */
+	val = INT_MSK_DPHY_FATAL_ERR_SOT_LANE0 |
+	      INT_MSK_DPHY_FATAL_ERR_SOT_LANE0;
+	dw_writel(csi2, val, int_msk_dphy_fatal);
+
+	val = INT_ST_PKT_FATAL_ERR_ECC | INT_ST_PKT_FATAL_ERR_PAYLOAD;
+	dw_writel(csi2, val, int_msk_pkt_fatal);
+
+	val = INT_MSK_PKT_FATAL_ERR_ECC | INT_MSK_PKT_FATAL_ERR_PAYLOAD;
+	dw_writel(csi2, val, int_msk_dphy);
+
+	val = INT_ST_IPI_FATAL_ERR_IFFIFO_UNDERFLOW |
+	      INT_ST_IPI_FATAL_ERR_IFFIFO_OVERFLOW |
+	      INT_ST_IPI_FATAL_ERR_FRAME_SYNC |
+	      INT_ST_IPI_FATAL_ERR_FIFO_NOT_EMPTY |
+	      INT_ST_IPI_FATAL_ERR_HLINE_TIME |
+	      INT_ST_IPI_FATAL_ERR_FIFO_OVERFLOW |
+	      INT_ST_IPI_FATAL_ERR_PD_FIFO_OVERFLOW;
+
+	dw_writel(csi2, val, int_msk_ipi_fatal);
+}
+
+static void dw_csi2_disable_irq(struct dw_mipi_csi2_dev *csi2)
+{
+	dw_writel(csi2, 0, int_msk_dphy_fatal);
+	dw_writel(csi2, 0, int_msk_pkt_fatal);
+	dw_writel(csi2, 0, int_msk_dphy);
+	dw_writel(csi2, 0, int_msk_ipi_fatal);
+}
+
 static int csi2_start(struct dw_mipi_csi2_dev *csi2, int bpp)
 {
 	unsigned int lanes;
@@ -393,6 +501,8 @@ static int csi2_start(struct dw_mipi_csi2_dev *csi2, int bpp)
 	if (ret)
 		goto err_stop_upstream;
 
+	dw_csi2_enable_irq(csi2);
+
 	return 0;
 
 err_stop_upstream:
@@ -422,6 +532,8 @@ static void csi2_stop(struct dw_mipi_csi2_dev *csi2)
 
 	csi2_enable(csi2, false);
 
+	dw_csi2_disable_irq(csi2);
+
 	pm_runtime_put(csi2->dev);
 }
 
@@ -729,6 +841,42 @@ static int dw_detect_version(struct dw_mipi_csi2_dev *csi2)
 	return 0;
 }
 
+static irqreturn_t dw_csi2_irq_handler(int irq, void *priv)
+{
+	struct dw_mipi_csi2_dev *csi2 = priv;
+	u32 status;
+	int i;
+
+	/* Hardware auto clean after read */
+	status = dw_readl(csi2, int_st_main);
+
+	for (i = 0; i < csi2->num_event; i++) {
+		struct dw_csi2_event *event = &csi2->event[i];
+
+		if (status & event->mask)
+			event->counter++;
+	}
+
+	return IRQ_HANDLED;
+}
+
+static void dw_mipi_csi_create_debugfs(struct dw_mipi_csi2_dev *csi2)
+{
+	int i;
+
+	csi2->debugfs_root = debugfs_create_dir(dev_name(csi2->dev), NULL);
+
+	if (!csi2->debugfs_root)
+		return;
+
+	for (i = 0; i < csi2->num_event; i++) {
+		struct dw_csi2_event *event = &csi2->event[i];
+
+		debugfs_create_u32(event->name, 0600, csi2->debugfs_root,
+				   &event->counter);
+	}
+}
+
 int dw_mipi_csi2_init(struct platform_device *pdev, struct dw_mipi_csi2_dev *csi2,
 		      const struct dw_mipi_csi2_config *config)
 {
@@ -798,6 +946,27 @@ int dw_mipi_csi2_init(struct platform_device *pdev, struct dw_mipi_csi2_dev *csi
 	if (ret)
 		return dev_err_probe(&pdev->dev, ret, "Failed to detect IP version");
 
+	if (config->has_irq) {
+		int irq;
+
+		csi2->event = devm_kmemdup(&pdev->dev, dw_events, sizeof(dw_events), GFP_KERNEL);
+		csi2->num_event = ARRAY_SIZE(dw_events);
+
+		if (!csi2->event)
+			return -ENOMEM;
+
+		irq = platform_get_irq(pdev, 0);
+		if (irq < 0)
+			return dev_err_probe(&pdev->dev, irq, "Failed to get IRQ\n");
+
+		ret = devm_request_irq(&pdev->dev, irq, dw_csi2_irq_handler, 0,
+				       dev_name(&pdev->dev), csi2);
+		if (ret < 0)
+			return dev_err_probe(&pdev->dev, ret, "Failed to request IRQ\n");
+	}
+
+	dw_mipi_csi_create_debugfs(csi2);
+
 	return csi2_async_register(csi2);
 
 }
@@ -807,5 +976,7 @@ void dw_mipi_csi2_deinit(struct dw_mipi_csi2_dev *csi2)
 {
 	v4l2_async_unregister_subdev(&csi2->sd);
 	media_entity_cleanup(&csi2->sd.entity);
+
+	debugfs_remove(csi2->debugfs_root);
 }
 EXPORT_SYMBOL_GPL(dw_mipi_csi2_deinit);
diff --git a/include/media/dw-mipi-csi2.h b/include/media/dw-mipi-csi2.h
index 14a80c09fd273c334f91ea70d955dcf92b6646ce..20ce6a21f0674cad54f01edb508dce14cd07a8dd 100644
--- a/include/media/dw-mipi-csi2.h
+++ b/include/media/dw-mipi-csi2.h
@@ -27,6 +27,7 @@ struct dw_mipi_csi2_config {
 	u32	num_pads;	/* Max 64 pad now */
 	u32	sink_pad_mask;
 	bool	has_phy: 1;
+	bool	has_irq: 1;
 };
 
 struct dw_mipi_tstif {
@@ -44,6 +45,8 @@ static inline int dw_mipi_tstif_write(struct dw_mipi_tstif *tstif, u32 indice, u
 	return  tstif->write(tstif, indice, data);
 }
 
+struct dw_csi2_event;
+
 struct dw_mipi_csi2_dev {
 	struct device			*dev;
 	struct v4l2_subdev		sd;
@@ -74,6 +77,11 @@ struct dw_mipi_csi2_dev {
 	bool				sink_linked[DW_MAX_PAD_NUM];
 	const struct dw_mipi_csi2_config *config;
 
+	struct dw_csi2_event		*event;
+	int				num_event;
+
+	struct dentry			*debugfs_root;
+
 	struct dw_mipi_tstif		tstif;
 };
 

-- 
2.34.1



From Frank.Li at nxp.com  Fri Aug  8 15:39:26 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:26 -0400
Subject: [PATCH v2 23/32] media: synopsys: csi2: Handle alignment
 requirement for width
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <20250808-95_cam-v2-23-4b29fa6919a7@nxp.com>

bpp * width must align to 8. Use media_bus_fmt_to_csi2_bpp() and
v4l_get_required_align_by_bpp() to get width's alignment requirement.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/media/platform/synopsys/mipi-csi2.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/media/platform/synopsys/mipi-csi2.c b/drivers/media/platform/synopsys/mipi-csi2.c
index dcad69cea99f3172786156699513f8cc8771ad2a..5c41b9570dcb97f58018bbaba1dc67a3c120a60b 100644
--- a/drivers/media/platform/synopsys/mipi-csi2.c
+++ b/drivers/media/platform/synopsys/mipi-csi2.c
@@ -11,6 +11,7 @@
 #include <linux/io.h>
 #include <linux/iopoll.h>
 #include <linux/irq.h>
+#include <linux/limits.h>
 #include <linux/module.h>
 #include <linux/of_graph.h>
 #include <linux/platform_device.h>
@@ -664,15 +665,31 @@ static int csi2_set_fmt(struct v4l2_subdev *sd,
 {
 	struct dw_mipi_csi2_dev *csi2 = sd_to_dev(sd);
 	struct v4l2_mbus_framefmt *fmt;
+	u32 align;
+	u32 bpp;
 
 	if (sdformat->pad >= (csi2->num_src_pads + csi2->num_sink_pads))
 		return -EINVAL;
 
+	/*
+	 * The CSIS can't transcode in any way, the source format can't be
+	 * modified.
+	 */
+	if (sdformat->pad < csi2->num_src_pads)
+		return v4l2_subdev_get_fmt(sd, sd_state, sdformat);
+
 	guard(mutex)(&csi2->lock);
 
 	if (csi2->stream_count > 0)
 		return -EBUSY;
 
+	bpp = media_bus_fmt_to_csi2_bpp(sdformat->format.code);
+
+	align = v4l_get_required_align_by_bpp(bpp, 3); /* need align to 2^3 */
+
+	v4l_bound_align_image(&sdformat->format.width, 1, U16_MAX, align,
+			      &sdformat->format.height, 1, U16_MAX, 0, 0);
+
 	/* Output pads mirror active input pad, no limits on input pads */
 	if (!(csi2->config->sink_pad_mask & BIT(sdformat->pad)))
 		sdformat->format = csi2->format_mbus;

-- 
2.34.1



From Frank.Li at nxp.com  Fri Aug  8 15:39:27 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:27 -0400
Subject: [PATCH v2 24/32] media: synopsys: csi2: Add register prefix to
 register field definitions
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <20250808-95_cam-v2-24-4b29fa6919a7@nxp.com>

Add register prefix to register field definitions to improve readability.

No functional change.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/media/platform/synopsys/mipi-csi2.c | 30 ++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/media/platform/synopsys/mipi-csi2.c b/drivers/media/platform/synopsys/mipi-csi2.c
index 5c41b9570dcb97f58018bbaba1dc67a3c120a60b..df19b960d33681452af49dad5e6bbb94daa63489 100644
--- a/drivers/media/platform/synopsys/mipi-csi2.c
+++ b/drivers/media/platform/synopsys/mipi-csi2.c
@@ -146,16 +146,16 @@ dw_csi2_reg_err((csi2), #__name))
 readl((csi2)->base + ((csi2)->regs->__name & ~DW_REG_EXIST)) : \
 dw_csi2_reg_err(csi2, #__name))
 
-#define PHY_STOPSTATEDATA_BIT	4
-#define PHY_STOPSTATEDATA(n)	BIT(PHY_STOPSTATEDATA_BIT + (n))
-#define PHY_RXCLKACTIVEHS	BIT(8)
-#define PHY_RXULPSCLKNOT	BIT(9)
-#define PHY_STOPSTATECLK	BIT(10)
+#define PHY_STATE_STOPSTATEDATA_BIT	4
+#define PHY_STATE_STOPSTATEDATA(n)	BIT(PHY_STATE_STOPSTATEDATA_BIT + (n))
+#define PHY_STATE_RXCLKACTIVEHS	BIT(8)
+#define PHY_STATE_RXULPSCLKNOT	BIT(9)
+#define PHY_STATE_STOPSTATECLK	BIT(10)
 
-#define PHY_TESTCLR		BIT(0)
-#define PHY_TESTCLK		BIT(1)
+#define DPHY_TEST_CTRL0_TEST_CLR		BIT(0)
+#define DPHY_TEST_CTRL0_TEST_CLKEN	BIT(1)
 
-#define PHY_TESTEN		BIT(16)
+#define DPHY_TEST_CTRL1_TEST_EN		BIT(16)
 
 #define sd_to_dev sd_to_dw_mipi_csi2_dev
 
@@ -235,20 +235,20 @@ static int dw_mipi_csi2_phy_write(struct dw_mipi_tstif *tstif,
 	struct dw_mipi_csi2_dev *csi2 = container_of(tstif, struct dw_mipi_csi2_dev, tstif);
 
 	/* Clear PHY test interface */
-	dw_writel(csi2, PHY_TESTCLR, phy_tst_ctrl0);
+	dw_writel(csi2, DPHY_TEST_CTRL0_TEST_CLR, phy_tst_ctrl0);
 	dw_writel(csi2, 0x0, phy_tst_ctrl1);
 	dw_writel(csi2, 0x0, phy_tst_ctrl0);
 
 	/* Raise test interface strobe signal */
-	dw_writel(csi2, PHY_TESTCLK, phy_tst_ctrl0);
+	dw_writel(csi2, DPHY_TEST_CTRL0_TEST_CLKEN, phy_tst_ctrl0);
 
 	/* Configure address write on falling edge and lower strobe signal */
-	dw_writel(csi2, PHY_TESTEN | test_code, phy_tst_ctrl1);
+	dw_writel(csi2, DPHY_TEST_CTRL1_TEST_EN | test_code, phy_tst_ctrl1);
 	dw_writel(csi2, 0x0, phy_tst_ctrl0);
 
 	/* Configure data write on rising edge and raise strobe signal */
 	dw_writel(csi2, test_data, phy_tst_ctrl1);
-	dw_writel(csi2, PHY_TESTCLK, phy_tst_ctrl0);
+	dw_writel(csi2, DPHY_TEST_CTRL0_TEST_CLKEN, phy_tst_ctrl0);
 
 	/* Clear strobe signal */
 	dw_writel(csi2, 0x0, phy_tst_ctrl0);
@@ -271,7 +271,7 @@ static int __maybe_unused csi2_dphy_wait_ulp(struct dw_mipi_csi2_dev *csi2)
 	int ret;
 
 	/* wait for ULP on clock lane */
-	ret = read_poll_timeout(dw_readl, reg, !(reg & PHY_RXULPSCLKNOT),
+	ret = read_poll_timeout(dw_readl, reg, !(reg & PHY_STATE_RXULPSCLKNOT),
 				0, 500000, 0, csi2, phy_state);
 	if (ret) {
 		v4l2_err(&csi2->sd, "ULP timeout, phy_state = 0x%08x\n", reg);
@@ -294,7 +294,7 @@ static void csi2_dphy_wait_stopstate(struct dw_mipi_csi2_dev *csi2, unsigned int
 	u32 mask, reg;
 	int ret;
 
-	mask = PHY_STOPSTATECLK | (((1 << lanes) - 1) << PHY_STOPSTATEDATA_BIT);
+	mask = PHY_STATE_STOPSTATECLK | (((1 << lanes) - 1) << PHY_STATE_STOPSTATEDATA_BIT);
 
 	ret = read_poll_timeout(dw_readl, reg, (reg & mask) == mask, 0, 500000, 0, csi2, phy_state);
 	if (ret) {
@@ -309,7 +309,7 @@ static int csi2_dphy_wait_clock_lane(struct dw_mipi_csi2_dev *csi2)
 	u32 reg;
 	int ret;
 
-	ret = read_poll_timeout(dw_readl, reg, (reg & PHY_RXCLKACTIVEHS),
+	ret = read_poll_timeout(dw_readl, reg, (reg & PHY_STATE_RXCLKACTIVEHS),
 				0, 500000, 0, csi2, phy_state);
 	if (ret) {
 		v4l2_err(&csi2->sd, "clock lane timeout, phy_state = 0x%08x\n",

-- 
2.34.1



From Frank.Li at nxp.com  Fri Aug  8 15:39:28 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:28 -0400
Subject: [PATCH v2 25/32] media: synopsys: csi2: Add need_dphy_reset in
 config
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <20250808-95_cam-v2-25-4b29fa6919a7@nxp.com>

Add need_dphy_reset in config to indicate need keep dphy reset state during
config dphy because some SoC like i.MX93 need it.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/media/platform/synopsys/mipi-csi2.c | 45 +++++++++++++++++++++++++++++
 include/media/dw-mipi-csi2.h                |  1 +
 2 files changed, 46 insertions(+)

diff --git a/drivers/media/platform/synopsys/mipi-csi2.c b/drivers/media/platform/synopsys/mipi-csi2.c
index df19b960d33681452af49dad5e6bbb94daa63489..d1f08c8384ad45d47ffe81b6dc5f225aed43e21a 100644
--- a/drivers/media/platform/synopsys/mipi-csi2.c
+++ b/drivers/media/platform/synopsys/mipi-csi2.c
@@ -447,6 +447,45 @@ static void dw_csi2_disable_irq(struct dw_mipi_csi2_dev *csi2)
 	dw_writel(csi2, 0, int_msk_ipi_fatal);
 }
 
+static void dw_csi2_dphy_reset(struct dw_mipi_csi2_dev *csi2)
+{
+	u32 val;
+
+	/* Release synopsis DPHY test codes from reset */
+	dw_writel(csi2, 0, dphy_rstz);
+	dw_writel(csi2, 0, phy_shutdownz);
+
+	val = dw_readl(csi2, phy_tst_ctrl0);
+	val &= ~DPHY_TEST_CTRL0_TEST_CLR;
+	dw_writel(csi2, val, phy_tst_ctrl0);
+
+	/*
+	 * ndelay is not necessary have MMIO operation, need dummy read to make
+	 * sure above write reach target.
+	 */
+	val = dw_readl(csi2, phy_tst_ctrl0);
+	/* Wait for at least 15ns */
+	ndelay(15);
+	val |= DPHY_TEST_CTRL0_TEST_CLR;
+	dw_writel(csi2, val, phy_tst_ctrl0);
+}
+
+static void dw_csi2_dphy_release_reset(struct dw_mipi_csi2_dev *csi2)
+{
+	/* Release PHY from reset */
+	dw_writel(csi2, 0x1, phy_shutdownz);
+	/*
+	 * ndelay is not necessary have MMIO operation, need dummy read to make
+	 * sure above write reach target.
+	 */
+	dw_readl(csi2, phy_shutdownz);
+	ndelay(5);
+	dw_writel(csi2, 0x1, dphy_rstz);
+
+	dw_readl(csi2, dphy_rstz);
+	ndelay(5);
+}
+
 static int csi2_start(struct dw_mipi_csi2_dev *csi2, int bpp)
 {
 	unsigned int lanes;
@@ -460,6 +499,9 @@ static int csi2_start(struct dw_mipi_csi2_dev *csi2, int bpp)
 	if (ret)
 		goto err_phy_prep;
 
+	if (csi2->config->need_dphy_reset)
+		dw_csi2_dphy_reset(csi2);
+
 	/* setup the gasket */
 	if (csi2->config && csi2->config->gasket_init)
 		csi2->config->gasket_init(csi2);
@@ -482,6 +524,9 @@ static int csi2_start(struct dw_mipi_csi2_dev *csi2, int bpp)
 	if (ret)
 		goto err_phy_power_on;
 
+	if (csi2->config->need_dphy_reset)
+		dw_csi2_dphy_release_reset(csi2);
+
 	csi2_enable(csi2, true);
 
 	/* Step 5 */
diff --git a/include/media/dw-mipi-csi2.h b/include/media/dw-mipi-csi2.h
index 20ce6a21f0674cad54f01edb508dce14cd07a8dd..d1afd8c6d95457c28d7e1de6935908437372572d 100644
--- a/include/media/dw-mipi-csi2.h
+++ b/include/media/dw-mipi-csi2.h
@@ -28,6 +28,7 @@ struct dw_mipi_csi2_config {
 	u32	sink_pad_mask;
 	bool	has_phy: 1;
 	bool	has_irq: 1;
+	bool	need_dphy_reset: 1;
 };
 
 struct dw_mipi_tstif {

-- 
2.34.1



From Frank.Li at nxp.com  Fri Aug  8 15:39:29 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:29 -0400
Subject: [PATCH v2 26/32] media: synopsys: csi2: Add default simple
 dw_csi2_subdev_init_state
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <20250808-95_cam-v2-26-4b29fa6919a7@nxp.com>

Add default simple dw_csi2_subdev_init_state, which have 1 sink and 1
source pad, 1920x1080p and MEDIA_BUS_FMT_UYVY8_1X16 format.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/media/platform/synopsys/mipi-csi2.c | 57 ++++++++++++++++++++++++++++-
 1 file changed, 56 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/synopsys/mipi-csi2.c b/drivers/media/platform/synopsys/mipi-csi2.c
index d1f08c8384ad45d47ffe81b6dc5f225aed43e21a..7a3776df3e074aa823ae89c824bb942475c95045 100644
--- a/drivers/media/platform/synopsys/mipi-csi2.c
+++ b/drivers/media/platform/synopsys/mipi-csi2.c
@@ -831,6 +831,59 @@ static const struct v4l2_async_notifier_operations csi2_notify_ops = {
 	.unbind = csi2_notify_unbind,
 };
 
+static const struct v4l2_mbus_framefmt dwc_csi_default_fmt = {
+	.code = MEDIA_BUS_FMT_UYVY8_1X16,
+	.width = 1920,
+	.height = 1080,
+	.field = V4L2_FIELD_NONE,
+	.colorspace = V4L2_COLORSPACE_SMPTE170M,
+	.xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(V4L2_COLORSPACE_SMPTE170M),
+	.ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(V4L2_COLORSPACE_SMPTE170M),
+	.quantization = V4L2_QUANTIZATION_LIM_RANGE,
+};
+
+static int dw_csi2_subdev_set_routing(struct v4l2_subdev *sd,
+				      struct v4l2_subdev_state *state,
+				      struct v4l2_subdev_krouting *routing)
+{
+	int ret;
+
+	if (routing->num_routes > V4L2_FRAME_DESC_ENTRY_MAX)
+		return -EINVAL;
+
+	ret = v4l2_subdev_routing_validate(sd, routing,
+					   V4L2_SUBDEV_ROUTING_ONLY_1_TO_1);
+	if (ret)
+		return ret;
+
+	return v4l2_subdev_set_routing_with_fmt(sd, state, routing, &dwc_csi_default_fmt);
+}
+
+static int dw_csi2_subdev_init_state_simple(struct v4l2_subdev *sd,
+					    struct v4l2_subdev_state *sd_state)
+{
+	struct v4l2_subdev_route routes[] = {
+		{
+			.sink_pad = 0,
+			.sink_stream = 0,
+			.source_pad = 1,
+			.source_stream = 0,
+			.flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,
+		},
+	};
+
+	struct v4l2_subdev_krouting routing = {
+		.num_routes = ARRAY_SIZE(routes),
+		.routes = routes,
+	};
+
+	return dw_csi2_subdev_set_routing(sd, sd_state, &routing);
+}
+
+static const struct v4l2_subdev_internal_ops dw_csi2_simple_internal_ops = {
+	.init_state = dw_csi2_subdev_init_state_simple,
+};
+
 static int csi2_async_register(struct dw_mipi_csi2_dev *csi2)
 {
 	struct v4l2_fwnode_endpoint vep = {
@@ -954,7 +1007,9 @@ int dw_mipi_csi2_init(struct platform_device *pdev, struct dw_mipi_csi2_dev *csi
 
 	csi2->sd.owner = config->module;
 	strscpy(csi2->sd.name, config->name, sizeof(csi2->sd.name));
-	csi2->sd.internal_ops = config->internal_ops;
+	csi2->sd.internal_ops = config->internal_ops ?
+					config->internal_ops :
+					&dw_csi2_simple_internal_ops;
 	csi2->sd.grp_id = config->grp_id;
 	csi2->config = config;
 

-- 
2.34.1



From Frank.Li at nxp.com  Fri Aug  8 15:39:30 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:30 -0400
Subject: [PATCH v2 27/32] media: synopsys: csi2: Add v150 lane stop state
 register bit define
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <20250808-95_cam-v2-27-4b29fa6919a7@nxp.com>

v150 move lane stop state into new register phy_stopstate and field
position also changed.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/media/platform/synopsys/mipi-csi2.c | 40 +++++++++++++++++++++++++++--
 1 file changed, 38 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/synopsys/mipi-csi2.c b/drivers/media/platform/synopsys/mipi-csi2.c
index 7a3776df3e074aa823ae89c824bb942475c95045..a9bf7ce57adc4d2b071f2f7c39f19855dc226a40 100644
--- a/drivers/media/platform/synopsys/mipi-csi2.c
+++ b/drivers/media/platform/synopsys/mipi-csi2.c
@@ -31,6 +31,7 @@ struct dw_csi2_regs {
 	u32	dphy_rstz;
 	u32	resetn;
 	u32	phy_state;
+	u32	phy_stopstate;
 	u32	data_ids_1;
 	u32	data_ids_2;
 	u32	err1;
@@ -86,6 +87,7 @@ static const struct dw_csi2_regs dw_csi2_v150 = {
 	.phy_shutdownz = DW_REG(0x40),
 	.dphy_rstz = DW_REG(0x44),
 	.phy_state = DW_REG(0x48),
+	.phy_stopstate = DW_REG(0x4c),
 	.phy_tst_ctrl0 = DW_REG(0x50),
 	.phy_tst_ctrl1 = DW_REG(0x54),
 	.int_st_dphy_fatal = DW_REG(0xe0),
@@ -147,10 +149,13 @@ readl((csi2)->base + ((csi2)->regs->__name & ~DW_REG_EXIST)) : \
 dw_csi2_reg_err(csi2, #__name))
 
 #define PHY_STATE_STOPSTATEDATA_BIT	4
+#define PHY_STATE_STOPSTATEDATA_BIT_V150	0
 #define PHY_STATE_STOPSTATEDATA(n)	BIT(PHY_STATE_STOPSTATEDATA_BIT + (n))
 #define PHY_STATE_RXCLKACTIVEHS	BIT(8)
+#define PHY_STATE_RXCLKACTIVEHS_V150	BIT(17)
 #define PHY_STATE_RXULPSCLKNOT	BIT(9)
 #define PHY_STATE_STOPSTATECLK	BIT(10)
+#define PHY_STATE_STOPSTATECLK_V150		BIT(16)
 
 #define DPHY_TEST_CTRL0_TEST_CLR		BIT(0)
 #define DPHY_TEST_CTRL0_TEST_CLKEN	BIT(1)
@@ -289,7 +294,8 @@ static int __maybe_unused csi2_dphy_wait_ulp(struct dw_mipi_csi2_dev *csi2)
 }
 
 /* Waits for low-power LP-11 state on data and clock lanes. */
-static void csi2_dphy_wait_stopstate(struct dw_mipi_csi2_dev *csi2, unsigned int lanes)
+static void csi2_dphy_wait_stopstate_v0(struct dw_mipi_csi2_dev *csi2,
+					unsigned int lanes)
 {
 	u32 mask, reg;
 	int ret;
@@ -303,13 +309,43 @@ static void csi2_dphy_wait_stopstate(struct dw_mipi_csi2_dev *csi2, unsigned int
 	}
 }
 
+static void csi2_dphy_wait_stopstate_v150(struct dw_mipi_csi2_dev *csi2,
+					  unsigned int lanes)
+{
+	u32 mask, reg;
+	int ret;
+
+	mask = PHY_STATE_STOPSTATECLK_V150 | (((1 << lanes) - 1) <<
+	       PHY_STATE_STOPSTATEDATA_BIT_V150);
+
+	ret = read_poll_timeout(dw_readl, reg, (reg & mask) == mask, 0, 500000,
+				0, csi2, phy_stopstate);
+	if (ret) {
+		v4l2_warn(&csi2->sd, "LP-11 wait timeout, likely a sensor driver bug, expect capture failures.\n");
+		v4l2_warn(&csi2->sd, "phy_state = 0x%08x\n", reg);
+	}
+}
+
+static void csi2_dphy_wait_stopstate(struct dw_mipi_csi2_dev *csi2,
+				     unsigned int lanes)
+{
+	if (csi2->regs == &dw_csi2_v0)
+		return csi2_dphy_wait_stopstate_v0(csi2, lanes);
+
+	csi2_dphy_wait_stopstate_v150(csi2, lanes);
+}
+
 /* Wait for active clock on the clock lane. */
 static int csi2_dphy_wait_clock_lane(struct dw_mipi_csi2_dev *csi2)
 {
+	u32 mask;
 	u32 reg;
 	int ret;
 
-	ret = read_poll_timeout(dw_readl, reg, (reg & PHY_STATE_RXCLKACTIVEHS),
+	mask = csi2->regs == &dw_csi2_v0 ?  PHY_STATE_RXCLKACTIVEHS :
+					    PHY_STATE_RXCLKACTIVEHS_V150;
+
+	ret = read_poll_timeout(dw_readl, reg, (reg & mask),
 				0, 500000, 0, csi2, phy_state);
 	if (ret) {
 		v4l2_err(&csi2->sd, "clock lane timeout, phy_state = 0x%08x\n",

-- 
2.34.1



From Frank.Li at nxp.com  Fri Aug  8 15:39:31 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:31 -0400
Subject: [PATCH v2 28/32] media: synopsys: csi2: use standard
 v4l2_subdev_get_fmt() function
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <20250808-95_cam-v2-28-4b29fa6919a7@nxp.com>

Use standard v4l2_subdev_get_fmt() to simple code and add missed call
v4l2_subdev_init_finalize().

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/media/platform/synopsys/mipi-csi2.c | 49 ++++++++++-------------------
 1 file changed, 16 insertions(+), 33 deletions(-)

diff --git a/drivers/media/platform/synopsys/mipi-csi2.c b/drivers/media/platform/synopsys/mipi-csi2.c
index a9bf7ce57adc4d2b071f2f7c39f19855dc226a40..f174dfded167fbd52a72894c3f63871812ca799b 100644
--- a/drivers/media/platform/synopsys/mipi-csi2.c
+++ b/drivers/media/platform/synopsys/mipi-csi2.c
@@ -714,38 +714,13 @@ static int csi2_link_setup(struct media_entity *entity,
 	return ret;
 }
 
-static struct v4l2_mbus_framefmt *
-__csi2_get_fmt(struct dw_mipi_csi2_dev *csi2, struct v4l2_subdev_state *sd_state,
-	       unsigned int pad, enum v4l2_subdev_format_whence which)
-{
-	if (which == V4L2_SUBDEV_FORMAT_TRY)
-		return v4l2_subdev_state_get_format(sd_state, pad);
-	else
-		return &csi2->format_mbus;
-}
-
-static int csi2_get_fmt(struct v4l2_subdev *sd,
-			struct v4l2_subdev_state *sd_state,
-			struct v4l2_subdev_format *sdformat)
-{
-	struct dw_mipi_csi2_dev *csi2 = sd_to_dev(sd);
-	struct v4l2_mbus_framefmt *fmt;
-
-	guard(mutex)(&csi2->lock);
-
-	fmt = __csi2_get_fmt(csi2, sd_state, sdformat->pad, sdformat->which);
-
-	sdformat->format = *fmt;
-
-	return 0;
-}
-
 static int csi2_set_fmt(struct v4l2_subdev *sd,
 			struct v4l2_subdev_state *sd_state,
 			struct v4l2_subdev_format *sdformat)
 {
 	struct dw_mipi_csi2_dev *csi2 = sd_to_dev(sd);
 	struct v4l2_mbus_framefmt *fmt;
+	int i;
 	u32 align;
 	u32 bpp;
 
@@ -756,7 +731,7 @@ static int csi2_set_fmt(struct v4l2_subdev *sd,
 	 * The CSIS can't transcode in any way, the source format can't be
 	 * modified.
 	 */
-	if (sdformat->pad < csi2->num_src_pads)
+	if (csi2->pad[sdformat->pad].flags == MEDIA_PAD_FL_SOURCE)
 		return v4l2_subdev_get_fmt(sd, sd_state, sdformat);
 
 	guard(mutex)(&csi2->lock);
@@ -771,13 +746,17 @@ static int csi2_set_fmt(struct v4l2_subdev *sd,
 	v4l_bound_align_image(&sdformat->format.width, 1, U16_MAX, align,
 			      &sdformat->format.height, 1, U16_MAX, 0, 0);
 
-	/* Output pads mirror active input pad, no limits on input pads */
-	if (!(csi2->config->sink_pad_mask & BIT(sdformat->pad)))
-		sdformat->format = csi2->format_mbus;
+	fmt = v4l2_subdev_state_get_format(sd_state, sdformat->pad);
+	*fmt = sdformat->format;
 
-	fmt = __csi2_get_fmt(csi2, sd_state, sdformat->pad, sdformat->which);
+	/* Output pads mirror active input pad, no limits on input pads */
+	for (i = 0; i < csi2->config->num_pads; i++)
+		if (csi2->pad[i].flags == MEDIA_PAD_FL_SOURCE) {
+			fmt = v4l2_subdev_state_get_format(sd_state, i);
+			*fmt = sdformat->format;
+		}
 
-	*fmt = sdformat->format;
+	csi2->format_mbus = *fmt;
 
 	return 0;
 }
@@ -818,7 +797,7 @@ static const struct media_entity_operations csi2_entity_ops = {
 };
 
 static const struct v4l2_subdev_pad_ops csi2_pad_ops = {
-	.get_fmt = csi2_get_fmt,
+	.get_fmt = v4l2_subdev_get_fmt,
 	.set_fmt = csi2_set_fmt,
 	.enable_streams = dw_csi2_enable_streams,
 	.disable_streams = dw_csi2_disable_streams,
@@ -1071,6 +1050,10 @@ int dw_mipi_csi2_init(struct platform_device *pdev, struct dw_mipi_csi2_dev *csi
 	if (ret)
 		return ret;
 
+	ret = v4l2_subdev_init_finalize(&csi2->sd);
+	if (ret)
+		return ret;
+
 	ret = devm_add_action_or_reset(&pdev->dev, csi2_nf_cleanup, csi2);
 	if (ret)
 		return ret;

-- 
2.34.1



From Frank.Li at nxp.com  Fri Aug  8 15:39:32 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:32 -0400
Subject: [PATCH v2 29/32] media: synopsys: csi2: Add customize
 get_frame_desc() callback
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <20250808-95_cam-v2-29-4b29fa6919a7@nxp.com>

Add customize get_frame_desc() callback to work with existed isi drivers.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/media/platform/synopsys/mipi-csi2.c | 73 +++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)

diff --git a/drivers/media/platform/synopsys/mipi-csi2.c b/drivers/media/platform/synopsys/mipi-csi2.c
index f174dfded167fbd52a72894c3f63871812ca799b..8051cfcd8ee158c5efccae9aff124c01a878e916 100644
--- a/drivers/media/platform/synopsys/mipi-csi2.c
+++ b/drivers/media/platform/synopsys/mipi-csi2.c
@@ -761,6 +761,78 @@ static int csi2_set_fmt(struct v4l2_subdev *sd,
 	return 0;
 }
 
+static int dw_csi2_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
+				  struct v4l2_mbus_frame_desc *fd)
+{
+	struct dw_mipi_csi2_dev *csi2 = sd_to_dev(sd);
+	struct v4l2_mbus_frame_desc source_fd;
+	struct v4l2_subdev_route *route;
+	struct v4l2_subdev_state *state;
+	int data_type;
+	int ret;
+
+	if (!(csi2->pad[pad].flags & MEDIA_PAD_FL_SOURCE))
+		return -EINVAL;
+
+	memset(fd, 0, sizeof(*fd));
+
+	data_type = media_bus_fmt_to_csi2_dt(csi2->format_mbus.code);
+
+	ret = v4l2_subdev_call(csi2->src_sd, pad, get_frame_desc,
+			       csi2->remote_pad, &source_fd);
+	if (ret < 0) {
+		dev_info(csi2->dev,
+			 "Remote sub-device on pad %d should implement .get_frame_desc! Forcing VC = 0 and DT = %x\n",
+			 pad, data_type);
+		fd->type = V4L2_MBUS_FRAME_DESC_TYPE_CSI2;
+		fd->num_entries = 1;
+		fd->entry[0].pixelcode = csi2->format_mbus.code;
+		fd->entry[0].bus.csi2.vc = 0;
+		fd->entry[0].bus.csi2.dt = data_type;
+
+		return 0;
+	}
+
+	fd->type = V4L2_MBUS_FRAME_DESC_TYPE_CSI2;
+
+	state = v4l2_subdev_lock_and_get_active_state(sd);
+
+	for_each_active_route(&state->routing, route) {
+		struct v4l2_mbus_frame_desc_entry *entry = NULL;
+		unsigned int i;
+
+		if (route->source_pad != pad)
+			continue;
+
+		for (i = 0; i < source_fd.num_entries; ++i) {
+			if (source_fd.entry[i].stream == route->sink_stream) {
+				entry = &source_fd.entry[i];
+				break;
+			}
+		}
+
+		if (!entry) {
+			dev_err(csi2->dev,
+				"Failed to find stream from source frames desc\n");
+			ret = -EPIPE;
+			goto out_unlock;
+		}
+
+		fd->entry[fd->num_entries].stream = route->source_stream;
+		fd->entry[fd->num_entries].flags = entry->flags;
+		fd->entry[fd->num_entries].length = entry->length;
+		fd->entry[fd->num_entries].pixelcode = entry->pixelcode;
+		fd->entry[fd->num_entries].bus.csi2.vc = entry->bus.csi2.vc;
+		fd->entry[fd->num_entries].bus.csi2.dt = entry->bus.csi2.dt;
+
+		fd->num_entries++;
+	}
+
+out_unlock:
+	v4l2_subdev_unlock_state(state);
+	return ret;
+}
+
 /* --------------- CORE OPS --------------- */
 
 static int csi2_log_status(struct v4l2_subdev *sd)
@@ -799,6 +871,7 @@ static const struct media_entity_operations csi2_entity_ops = {
 static const struct v4l2_subdev_pad_ops csi2_pad_ops = {
 	.get_fmt = v4l2_subdev_get_fmt,
 	.set_fmt = csi2_set_fmt,
+	.get_frame_desc = dw_csi2_get_frame_desc,
 	.enable_streams = dw_csi2_enable_streams,
 	.disable_streams = dw_csi2_disable_streams,
 };

-- 
2.34.1



From Frank.Li at nxp.com  Fri Aug  8 15:39:33 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:33 -0400
Subject: [PATCH v2 30/32] media: synopsys: csi2: Add Image Pixel Interface
 (IPI) support for v150
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <20250808-95_cam-v2-30-4b29fa6919a7@nxp.com>

Add Image Pixel Interface (IPI) support for v150. Check the ipi_mode
register to determine whether the hardware supports IPI.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/media/platform/synopsys/mipi-csi2.c | 82 +++++++++++++++++++++++++++++
 1 file changed, 82 insertions(+)

diff --git a/drivers/media/platform/synopsys/mipi-csi2.c b/drivers/media/platform/synopsys/mipi-csi2.c
index 8051cfcd8ee158c5efccae9aff124c01a878e916..48ae455a77b2365b6df8a79a366b37c7f1dfe590 100644
--- a/drivers/media/platform/synopsys/mipi-csi2.c
+++ b/drivers/media/platform/synopsys/mipi-csi2.c
@@ -40,6 +40,11 @@ struct dw_csi2_regs {
 	u32	msk2;
 	u32	phy_tst_ctrl0;
 	u32	phy_tst_ctrl1;
+	u32	ipi_softrstn;
+	u32	ipi_datatype;
+	u32	ipi_vcid;
+	u32	ipi_mode;
+	u32	ipi_mem_flush;
 	u32	int_st_main;
 	u32	int_st_dphy_fatal;
 	u32	int_msk_dphy_fatal;
@@ -90,6 +95,11 @@ static const struct dw_csi2_regs dw_csi2_v150 = {
 	.phy_stopstate = DW_REG(0x4c),
 	.phy_tst_ctrl0 = DW_REG(0x50),
 	.phy_tst_ctrl1 = DW_REG(0x54),
+	.ipi_mode = DW_REG(0x80),
+	.ipi_vcid = DW_REG(0x84),
+	.ipi_datatype = DW_REG(0x88),
+	.ipi_mem_flush = DW_REG(0x8c),
+	.ipi_softrstn = DW_REG(0xa0),
 	.int_st_dphy_fatal = DW_REG(0xe0),
 	.int_msk_dphy_fatal = DW_REG(0xe4),
 	.int_force_dphy_fatal = DW_REG(0xe8),
@@ -115,6 +125,31 @@ static const struct dw_csi2_regs dw_csi2_v150 = {
 #define INT_ST_MAIN_ERR_PHY			BIT(16)
 #define INT_ST_MAIN_FATAL_ERR_IPI		BIT(18)
 
+#define IPI_VCID_VC(x)				FIELD_PREP(GENMASK(1, 0), (x))
+#define IPI_VCID_VC_0_1(x)			FIELD_PREP(GENMASK(3, 2), (x))
+#define IPI_VCID_VC_2				BIT(4)
+
+#define IPI_DATA_TYPE_DT(x)			FIELD_PREP(GENMASK(5, 0), (x))
+#define IPI_DATA_TYPE_EMB_DATA_EN		BIT(8)
+
+#define IPI_MODE_CONTROLLER			BIT(1)
+#define IPI_MODE_COLOR_MODE16			BIT(8)
+#define IPI_MODE_CUT_THROUGH			BIT(16)
+#define IPI_MODE_ENABLE				BIT(24)
+
+#define IPI_MEM_FLUSH_AUTO			BIT(8)
+
+#define INT_ST_MAIN_FATAL_ERR_PHY		BIT(0)
+#define INT_ST_MAIN_FATAL_ERR_PKT		BIT(1)
+#define INT_ST_MAIN_FATAL_ERR_BNDRY_FRAMEL	BIT(2)
+#define INT_ST_MAIN_FATAL_ERR_SEQ_FRAME		BIT(3)
+#define INT_ST_MAIN_FATAL_ERR_CRC_FRAME		BIT(4)
+#define INT_ST_MAIN_FATAL_ERR_PLD_CRC		BIT(5)
+#define INT_ST_MAIN_ERR_DID			BIT(6)
+#define INT_ST_MAIN_ERR_ECC			BIT(7)
+#define INT_ST_MAIN_ERR_PHY			BIT(16)
+#define INT_ST_MAIN_FATAL_ERR_IPI		BIT(18)
+
 #define INT_MSK_DPHY_FATAL_ERR_SOT_LANE0	BIT(0)
 #define INT_MSK_DPHY_FATAL_ERR_SOT_LANE1	BIT(1)
 
@@ -449,6 +484,48 @@ static int dw_mipi_csi2_phy_prep(struct dw_mipi_csi2_dev *csi2, int bpp)
 	return ret;
 }
 
+static void dw_csi2_device_ipi_config(struct dw_mipi_csi2_dev *csi2)
+{
+	int dt = media_bus_fmt_to_csi2_dt(csi2->format_mbus.code);
+	u32 val;
+
+	/* Do IPI soft reset */
+	dw_writel(csi2, 0x0, ipi_softrstn);
+	dw_writel(csi2, 0x1, ipi_softrstn);
+
+	/* Select virtual channel and data type to be processed by IPI */
+	val = IPI_DATA_TYPE_DT(dt);
+	dw_writel(csi2, val, ipi_datatype);
+
+	/* Set virtual channel 0 as default */
+	val  = IPI_VCID_VC(0);
+	dw_writel(csi2, val, ipi_vcid);
+
+	/*
+	 * Select IPI camera timing mode and allow the pixel stream
+	 * to be non-continuous when pixel interface FIFO is empty
+	 */
+	val = dw_readl(csi2, ipi_mode);
+	val &= ~IPI_MODE_CONTROLLER;
+	val &= ~IPI_MODE_COLOR_MODE16;
+	val |= IPI_MODE_CUT_THROUGH;
+	dw_writel(csi2, val, ipi_mode);
+}
+
+static void dw_csi2_ipi_enable(struct dw_mipi_csi2_dev *csi2)
+{
+	u32 val;
+
+	/* Memory is automatically flushed at each Frame Start */
+	val = IPI_MEM_FLUSH_AUTO;
+	dw_writel(csi2, val, ipi_mem_flush);
+
+	/* Enable IPI */
+	val = dw_readl(csi2, ipi_mode);
+	val |= IPI_MODE_ENABLE;
+	dw_writel(csi2, val, ipi_mode);
+}
+
 static void dw_csi2_enable_irq(struct dw_mipi_csi2_dev *csi2)
 {
 	u32 val;
@@ -583,6 +660,11 @@ static int csi2_start(struct dw_mipi_csi2_dev *csi2, int bpp)
 	if (ret)
 		goto err_stop_upstream;
 
+	if (csi2->regs->ipi_mode) {
+		dw_csi2_device_ipi_config(csi2);
+		dw_csi2_ipi_enable(csi2);
+	}
+
 	dw_csi2_enable_irq(csi2);
 
 	return 0;

-- 
2.34.1



From Frank.Li at nxp.com  Fri Aug  8 15:39:34 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:34 -0400
Subject: [PATCH v2 31/32] media: synopsys: csi2: Remove source pad
 connected check at dw_csi2_enable_streams()
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <20250808-95_cam-v2-31-4b29fa6919a7@nxp.com>

link_setup() callback is not called if remote linked subdev use flag
MEDIA_LNK_FL_ENABLED.

Driver needn't track if source pad is connected since framework already do
that. So remove these check and related variable.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/media/platform/synopsys/mipi-csi2.c | 21 +++------------------
 include/media/dw-mipi-csi2.h                |  1 -
 2 files changed, 3 insertions(+), 19 deletions(-)

diff --git a/drivers/media/platform/synopsys/mipi-csi2.c b/drivers/media/platform/synopsys/mipi-csi2.c
index 48ae455a77b2365b6df8a79a366b37c7f1dfe590..01c590a953f3f89ebb56bc42e820b09a8afbf5b9 100644
--- a/drivers/media/platform/synopsys/mipi-csi2.c
+++ b/drivers/media/platform/synopsys/mipi-csi2.c
@@ -710,18 +710,12 @@ static int dw_csi2_enable_streams(struct v4l2_subdev *sd,
 				  u64 streams_mask)
 {
 	struct dw_mipi_csi2_dev *csi2 = sd_to_dev(sd);
-	int i, ret = 0;
+	int ret = 0;
 
 	guard(mutex)(&csi2->lock);
 
-	if (!csi2->src_sd)
-		return -EPIPE;
 
-	for (i = 0; i < csi2->num_sink_pads; i++) {
-		if (csi2->sink_linked[i])
-			break;
-	}
-	if (i >= csi2->num_sink_pads)
+	if (!csi2->src_sd)
 		return -EPIPE;
 
 	if (csi2->stream_count)
@@ -773,16 +767,7 @@ static int csi2_link_setup(struct media_entity *entity,
 
 	guard(mutex)(&csi2->lock);
 
-	if (local->flags & MEDIA_PAD_FL_SOURCE) {
-		if (flags & MEDIA_LNK_FL_ENABLED) {
-			if (csi2->sink_linked[local->index - 1])
-				return -EBUSY;
-
-			csi2->sink_linked[local->index - 1] = true;
-		} else {
-			csi2->sink_linked[local->index - 1] = false;
-		}
-	} else {
+	if (local->flags & MEDIA_PAD_FL_SINK) {
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (csi2->src_sd)
 				return -EBUSY;
diff --git a/include/media/dw-mipi-csi2.h b/include/media/dw-mipi-csi2.h
index d1afd8c6d95457c28d7e1de6935908437372572d..977a9e27cc50ad6ecfb47ebf8d42f115bc51c1ae 100644
--- a/include/media/dw-mipi-csi2.h
+++ b/include/media/dw-mipi-csi2.h
@@ -75,7 +75,6 @@ struct dw_mipi_csi2_dev {
 
 	int				stream_count;
 	struct v4l2_subdev		*src_sd;
-	bool				sink_linked[DW_MAX_PAD_NUM];
 	const struct dw_mipi_csi2_config *config;
 
 	struct dw_csi2_event		*event;

-- 
2.34.1



From Frank.Li at nxp.com  Fri Aug  8 15:39:35 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Fri, 08 Aug 2025 18:39:35 -0400
Subject: [PATCH v2 32/32] media: synopsys: csi2: Add simple synopsys
 platform driver
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <20250808-95_cam-v2-32-4b29fa6919a7@nxp.com>

Add simple synosys platform driver, which use standard PHY interface and
only 1 sink and 1 source pad. No format convert between source and sink
pad.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/media/platform/synopsys/Kconfig            |  8 +++
 drivers/media/platform/synopsys/Makefile           |  1 +
 drivers/media/platform/synopsys/mipi-csi2-simple.c | 75 ++++++++++++++++++++++
 3 files changed, 84 insertions(+)

diff --git a/drivers/media/platform/synopsys/Kconfig b/drivers/media/platform/synopsys/Kconfig
index e54dad835349d420dead6d5313c0623567c28c0b..642b7dcd8dfb1bafa3b6dbdba1a1d99559d3c01a 100644
--- a/drivers/media/platform/synopsys/Kconfig
+++ b/drivers/media/platform/synopsys/Kconfig
@@ -12,4 +12,12 @@ config VIDEO_SYNOPSYS_MIPI_CSI2
           To compile this driver as a module, choose M here. The module
           will be called synopsys_hdmirx
 
+config VIDEO_SYNOPSYS_MIPI_CSI2_SIMPLE
+	tristate "Simple Synopsys DesignWare HDMI Receiver platform driver"
+	depends on VIDEO_SYNOPSYS_MIPI_CSI2
+	help
+	  Simple platform Synopsys MIPI CSI2 platform driver, which not format
+	  convert between sink and source pad. Only 1 source pad and 1 sink
+	  pad, use standard PHY interface to initialize DPHY.
+
 source "drivers/media/platform/synopsys/hdmirx/Kconfig"
diff --git a/drivers/media/platform/synopsys/Makefile b/drivers/media/platform/synopsys/Makefile
index 045ed3177738e6d28aa223804b79e6774e141dc8..cac610c8e08abeebdbf14157d8edcdc5a635dd00 100644
--- a/drivers/media/platform/synopsys/Makefile
+++ b/drivers/media/platform/synopsys/Makefile
@@ -2,3 +2,4 @@
 obj-y += hdmirx/
 
 obj-$(CONFIG_VIDEO_SYNOPSYS_MIPI_CSI2) += mipi-csi2.o
+obj-$(CONFIG_VIDEO_SYNOPSYS_MIPI_CSI2_SIMPLE) += mipi-csi2-simple.o
diff --git a/drivers/media/platform/synopsys/mipi-csi2-simple.c b/drivers/media/platform/synopsys/mipi-csi2-simple.c
new file mode 100644
index 0000000000000000000000000000000000000000..bf34a515b41290339db06d74d7135c575a8bf031
--- /dev/null
+++ b/drivers/media/platform/synopsys/mipi-csi2-simple.c
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Synosis MIPI CSI-2 Simple platform driver
+ *
+ * Copyright (c) 2025 NXP.
+ */
+#include <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+
+#include <media/dw-mipi-csi2.h>
+
+struct simple_csi2 {
+	struct dw_mipi_csi2_dev dw;
+};
+
+static const struct dw_mipi_csi2_config simple_config = {
+	.module = THIS_MODULE,
+	.name = "dw-mipi-csi2",
+	.num_pads = 2,
+	.sink_pad_mask = BIT(0),
+	.has_irq = true,
+	.has_phy = true,
+	.need_dphy_reset = true,
+};
+
+static DEFINE_RUNTIME_DEV_PM_OPS(csi2_pm_ops, dw_mipi_csi2_runtime_suspend,
+				 dw_mipi_csi2_runtime_resume, NULL);
+
+static int csi2_probe(struct platform_device *pdev)
+{
+	struct simple_csi2 *csi2;
+
+	csi2 = devm_kzalloc(&pdev->dev, sizeof(*csi2), GFP_KERNEL);
+	if (!csi2)
+		return -ENOMEM;
+
+	return dw_mipi_csi2_init(pdev, &csi2->dw, &simple_config);
+}
+
+static void csi2_remove(struct platform_device *pdev)
+{
+	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
+	struct dw_mipi_csi2_dev *csi2 = sd_to_dw_mipi_csi2_dev(sd);
+
+	dw_mipi_csi2_deinit(csi2);
+}
+
+static const struct of_device_id csi2_dt_ids[] = {
+	{ .compatible = "snps,dw-mipi-csi2-v150" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, csi2_dt_ids);
+
+static struct platform_driver csi2_driver = {
+	.driver = {
+		.name = "dw-mipi-csi2",
+		.of_match_table = csi2_dt_ids,
+		.pm = pm_ptr(&csi2_pm_ops),
+	},
+	.probe = csi2_probe,
+	.remove = csi2_remove,
+};
+
+module_platform_driver(csi2_driver);
+
+MODULE_DESCRIPTION("Simple Synosis MIPI CSI-2 Receiver platform driver");
+MODULE_AUTHOR("Frank Li <Frank.li at nxp.com>");
+MODULE_LICENSE("GPL");

-- 
2.34.1



From dmitry.baryshkov at oss.qualcomm.com  Sat Aug  9 00:30:09 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Sat, 9 Aug 2025 10:30:09 +0300
Subject: [PATCH V1 4/4] phy: qcom-qmp-ufs: read max-microamp values from
 device tree
In-Reply-To: <20250806154340.20122-5-quic_nitirawa@quicinc.com>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
 <20250806154340.20122-5-quic_nitirawa@quicinc.com>
Message-ID: <5nsglhsnqdx4l44r36zmxumcpbbwhns4432hm3lvttsgyjaknb@feobdhpzzo65>

On Wed, Aug 06, 2025 at 09:13:40PM +0530, Nitin Rawat wrote:
> Add support in QMP PHY driver to read optional vdda-phy-max-microamp
> and vdda-pll-max-microamp properties from the device tree.
> 
> These properties define the expected maximum current (in microamps) for
> each supply. The driver uses this information to configure regulators
> more accurately and ensure they operate in the correct mode based on
> client load requirements.

What defines those load values? Are they actually dependent on the
platform? On the SoC? On the board design? On the UFS gear?

> 
> If the property is not present, the driver defaults load to
> `QMP_VREG_UNUSED`.
> 
> Signed-off-by: Nitin Rawat <quic_nitirawa at quicinc.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 22 +++++++++++++++++++---
>  1 file changed, 19 insertions(+), 3 deletions(-)
> 

-- 
With best wishes
Dmitry


From dmitry.baryshkov at oss.qualcomm.com  Sat Aug  9 00:57:41 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Sat, 9 Aug 2025 10:57:41 +0300
Subject: [PATCH v4 4/6] phy: qcom: qmp-combo: introduce QMPPHY_MODE
In-Reply-To: <20250807-topic-4ln_dp_respin-v4-4-43272d6eca92@oss.qualcomm.com>
References: <20250807-topic-4ln_dp_respin-v4-0-43272d6eca92@oss.qualcomm.com>
 <20250807-topic-4ln_dp_respin-v4-4-43272d6eca92@oss.qualcomm.com>
Message-ID: <pcmy74pebeskhfactygabzjinpbcfhluhdx7rlbx7kds5wynf7@hdlkfpkg4va7>

On Thu, Aug 07, 2025 at 06:33:22PM +0200, Konrad Dybcio wrote:
> From: Neil Armstrong <neil.armstrong at linaro.org>
> 
> Introduce an enum for the QMP Combo PHY modes, use it in the
> QMP commmon phy init function and default to COMBO mode.
> 
> Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
> [konrad: some renaming and rewording]
> Signed-off-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 44 +++++++++++++++++++++++++++----
>  1 file changed, 39 insertions(+), 5 deletions(-)
> 

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>


-- 
With best wishes
Dmitry


From dmitry.baryshkov at oss.qualcomm.com  Sat Aug  9 01:13:13 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Sat, 9 Aug 2025 11:13:13 +0300
Subject: [PATCH v4 5/6] phy: qcom: qmp-combo: register a typec mux to
 change the QMPPHY_MODE
In-Reply-To: <20250807-topic-4ln_dp_respin-v4-5-43272d6eca92@oss.qualcomm.com>
References: <20250807-topic-4ln_dp_respin-v4-0-43272d6eca92@oss.qualcomm.com>
 <20250807-topic-4ln_dp_respin-v4-5-43272d6eca92@oss.qualcomm.com>
Message-ID: <ibrupwvn5frzb4vo3eukb7p7pzonaxwhygshz743wmyrbprkcq@xcpt4ryzvwqr>

On Thu, Aug 07, 2025 at 06:33:23PM +0200, Konrad Dybcio wrote:
> From: Neil Armstrong <neil.armstrong at linaro.org>
> 
> Register a typec mux in order to change the PHY mode on the Type-C
> mux events depending on the mode and the svid when in Altmode setup.
> 
> The DisplayPort phy should be left enabled if is still powered on
> by the DRM DisplayPort controller, so bail out until the DisplayPort
> PHY is not powered off.
> 
> The Type-C Mode/SVID only changes on plug/unplug, and USB SAFE states
> will be set in between of USB-Only, Combo and DisplayPort Only so
> this will leave enough time to the DRM DisplayPort controller to
> turn of the DisplayPort PHY.
> 
> Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
> [konrad: renaming, rewording, bug fixes]
> Signed-off-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 118 ++++++++++++++++++++++++++++--
>  1 file changed, 113 insertions(+), 5 deletions(-)
> 
> +
> +	if (qmp->qmpphy_mode != QMPPHY_MODE_USB3_ONLY && qmp->dp_powered_on) {
> +		dev_dbg(qmp->dev, "typec_mux_set: DP PHY is still in use, delaying switch\n");
> +		return 0;
> +	}

I can't say that I'm fully happy about it, nevertheless:

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>


-- 
With best wishes
Dmitry


From krishna.chundru at oss.qualcomm.com  Sat Aug  9 02:59:15 2025
From: krishna.chundru at oss.qualcomm.com (Krishna Chaitanya Chundru)
Date: Sat, 09 Aug 2025 15:29:15 +0530
Subject: [PATCH 0/4] arm64: dts: qcom: Add PCIe Support for sm8750
Message-ID: <20250809-pakala-v1-0-abf1c416dbaa@oss.qualcomm.com>

Describe PCIe controller and PHY. Also add required system resources like
regulators, clocks, interrupts and registers configuration for PCIe.

Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
---
Krishna Chaitanya Chundru (4):
      dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Document the SM8750 QMP PCIe PHY Gen3 x2
      phy: qcom-qmp-pcie: add dual lane PHY support for SM8750
      dt-bindings: PCI: qcom,pcie-sm8550: Add SM8750 compatible
      arm64: dts: qcom: sm8750: Add PCIe PHY and controller node

 .../devicetree/bindings/pci/qcom,pcie-sm8550.yaml  |   1 +
 .../bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml   |   2 +
 arch/arm64/boot/dts/qcom/sm8750.dtsi               | 174 ++++++++++++++++++++-
 drivers/phy/qualcomm/phy-qcom-qmp-pcie.c           | 149 ++++++++++++++++++
 drivers/phy/qualcomm/phy-qcom-qmp-pcs-v7.h         |   2 +
 .../phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v7.h    |   4 +-
 6 files changed, 330 insertions(+), 2 deletions(-)
---
base-commit: 37816488247ddddbc3de113c78c83572274b1e2e
change-id: 20250809-pakala-25a7c1ddba85

Best regards,
-- 
Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>



From krishna.chundru at oss.qualcomm.com  Sat Aug  9 02:59:16 2025
From: krishna.chundru at oss.qualcomm.com (Krishna Chaitanya Chundru)
Date: Sat, 09 Aug 2025 15:29:16 +0530
Subject: [PATCH 1/4] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Document
 the SM8750 QMP PCIe PHY Gen3 x2
In-Reply-To: <20250809-pakala-v1-0-abf1c416dbaa@oss.qualcomm.com>
References: <20250809-pakala-v1-0-abf1c416dbaa@oss.qualcomm.com>
Message-ID: <20250809-pakala-v1-1-abf1c416dbaa@oss.qualcomm.com>

Document the QMP PCIe PHY on the SM8750 platform.

Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
---
 Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml | 2 ++
 1 file changed, 2 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 a1ae8c7988c891a11f6872e58d25e9d04abb41ce..cb706cf8219d015cc21c1c7ea1cae49b4bf0319f 100644
--- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
@@ -42,6 +42,7 @@ properties:
       - qcom,sm8550-qmp-gen4x2-pcie-phy
       - qcom,sm8650-qmp-gen3x2-pcie-phy
       - qcom,sm8650-qmp-gen4x2-pcie-phy
+      - qcom,sm8750-qmp-gen3x2-pcie-phy
       - qcom,x1e80100-qmp-gen3x2-pcie-phy
       - qcom,x1e80100-qmp-gen4x2-pcie-phy
       - qcom,x1e80100-qmp-gen4x4-pcie-phy
@@ -164,6 +165,7 @@ allOf:
               - qcom,sm8550-qmp-gen4x2-pcie-phy
               - qcom,sm8650-qmp-gen3x2-pcie-phy
               - qcom,sm8650-qmp-gen4x2-pcie-phy
+              - qcom,sm8750-qmp-gen3x2-pcie-phy
     then:
       properties:
         clocks:

-- 
2.34.1



From krishna.chundru at oss.qualcomm.com  Sat Aug  9 02:59:17 2025
From: krishna.chundru at oss.qualcomm.com (Krishna Chaitanya Chundru)
Date: Sat, 09 Aug 2025 15:29:17 +0530
Subject: [PATCH 2/4] phy: qcom-qmp-pcie: add dual lane PHY support for
 SM8750
In-Reply-To: <20250809-pakala-v1-0-abf1c416dbaa@oss.qualcomm.com>
References: <20250809-pakala-v1-0-abf1c416dbaa@oss.qualcomm.com>
Message-ID: <20250809-pakala-v1-2-abf1c416dbaa@oss.qualcomm.com>

The PCIe Gen3 x2 PHY for SM8750 uses new phy, add the
required registers and offsets for this phy.

Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-pcie.c           | 149 +++++++++++++++++++++
 drivers/phy/qualcomm/phy-qcom-qmp-pcs-v7.h         |   2 +
 .../phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v7.h    |   4 +-
 3 files changed, 154 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index 95830dcfdec9b1f68fd55d1cc3c102985cfafcc1..8fdc146ef73221392371c00afb21d673dbf46d49 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -93,6 +93,13 @@ static const unsigned int pciephy_v6_regs_layout[QPHY_LAYOUT_SIZE] = {
 	[QPHY_PCS_POWER_DOWN_CONTROL]	= QPHY_V6_PCS_POWER_DOWN_CONTROL,
 };
 
+static const unsigned int pciephy_v7_regs_layout[QPHY_LAYOUT_SIZE] = {
+	[QPHY_SW_RESET]			= QPHY_V7_PCS_SW_RESET,
+	[QPHY_START_CTRL]		= QPHY_V7_PCS_START_CONTROL,
+	[QPHY_PCS_STATUS]		= QPHY_V7_PCS_PCS_STATUS1,
+	[QPHY_PCS_POWER_DOWN_CONTROL]	= QPHY_V7_PCS_POWER_DOWN_CONTROL,
+};
+
 static const struct qmp_phy_init_tbl msm8998_pcie_serdes_tbl[] = {
 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
@@ -2590,6 +2597,108 @@ static const struct qmp_phy_init_tbl sm8650_qmp_gen4x2_pcie_rx_tbl[] = {
 	QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B6, 0xff),
 };
 
+static const struct qmp_phy_init_tbl sm8750_qmp_gen3x2_pcie_serdes_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_SSC_EN_CENTER, 0x1),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_SSC_PER1, 0x62),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_SSC_PER2, 0x02),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_SSC_STEP_SIZE1_MODE0, 0xf8),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_SSC_STEP_SIZE2_MODE0, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_SSC_STEP_SIZE1_MODE1, 0x93),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_SSC_STEP_SIZE2_MODE1, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_CLK_ENABLE1, 0x90),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_SYS_CLK_CTRL, 0x82),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_PLL_IVCO, 0x07),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_CP_CTRL_MODE0, 0x02),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_CP_CTRL_MODE1, 0x02),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_PLL_RCTRL_MODE0, 0x16),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_PLL_RCTRL_MODE1, 0x16),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_PLL_CCTRL_MODE0, 0x36),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_PLL_CCTRL_MODE1, 0x36),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_SYSCLK_EN_SEL, 0x08),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_BG_TIMER, 0x0a),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_LOCK_CMP_EN, 0x42),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_LOCK_CMP1_MODE0, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_LOCK_CMP2_MODE0, 0x0d),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_LOCK_CMP1_MODE1, 0x0a),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_LOCK_CMP2_MODE1, 0x1a),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_DEC_START_MODE0, 0x41),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_DEC_START_MODE1, 0x34),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_DIV_FRAC_START1_MODE0, 0xab),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_DIV_FRAC_START2_MODE0, 0xaa),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_DIV_FRAC_START3_MODE0, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_DIV_FRAC_START1_MODE1, 0x55),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_DIV_FRAC_START2_MODE1, 0x55),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_DIV_FRAC_START3_MODE1, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_VCO_TUNE_MAP, 0x14),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_CLK_SELECT, 0x34),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_HSCLK_SEL_1, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_CORECLK_DIV_MODE1, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_CMN_CONFIG_1, 0x16),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_ADDITIONAL_MISC_3,	0x0F),
+	QMP_PHY_INIT_CFG(QSERDES_V7_COM_CORE_CLK_EN, 0xA0),
+};
+
+static const struct qmp_phy_init_tbl sm8750_qmp_gen3x2_pcie_rx_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_V7_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
+	QMP_PHY_INIT_CFG(QSERDES_V7_RX_GM_CAL, 0x11),
+	QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_00_HIGH,	0xBF),
+	QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_00_HIGH2, 0xBF),
+	QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_00_HIGH3, 0xB7),
+	QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_00_HIGH4, 0xEA),
+	QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_00_LOW, 0x3F),
+	QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_01_HIGH, 0x09),
+	QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_01_HIGH2, 0x49),
+	QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_01_HIGH3, 0x1B),
+	QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_01_HIGH4, 0x9C),
+	QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_01_LOW, 0xD1),
+	QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_10_HIGH, 0x09),
+	QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_10_HIGH2, 0x49),
+	QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_10_HIGH3, 0x1B),
+	QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_10_HIGH4, 0x9C),
+	QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_10_LOW, 0xD1),
+	QMP_PHY_INIT_CFG(QSERDES_V7_RX_TX_ADAPT_PRE_THRESH1, 0x3E),
+	QMP_PHY_INIT_CFG(QSERDES_V7_RX_TX_ADAPT_PRE_THRESH2, 0x1E),
+	QMP_PHY_INIT_CFG(QSERDES_V7_RX_TX_ADAPT_POST_THRESH, 0xD2),
+	QMP_PHY_INIT_CFG(QSERDES_V7_RX_UCDR_FO_GAIN, 0x09),
+	QMP_PHY_INIT_CFG(QSERDES_V7_RX_UCDR_SO_GAIN, 0x05),
+	QMP_PHY_INIT_CFG(QSERDES_V7_RX_UCDR_SB2_THRESH1, 0x08),
+	QMP_PHY_INIT_CFG(QSERDES_V7_RX_UCDR_SB2_THRESH2, 0x08),
+	QMP_PHY_INIT_CFG(QSERDES_V7_RX_VGA_CAL_CNTRL2, 0x09),
+	QMP_PHY_INIT_CFG(QSERDES_V7_RX_SIGDET_ENABLES, 0x1C),
+	QMP_PHY_INIT_CFG(QSERDES_V7_RX_SIGDET_CNTRL, 0x60),
+	QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_IDAC_TSETTLE_LOW, 0x07),
+	QMP_PHY_INIT_CFG(QSERDES_V7_RX_SIGDET_CAL_TRIM, 0x08),
+};
+
+static const struct qmp_phy_init_tbl sm8750_qmp_gen3x2_pcie_tx_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_V7_TX_LANE_MODE_1,	0x35),
+	QMP_PHY_INIT_CFG(QSERDES_V7_TX_LANE_MODE_3,	0x10),
+	QMP_PHY_INIT_CFG(QSERDES_V7_TX_LANE_MODE_4,	0x31),
+	QMP_PHY_INIT_CFG(QSERDES_V7_TX_LANE_MODE_5,	0x7F),
+	QMP_PHY_INIT_CFG(QSERDES_V7_TX_PI_QEC_CTRL,	0x02),
+	QMP_PHY_INIT_CFG(QSERDES_V7_TX_RES_CODE_LANE_OFFSET_RX, 0x08),
+	QMP_PHY_INIT_CFG(QSERDES_V7_TX_RES_CODE_LANE_OFFSET_TX, 0x14),
+};
+
+static const struct qmp_phy_init_tbl sm8750_qmp_gen3x2_pcie_pcs_tbl[] = {
+	QMP_PHY_INIT_CFG(QPHY_V7_PCS_REFGEN_REQ_CONFIG1, 0x05),
+	QMP_PHY_INIT_CFG(QPHY_V7_PCS_RX_SIGDET_LVL, 0x77),
+	QMP_PHY_INIT_CFG(QPHY_V7_PCS_RATE_SLEW_CNTRL1, 0x0B),
+	QMP_PHY_INIT_CFG(QPHY_V7_PCS_EQ_CONFIG2, 0x0F),
+	QMP_PHY_INIT_CFG(QPHY_V7_PCS_PCS_TX_RX_CONFIG, 0x8C),
+	QMP_PHY_INIT_CFG(QPHY_V7_PCS_G12S1_TXDEEMPH_M6DB, 0x17),
+	QMP_PHY_INIT_CFG(QPHY_V7_PCS_G3S2_PRE_GAIN,	0x2E),
+};
+
+static const struct qmp_phy_init_tbl sm8750_qmp_gen3x2_pcie_pcs_misc_tbl[] = {
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_EQ_CONFIG1, 0x1E),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_RXEQEVAL_TIME, 0x27),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_POWER_STATE_CONFIG2, 0x1D),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_POWER_STATE_CONFIG4, 0x07),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xC1),
+	QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
+};
+
 static const struct qmp_phy_init_tbl sa8775p_qmp_gen4x2_pcie_serdes_alt_tbl[] = {
 	QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
 	QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_IVCO, 0x0f),
@@ -3207,6 +3316,16 @@ static const struct qmp_pcie_offsets qmp_pcie_offsets_v5_30 = {
 	.rx2		= 0x3a00,
 };
 
+static const struct qmp_pcie_offsets qmp_pcie_offsets_v7 = {
+	.serdes		= 0x0,
+	.pcs		= 0x400,
+	.pcs_misc	= 0x800,
+	.tx		= 0x1000,
+	.rx		= 0x1200,
+	.tx2		= 0x1800,
+	.rx2		= 0x1a00,
+};
+
 static const struct qmp_pcie_offsets qmp_pcie_offsets_v6_20 = {
 	.serdes		= 0x1000,
 	.pcs		= 0x1200,
@@ -3996,6 +4115,33 @@ static const struct qmp_phy_cfg sm8550_qmp_gen3x2_pciephy_cfg = {
 	.phy_status		= PHYSTATUS,
 };
 
+static const struct qmp_phy_cfg sm8750_qmp_gen3x2_pciephy_cfg = {
+	.lanes = 2,
+
+	.offsets		= &qmp_pcie_offsets_v7,
+
+	.tbls = {
+		.serdes		= sm8750_qmp_gen3x2_pcie_serdes_tbl,
+		.serdes_num	= ARRAY_SIZE(sm8750_qmp_gen3x2_pcie_serdes_tbl),
+		.tx		= sm8750_qmp_gen3x2_pcie_tx_tbl,
+		.tx_num		= ARRAY_SIZE(sm8750_qmp_gen3x2_pcie_tx_tbl),
+		.rx		= sm8750_qmp_gen3x2_pcie_rx_tbl,
+		.rx_num		= ARRAY_SIZE(sm8750_qmp_gen3x2_pcie_rx_tbl),
+		.pcs		= sm8750_qmp_gen3x2_pcie_pcs_tbl,
+		.pcs_num	= ARRAY_SIZE(sm8750_qmp_gen3x2_pcie_pcs_tbl),
+		.pcs_misc	= sm8750_qmp_gen3x2_pcie_pcs_misc_tbl,
+		.pcs_misc_num	= ARRAY_SIZE(sm8750_qmp_gen3x2_pcie_pcs_misc_tbl),
+	},
+	.reset_list		= sdm845_pciephy_reset_l,
+	.num_resets		= ARRAY_SIZE(sdm845_pciephy_reset_l),
+	.vreg_list		= qmp_phy_vreg_l,
+	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
+	.regs			= pciephy_v7_regs_layout,
+
+	.pwrdn_ctrl		= SW_PWRDN | REFCLK_DRV_DSBL,
+	.phy_status		= PHYSTATUS,
+};
+
 static const struct qmp_phy_cfg sm8550_qmp_gen4x2_pciephy_cfg = {
 	.lanes = 2,
 
@@ -5099,6 +5245,9 @@ static const struct of_device_id qmp_pcie_of_match_table[] = {
 	}, {
 		.compatible = "qcom,sm8650-qmp-gen4x2-pcie-phy",
 		.data = &sm8650_qmp_gen4x2_pciephy_cfg,
+	}, {
+		.compatible = "qcom,sm8750-qmp-gen3x2-pcie-phy",
+		.data = &sm8750_qmp_gen3x2_pciephy_cfg,
 	}, {
 		.compatible = "qcom,x1e80100-qmp-gen3x2-pcie-phy",
 		.data = &sm8550_qmp_gen3x2_pciephy_cfg,
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v7.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v7.h
index c7759892ed2ea046b372ffac23c3ab75c8015a2b..4b7fcaa6a37458647d03e451ec22dae6337326d1 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v7.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v7.h
@@ -17,6 +17,8 @@
 #define QPHY_V7_PCS_LOCK_DETECT_CONFIG3		0x0cc
 #define QPHY_V7_PCS_LOCK_DETECT_CONFIG6		0x0d8
 #define QPHY_V7_PCS_REFGEN_REQ_CONFIG1		0x0dc
+#define QPHY_V7_PCS_G12S1_TXDEEMPH_M6DB		0x168
+#define QPHY_V7_PCS_G3S2_PRE_GAIN		0x170
 #define QPHY_V7_PCS_RX_SIGDET_LVL		0x188
 #define QPHY_V7_PCS_RCVR_DTCT_DLY_P1U2_L	0x190
 #define QPHY_V7_PCS_RCVR_DTCT_DLY_P1U2_H	0x194
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v7.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v7.h
index 91f865b11347af82c38a33e08bcae7b67a7bec26..6ab943ff57ff666e4f23f4ad0b4eff211c6dbfd0 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v7.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v7.h
@@ -40,6 +40,8 @@
 #define QSERDES_V7_RX_UCDR_SB2_GAIN1				0x54
 #define QSERDES_V7_RX_UCDR_SB2_GAIN2				0x58
 #define QSERDES_V7_RX_AUX_DATA_TCOARSE_TFINE			0x60
+#define QSERDES_V7_RX_TX_ADAPT_PRE_THRESH1			0xc4
+#define QSERDES_V7_RX_TX_ADAPT_PRE_THRESH2			0xc8
 #define QSERDES_V7_RX_TX_ADAPT_POST_THRESH			0xcc
 #define QSERDES_V7_RX_VGA_CAL_CNTRL1				0xd4
 #define QSERDES_V7_RX_VGA_CAL_CNTRL2				0xd8
@@ -50,7 +52,7 @@
 #define QSERDES_V7_RX_RX_IDAC_TSETTLE_LOW			0xf8
 #define QSERDES_V7_RX_RX_IDAC_TSETTLE_HIGH			0xfc
 #define QSERDES_V7_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1		0x110
-#define QSERDES_V7_RX_SIDGET_ENABLES				0x118
+#define QSERDES_V7_RX_SIGDET_ENABLES				0x118
 #define QSERDES_V7_RX_SIGDET_CNTRL				0x11c
 #define QSERDES_V7_RX_SIGDET_DEGLITCH_CNTRL			0x124
 #define QSERDES_V7_RX_RX_MODE_00_LOW				0x15c

-- 
2.34.1



From krishna.chundru at oss.qualcomm.com  Sat Aug  9 02:59:18 2025
From: krishna.chundru at oss.qualcomm.com (Krishna Chaitanya Chundru)
Date: Sat, 09 Aug 2025 15:29:18 +0530
Subject: [PATCH 3/4] dt-bindings: PCI: qcom,pcie-sm8550: Add SM8750
 compatible
In-Reply-To: <20250809-pakala-v1-0-abf1c416dbaa@oss.qualcomm.com>
References: <20250809-pakala-v1-0-abf1c416dbaa@oss.qualcomm.com>
Message-ID: <20250809-pakala-v1-3-abf1c416dbaa@oss.qualcomm.com>

On the Qualcomm SM8750 platform the PCIe host is compatible with the
DWC controller present on the SM8550 platorm.

Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
---
 Documentation/devicetree/bindings/pci/qcom,pcie-sm8550.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-sm8550.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-sm8550.yaml
index dbce671ba011c8991842af6d6c761ec081be24cb..38b561e23c1fda677ce2d4257e1084a384648835 100644
--- a/Documentation/devicetree/bindings/pci/qcom,pcie-sm8550.yaml
+++ b/Documentation/devicetree/bindings/pci/qcom,pcie-sm8550.yaml
@@ -22,6 +22,7 @@ properties:
           - enum:
               - qcom,sar2130p-pcie
               - qcom,pcie-sm8650
+              - qcom,pcie-sm8750
           - const: qcom,pcie-sm8550
 
   reg:

-- 
2.34.1



From krishna.chundru at oss.qualcomm.com  Sat Aug  9 02:59:19 2025
From: krishna.chundru at oss.qualcomm.com (Krishna Chaitanya Chundru)
Date: Sat, 09 Aug 2025 15:29:19 +0530
Subject: [PATCH 4/4] arm64: dts: qcom: sm8750: Add PCIe PHY and controller
 node
In-Reply-To: <20250809-pakala-v1-0-abf1c416dbaa@oss.qualcomm.com>
References: <20250809-pakala-v1-0-abf1c416dbaa@oss.qualcomm.com>
Message-ID: <20250809-pakala-v1-4-abf1c416dbaa@oss.qualcomm.com>

Add PCIe controller and PHY nodes which supports data rates of 8GT/s
and x2 lane.

Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/sm8750.dtsi | 174 ++++++++++++++++++++++++++++++++++-
 1 file changed, 173 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/sm8750.dtsi b/arch/arm64/boot/dts/qcom/sm8750.dtsi
index 4643705021c6ca095a16d8d7cc3adac920b21e82..866c1eb8729953f6cb27c7cf995a1a8d55140e40 100644
--- a/arch/arm64/boot/dts/qcom/sm8750.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8750.dtsi
@@ -631,7 +631,7 @@ gcc: clock-controller at 100000 {
 			clocks = <&bi_tcxo_div2>,
 				 <0>,
 				 <&sleep_clk>,
-				 <0>,
+				 <&pcie0_phy>,
 				 <0>,
 				 <0>,
 				 <0>,
@@ -3304,6 +3304,178 @@ gic_its: msi-controller at 16040000 {
 			};
 		};
 
+		pcie0: pcie at 1c00000 {
+			device_type = "pci";
+			compatible = "qcom,pcie-sm8750", "qcom,pcie-sm8550";
+			reg = <0 0x01c00000 0 0x3000>,
+			      <0 0x40000000 0 0xf1d>,
+			      <0 0x40000f20 0 0xa8>,
+			      <0 0x40001000 0 0x1000>,
+			      <0 0x40100000 0 0x100000>;
+			reg-names = "parf", "dbi", "elbi", "atu", "config";
+
+			interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "msi0",
+					  "msi1",
+					  "msi2",
+					  "msi3",
+					  "msi4",
+					  "msi5",
+					  "msi6",
+					  "msi7",
+					  "global";
+
+			clocks = <&gcc GCC_PCIE_0_AUX_CLK>,
+				 <&gcc GCC_PCIE_0_CFG_AHB_CLK>,
+				 <&gcc GCC_PCIE_0_MSTR_AXI_CLK>,
+				 <&gcc GCC_PCIE_0_SLV_AXI_CLK>,
+				 <&gcc GCC_PCIE_0_SLV_Q2A_AXI_CLK>,
+				 <&gcc GCC_DDRSS_PCIE_SF_QTB_CLK>,
+				 <&gcc GCC_AGGRE_NOC_PCIE_AXI_CLK>,
+				 <&gcc GCC_CNOC_PCIE_SF_AXI_CLK>;
+			clock-names = "aux",
+				      "cfg",
+				      "bus_master",
+				      "bus_slave",
+				      "slave_q2a",
+				      "ddrss_sf_tbu",
+				      "noc_aggr",
+				      "cnoc_sf_axi";
+
+			resets = <&gcc GCC_PCIE_0_BCR>;
+			reset-names = "pci";
+
+			interconnects = <&pcie_noc MASTER_PCIE_0 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_0 QCOM_ICC_TAG_ALWAYS>;
+			interconnect-names = "pcie-mem",
+					     "cpu-pcie";
+
+			power-domains = <&gcc GCC_PCIE_0_GDSC>;
+
+			iommu-map = <0     &apps_smmu 0x1400 0x1>,
+				    <0x100 &apps_smmu 0x1401 0x1>;
+
+			interrupt-map = <0 0 0 1 &intc 0 0 0 149 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 2 &intc 0 0 0 150 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 3 &intc 0 0 0 151 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 4 &intc 0 0 0 152 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-map-mask = <0 0 0 0x7>;
+			#interrupt-cells = <1>;
+
+			msi-map = <0x0 &gic_its 0x1400 0x1>,
+				  <0x100 &gic_its 0x1401 0x1>;
+			msi-map-mask = <0xff00>;
+
+			linux,pci-domain = <0>;
+			num-lanes = <2>;
+			bus-range = <0 0xff>;
+
+			phys = <&pcie0_phy>;
+			phy-names = "pciephy";
+
+			#address-cells = <3>;
+			#size-cells = <2>;
+			ranges = <0x01000000 0 0x00000000 0 0x40200000 0 0x100000>,
+				 <0x02000000 0 0x60300000 0 0x40300000 0 0x3d00000>;
+
+			dma-coherent;
+
+			operating-points-v2 = <&pcie0_opp_table>;
+
+			status = "disabled";
+
+			pcie0_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 2 x2 */
+				opp-10000000 {
+					opp-hz = /bits/ 64 <10000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <1000000 1>;
+				};
+
+				/* GEN 3 x1 */
+				opp-8000000 {
+					opp-hz = /bits/ 64 <8000000>;
+					required-opps = <&rpmhpd_opp_nom>;
+					opp-peak-kBps = <984500 1>;
+				};
+
+				/* GEN 3 x2 */
+				opp-16000000 {
+					opp-hz = /bits/ 64 <16000000>;
+					required-opps = <&rpmhpd_opp_nom>;
+					opp-peak-kBps = <1969000 1>;
+				};
+
+			};
+
+			pcieport0: pcie at 0 {
+				device_type = "pci";
+				reg = <0x0 0x0 0x0 0x0 0x0>;
+				bus-range = <0x01 0xff>;
+
+				#address-cells = <3>;
+				#size-cells = <2>;
+				ranges;
+			};
+		};
+
+		pcie0_phy: phy at 1c06000 {
+			compatible = "qcom,sm8750-qmp-gen3x2-pcie-phy";
+			reg = <0 0x01c06000 0 0x2000>;
+
+			clocks = <&gcc GCC_PCIE_0_AUX_CLK>,
+				 <&gcc GCC_PCIE_0_CFG_AHB_CLK>,
+				 <&tcsrcc TCSR_PCIE_0_CLKREF_EN>,
+				 <&gcc GCC_PCIE_0_PHY_RCHNG_CLK>,
+				 <&gcc GCC_PCIE_0_PIPE_CLK>;
+			clock-names = "aux",
+				      "cfg_ahb",
+				      "ref",
+				      "rchng",
+				      "pipe";
+
+			assigned-clocks = <&gcc GCC_PCIE_0_PHY_RCHNG_CLK>;
+			assigned-clock-rates = <100000000>;
+
+			resets = <&gcc GCC_PCIE_0_PHY_BCR>;
+			reset-names = "phy";
+
+			power-domains = <&gcc GCC_PCIE_0_PHY_GDSC>;
+
+			#clock-cells = <0>;
+			clock-output-names = "pcie0_pipe_clk";
+
+			#phy-cells = <0>;
+
+			status = "disabled";
+		};
+
 		ufs_mem_phy: phy at 1d80000 {
 			compatible = "qcom,sm8750-qmp-ufs-phy";
 			reg = <0x0 0x01d80000 0x0 0x2000>;

-- 
2.34.1



From mani at kernel.org  Sat Aug  9 04:07:16 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Sat, 9 Aug 2025 16:37:16 +0530
Subject: [PATCH V1 2/4] arm64: dts: qcom: sm8750: add max-microamp for
 UFS PHY and PLL supplies
In-Reply-To: <5e32be05-0dbd-4d6f-879d-8ce97fb430ba@quicinc.com>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
 <20250806154340.20122-3-quic_nitirawa@quicinc.com>
 <20250808-calm-boa-of-swiftness-a4a7ce@kuoka>
 <9af71063-0629-4ccc-bc76-3fb588677bf4@oss.qualcomm.com>
 <292907f3-25d6-40d9-be6e-b6b83e646d73@kernel.org>
 <5e32be05-0dbd-4d6f-879d-8ce97fb430ba@quicinc.com>
Message-ID: <rh3qxu2rijpjswfash3rpmmh6sw47l3b6j5p5upti6zffknasz@cywwm3fypghd>

On Fri, Aug 08, 2025 at 08:49:45PM GMT, Nitin Rawat wrote:
> 
> 
> On 8/8/2025 3:09 PM, Krzysztof Kozlowski wrote:
> > On 08/08/2025 10:58, Konrad Dybcio wrote:
> > > On 8/8/25 9:29 AM, Krzysztof Kozlowski wrote:
> > > > On Wed, Aug 06, 2025 at 09:13:38PM +0530, Nitin Rawat wrote:
> > > > > Add `vdda-phy-max-microamp` and `vdda-pll-max-microamp` properties to
> > > > > the UFS PHY node in the device tree.
> > > > > 
> > > > > These properties define the maximum current (in microamps) expected
> > > > > from the PHY and PLL regulators. This allows the PHY driver to
> > > > > configure regulator load accurately and ensure proper regulator
> > > > > mode based on load requirements.
> > > > 
> > > > That's not the property of phy, but regulator.
> > > > 
> > > > Also reasoning is here incomplete - you just post downstream code. :/
> > > 
> > > The reason for this change is good, but perhaps not explained clearly
> > > 
> > > All of these values refer to the maximum current draw that needs to be
> > > allocated on a shared voltage supply for this peripheral (because the
> > 
> > 
> > It sounds very different than how much it can be drawn. How much can be
> > drawn is the property of the regulator. The regulator knows how much
> > current it can support.
> 
> Consumers are aware of their dynamic load requirements, which can vary at
> runtime?this awareness is not reciprocal. The power grid is designed based
> on the collective load requirements of all clients sharing the same power
> rail.
> 
> Since regulators can operate in multiple modes for power optimization, each
> consumer is expected to vote for its runtime power needs. These votes help
> the regulator framework maintain the regulator in the appropriate mode,
> ensuring stable and efficient operation across all clients.
> 
> 
> Stability issues can arise if each consumer does not vote for its own load
> requirement.
> For example, consider a scenario where a single regulator is shared by two
> consumers.
> 
> If the first client requests low-power mode by voting for zero or a minimal
> load to regulator framework during its driver's LPM sequence, and the second
> client (e.g., UFS PHY) has not voted for its own load requirement through
> the regulator framework, the regulator may transition to low-power mode.
> This can lead to issues for the second client, which expects a higher power
> state to operate correctly.
> 

I think we all agree on consumers setting the load for shared regulators, but
the naming and description of the DT property is what causing confusion here.
There is no way the consumers can set the *max* current draw for a shared
regulator. They can only request load as per their requirement. But the max
current draw is a regulator constraint.

> 
> > 
> > 
> > > supply's capabilities change depending on the maximum potential load
> > > at any given time, which the regulator driver must be aware of)
> > > 
> > > This is a property of a regulator *consumer*, i.e. if we had a chain
> > > of LEDs hanging off of this supply, we'd need to specify NUM_LEDS *
> > > MAX_CURR under the "led chain" device, to make sure that if the
> > > aggregated current requirements go over a certain threshold (which is
> > > unknown to Linux and hidden in RPMh fw), the regulator can be
> > > reconfigured to allow for a higher current draw (likely at some
> > > downgrade to efficiency)
> > 
> > 
> > The problem is that rationale is downstream. Instead I want to see some
> > reason: e.g. datasheets, spec, type of UFS device (that was the argument
> > in the driver patch discussion).
> 
> 
> The PHY load requirements for consumers such as UFS, USB, PCIe are defined
> by Qualcomm?s PHY IP and are well-documented in Qualcomm?s datasheets and
> power grid documentation. These values can depending on the process or
> technology node, board design, and even the chip foundry used.
> 
> As a result, the load values can differ across SoCs or may be even
> board(unlikely though) due to variations in any of these parameters.
> 

Okay. This goes into the commit message and possibly some part of it to property
description also.

- Mani

-- 
????????? ????????


From bmasney at redhat.com  Sun Aug 10 15:45:28 2025
From: bmasney at redhat.com (Brian Masney)
Date: Sun, 10 Aug 2025 18:45:28 -0400
Subject: [PATCH v2 0/9] phy: convert from clk round_rate() to
 determine_rate()
Message-ID: <20250810-phy-clk-round-rate-v2-0-9162470bb9f2@redhat.com>

The round_rate() clk ops is deprecated in the clk framework in favor
of the determine_rate() clk ops, so let's go ahead and convert the
drivers in the phy subsystem using the Coccinelle semantic patch
posted below. I did a few minor cosmetic cleanups of the code in a
few cases.

Changes since v1:
- Patch 8 (phy-rockchip-samsung-hdptx): fix returning error code
  (Cristian)

Coccinelle semantic patch:

    virtual patch

    // Look up the current name of the round_rate function
    @ has_round_rate @
    identifier round_rate_name =~ ".*_round_rate";
    identifier hw_param, rate_param, parent_rate_param;
    @@

    long round_rate_name(struct clk_hw *hw_param, unsigned long rate_param,
                  unsigned long *parent_rate_param)
    {
    	...
    }

    // Rename the route_rate function name to determine_rate()
    @ script:python generate_name depends on has_round_rate @
    round_rate_name << has_round_rate.round_rate_name;
    new_name;
    @@

    coccinelle.new_name = round_rate_name.replace("_round_rate", "_determine_rate")

    // Change rate to req->rate; also change occurrences of 'return XXX'.
    @ chg_rate depends on generate_name @
    identifier has_round_rate.round_rate_name;
    identifier has_round_rate.hw_param;
    identifier has_round_rate.rate_param;
    identifier has_round_rate.parent_rate_param;
    identifier ERR =~ "E.*";
    expression E;
    @@

    long round_rate_name(struct clk_hw *hw_param, unsigned long rate_param,
                  unsigned long *parent_rate_param)
    {
    <...
    (
    -return -ERR;
    +return -ERR;
    |
    - return rate_param;
    + return 0;
    |
    - return E;
    + req->rate = E;
    +
    + return 0;
    |
    - rate_param
    + req->rate
    )
    ...>
    }

    // Coccinelle only transforms the first occurrence of the rate parameter
    // Run a second time. FIXME: Is there a better way to do this?
    @ chg_rate2 depends on generate_name @
    identifier has_round_rate.round_rate_name;
    identifier has_round_rate.hw_param;
    identifier has_round_rate.rate_param;
    identifier has_round_rate.parent_rate_param;
    @@

    long round_rate_name(struct clk_hw *hw_param, unsigned long rate_param,
                  unsigned long *parent_rate_param)
    {
    <...
    - rate_param
    + req->rate
    ...>
    }

    // Change parent_rate to req->best_parent_rate
    @ chg_parent_rate depends on generate_name @
    identifier has_round_rate.round_rate_name;
    identifier has_round_rate.hw_param;
    identifier has_round_rate.rate_param;
    identifier has_round_rate.parent_rate_param;
    @@

    long round_rate_name(struct clk_hw *hw_param, unsigned long rate_param,
                  unsigned long *parent_rate_param)
    {
    <...
    (
    - *parent_rate_param
    + req->best_parent_rate
    |
    - parent_rate_param
    + &req->best_parent_rate
    )
    ...>
    }

    // Convert the function definition from round_rate() to determine_rate()
    @ func_definition depends on chg_rate @
    identifier has_round_rate.round_rate_name;
    identifier has_round_rate.hw_param;
    identifier has_round_rate.rate_param;
    identifier has_round_rate.parent_rate_param;
    identifier generate_name.new_name;
    @@

    - long round_rate_name(struct clk_hw *hw_param, unsigned long rate_param,
    -               unsigned long *parent_rate_param)
    + int new_name(struct clk_hw *hw, struct clk_rate_request *req)
    {
        ...
    }

    // Update the ops from round_rate() to determine_rate()
    @ ops depends on func_definition @
    identifier has_round_rate.round_rate_name;
    identifier generate_name.new_name;
    @@

    {
        ...,
    -   .round_rate = round_rate_name,
    +   .determine_rate = new_name,
        ...,
    }

Note that I used coccinelle 1.2 instead of 1.3 since the newer version
adds unnecessary braces as described in this post.
https://lore.kernel.org/cocci/67642477-5f3e-4b2a-914d-579a54f48cbd at intel.com/

Signed-off-by: Brian Masney <bmasney at redhat.com>
---
Brian Masney (9):
      phy: freescale: phy-fsl-samsung-hdmi: convert from round_rate() to determine_rate()
      phy: mediatek: phy-mtk-hdmi-mt2701: convert from round_rate() to determine_rate()
      phy: mediatek: phy-mtk-hdmi-mt8173: convert from round_rate() to determine_rate()
      phy: mediatek: phy-mtk-hdmi-mt8195: convert from round_rate() to determine_rate()
      phy: mediatek: phy-mtk-mipi-dsi-mt8173: convert from round_rate() to determine_rate()
      phy: mediatek: phy-mtk-mipi-dsi-mt8183: convert from round_rate() to determine_rate()
      phy: rockchip: phy-rockchip-inno-hdmi: convert from round_rate() to determine_rate()
      phy: rockchip: phy-rockchip-samsung-hdptx: convert from round_rate() to determine_rate()
      phy: ti: phy-j721e-wiz: convert from round_rate() to determine_rate()

 drivers/phy/freescale/phy-fsl-samsung-hdmi.c      | 13 ++++++----
 drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c        |  8 +++---
 drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c        | 16 ++++++------
 drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c        | 10 ++++----
 drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c    | 10 +++++---
 drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c    | 10 +++++---
 drivers/phy/rockchip/phy-rockchip-inno-hdmi.c     | 30 ++++++++++++-----------
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 14 ++++++-----
 drivers/phy/ti/phy-j721e-wiz.c                    | 11 ++++++---
 9 files changed, 68 insertions(+), 54 deletions(-)
---
base-commit: 8f5ae30d69d7543eee0d70083daf4de8fe15d585
change-id: 20250710-phy-clk-round-rate-4aa7ef160fe9

Best regards,
-- 
Brian Masney <bmasney at redhat.com>



From bmasney at redhat.com  Sun Aug 10 15:45:29 2025
From: bmasney at redhat.com (Brian Masney)
Date: Sun, 10 Aug 2025 18:45:29 -0400
Subject: [PATCH v2 1/9] phy: freescale: phy-fsl-samsung-hdmi: convert from
 round_rate() to determine_rate()
In-Reply-To: <20250810-phy-clk-round-rate-v2-0-9162470bb9f2@redhat.com>
References: <20250810-phy-clk-round-rate-v2-0-9162470bb9f2@redhat.com>
Message-ID: <20250810-phy-clk-round-rate-v2-1-9162470bb9f2@redhat.com>

The round_rate() clk ops is deprecated, so migrate this driver from
round_rate() to determine_rate() using the Coccinelle semantic patch
on the cover letter of this series.

Signed-off-by: Brian Masney <bmasney at redhat.com>
---
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index 191c282246d96e3f6c5a8d17abe078892882bf44..d010fec15671d33cc363af79e9f1c3f26ecb3464 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -570,17 +570,20 @@ const struct phy_config *fsl_samsung_hdmi_phy_find_settings(struct fsl_samsung_h
 	return fract_div_phy;
 }
 
-static long fsl_samsung_hdmi_phy_clk_round_rate(struct clk_hw *hw,
-						unsigned long rate, unsigned long *parent_rate)
+static int fsl_samsung_hdmi_phy_clk_determine_rate(struct clk_hw *hw,
+						   struct clk_rate_request *req)
 {
 	struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw);
-	const struct phy_config *target_settings = fsl_samsung_hdmi_phy_find_settings(phy, rate);
+	const struct phy_config *target_settings = fsl_samsung_hdmi_phy_find_settings(phy,
+										      req->rate);
 
 	if (target_settings == NULL)
 		return -EINVAL;
 
 	dev_dbg(phy->dev, "round_rate, closest rate = %u\n", target_settings->pixclk);
-	return target_settings->pixclk;
+	req->rate = target_settings->pixclk;
+
+	return 0;
 }
 
 static int fsl_samsung_hdmi_phy_clk_set_rate(struct clk_hw *hw,
@@ -599,7 +602,7 @@ static int fsl_samsung_hdmi_phy_clk_set_rate(struct clk_hw *hw,
 
 static const struct clk_ops phy_clk_ops = {
 	.recalc_rate = phy_clk_recalc_rate,
-	.round_rate = fsl_samsung_hdmi_phy_clk_round_rate,
+	.determine_rate = fsl_samsung_hdmi_phy_clk_determine_rate,
 	.set_rate = fsl_samsung_hdmi_phy_clk_set_rate,
 };
 

-- 
2.50.1



From bmasney at redhat.com  Sun Aug 10 15:45:30 2025
From: bmasney at redhat.com (Brian Masney)
Date: Sun, 10 Aug 2025 18:45:30 -0400
Subject: [PATCH v2 2/9] phy: mediatek: phy-mtk-hdmi-mt2701: convert from
 round_rate() to determine_rate()
In-Reply-To: <20250810-phy-clk-round-rate-v2-0-9162470bb9f2@redhat.com>
References: <20250810-phy-clk-round-rate-v2-0-9162470bb9f2@redhat.com>
Message-ID: <20250810-phy-clk-round-rate-v2-2-9162470bb9f2@redhat.com>

The round_rate() clk ops is deprecated, so migrate this driver from
round_rate() to determine_rate() using the Coccinelle semantic patch
on the cover letter of this series.

Signed-off-by: Brian Masney <bmasney at redhat.com>
---
 drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c b/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c
index e51b2d13eab473dddace48c75c2a8d73c8c65635..b0b6497e7eedcb6867541b573d22156ded29a4d5 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c
+++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c
@@ -90,10 +90,10 @@ static void mtk_hdmi_pll_unprepare(struct clk_hw *hw)
 	usleep_range(80, 100);
 }
 
-static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
-				    unsigned long *parent_rate)
+static int mtk_hdmi_pll_determine_rate(struct clk_hw *hw,
+				       struct clk_rate_request *req)
 {
-	return rate;
+	return 0;
 }
 
 static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -170,7 +170,7 @@ static const struct clk_ops mtk_hdmi_phy_pll_ops = {
 	.prepare = mtk_hdmi_pll_prepare,
 	.unprepare = mtk_hdmi_pll_unprepare,
 	.set_rate = mtk_hdmi_pll_set_rate,
-	.round_rate = mtk_hdmi_pll_round_rate,
+	.determine_rate = mtk_hdmi_pll_determine_rate,
 	.recalc_rate = mtk_hdmi_pll_recalc_rate,
 };
 

-- 
2.50.1



From bmasney at redhat.com  Sun Aug 10 15:45:31 2025
From: bmasney at redhat.com (Brian Masney)
Date: Sun, 10 Aug 2025 18:45:31 -0400
Subject: [PATCH v2 3/9] phy: mediatek: phy-mtk-hdmi-mt8173: convert from
 round_rate() to determine_rate()
In-Reply-To: <20250810-phy-clk-round-rate-v2-0-9162470bb9f2@redhat.com>
References: <20250810-phy-clk-round-rate-v2-0-9162470bb9f2@redhat.com>
Message-ID: <20250810-phy-clk-round-rate-v2-3-9162470bb9f2@redhat.com>

The round_rate() clk ops is deprecated, so migrate this driver from
round_rate() to determine_rate() using the Coccinelle semantic patch
on the cover letter of this series.

Signed-off-by: Brian Masney <bmasney at redhat.com>
---
 drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c b/drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c
index d04758396046363ab9edc584ae10bf31e9c5fb0f..58c6596c8c20bdacf96a97709b8f5709f447e85b 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c
+++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c
@@ -118,18 +118,18 @@ static void mtk_hdmi_pll_unprepare(struct clk_hw *hw)
 	usleep_range(100, 150);
 }
 
-static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
-				    unsigned long *parent_rate)
+static int mtk_hdmi_pll_determine_rate(struct clk_hw *hw,
+				       struct clk_rate_request *req)
 {
 	struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
 
-	hdmi_phy->pll_rate = rate;
-	if (rate <= 74250000)
-		*parent_rate = rate;
+	hdmi_phy->pll_rate = req->rate;
+	if (req->rate <= 74250000)
+		req->best_parent_rate = req->rate;
 	else
-		*parent_rate = rate / 2;
+		req->best_parent_rate = req->rate / 2;
 
-	return rate;
+	return 0;
 }
 
 static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -223,7 +223,7 @@ static const struct clk_ops mtk_hdmi_phy_pll_ops = {
 	.prepare = mtk_hdmi_pll_prepare,
 	.unprepare = mtk_hdmi_pll_unprepare,
 	.set_rate = mtk_hdmi_pll_set_rate,
-	.round_rate = mtk_hdmi_pll_round_rate,
+	.determine_rate = mtk_hdmi_pll_determine_rate,
 	.recalc_rate = mtk_hdmi_pll_recalc_rate,
 };
 

-- 
2.50.1



From bmasney at redhat.com  Sun Aug 10 15:45:32 2025
From: bmasney at redhat.com (Brian Masney)
Date: Sun, 10 Aug 2025 18:45:32 -0400
Subject: [PATCH v2 4/9] phy: mediatek: phy-mtk-hdmi-mt8195: convert from
 round_rate() to determine_rate()
In-Reply-To: <20250810-phy-clk-round-rate-v2-0-9162470bb9f2@redhat.com>
References: <20250810-phy-clk-round-rate-v2-0-9162470bb9f2@redhat.com>
Message-ID: <20250810-phy-clk-round-rate-v2-4-9162470bb9f2@redhat.com>

The round_rate() clk ops is deprecated, so migrate this driver from
round_rate() to determine_rate() using the Coccinelle semantic patch
on the cover letter of this series.

Signed-off-by: Brian Masney <bmasney at redhat.com>
---
 drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
index b38f3ae26b3f3d8c9e73b43d86510acf6cedb471..1426a2db984d53b91125b18f7725738c44f19555 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
+++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
@@ -418,13 +418,13 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 	return mtk_hdmi_pll_calc(hdmi_phy, hw, rate, parent_rate);
 }
 
-static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
-				    unsigned long *parent_rate)
+static int mtk_hdmi_pll_determine_rate(struct clk_hw *hw,
+				       struct clk_rate_request *req)
 {
 	struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
 
-	hdmi_phy->pll_rate = rate;
-	return rate;
+	hdmi_phy->pll_rate = req->rate;
+	return 0;
 }
 
 static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
@@ -439,7 +439,7 @@ static const struct clk_ops mtk_hdmi_pll_ops = {
 	.prepare = mtk_hdmi_pll_prepare,
 	.unprepare = mtk_hdmi_pll_unprepare,
 	.set_rate = mtk_hdmi_pll_set_rate,
-	.round_rate = mtk_hdmi_pll_round_rate,
+	.determine_rate = mtk_hdmi_pll_determine_rate,
 	.recalc_rate = mtk_hdmi_pll_recalc_rate,
 };
 

-- 
2.50.1



From bmasney at redhat.com  Sun Aug 10 15:45:33 2025
From: bmasney at redhat.com (Brian Masney)
Date: Sun, 10 Aug 2025 18:45:33 -0400
Subject: [PATCH v2 5/9] phy: mediatek: phy-mtk-mipi-dsi-mt8173: convert
 from round_rate() to determine_rate()
In-Reply-To: <20250810-phy-clk-round-rate-v2-0-9162470bb9f2@redhat.com>
References: <20250810-phy-clk-round-rate-v2-0-9162470bb9f2@redhat.com>
Message-ID: <20250810-phy-clk-round-rate-v2-5-9162470bb9f2@redhat.com>

The round_rate() clk ops is deprecated, so migrate this driver from
round_rate() to determine_rate() using the Coccinelle semantic patch
on the cover letter of this series.

Signed-off-by: Brian Masney <bmasney at redhat.com>
---
 drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c
index 673cb0f08959e0e4f2b1ade2ebaf796e8b76f8bc..438ff3605d90121b7bfe02b3ddca8194437ed9ba 100644
--- a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c
+++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c
@@ -237,16 +237,18 @@ static void mtk_mipi_tx_pll_unprepare(struct clk_hw *hw)
 	mtk_phy_clear_bits(base + MIPITX_DSI_PLL_CON0, RG_DSI_MPPLL_DIV_MSK);
 }
 
-static long mtk_mipi_tx_pll_round_rate(struct clk_hw *hw, unsigned long rate,
-				       unsigned long *prate)
+static int mtk_mipi_tx_pll_determine_rate(struct clk_hw *hw,
+					  struct clk_rate_request *req)
 {
-	return clamp_val(rate, 50000000, 1250000000);
+	req->rate = clamp_val(req->rate, 50000000, 1250000000);
+
+	return 0;
 }
 
 static const struct clk_ops mtk_mipi_tx_pll_ops = {
 	.prepare = mtk_mipi_tx_pll_prepare,
 	.unprepare = mtk_mipi_tx_pll_unprepare,
-	.round_rate = mtk_mipi_tx_pll_round_rate,
+	.determine_rate = mtk_mipi_tx_pll_determine_rate,
 	.set_rate = mtk_mipi_tx_pll_set_rate,
 	.recalc_rate = mtk_mipi_tx_pll_recalc_rate,
 };

-- 
2.50.1



From bmasney at redhat.com  Sun Aug 10 15:45:34 2025
From: bmasney at redhat.com (Brian Masney)
Date: Sun, 10 Aug 2025 18:45:34 -0400
Subject: [PATCH v2 6/9] phy: mediatek: phy-mtk-mipi-dsi-mt8183: convert
 from round_rate() to determine_rate()
In-Reply-To: <20250810-phy-clk-round-rate-v2-0-9162470bb9f2@redhat.com>
References: <20250810-phy-clk-round-rate-v2-0-9162470bb9f2@redhat.com>
Message-ID: <20250810-phy-clk-round-rate-v2-6-9162470bb9f2@redhat.com>

The round_rate() clk ops is deprecated, so migrate this driver from
round_rate() to determine_rate() using the Coccinelle semantic patch
on the cover letter of this series.

Signed-off-by: Brian Masney <bmasney at redhat.com>
---
 drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
index 553725e1269c9d7ad88f89367dfa1cf367aaf1ce..a54d44ef70ab49937d210f04fdf42300e8e5f2de 100644
--- a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
+++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
@@ -97,16 +97,18 @@ static void mtk_mipi_tx_pll_disable(struct clk_hw *hw)
 	mtk_phy_clear_bits(base + MIPITX_PLL_PWR, AD_DSI_PLL_SDM_PWR_ON);
 }
 
-static long mtk_mipi_tx_pll_round_rate(struct clk_hw *hw, unsigned long rate,
-				       unsigned long *prate)
+static int mtk_mipi_tx_pll_determine_rate(struct clk_hw *hw,
+					  struct clk_rate_request *req)
 {
-	return clamp_val(rate, 125000000, 1600000000);
+	req->rate = clamp_val(req->rate, 125000000, 1600000000);
+
+	return 0;
 }
 
 static const struct clk_ops mtk_mipi_tx_pll_ops = {
 	.enable = mtk_mipi_tx_pll_enable,
 	.disable = mtk_mipi_tx_pll_disable,
-	.round_rate = mtk_mipi_tx_pll_round_rate,
+	.determine_rate = mtk_mipi_tx_pll_determine_rate,
 	.set_rate = mtk_mipi_tx_pll_set_rate,
 	.recalc_rate = mtk_mipi_tx_pll_recalc_rate,
 };

-- 
2.50.1



From bmasney at redhat.com  Sun Aug 10 15:45:35 2025
From: bmasney at redhat.com (Brian Masney)
Date: Sun, 10 Aug 2025 18:45:35 -0400
Subject: [PATCH v2 7/9] phy: rockchip: phy-rockchip-inno-hdmi: convert from
 round_rate() to determine_rate()
In-Reply-To: <20250810-phy-clk-round-rate-v2-0-9162470bb9f2@redhat.com>
References: <20250810-phy-clk-round-rate-v2-0-9162470bb9f2@redhat.com>
Message-ID: <20250810-phy-clk-round-rate-v2-7-9162470bb9f2@redhat.com>

The round_rate() clk ops is deprecated, so migrate this driver from
round_rate() to determine_rate() using the Coccinelle semantic patch
on the cover letter of this series.

Signed-off-by: Brian Masney <bmasney at redhat.com>
---
 drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 30 ++++++++++++++-------------
 1 file changed, 16 insertions(+), 14 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
index 8dcc2bb777b5455d21a10f06c5ad842b2ddbc834..1483907413faa5ce1dc8614db05e6e929410404d 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
@@ -749,22 +749,23 @@ unsigned long inno_hdmi_phy_rk3228_clk_recalc_rate(struct clk_hw *hw,
 	return vco;
 }
 
-static long inno_hdmi_phy_rk3228_clk_round_rate(struct clk_hw *hw,
-						unsigned long rate,
-						unsigned long *parent_rate)
+static int inno_hdmi_phy_rk3228_clk_determine_rate(struct clk_hw *hw,
+						   struct clk_rate_request *req)
 {
 	const struct pre_pll_config *cfg = pre_pll_cfg_table;
 
-	rate = (rate / 1000) * 1000;
+	req->rate = (req->rate / 1000) * 1000;
 
 	for (; cfg->pixclock != 0; cfg++)
-		if (cfg->pixclock == rate && !cfg->fracdiv)
+		if (cfg->pixclock == req->rate && !cfg->fracdiv)
 			break;
 
 	if (cfg->pixclock == 0)
 		return -EINVAL;
 
-	return cfg->pixclock;
+	req->rate = cfg->pixclock;
+
+	return 0;
 }
 
 static int inno_hdmi_phy_rk3228_clk_set_rate(struct clk_hw *hw,
@@ -835,7 +836,7 @@ static const struct clk_ops inno_hdmi_phy_rk3228_clk_ops = {
 	.unprepare = inno_hdmi_phy_rk3228_clk_unprepare,
 	.is_prepared = inno_hdmi_phy_rk3228_clk_is_prepared,
 	.recalc_rate = inno_hdmi_phy_rk3228_clk_recalc_rate,
-	.round_rate = inno_hdmi_phy_rk3228_clk_round_rate,
+	.determine_rate = inno_hdmi_phy_rk3228_clk_determine_rate,
 	.set_rate = inno_hdmi_phy_rk3228_clk_set_rate,
 };
 
@@ -906,22 +907,23 @@ unsigned long inno_hdmi_phy_rk3328_clk_recalc_rate(struct clk_hw *hw,
 	return inno->pixclock;
 }
 
-static long inno_hdmi_phy_rk3328_clk_round_rate(struct clk_hw *hw,
-						unsigned long rate,
-						unsigned long *parent_rate)
+static int inno_hdmi_phy_rk3328_clk_determine_rate(struct clk_hw *hw,
+						   struct clk_rate_request *req)
 {
 	const struct pre_pll_config *cfg = pre_pll_cfg_table;
 
-	rate = (rate / 1000) * 1000;
+	req->rate = (req->rate / 1000) * 1000;
 
 	for (; cfg->pixclock != 0; cfg++)
-		if (cfg->pixclock == rate)
+		if (cfg->pixclock == req->rate)
 			break;
 
 	if (cfg->pixclock == 0)
 		return -EINVAL;
 
-	return cfg->pixclock;
+	req->rate = cfg->pixclock;
+
+	return 0;
 }
 
 static int inno_hdmi_phy_rk3328_clk_set_rate(struct clk_hw *hw,
@@ -989,7 +991,7 @@ static const struct clk_ops inno_hdmi_phy_rk3328_clk_ops = {
 	.unprepare = inno_hdmi_phy_rk3328_clk_unprepare,
 	.is_prepared = inno_hdmi_phy_rk3328_clk_is_prepared,
 	.recalc_rate = inno_hdmi_phy_rk3328_clk_recalc_rate,
-	.round_rate = inno_hdmi_phy_rk3328_clk_round_rate,
+	.determine_rate = inno_hdmi_phy_rk3328_clk_determine_rate,
 	.set_rate = inno_hdmi_phy_rk3328_clk_set_rate,
 };
 

-- 
2.50.1



From bmasney at redhat.com  Sun Aug 10 15:45:36 2025
From: bmasney at redhat.com (Brian Masney)
Date: Sun, 10 Aug 2025 18:45:36 -0400
Subject: [PATCH v2 8/9] phy: rockchip: phy-rockchip-samsung-hdptx: convert
 from round_rate() to determine_rate()
In-Reply-To: <20250810-phy-clk-round-rate-v2-0-9162470bb9f2@redhat.com>
References: <20250810-phy-clk-round-rate-v2-0-9162470bb9f2@redhat.com>
Message-ID: <20250810-phy-clk-round-rate-v2-8-9162470bb9f2@redhat.com>

The round_rate() clk ops is deprecated, so migrate this driver from
round_rate() to determine_rate() using the Coccinelle semantic patch
on the cover letter of this series.

Signed-off-by: Brian Masney <bmasney at redhat.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index 79db57ee90d1487b51f4ddadde870a275dd7b17b..0d4e578c8c6a08aad355aa8aa5a1cf75c7d354ed 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -1869,8 +1869,8 @@ static unsigned long rk_hdptx_phy_clk_recalc_rate(struct clk_hw *hw,
 	return hdptx->hw_rate;
 }
 
-static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
-					unsigned long *parent_rate)
+static int rk_hdptx_phy_clk_determine_rate(struct clk_hw *hw,
+					   struct clk_rate_request *req)
 {
 	struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);
 
@@ -1879,9 +1879,9 @@ static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
 	 * To be dropped as soon as the RK DW HDMI QP bridge driver
 	 * switches to make use of phy_configure().
 	 */
-	if (!hdptx->restrict_rate_change && rate != hdptx->hdmi_cfg.tmds_char_rate) {
+	if (!hdptx->restrict_rate_change && req->rate != hdptx->hdmi_cfg.tmds_char_rate) {
 		struct phy_configure_opts_hdmi hdmi = {
-			.tmds_char_rate = rate,
+			.tmds_char_rate = req->rate,
 		};
 		int ret = rk_hdptx_phy_verify_hdmi_config(hdptx, &hdmi);
 
@@ -1896,7 +1896,9 @@ static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
 	 * hence ensure rk_hdptx_phy_clk_set_rate() won't be invoked with
 	 * a different rate argument.
 	 */
-	return hdptx->hdmi_cfg.tmds_char_rate;
+	req->rate = hdptx->hdmi_cfg.tmds_char_rate;
+
+	return 0;
 }
 
 static int rk_hdptx_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -1925,7 +1927,7 @@ static const struct clk_ops hdptx_phy_clk_ops = {
 	.prepare = rk_hdptx_phy_clk_prepare,
 	.unprepare = rk_hdptx_phy_clk_unprepare,
 	.recalc_rate = rk_hdptx_phy_clk_recalc_rate,
-	.round_rate = rk_hdptx_phy_clk_round_rate,
+	.determine_rate = rk_hdptx_phy_clk_determine_rate,
 	.set_rate = rk_hdptx_phy_clk_set_rate,
 };
 

-- 
2.50.1



From bmasney at redhat.com  Sun Aug 10 15:45:37 2025
From: bmasney at redhat.com (Brian Masney)
Date: Sun, 10 Aug 2025 18:45:37 -0400
Subject: [PATCH v2 9/9] phy: ti: phy-j721e-wiz: convert from round_rate()
 to determine_rate()
In-Reply-To: <20250810-phy-clk-round-rate-v2-0-9162470bb9f2@redhat.com>
References: <20250810-phy-clk-round-rate-v2-0-9162470bb9f2@redhat.com>
Message-ID: <20250810-phy-clk-round-rate-v2-9-9162470bb9f2@redhat.com>

The round_rate() clk ops is deprecated, so migrate this driver from
round_rate() to determine_rate() using the Coccinelle semantic patch
on the cover letter of this series.

Signed-off-by: Brian Masney <bmasney at redhat.com>
---
 drivers/phy/ti/phy-j721e-wiz.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c
index ab2a4f2c0a5bf3aa4b77045f4da8b0ddcc079f7a..12dafb2bd49bc33c13dd49246bc26df082e3dd40 100644
--- a/drivers/phy/ti/phy-j721e-wiz.c
+++ b/drivers/phy/ti/phy-j721e-wiz.c
@@ -934,12 +934,15 @@ static unsigned long wiz_clk_div_recalc_rate(struct clk_hw *hw,
 	return divider_recalc_rate(hw, parent_rate, val, div->table, 0x0, 2);
 }
 
-static long wiz_clk_div_round_rate(struct clk_hw *hw, unsigned long rate,
-				   unsigned long *prate)
+static int wiz_clk_div_determine_rate(struct clk_hw *hw,
+				      struct clk_rate_request *req)
 {
 	struct wiz_clk_divider *div = to_wiz_clk_div(hw);
 
-	return divider_round_rate(hw, rate, prate, div->table, 2, 0x0);
+	req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate,
+				       div->table, 2, 0x0);
+
+	return 0;
 }
 
 static int wiz_clk_div_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -958,7 +961,7 @@ static int wiz_clk_div_set_rate(struct clk_hw *hw, unsigned long rate,
 
 static const struct clk_ops wiz_clk_div_ops = {
 	.recalc_rate = wiz_clk_div_recalc_rate,
-	.round_rate = wiz_clk_div_round_rate,
+	.determine_rate = wiz_clk_div_determine_rate,
 	.set_rate = wiz_clk_div_set_rate,
 };
 

-- 
2.50.1



From ziyue.zhang at oss.qualcomm.com  Mon Aug 11 00:11:27 2025
From: ziyue.zhang at oss.qualcomm.com (Ziyue Zhang)
Date: Mon, 11 Aug 2025 15:11:27 +0800
Subject: [PATCH v10 1/5] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Update pcie phy bindings for qcs8300
In-Reply-To: <20250811071131.982983-1-ziyue.zhang@oss.qualcomm.com>
References: <20250811071131.982983-1-ziyue.zhang@oss.qualcomm.com>
Message-ID: <20250811071131.982983-2-ziyue.zhang@oss.qualcomm.com>

The gcc_aux_clk is not required by the PCIe PHY on qcs8300 and is not
specified in the device tree node. Hence, move the qcs8300 phy
compatibility entry into the list of PHYs that require six clocks.

Removed the phy_aux clock from the PCIe PHY binding as it is no longer
used by any instance.

Fixes: e46e59b77a9e ("dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Document the QCS8300 QMP PCIe PHY Gen4 x2")

Signed-off-by: Ziyue Zhang <ziyue.zhang at oss.qualcomm.com>
Acked-by: Rob Herring (Arm) <robh at kernel.org>
Reviewed-by: Johan Hovold <johan+linaro at kernel.org>
---
 .../phy/qcom,sc8280xp-qmp-pcie-phy.yaml         | 17 ++---------------
 1 file changed, 2 insertions(+), 15 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 b6f140bf5b3b..3379ce24bf33 100644
--- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
@@ -54,7 +54,7 @@ properties:
 
   clocks:
     minItems: 5
-    maxItems: 7
+    maxItems: 6
 
   clock-names:
     minItems: 5
@@ -65,7 +65,6 @@ properties:
       - enum: [rchng, refgen]
       - const: pipe
       - const: pipediv2
-      - const: phy_aux
 
   power-domains:
     maxItems: 1
@@ -176,6 +175,7 @@ allOf:
         compatible:
           contains:
             enum:
+              - qcom,qcs8300-qmp-gen4x2-pcie-phy
               - qcom,sa8775p-qmp-gen4x2-pcie-phy
               - qcom,sa8775p-qmp-gen4x4-pcie-phy
               - qcom,sc8280xp-qmp-gen3x1-pcie-phy
@@ -193,19 +193,6 @@ allOf:
         clock-names:
           minItems: 6
 
-  - if:
-      properties:
-        compatible:
-          contains:
-            enum:
-              - qcom,qcs8300-qmp-gen4x2-pcie-phy
-    then:
-      properties:
-        clocks:
-          minItems: 7
-        clock-names:
-          minItems: 7
-
   - if:
       properties:
         compatible:
-- 
2.43.0



From ziyue.zhang at oss.qualcomm.com  Mon Aug 11 00:11:31 2025
From: ziyue.zhang at oss.qualcomm.com (Ziyue Zhang)
Date: Mon, 11 Aug 2025 15:11:31 +0800
Subject: [PATCH v10 5/5] arm64: dts: qcom: qcs8300-ride: enable pcie1 interface
In-Reply-To: <20250811071131.982983-1-ziyue.zhang@oss.qualcomm.com>
References: <20250811071131.982983-1-ziyue.zhang@oss.qualcomm.com>
Message-ID: <20250811071131.982983-6-ziyue.zhang@oss.qualcomm.com>

Add configurations in devicetree for PCIe1, board related gpios,
PMIC regulators, etc for qcs8300-ride platform.

Reviewed-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
Signed-off-by: Ziyue Zhang <ziyue.zhang at oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/qcs8300-ride.dts | 40 +++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts
index e8e382db2b99..bec2905c5d8f 100644
--- a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts
+++ b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts
@@ -325,6 +325,23 @@ &pcie0_phy {
 	status = "okay";
 };
 
+&pcie1 {
+	perst-gpios = <&tlmm 23 GPIO_ACTIVE_LOW>;
+	wake-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>;
+
+	pinctrl-0 = <&pcie1_default_state>;
+	pinctrl-names = "default";
+
+	status = "okay";
+};
+
+&pcie1_phy {
+	vdda-phy-supply = <&vreg_l6a>;
+	vdda-pll-supply = <&vreg_l5a>;
+
+	status = "okay";
+};
+
 &qupv3_id_0 {
 	status = "okay";
 };
@@ -388,6 +405,29 @@ perst-pins {
 			bias-pull-down;
 		};
 	};
+
+   pcie1_default_state: pcie1-default-state {
+		wake-pins {
+			pins = "gpio21";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-up;
+		};
+
+		clkreq-pins {
+			pins = "gpio22";
+			function = "pcie1_clkreq";
+			drive-strength = <2>;
+			bias-pull-up;
+		};
+
+		perst-pins {
+			pins = "gpio23";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-down;
+		};
+	};
 };
 
 &uart7 {
-- 
2.43.0



From ziyue.zhang at oss.qualcomm.com  Mon Aug 11 00:11:30 2025
From: ziyue.zhang at oss.qualcomm.com (Ziyue Zhang)
Date: Mon, 11 Aug 2025 15:11:30 +0800
Subject: [PATCH v10 4/5] arm64: dts: qcom: qcs8300: enable pcie1
In-Reply-To: <20250811071131.982983-1-ziyue.zhang@oss.qualcomm.com>
References: <20250811071131.982983-1-ziyue.zhang@oss.qualcomm.com>
Message-ID: <20250811071131.982983-5-ziyue.zhang@oss.qualcomm.com>

Add configurations in devicetree for PCIe1, including registers, clocks,
interrupts and phy setting sequence.

Add PCIe lane equalization preset properties for 8 GT/s and 16GT/s.

Acked-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Ziyue Zhang <ziyue.zhang at oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/qcs8300.dtsi | 124 +++++++++++++++++++++++++-
 1 file changed, 123 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/qcs8300.dtsi b/arch/arm64/boot/dts/qcom/qcs8300.dtsi
index 7b7009567999..0dc536494ac7 100644
--- a/arch/arm64/boot/dts/qcom/qcs8300.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcs8300.dtsi
@@ -620,7 +620,7 @@ gcc: clock-controller at 100000 {
 			clocks = <&rpmhcc RPMH_CXO_CLK>,
 				 <&sleep_clk>,
 				 <&pcie0_phy>,
-				 <0>,
+				 <&pcie1_phy>,
 				 <0>,
 				 <0>,
 				 <0>,
@@ -2136,6 +2136,128 @@ pcie0_phy: phy at 1c04000 {
 			status = "disabled";
 		};
 
+		pcie1: pci at 1c10000 {
+			device_type = "pci";
+			compatible = "qcom,pcie-qcs8300", "qcom,pcie-sa8775p";
+			reg = <0x0 0x01c10000 0x0 0x3000>,
+			      <0x0 0x60000000 0x0 0xf20>,
+			      <0x0 0x60000f20 0x0 0xa8>,
+			      <0x0 0x60001000 0x0 0x4000>,
+			      <0x0 0x60100000 0x0 0x100000>,
+			      <0x0 0x01c13000 0x0 0x1000>;
+			reg-names = "parf",
+				    "dbi",
+				    "elbi",
+				    "atu",
+				    "config",
+				    "mhi";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			ranges = <0x01000000 0x0 0x00000000 0x0 0x60200000 0x0 0x100000>,
+				 <0x02000000 0x0 0x60300000 0x0 0x60300000 0x0 0x1fd00000>;
+			bus-range = <0x00 0xff>;
+
+			dma-coherent;
+
+			linux,pci-domain = <1>;
+			num-lanes = <4>;
+
+			interrupts = <GIC_SPI 519 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 518 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 GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 2 &intc GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 3 &intc GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 4 &intc GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
+
+			clocks = <&gcc GCC_PCIE_1_AUX_CLK>,
+				 <&gcc GCC_PCIE_1_CFG_AHB_CLK>,
+				 <&gcc GCC_PCIE_1_MSTR_AXI_CLK>,
+				 <&gcc GCC_PCIE_1_SLV_AXI_CLK>,
+				 <&gcc GCC_PCIE_1_SLV_Q2A_AXI_CLK>;
+			clock-names = "aux",
+				      "cfg",
+				      "bus_master",
+				      "bus_slave",
+				      "slave_q2a";
+
+			assigned-clocks = <&gcc GCC_PCIE_1_AUX_CLK>;
+			assigned-clock-rates = <19200000>;
+
+			interconnects = <&pcie_anoc MASTER_PCIE_1 QCOM_ICC_TAG_ALWAYS
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+					<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &config_noc SLAVE_PCIE_1 QCOM_ICC_TAG_ACTIVE_ONLY>;
+			interconnect-names = "pcie-mem", "cpu-pcie";
+
+			iommu-map = <0x0 &pcie_smmu 0x0080 0x1>,
+				    <0x100 &pcie_smmu 0x0081 0x1>;
+
+			resets = <&gcc GCC_PCIE_1_BCR>,
+				 <&gcc GCC_PCIE_1_LINK_DOWN_BCR>;
+			reset-names = "pci",
+				      "link_down";
+
+			power-domains = <&gcc GCC_PCIE_1_GDSC>;
+
+			phys = <&pcie1_phy>;
+			phy-names = "pciephy";
+
+			eq-presets-8gts = /bits/ 16 <0x5555 0x5555 0x5555 0x5555
+						     0x5555 0x5555 0x5555 0x5555>;
+			eq-presets-16gts = /bits/ 8 <0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x55>;
+
+			status = "disabled";
+		};
+
+		pcie1_phy: phy at 1c14000 {
+			compatible = "qcom,sa8775p-qmp-gen4x4-pcie-phy";
+			reg = <0x0 0x01c14000 0x0 0x4000>;
+
+			clocks = <&gcc GCC_PCIE_1_PHY_AUX_CLK>,
+				 <&gcc GCC_PCIE_1_CFG_AHB_CLK>,
+				 <&gcc GCC_PCIE_CLKREF_EN>,
+				 <&gcc GCC_PCIE_1_PHY_RCHNG_CLK>,
+				 <&gcc GCC_PCIE_1_PIPE_CLK>,
+				 <&gcc GCC_PCIE_1_PIPEDIV2_CLK>;
+			clock-names = "aux",
+				      "cfg_ahb",
+				      "ref",
+				      "rchng",
+				      "pipe",
+				      "pipediv2";
+
+			assigned-clocks = <&gcc GCC_PCIE_1_PHY_RCHNG_CLK>;
+			assigned-clock-rates = <100000000>;
+
+			resets = <&gcc GCC_PCIE_1_PHY_BCR>;
+			reset-names = "phy";
+
+			#clock-cells = <0>;
+			clock-output-names = "pcie_1_pipe_clk";
+
+			#phy-cells = <0>;
+
+			status = "disabled";
+		};
+
 		ufs_mem_hc: ufs at 1d84000 {
 			compatible = "qcom,qcs8300-ufshc", "qcom,ufshc", "jedec,ufs-2.0";
 			reg = <0x0 0x01d84000 0x0 0x3000>;
-- 
2.43.0



From ziyue.zhang at oss.qualcomm.com  Mon Aug 11 00:11:28 2025
From: ziyue.zhang at oss.qualcomm.com (Ziyue Zhang)
Date: Mon, 11 Aug 2025 15:11:28 +0800
Subject: [PATCH v10 2/5] arm64: dts: qcom: qcs8300: enable pcie0
In-Reply-To: <20250811071131.982983-1-ziyue.zhang@oss.qualcomm.com>
References: <20250811071131.982983-1-ziyue.zhang@oss.qualcomm.com>
Message-ID: <20250811071131.982983-3-ziyue.zhang@oss.qualcomm.com>

Add configurations in devicetree for PCIe0, including registers, clocks,
interrupts and phy setting sequence.

Add PCIe lane equalization preset properties for 8 GT/s and 16GT/s

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Reviewed-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
Signed-off-by: Ziyue Zhang <ziyue.zhang at oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/qcs8300.dtsi | 172 +++++++++++++++++++++++++-
 1 file changed, 171 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/qcs8300.dtsi b/arch/arm64/boot/dts/qcom/qcs8300.dtsi
index 7ada029c32c1..7b7009567999 100644
--- a/arch/arm64/boot/dts/qcom/qcs8300.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcs8300.dtsi
@@ -619,7 +619,7 @@ gcc: clock-controller at 100000 {
 			#power-domain-cells = <1>;
 			clocks = <&rpmhcc RPMH_CXO_CLK>,
 				 <&sleep_clk>,
-				 <0>,
+				 <&pcie0_phy>,
 				 <0>,
 				 <0>,
 				 <0>,
@@ -1966,6 +1966,176 @@ mmss_noc: interconnect at 17a0000 {
 			qcom,bcm-voters = <&apps_bcm_voter>;
 		};
 
+		pcie0: pci at 1c00000 {
+			device_type = "pci";
+			compatible = "qcom,pcie-qcs8300", "qcom,pcie-sa8775p";
+			reg = <0x0 0x01c00000 0x0 0x3000>,
+			      <0x0 0x40000000 0x0 0xf20>,
+			      <0x0 0x40000f20 0x0 0xa8>,
+			      <0x0 0x40001000 0x0 0x4000>,
+			      <0x0 0x40100000 0x0 0x100000>,
+			      <0x0 0x01c03000 0x0 0x1000>;
+			reg-names = "parf",
+				    "dbi",
+				    "elbi",
+				    "atu",
+				    "config",
+				    "mhi";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			ranges = <0x01000000 0x0 0x00000000 0x0 0x40200000 0x0 0x100000>,
+				 <0x02000000 0x0 0x40300000 0x0 0x40300000 0x0 0x1fd00000>;
+			bus-range = <0x00 0xff>;
+
+			dma-coherent;
+
+			linux,pci-domain = <0>;
+			num-lanes = <2>;
+
+			interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 306 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 GIC_SPI 434 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 2 &intc GIC_SPI 435 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 3 &intc GIC_SPI 438 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 4 &intc GIC_SPI 439 IRQ_TYPE_LEVEL_HIGH>;
+
+			clocks = <&gcc GCC_PCIE_0_AUX_CLK>,
+				 <&gcc GCC_PCIE_0_CFG_AHB_CLK>,
+				 <&gcc GCC_PCIE_0_MSTR_AXI_CLK>,
+				 <&gcc GCC_PCIE_0_SLV_AXI_CLK>,
+				 <&gcc GCC_PCIE_0_SLV_Q2A_AXI_CLK>;
+			clock-names = "aux",
+				      "cfg",
+				      "bus_master",
+				      "bus_slave",
+				      "slave_q2a";
+
+			assigned-clocks = <&gcc GCC_PCIE_0_AUX_CLK>;
+			assigned-clock-rates = <19200000>;
+
+			interconnects = <&pcie_anoc MASTER_PCIE_0 QCOM_ICC_TAG_ALWAYS
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+					<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &config_noc SLAVE_PCIE_0 QCOM_ICC_TAG_ACTIVE_ONLY>;
+			interconnect-names = "pcie-mem",
+					     "cpu-pcie";
+
+			iommu-map = <0x0 &pcie_smmu 0x0000 0x1>,
+				    <0x100 &pcie_smmu 0x0001 0x1>;
+
+			resets = <&gcc GCC_PCIE_0_BCR>,
+				 <&gcc GCC_PCIE_0_LINK_DOWN_BCR>;
+			reset-names = "pci",
+				      "link_down";
+
+			power-domains = <&gcc GCC_PCIE_0_GDSC>;
+
+			phys = <&pcie0_phy>;
+			phy-names = "pciephy";
+
+			eq-presets-8gts = /bits/ 16 <0x5555 0x5555 0x5555 0x5555
+						     0x5555 0x5555 0x5555 0x5555>;
+			eq-presets-16gts = /bits/ 8 <0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x55>;
+
+			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_svs_l1>;
+					opp-peak-kBps = <250000 1>;
+				};
+
+				/* GEN 1 x2 and GEN 2 x1 */
+				opp-5000000 {
+					opp-hz = /bits/ 64 <5000000>;
+					required-opps = <&rpmhpd_opp_svs_l1>;
+					opp-peak-kBps = <500000 1>;
+				};
+
+				/* GEN 2 x2 */
+				opp-10000000 {
+					opp-hz = /bits/ 64 <10000000>;
+					required-opps = <&rpmhpd_opp_svs_l1>;
+					opp-peak-kBps = <1000000 1>;
+				};
+
+				/* GEN 3 x1 */
+				opp-8000000 {
+					opp-hz = /bits/ 64 <8000000>;
+					required-opps = <&rpmhpd_opp_svs_l1>;
+					opp-peak-kBps = <984500 1>;
+				};
+
+				/* GEN 3 x2 and GEN 4 x1 */
+				opp-16000000 {
+					opp-hz = /bits/ 64 <16000000>;
+					required-opps = <&rpmhpd_opp_nom>;
+					opp-peak-kBps = <1969000 1>;
+				};
+
+				/* GEN 4 x2 */
+				opp-32000000 {
+					opp-hz = /bits/ 64 <32000000>;
+					required-opps = <&rpmhpd_opp_nom>;
+					opp-peak-kBps = <3938000 1>;
+				};
+			};
+		};
+
+		pcie0_phy: phy at 1c04000 {
+			compatible = "qcom,qcs8300-qmp-gen4x2-pcie-phy";
+			reg = <0x0 0x01c04000 0x0 0x2000>;
+
+			clocks = <&gcc GCC_PCIE_0_PHY_AUX_CLK>,
+				 <&gcc GCC_PCIE_0_CFG_AHB_CLK>,
+				 <&gcc GCC_PCIE_CLKREF_EN>,
+				 <&gcc GCC_PCIE_0_PHY_RCHNG_CLK>,
+				 <&gcc GCC_PCIE_0_PIPE_CLK>,
+				 <&gcc GCC_PCIE_0_PIPEDIV2_CLK>;
+			clock-names = "aux",
+				      "cfg_ahb",
+				      "ref",
+				      "rchng",
+				      "pipe",
+				      "pipediv2";
+
+			resets = <&gcc GCC_PCIE_0_PHY_BCR>;
+			reset-names = "phy";
+
+			assigned-clocks = <&gcc GCC_PCIE_0_PHY_RCHNG_CLK>;
+			assigned-clock-rates = <100000000>;
+
+			#clock-cells = <0>;
+			clock-output-names = "pcie_0_pipe_clk";
+
+			#phy-cells = <0>;
+
+			status = "disabled";
+		};
+
 		ufs_mem_hc: ufs at 1d84000 {
 			compatible = "qcom,qcs8300-ufshc", "qcom,ufshc", "jedec,ufs-2.0";
 			reg = <0x0 0x01d84000 0x0 0x3000>;
-- 
2.43.0



From ziyue.zhang at oss.qualcomm.com  Mon Aug 11 00:11:29 2025
From: ziyue.zhang at oss.qualcomm.com (Ziyue Zhang)
Date: Mon, 11 Aug 2025 15:11:29 +0800
Subject: [PATCH v10 3/5] arm64: dts: qcom: qcs8300-ride: enable pcie0 interface
In-Reply-To: <20250811071131.982983-1-ziyue.zhang@oss.qualcomm.com>
References: <20250811071131.982983-1-ziyue.zhang@oss.qualcomm.com>
Message-ID: <20250811071131.982983-4-ziyue.zhang@oss.qualcomm.com>

Add configurations in devicetree for PCIe0, board related gpios,
PMIC regulators, etc for qcs8300-ride board.

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Reviewed-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
Signed-off-by: Ziyue Zhang <ziyue.zhang at oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/qcs8300-ride.dts | 40 +++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts
index 8c166ead912c..e8e382db2b99 100644
--- a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts
+++ b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts
@@ -308,6 +308,23 @@ &iris {
 	status = "okay";
 };
 
+&pcie0 {
+	perst-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>;
+	wake-gpios = <&tlmm 0 GPIO_ACTIVE_HIGH>;
+
+	pinctrl-0 = <&pcie0_default_state>;
+	pinctrl-names = "default";
+
+	status = "okay";
+};
+
+&pcie0_phy {
+	vdda-phy-supply = <&vreg_l6a>;
+	vdda-pll-supply = <&vreg_l5a>;
+
+	status = "okay";
+};
+
 &qupv3_id_0 {
 	status = "okay";
 };
@@ -348,6 +365,29 @@ ethernet0_mdio: ethernet0-mdio-pins {
 			bias-pull-up;
 		};
 	};
+
+	pcie0_default_state: pcie0-default-state {
+		wake-pins {
+			pins = "gpio0";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-up;
+		};
+
+		clkreq-pins {
+			pins = "gpio1";
+			function = "pcie0_clkreq";
+			drive-strength = <2>;
+			bias-pull-up;
+		};
+
+		perst-pins {
+			pins = "gpio2";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-down;
+		};
+	};
 };
 
 &uart7 {
-- 
2.43.0



From ziyue.zhang at oss.qualcomm.com  Mon Aug 11 00:11:26 2025
From: ziyue.zhang at oss.qualcomm.com (Ziyue Zhang)
Date: Mon, 11 Aug 2025 15:11:26 +0800
Subject: [PATCH v10 0/5] pci: qcom: Add QCS8300 PCIe support
Message-ID: <20250811071131.982983-1-ziyue.zhang@oss.qualcomm.com>

This series depend on the sa8775p gcc_aux_clock and link_down reset change
https://lore.kernel.org/all/20250725102231.3608298-2-ziyue.zhang at oss.qualcomm.com/

This series adds document, phy, configs support for PCIe in QCS8300.
It also adds 'link_down' reset for sa8775p.

Have follwing changes:
	- Add dedicated schema for the PCIe controllers found on QCS8300.
	- Add compatible for qcs8300 platform.
	- Add configurations in devicetree for PCIe0, including registers, clocks, interrupts and phy setting sequence.
	- Add configurations in devicetree for PCIe1, including registers, clocks, interrupts and phy setting sequence.

Signed-off-by: Krishna chaitanya chundru <quic_krichai at quicinc.com>
Signed-off-by: Ziyue Zhang <quic_ziyuzhan at quicinc.com>
---
Changes in v10:
- Update PHY max_items (Johan)
- Link to v9: https://lore.kernel.org/all/20250725104037.4054070-1-ziyue.zhang at oss.qualcomm.com/

Changes in v9:
- Fix DTB error (Vinod)
- Link to v8: https://lore.kernel.org/all/20250714081529.3847385-1-ziyue.zhang at oss.qualcomm.com/

Changes in v8:
- rebase sc8280xp-qmp-pcie-phy change to solve conflicts.
- Add Fixes tag to phy change (Johan)
- Link to v7: https://lore.kernel.org/all/20250625092539.762075-1-quic_ziyuzhan at quicinc.com/

Changes in v7:
- rebase qcs8300-ride.dtsi change to solve conflicts.
- Link to v6: https://lore.kernel.org/all/20250529035635.4162149-1-quic_ziyuzhan at quicinc.com/

Changes in v6:
- move the qcs8300 and sa8775p phy compatibility entry into the list of PHYs that require six clocks
- Update QCS8300 and sa8775p phy dt, remove aux clock.
- Fixed compile error found by kernel test robot
- Link to v5: https://lore.kernel.org/all/20250507031019.4080541-1-quic_ziyuzhan at quicinc.com/

Changes in v5:
- Add QCOM PCIe controller version in commit msg (Mani)
- Modify platform dts change subject (Dmitry)
- Fixed compile error found by kernel test robot
- Link to v4: https://lore.kernel.org/linux-phy/20241220055239.2744024-1-quic_ziyuzhan at quicinc.com/

Changes in v4:
- Add received tag
- Fixed compile error found by kernel test robot
- Link to v3: https://lore.kernel.org/lkml/202412211301.bQO6vXpo-lkp at intel.com/T/#mdd63e5be39acbf879218aef91c87b12d4540e0f7

Changes in v3:
- Add received tag(Rob & Dmitry)
- Update pcie_phy in gcc node to soc dtsi(Dmitry & Konrad)
- remove pcieprot0 node(Konrad & Mani)
- Fix format comments(Konrad)
- Update base-commit to tag: next-20241213(Bjorn)
- Corrected of_device_id.data from 1.9.0 to 1.34.0.
- Link to v2: https://lore.kernel.org/all/20241128081056.1361739-1-quic_ziyuzhan at quicinc.com/

Changes in v2:
- Fix some format comments and match the style in x1e80100(Konrad)
- Add global interrupt for PCIe0 and PCIe1(Konrad)
- split the soc dtsi and the platform dts into two changes(Konrad)
- Link to v1: https://lore.kernel.org/all/20241114095409.2682558-1-quic_ziyuzhan at quicinc.com/

Ziyue Zhang (5):
  dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Update pcie phy bindings
    for qcs8300
  arm64: dts: qcom: qcs8300: enable pcie0
  arm64: dts: qcom: qcs8300-ride: enable pcie0 interface
  arm64: dts: qcom: qcs8300: enable pcie1
  arm64: dts: qcom: qcs8300-ride: enable pcie1 interface

 .../phy/qcom,sc8280xp-qmp-pcie-phy.yaml       |  17 +-
 arch/arm64/boot/dts/qcom/qcs8300-ride.dts     |  80 +++++
 arch/arm64/boot/dts/qcom/qcs8300.dtsi         | 296 +++++++++++++++++-
 3 files changed, 376 insertions(+), 17 deletions(-)


base-commit: e2622a23e8405644c7188af39d4c1bd2b405bb27
-- 
2.43.0



From ziyue.zhang at oss.qualcomm.com  Mon Aug 11 00:30:08 2025
From: ziyue.zhang at oss.qualcomm.com (Ziyue Zhang)
Date: Mon, 11 Aug 2025 15:30:08 +0800
Subject: [PATCH v9 0/2] pci: qcom: Add QCS615 PCIe support
In-Reply-To: <20250725112346.614316-1-ziyue.zhang@oss.qualcomm.com>
References: <20250725112346.614316-1-ziyue.zhang@oss.qualcomm.com>
Message-ID: <e9e77527-202c-411e-add2-2af9d82b8e8d@oss.qualcomm.com>


On 7/25/2025 7:23 PM, Ziyue Zhang wrote:
> This series adds document, phy, configs support for PCIe in QCS615.
>
> This series depend on the dt-bindings change
> https://lore.kernel.org/all/20250521-topic-8150_pcie_drop_clocks-v1-0-3d42e84f6453 at oss.qualcomm.com/
>
> Signed-off-by: Krishna chaitanya chundru <quic_krichai at quicinc.com>
> Signed-off-by: Ziyue Zhang <ziyue.zhang at oss.qualcomm.com>
> ---
> Have following changes:
> 	- Add a new Document the QCS615 PCIe Controller
> 	- Add configurations in devicetree for PCIe, including registers, clocks, interrupts and phy setting sequence.
> 	- Add configurations in devicetree for PCIe, platform related gpios, PMIC regulators, etc.
>
> Changes in v9:
> - Patch rebased
> - Link to v8: https://lore.kernel.org/all/20250703095630.669044-1-ziyue.zhang at oss.qualcomm.com/
>
> Changes in v8:
> - Fix scripts/checkpatch.pl error (Krzystof)
> - Link to v7: https://lore.kernel.org/all/20250702103549.712039-1-ziyue.zhang at oss.qualcomm.com/
>
> Changes in v7:
> - Add Fixes tag to phy bindings patch (Johan)
> - QCS615 is Gen3 controller but Gen2 phy, so limited max link speed to Gen2.
> - Remove eq-presets-8gts and oppopp-8000000 for only support Gen2.
> - Link to v6: https://lore.kernel.org/all/t6bwkld55a2dcozxz7rxnvdgpjis6oveqzkh4s7nvxgikws4rl at fn2sd7zlabhe/
>
> Changes in v6:
> - Change PCIe equalization setting to one lane
> - Add reviewed by tags
> - Link to v5: https://lore.kernel.org/all/t6bwkld55a2dcozxz7rxnvdgpjis6oveqzkh4s7nvxgikws4rl at fn2sd7zlabhe/
>
> Changes in v5:
> - Drop qcs615-pcie.yaml and use sm8150, as qcs615 is the downgraded
>    version of sm8150, which can share the same yaml.
> - Drop compatible enrty in driver and use sm8150's enrty (Krzysztof)
> - Fix the DT format problem (Konrad)
> - Link to v4: https://lore.kernel.org/all/20250507031559.4085159-1-quic_ziyuzhan at quicinc.com/
>
> Changes in v4:
> - Fixed compile error found by kernel test robot(Krzysztof)
> - Update DT format (Konrad & Krzysztof)
> - Remove QCS8550 compatible use QCS615 compatible only (Konrad)
> - Update phy dt bindings to fix the dtb check errors.
> - Link to v3: https://lore.kernel.org/all/20250310065613.151598-1-quic_ziyuzhan at quicinc.com/
>
> Changes in v3:
> - Update qcs615 dt-bindings to fit the qcom-soc.yaml (Krzysztof & Dmitry)
> - Removed the driver patch and using fallback method (Mani)
> - Update DT format, keep it same with the x1e801000.dtsi (Konrad)
> - Update DT commit message (Bojor)
> - Link to v2: https://lore.kernel.org/all/20241122023314.1616353-1-quic_ziyuzhan at quicinc.com/
>
> Changes in v2:
> - Update commit message for qcs615 phy
> - Update qcs615 phy, using lowercase hex
> - Removed redundant function
> - split the soc dtsi and the platform dts into two changes
> - Link to v1: https://lore.kernel.org/all/20241118082619.177201-1-quic_ziyuzhan at quicinc.com/
>
>
> Krishna chaitanya chundru (2):
>    arm64: dts: qcom: qcs615: enable pcie
>    arm64: dts: qcom: qcs615-ride: Enable PCIe interface
>
>   arch/arm64/boot/dts/qcom/qcs615-ride.dts |  42 +++++++
>   arch/arm64/boot/dts/qcom/sm6150.dtsi     | 138 +++++++++++++++++++++++
>   2 files changed, 180 insertions(+)
>
>
> base-commit: d7af19298454ed155f5cf67201a70f5cf836c842
Hi Maintainers,

It seems the patches get reviewed tag for a long time, can you give this

series further comment or help me to merge them ?
Thanks very much.

BRs
Ziyue


From neil.armstrong at linaro.org  Mon Aug 11 00:40:06 2025
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Mon, 11 Aug 2025 09:40:06 +0200
Subject: [PATCH v4 2/6] phy: qcom: qmp-combo: Rename 'mode' to 'phy_mode'
In-Reply-To: <20250807-topic-4ln_dp_respin-v4-2-43272d6eca92@oss.qualcomm.com>
References: <20250807-topic-4ln_dp_respin-v4-0-43272d6eca92@oss.qualcomm.com>
 <20250807-topic-4ln_dp_respin-v4-2-43272d6eca92@oss.qualcomm.com>
Message-ID: <9f2bdd43-da4c-47b2-bba5-d69bc0b06ac7@linaro.org>

On 07/08/2025 18:33, Konrad Dybcio wrote:
> From: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
> 
> There are a numbers of ""modes"" involved: USB mode, Type-C mode (with
> its altmodes), phy_mode and QMP_PHY mode (DP/combo/USB/off).
> 
> Rename the generic sounding 'mode' to 'phy_mode' to hopefully make
> the code easier to follow.
> 
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>
> Signed-off-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
> ---
>   drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 12 ++++++------
>   1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
> index f07d097b129fb7b3fad003103b7468b16c1c4390..30749943f66280c3aa9e9673466f6f736d1adbc8 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
> @@ -1846,7 +1846,7 @@ struct qmp_combo {
>   	int init_count;
>   
>   	struct phy *usb_phy;
> -	enum phy_mode mode;
> +	enum phy_mode phy_mode;
>   	unsigned int usb_init_count;
>   
>   	struct phy *dp_phy;
> @@ -3282,7 +3282,7 @@ static int qmp_combo_usb_set_mode(struct phy *phy, enum phy_mode mode, int submo
>   {
>   	struct qmp_combo *qmp = phy_get_drvdata(phy);
>   
> -	qmp->mode = mode;
> +	qmp->phy_mode = mode;
>   
>   	return 0;
>   }
> @@ -3311,8 +3311,8 @@ static void qmp_combo_enable_autonomous_mode(struct qmp_combo *qmp)
>   	void __iomem *pcs_misc = qmp->pcs_misc;
>   	u32 intr_mask;
>   
> -	if (qmp->mode == PHY_MODE_USB_HOST_SS ||
> -	    qmp->mode == PHY_MODE_USB_DEVICE_SS)
> +	if (qmp->phy_mode == PHY_MODE_USB_HOST_SS ||
> +	    qmp->phy_mode == PHY_MODE_USB_DEVICE_SS)
>   		intr_mask = ARCVR_DTCT_EN | ALFPS_DTCT_EN;
>   	else
>   		intr_mask = ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL;
> @@ -3355,7 +3355,7 @@ static int __maybe_unused qmp_combo_runtime_suspend(struct device *dev)
>   {
>   	struct qmp_combo *qmp = dev_get_drvdata(dev);
>   
> -	dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->mode);
> +	dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->phy_mode);
>   
>   	if (!qmp->init_count) {
>   		dev_vdbg(dev, "PHY not initialized, bailing out\n");
> @@ -3375,7 +3375,7 @@ static int __maybe_unused qmp_combo_runtime_resume(struct device *dev)
>   	struct qmp_combo *qmp = dev_get_drvdata(dev);
>   	int ret = 0;
>   
> -	dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qmp->mode);
> +	dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qmp->phy_mode);
>   
>   	if (!qmp->init_count) {
>   		dev_vdbg(dev, "PHY not initialized, bailing out\n");
> 

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From konrad.dybcio at oss.qualcomm.com  Mon Aug 11 03:37:00 2025
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Mon, 11 Aug 2025 12:37:00 +0200
Subject: [PATCH v4 5/6] phy: qcom: qmp-combo: register a typec mux to
 change the QMPPHY_MODE
In-Reply-To: <ibrupwvn5frzb4vo3eukb7p7pzonaxwhygshz743wmyrbprkcq@xcpt4ryzvwqr>
References: <20250807-topic-4ln_dp_respin-v4-0-43272d6eca92@oss.qualcomm.com>
 <20250807-topic-4ln_dp_respin-v4-5-43272d6eca92@oss.qualcomm.com>
 <ibrupwvn5frzb4vo3eukb7p7pzonaxwhygshz743wmyrbprkcq@xcpt4ryzvwqr>
Message-ID: <619efc83-37f3-4b4e-b756-c53ecd2f6867@oss.qualcomm.com>

On 8/9/25 10:13 AM, Dmitry Baryshkov wrote:
> On Thu, Aug 07, 2025 at 06:33:23PM +0200, Konrad Dybcio wrote:
>> From: Neil Armstrong <neil.armstrong at linaro.org>
>>
>> Register a typec mux in order to change the PHY mode on the Type-C
>> mux events depending on the mode and the svid when in Altmode setup.
>>
>> The DisplayPort phy should be left enabled if is still powered on
>> by the DRM DisplayPort controller, so bail out until the DisplayPort
>> PHY is not powered off.
>>
>> The Type-C Mode/SVID only changes on plug/unplug, and USB SAFE states
>> will be set in between of USB-Only, Combo and DisplayPort Only so
>> this will leave enough time to the DRM DisplayPort controller to
>> turn of the DisplayPort PHY.
>>
>> Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
>> [konrad: renaming, rewording, bug fixes]
>> Signed-off-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
>> ---
>>  drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 118 ++++++++++++++++++++++++++++--
>>  1 file changed, 113 insertions(+), 5 deletions(-)
>>
>> +
>> +	if (qmp->qmpphy_mode != QMPPHY_MODE_USB3_ONLY && qmp->dp_powered_on) {
>> +		dev_dbg(qmp->dev, "typec_mux_set: DP PHY is still in use, delaying switch\n");
>> +		return 0;
>> +	}
> 
> I can't say that I'm fully happy about it, nevertheless:
> 
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>

IIUC we'll be able to get rid of it after the dp rework?

Konrad


From dmitry.baryshkov at oss.qualcomm.com  Mon Aug 11 03:55:47 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Mon, 11 Aug 2025 13:55:47 +0300
Subject: [PATCH v4 5/6] phy: qcom: qmp-combo: register a typec mux to
 change the QMPPHY_MODE
In-Reply-To: <619efc83-37f3-4b4e-b756-c53ecd2f6867@oss.qualcomm.com>
References: <20250807-topic-4ln_dp_respin-v4-0-43272d6eca92@oss.qualcomm.com>
 <20250807-topic-4ln_dp_respin-v4-5-43272d6eca92@oss.qualcomm.com>
 <ibrupwvn5frzb4vo3eukb7p7pzonaxwhygshz743wmyrbprkcq@xcpt4ryzvwqr>
 <619efc83-37f3-4b4e-b756-c53ecd2f6867@oss.qualcomm.com>
Message-ID: <y4yiyokoo7fclwlpyhct4o7mt6swustuciigqnte5pruust26q@ryvuwpd6h4qm>

On Mon, Aug 11, 2025 at 12:37:00PM +0200, Konrad Dybcio wrote:
> On 8/9/25 10:13 AM, Dmitry Baryshkov wrote:
> > On Thu, Aug 07, 2025 at 06:33:23PM +0200, Konrad Dybcio wrote:
> >> From: Neil Armstrong <neil.armstrong at linaro.org>
> >>
> >> Register a typec mux in order to change the PHY mode on the Type-C
> >> mux events depending on the mode and the svid when in Altmode setup.
> >>
> >> The DisplayPort phy should be left enabled if is still powered on
> >> by the DRM DisplayPort controller, so bail out until the DisplayPort
> >> PHY is not powered off.
> >>
> >> The Type-C Mode/SVID only changes on plug/unplug, and USB SAFE states
> >> will be set in between of USB-Only, Combo and DisplayPort Only so
> >> this will leave enough time to the DRM DisplayPort controller to
> >> turn of the DisplayPort PHY.
> >>
> >> Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
> >> [konrad: renaming, rewording, bug fixes]
> >> Signed-off-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
> >> ---
> >>  drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 118 ++++++++++++++++++++++++++++--
> >>  1 file changed, 113 insertions(+), 5 deletions(-)
> >>
> >> +
> >> +	if (qmp->qmpphy_mode != QMPPHY_MODE_USB3_ONLY && qmp->dp_powered_on) {
> >> +		dev_dbg(qmp->dev, "typec_mux_set: DP PHY is still in use, delaying switch\n");
> >> +		return 0;
> >> +	}
> > 
> > I can't say that I'm fully happy about it, nevertheless:
> > 
> > Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>
> 
> IIUC we'll be able to get rid of it after the dp rework?

Which one? The HPD? not really. My unhappiness is about the sync between
USB and DP. I'm unsure whether we need higher level of sync for
USB-or-DP PHYs.

-- 
With best wishes
Dmitry


From dmitry.baryshkov at oss.qualcomm.com  Mon Aug 11 03:58:52 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Mon, 11 Aug 2025 13:58:52 +0300
Subject: [PATCH 2/4] phy: qcom-qmp-pcie: add dual lane PHY support for
 SM8750
In-Reply-To: <20250809-pakala-v1-2-abf1c416dbaa@oss.qualcomm.com>
References: <20250809-pakala-v1-0-abf1c416dbaa@oss.qualcomm.com>
 <20250809-pakala-v1-2-abf1c416dbaa@oss.qualcomm.com>
Message-ID: <mjg63cvby3jtosoiswqg2kjxlubavyz5o27asthjazg2z2x6gj@3u4gywclkg3r>

On Sat, Aug 09, 2025 at 03:29:17PM +0530, Krishna Chaitanya Chundru wrote:
> The PCIe Gen3 x2 PHY for SM8750 uses new phy, add the
> required registers and offsets for this phy.
> 
> Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-pcie.c           | 149 +++++++++++++++++++++
>  drivers/phy/qualcomm/phy-qcom-qmp-pcs-v7.h         |   2 +
>  .../phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v7.h    |   4 +-
>  3 files changed, 154 insertions(+), 1 deletion(-)
> 

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>


-- 
With best wishes
Dmitry


From krzk at kernel.org  Mon Aug 11 04:08:55 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 11 Aug 2025 13:08:55 +0200
Subject: [PATCH 4/4] arm64: dts: qcom: sm8750: Add PCIe PHY and controller
 node
In-Reply-To: <20250809-pakala-v1-4-abf1c416dbaa@oss.qualcomm.com>
References: <20250809-pakala-v1-0-abf1c416dbaa@oss.qualcomm.com>
 <20250809-pakala-v1-4-abf1c416dbaa@oss.qualcomm.com>
Message-ID: <78c678c2-5f81-4e9b-88c4-365905f85702@kernel.org>

On 09/08/2025 11:59, Krishna Chaitanya Chundru wrote:
> Add PCIe controller and PHY nodes which supports data rates of 8GT/s
> and x2 lane.
> 
> Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
> ---
>  arch/arm64/boot/dts/qcom/sm8750.dtsi | 174 ++++++++++++++++++++++++++++++++++-
>  1 file changed, 173 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/qcom/sm8750.dtsi b/arch/arm64/boot/dts/qcom/sm8750.dtsi
> index 4643705021c6ca095a16d8d7cc3adac920b21e82..866c1eb8729953f6cb27c7cf995a1a8d55140e40 100644
> --- a/arch/arm64/boot/dts/qcom/sm8750.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sm8750.dtsi
> @@ -631,7 +631,7 @@ gcc: clock-controller at 100000 {
>  			clocks = <&bi_tcxo_div2>,
>  				 <0>,
>  				 <&sleep_clk>,
> -				 <0>,
> +				 <&pcie0_phy>,
>  				 <0>,
>  				 <0>,
>  				 <0>,
> @@ -3304,6 +3304,178 @@ gic_its: msi-controller at 16040000 {
>  			};
>  		};
>  
> +		pcie0: pcie at 1c00000 {
> +			device_type = "pci";
> +			compatible = "qcom,pcie-sm8750", "qcom,pcie-sm8550";
> +			reg = <0 0x01c00000 0 0x3000>,
> +			      <0 0x40000000 0 0xf1d>,
> +			      <0 0x40000f20 0 0xa8>,
> +			      <0 0x40001000 0 0x1000>,
> +			      <0 0x40100000 0 0x100000>;


Look at rest of the code - it's hex everywhere. Keep consistent style.

Best regards,
Krzysztof


From konrad.dybcio at oss.qualcomm.com  Mon Aug 11 04:12:59 2025
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Mon, 11 Aug 2025 13:12:59 +0200
Subject: [PATCH v4 5/6] phy: qcom: qmp-combo: register a typec mux to
 change the QMPPHY_MODE
In-Reply-To: <y4yiyokoo7fclwlpyhct4o7mt6swustuciigqnte5pruust26q@ryvuwpd6h4qm>
References: <20250807-topic-4ln_dp_respin-v4-0-43272d6eca92@oss.qualcomm.com>
 <20250807-topic-4ln_dp_respin-v4-5-43272d6eca92@oss.qualcomm.com>
 <ibrupwvn5frzb4vo3eukb7p7pzonaxwhygshz743wmyrbprkcq@xcpt4ryzvwqr>
 <619efc83-37f3-4b4e-b756-c53ecd2f6867@oss.qualcomm.com>
 <y4yiyokoo7fclwlpyhct4o7mt6swustuciigqnte5pruust26q@ryvuwpd6h4qm>
Message-ID: <4f6a7dc5-b0f8-491b-aa12-78be5f47ef2b@oss.qualcomm.com>

On 8/11/25 12:55 PM, Dmitry Baryshkov wrote:
> On Mon, Aug 11, 2025 at 12:37:00PM +0200, Konrad Dybcio wrote:
>> On 8/9/25 10:13 AM, Dmitry Baryshkov wrote:
>>> On Thu, Aug 07, 2025 at 06:33:23PM +0200, Konrad Dybcio wrote:
>>>> From: Neil Armstrong <neil.armstrong at linaro.org>
>>>>
>>>> Register a typec mux in order to change the PHY mode on the Type-C
>>>> mux events depending on the mode and the svid when in Altmode setup.
>>>>
>>>> The DisplayPort phy should be left enabled if is still powered on
>>>> by the DRM DisplayPort controller, so bail out until the DisplayPort
>>>> PHY is not powered off.
>>>>
>>>> The Type-C Mode/SVID only changes on plug/unplug, and USB SAFE states
>>>> will be set in between of USB-Only, Combo and DisplayPort Only so
>>>> this will leave enough time to the DRM DisplayPort controller to
>>>> turn of the DisplayPort PHY.
>>>>
>>>> Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
>>>> [konrad: renaming, rewording, bug fixes]
>>>> Signed-off-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
>>>> ---
>>>>  drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 118 ++++++++++++++++++++++++++++--
>>>>  1 file changed, 113 insertions(+), 5 deletions(-)
>>>>
>>>> +
>>>> +	if (qmp->qmpphy_mode != QMPPHY_MODE_USB3_ONLY && qmp->dp_powered_on) {
>>>> +		dev_dbg(qmp->dev, "typec_mux_set: DP PHY is still in use, delaying switch\n");
>>>> +		return 0;
>>>> +	}
>>>
>>> I can't say that I'm fully happy about it, nevertheless:
>>>
>>> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>
>>
>> IIUC we'll be able to get rid of it after the dp rework?
> 
> Which one? The HPD? not really. My unhappiness is about the sync between
> USB and DP. I'm unsure whether we need higher level of sync for
> USB-or-DP PHYs.

Unfortunately it'll only get worse with usb4, where the DP PLL may
need to be online (or not) for when we're tunneling DP data :(

Konrad



From konrad.dybcio at oss.qualcomm.com  Mon Aug 11 04:14:33 2025
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Mon, 11 Aug 2025 13:14:33 +0200
Subject: [PATCH 4/4] arm64: dts: qcom: sm8750: Add PCIe PHY and controller
 node
In-Reply-To: <20250809-pakala-v1-4-abf1c416dbaa@oss.qualcomm.com>
References: <20250809-pakala-v1-0-abf1c416dbaa@oss.qualcomm.com>
 <20250809-pakala-v1-4-abf1c416dbaa@oss.qualcomm.com>
Message-ID: <a6dbfe06-00bc-4fb0-9496-fb7ca849f832@oss.qualcomm.com>

On 8/9/25 11:59 AM, Krishna Chaitanya Chundru wrote:
> Add PCIe controller and PHY nodes which supports data rates of 8GT/s
> and x2 lane.
> 
> Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
> ---

[...]

> +			phys = <&pcie0_phy>;
> +			phy-names = "pciephy";
> +
> +			#address-cells = <3>;
> +			#size-cells = <2>;
> +			ranges = <0x01000000 0 0x00000000 0 0x40200000 0 0x100000>,
> +				 <0x02000000 0 0x60300000 0 0x40300000 0 0x3d00000>;

The BAR space is larger (0x2400_0000)

please align the overall node style with x1e80100.dtsi

Konrad


From geert at linux-m68k.org  Mon Aug 11 06:33:51 2025
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Mon, 11 Aug 2025 15:33:51 +0200
Subject: [PATCH v2 1/5] dt-bindings: phy: renesas,usb2-phy: Add RZ/T2H and
 RZ/N2H support
In-Reply-To: <20250808215209.3692744-2-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20250808215209.3692744-1-prabhakar.mahadev-lad.rj@bp.renesas.com> <20250808215209.3692744-2-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <CAMuHMdUWo=hYPWPrweoYn5rFC50aV5EV1xqwFHmLp27GRjEADw@mail.gmail.com>

Hi Prabhakar,

On Fri, 8 Aug 2025 at 23:52, Prabhakar <prabhakar.csengg at gmail.com> wrote:
> From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
>
> Document the USB2 PHY controller for the Renesas RZ/T2H (r9a09g077) and
> RZ/N2H (r9a09g087) SoCs. These SoCs share the same PHY block, which is
> similar to the one on RZ/G2L but differs in clocks, resets, and register
> bits. To account for these differences, a new compatible string
> `renesas,usb2-phy-r9a09g077` is introduced.
>
> The RZ/N2H SoC uses the same PHY as RZ/T2H, so it reuses the RZ/T2H
> compatible string as a fallback.
>
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> Acked-by: Conor Dooley <conor.dooley at microchip.com>

Thanks for your patch!

> --- a/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml
> +++ b/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml

> @@ -120,6 +126,17 @@ allOf:
>        required:
>          - resets
>
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: renesas,usb2-phy-r9a09g077
> +    then:
> +      properties:
> +        clocks:
> +          minItems: 2
> +        resets: false

By the time this hits upstream, you will probably have reset support
for RZ/T2H and RZ/N2H, so you just add renesas,usb2-phy-r9a09g077
to the conditional section above?

> +
>  additionalProperties: false
>
>  examples:

Reviewed-by: Geert Uytterhoeven <geert+renesas at glider.be>

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 krzysztof.kozlowski at linaro.org  Mon Aug 11 06:54:02 2025
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 11 Aug 2025 15:54:02 +0200
Subject: [PATCH RESEND 0/2] dt-bindings: Drop 'db' suffix duplicating
 dtschema
Message-ID: <20250811-dt-bindings-db-v1-0-457301523bb5@linaro.org>

Resending because all dependencies are merged.

Please take individual patches via respective subsystems (phy, leds).

Previously:
- Link to v1: https://lore.kernel.org/r/20250627-dt-bindings-db-v1-0-d5c7072acbee at linaro.org

Best regards,
Krzysztof

---
Krzysztof Kozlowski (2):
      dt-bindings: leds: issi,is31fl319x: Drop 'db' suffix duplicating dtschema
      dt-bindings: phy: fsl,imx8mq-usb: Drop 'db' suffix duplicating dtschema

 Documentation/devicetree/bindings/leds/issi,is31fl319x.yaml   | 1 -
 Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml | 1 -
 2 files changed, 2 deletions(-)
---
base-commit: b1549501188cc9eba732c25b033df7a53ccc341f
change-id: 20250627-dt-bindings-db-38eaa005ccd0

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From krzysztof.kozlowski at linaro.org  Mon Aug 11 06:54:03 2025
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 11 Aug 2025 15:54:03 +0200
Subject: [PATCH RESEND 1/2] dt-bindings: leds: issi,is31fl319x: Drop 'db'
 suffix duplicating dtschema
In-Reply-To: <20250811-dt-bindings-db-v1-0-457301523bb5@linaro.org>
References: <20250811-dt-bindings-db-v1-0-457301523bb5@linaro.org>
Message-ID: <20250811-dt-bindings-db-v1-1-457301523bb5@linaro.org>

A common property unit suffix '-db' was added to dtschema, thus
in-kernel bindings should not reference the type.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

---

RFC because this depends on dtschema changes and should be accepted
after new dtschema is released with this merged:
https://github.com/devicetree-org/dt-schema/pull/166
---
 Documentation/devicetree/bindings/leds/issi,is31fl319x.yaml | 1 -
 1 file changed, 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/leds/issi,is31fl319x.yaml b/Documentation/devicetree/bindings/leds/issi,is31fl319x.yaml
index 3c0431c51159e549920b17cf2ddfd1b85ecde810..906735acfbaf94fa08244f771139df207dd6e4da 100644
--- a/Documentation/devicetree/bindings/leds/issi,is31fl319x.yaml
+++ b/Documentation/devicetree/bindings/leds/issi,is31fl319x.yaml
@@ -42,7 +42,6 @@ properties:
     description: GPIO attached to the SDB pin.
 
   audio-gain-db:
-    $ref: /schemas/types.yaml#/definitions/uint32
     default: 0
     description: Audio gain selection for external analog modulation input.
     enum: [0, 3, 6, 9, 12, 15, 18, 21]

-- 
2.48.1



From krzysztof.kozlowski at linaro.org  Mon Aug 11 06:54:04 2025
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 11 Aug 2025 15:54:04 +0200
Subject: [PATCH RESEND 2/2] dt-bindings: phy: fsl,imx8mq-usb: Drop 'db'
 suffix duplicating dtschema
In-Reply-To: <20250811-dt-bindings-db-v1-0-457301523bb5@linaro.org>
References: <20250811-dt-bindings-db-v1-0-457301523bb5@linaro.org>
Message-ID: <20250811-dt-bindings-db-v1-2-457301523bb5@linaro.org>

A common property unit suffix '-db' was added to dtschema, thus
in-kernel bindings should not reference the type.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

---

RFC because this depends on dtschema changes and should be accepted
after new dtschema is released with this merged:
https://github.com/devicetree-org/dt-schema/pull/166
---
 Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml | 1 -
 1 file changed, 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml b/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml
index 22dd91591a09428214afaa4c9c8e37aae9bd8aba..6a47e08e0e97b286538798190225ca2966a7ab34 100644
--- a/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml
@@ -76,7 +76,6 @@ properties:
     description:
       Adjust TX de-emphasis attenuation in dB at nominal
       3.5dB point as per USB specification
-    $ref: /schemas/types.yaml#/definitions/uint32
     minimum: 0
     maximum: 36
 

-- 
2.48.1



From krzysztof.kozlowski at linaro.org  Mon Aug 11 07:19:23 2025
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 11 Aug 2025 16:19:23 +0200
Subject: [PATCH RESEND 1/2] dt-bindings: leds: issi,is31fl319x: Drop 'db'
 suffix duplicating dtschema
In-Reply-To: <20250811-dt-bindings-db-v1-1-457301523bb5@linaro.org>
References: <20250811-dt-bindings-db-v1-0-457301523bb5@linaro.org>
 <20250811-dt-bindings-db-v1-1-457301523bb5@linaro.org>
Message-ID: <deb5f02e-e26c-4e33-9e8b-2b3c04ddd4c9@linaro.org>

On 11/08/2025 15:54, Krzysztof Kozlowski wrote:
> A common property unit suffix '-db' was added to dtschema, thus
> in-kernel bindings should not reference the type.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> 
> ---
> 
> RFC because this depends on dtschema changes and should be accepted
> after new dtschema is released with this merged:
> https://github.com/devicetree-org/dt-schema/pull/166


This note is outdated - you can apply the patch.



Best regards,
Krzysztof


From krzysztof.kozlowski at linaro.org  Mon Aug 11 07:19:31 2025
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 11 Aug 2025 16:19:31 +0200
Subject: [PATCH RESEND 2/2] dt-bindings: phy: fsl,imx8mq-usb: Drop 'db'
 suffix duplicating dtschema
In-Reply-To: <20250811-dt-bindings-db-v1-2-457301523bb5@linaro.org>
References: <20250811-dt-bindings-db-v1-0-457301523bb5@linaro.org>
 <20250811-dt-bindings-db-v1-2-457301523bb5@linaro.org>
Message-ID: <6203a510-da79-42bf-9f85-7a2092b5057c@linaro.org>

On 11/08/2025 15:54, Krzysztof Kozlowski wrote:
> A common property unit suffix '-db' was added to dtschema, thus
> in-kernel bindings should not reference the type.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> 
> ---
> 
> RFC because this depends on dtschema changes and should be accepted
> after new dtschema is released with this merged:
> https://github.com/devicetree-org/dt-schema/pull/166


This note is outdated - you can apply the patch.


Best regards,
Krzysztof


From prabhakar.csengg at gmail.com  Mon Aug 11 08:08:23 2025
From: prabhakar.csengg at gmail.com (Lad, Prabhakar)
Date: Mon, 11 Aug 2025 16:08:23 +0100
Subject: [PATCH v2 1/5] dt-bindings: phy: renesas,usb2-phy: Add RZ/T2H and
 RZ/N2H support
In-Reply-To: <CAMuHMdUWo=hYPWPrweoYn5rFC50aV5EV1xqwFHmLp27GRjEADw@mail.gmail.com>
References: <20250808215209.3692744-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <20250808215209.3692744-2-prabhakar.mahadev-lad.rj@bp.renesas.com> <CAMuHMdUWo=hYPWPrweoYn5rFC50aV5EV1xqwFHmLp27GRjEADw@mail.gmail.com>
Message-ID: <CA+V-a8vW2-YG8=-u3kUcrou+nPVLn2uhE-W+JOHpu9Cahyw2ZQ@mail.gmail.com>

Hi Geert,

Thank you for the review.

On Mon, Aug 11, 2025 at 2:34?PM Geert Uytterhoeven <geert at linux-m68k.org> wrote:
>
> Hi Prabhakar,
>
> On Fri, 8 Aug 2025 at 23:52, Prabhakar <prabhakar.csengg at gmail.com> wrote:
> > From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> >
> > Document the USB2 PHY controller for the Renesas RZ/T2H (r9a09g077) and
> > RZ/N2H (r9a09g087) SoCs. These SoCs share the same PHY block, which is
> > similar to the one on RZ/G2L but differs in clocks, resets, and register
> > bits. To account for these differences, a new compatible string
> > `renesas,usb2-phy-r9a09g077` is introduced.
> >
> > The RZ/N2H SoC uses the same PHY as RZ/T2H, so it reuses the RZ/T2H
> > compatible string as a fallback.
> >
> > Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> > Acked-by: Conor Dooley <conor.dooley at microchip.com>
>
> Thanks for your patch!
>
> > --- a/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml
> > +++ b/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml
>
> > @@ -120,6 +126,17 @@ allOf:
> >        required:
> >          - resets
> >
> > +  - if:
> > +      properties:
> > +        compatible:
> > +          contains:
> > +            const: renesas,usb2-phy-r9a09g077
> > +    then:
> > +      properties:
> > +        clocks:
> > +          minItems: 2
> > +        resets: false
>
> By the time this hits upstream, you will probably have reset support
> for RZ/T2H and RZ/N2H, so you just add renesas,usb2-phy-r9a09g077
> to the conditional section above?
>
But the above will still be true as MRCTLA/E/I/M register doesn't have
any bits to reset USB{PHY} or am I missing something?

Cheers,
Prabhakar


From geert at linux-m68k.org  Mon Aug 11 08:17:48 2025
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Mon, 11 Aug 2025 17:17:48 +0200
Subject: [PATCH v2 1/5] dt-bindings: phy: renesas,usb2-phy: Add RZ/T2H and
 RZ/N2H support
In-Reply-To: <CA+V-a8vW2-YG8=-u3kUcrou+nPVLn2uhE-W+JOHpu9Cahyw2ZQ@mail.gmail.com>
References: <20250808215209.3692744-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <20250808215209.3692744-2-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <CAMuHMdUWo=hYPWPrweoYn5rFC50aV5EV1xqwFHmLp27GRjEADw@mail.gmail.com> <CA+V-a8vW2-YG8=-u3kUcrou+nPVLn2uhE-W+JOHpu9Cahyw2ZQ@mail.gmail.com>
Message-ID: <CAMuHMdVXZPhsKSbC1px9c733O-W74EHNOb9+Ag8hgsM2bPg7SQ@mail.gmail.com>

Hi Prabhakar,

On Mon, 11 Aug 2025 at 17:08, Lad, Prabhakar <prabhakar.csengg at gmail.com> wrote:
> On Mon, Aug 11, 2025 at 2:34?PM Geert Uytterhoeven <geert at linux-m68k.org> wrote:
> > On Fri, 8 Aug 2025 at 23:52, Prabhakar <prabhakar.csengg at gmail.com> wrote:
> > > From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> > >
> > > Document the USB2 PHY controller for the Renesas RZ/T2H (r9a09g077) and
> > > RZ/N2H (r9a09g087) SoCs. These SoCs share the same PHY block, which is
> > > similar to the one on RZ/G2L but differs in clocks, resets, and register
> > > bits. To account for these differences, a new compatible string
> > > `renesas,usb2-phy-r9a09g077` is introduced.
> > >
> > > The RZ/N2H SoC uses the same PHY as RZ/T2H, so it reuses the RZ/T2H
> > > compatible string as a fallback.
> > >
> > > Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> > > Acked-by: Conor Dooley <conor.dooley at microchip.com>
> >
> > Thanks for your patch!
> >
> > > --- a/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml
> > > +++ b/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml
> >
> > > @@ -120,6 +126,17 @@ allOf:
> > >        required:
> > >          - resets
> > >
> > > +  - if:
> > > +      properties:
> > > +        compatible:
> > > +          contains:
> > > +            const: renesas,usb2-phy-r9a09g077
> > > +    then:
> > > +      properties:
> > > +        clocks:
> > > +          minItems: 2
> > > +        resets: false
> >
> > By the time this hits upstream, you will probably have reset support
> > for RZ/T2H and RZ/N2H, so you just add renesas,usb2-phy-r9a09g077
> > to the conditional section above?
> >
> But the above will still be true as MRCTLA/E/I/M register doesn't have
> any bits to reset USB{PHY} or am I missing something?

You are correct. I overlooked that some modules lack reset bits.

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 andersson at kernel.org  Mon Aug 11 08:20:39 2025
From: andersson at kernel.org (Bjorn Andersson)
Date: Mon, 11 Aug 2025 10:20:39 -0500
Subject: [PATCH V1 1/4] dt-bindings: phy: Add max-microamp properties for
 PHY and PLL supplies
In-Reply-To: <20250806154340.20122-2-quic_nitirawa@quicinc.com>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
 <20250806154340.20122-2-quic_nitirawa@quicinc.com>
Message-ID: <jnsrcwcok6p63zddr3idsm2oa5kk3zi46atg7v3uvpu55vw4t4@vxslqznwhvyd>

On Wed, Aug 06, 2025 at 09:13:37PM +0530, Nitin Rawat wrote:
> Add two new optional properties to the SC8280XP QMP UFS PHY
> device tree binding:

Please start your commit message with a description of the problem
you're trying to solve.

> 
> - `vdda-phy-max-microamp`: Specifies the maximum current (in microamps)
> 			   that can be drawn from the PHY supply.
> - `vdda-pll-max-microamp`: Specifies the maximum current (in microamps)
> 			   that can be drawn from the PLL supply.

That's literally the content of the patch...use the commit message to
describe the problem you're solving and a technical description of the
solution to your problem (and in this case, why that solution goes in
the DeviceTree).

Regards,
Bjorn

> 
> These additions help define power requirements more precisely for
> regulators supplying the PHY and PLL blocks and ensuring the regulators
> is kept in correct mode based on the client load requirements.
> 
> Signed-off-by: Nitin Rawat <quic_nitirawa at quicinc.com>
> ---
>  .../bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml        | 10 ++++++++++
>  1 file changed, 10 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 a58370a6a5d3..4648642dc974 100644
> --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
> +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
> @@ -71,6 +71,16 @@ properties:
>  
>    vdda-pll-supply: true
>  
> +  vdda-phy-max-microamp:
> +    maxItems: 1
> +    description:
> +      Specifies max. load that can be drawn from phy supply.
> +
> +  vdda-pll-max-microamp:
> +    maxItems: 1
> +    description:
> +      Specifies max. load that can be drawn from pll supply.
> +
>    "#clock-cells":
>      const: 1
>  
> -- 
> 2.48.1
> 


From andersson at kernel.org  Mon Aug 11 08:25:36 2025
From: andersson at kernel.org (Bjorn Andersson)
Date: Mon, 11 Aug 2025 10:25:36 -0500
Subject: [PATCH V1 2/4] arm64: dts: qcom: sm8750: add max-microamp for
 UFS PHY and PLL supplies
In-Reply-To: <20250806154340.20122-3-quic_nitirawa@quicinc.com>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
 <20250806154340.20122-3-quic_nitirawa@quicinc.com>
Message-ID: <gvwdeswdx5rhdepxrgomtbeenh4o6zyi5banvp3y5gz2dkvopb@7pd6qmq4ypvg>

On Wed, Aug 06, 2025 at 09:13:38PM +0530, Nitin Rawat wrote:
> Add `vdda-phy-max-microamp` and `vdda-pll-max-microamp` properties to
> the UFS PHY node in the device tree.
> 
> These properties define the maximum current (in microamps) expected
> from the PHY and PLL regulators. This allows the PHY driver to
> configure regulator load accurately and ensure proper regulator
> mode based on load requirements.
> 

But doesn't this imply that these values are fixed for a given SoC?
Perhaps even for a given generation of the PHY/process?

Is there any case where these values need to be tweaked on a per-board
basis?


If not, I think these should be constants in the driver.

Regards,
Bjorn

> Signed-off-by: Nitin Rawat <quic_nitirawa at quicinc.com>
> ---
>  arch/arm64/boot/dts/qcom/sm8750-mtp.dts | 2 ++
>  arch/arm64/boot/dts/qcom/sm8750-qrd.dts | 2 ++
>  2 files changed, 4 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/qcom/sm8750-mtp.dts b/arch/arm64/boot/dts/qcom/sm8750-mtp.dts
> index 75cfbb510be5..2ae5915fe38d 100644
> --- a/arch/arm64/boot/dts/qcom/sm8750-mtp.dts
> +++ b/arch/arm64/boot/dts/qcom/sm8750-mtp.dts
> @@ -1032,7 +1032,9 @@ wcd_default: wcd-reset-n-active-state {
>  
>  &ufs_mem_phy {
>  	vdda-phy-supply = <&vreg_l1j_0p91>;
> +	vdda-phy-max-microamp = <213000>;
>  	vdda-pll-supply = <&vreg_l3g_1p2>;
> +	vdda-pll-max-microamp = <18300>;
>  
>  	status = "okay";
>  };
> diff --git a/arch/arm64/boot/dts/qcom/sm8750-qrd.dts b/arch/arm64/boot/dts/qcom/sm8750-qrd.dts
> index 13c7b9664c89..e9a41d34e2d6 100644
> --- a/arch/arm64/boot/dts/qcom/sm8750-qrd.dts
> +++ b/arch/arm64/boot/dts/qcom/sm8750-qrd.dts
> @@ -1039,7 +1039,9 @@ &uart7 {
>  
>  &ufs_mem_phy {
>  	vdda-phy-supply = <&vreg_l1j_0p91>;
> +	vdda-phy-max-microamp = <213000>;
>  	vdda-pll-supply = <&vreg_l3g_1p2>;
> +	vdda-pll-max-microamp = <18300>;
>  
>  	status = "okay";
>  };
> -- 
> 2.48.1
> 


From andersson at kernel.org  Mon Aug 11 08:50:27 2025
From: andersson at kernel.org (Bjorn Andersson)
Date: Mon, 11 Aug 2025 10:50:27 -0500
Subject: [PATCH V1 4/4] phy: qcom-qmp-ufs: read max-microamp values from
 device tree
In-Reply-To: <14566f49-7f7b-4583-98b7-8a473054f7c3@sirena.org.uk>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
 <20250806154340.20122-5-quic_nitirawa@quicinc.com>
 <f368b6da-1aa3-4b8e-9106-3c29d4ab5c5e@oss.qualcomm.com>
 <fe2bc07c-8fe9-47fd-bcd7-c2f0ebbd596f@sirena.org.uk>
 <aed1de56-fafe-4ccc-b542-69400b574def@oss.qualcomm.com>
 <acf89420-743b-4178-ac05-d4ca492bfee3@sirena.org.uk>
 <599b8a4b-324a-4543-ba27-0451f05c3dfd@quicinc.com>
 <3aa82f65-4812-4bf0-9323-96f40824a004@sirena.org.uk>
 <8c7f8cfc-2090-449e-b6ec-688a0021bac4@oss.qualcomm.com>
 <14566f49-7f7b-4583-98b7-8a473054f7c3@sirena.org.uk>
Message-ID: <kwp3q4r5rzahzro5f6l6ml24vbiutyxokrhjsbtzcb5kvanx5e@elagxv6w5dq7>

On Thu, Aug 07, 2025 at 08:09:56PM +0100, Mark Brown wrote:
> On Thu, Aug 07, 2025 at 07:43:15PM +0200, Konrad Dybcio wrote:
> > On 8/7/25 7:26 PM, Mark Brown wrote:
> 
> > > Note that that's specifying OPPs which is different...
> 
> > The microamp properties are in the top-level, not under OPP if
> > that's what you meant
> 
> I mean the OPPs use case is an existing well known one for dumping stuff
> into DT.
> 
> > > That doesn't mean that it's a good idea to put that information in the
> > > DT, nor if it is sensible to put in DT does it mean that it's a good
> > > idea to define a generic property that applies to all regulator
> > > consumers which is what I now think Konrad is proposing.
> 
> > Yeah, that's what I had in mind
> 
> > I was never able to get a reliable source for those numbers myselfe
> > either.. At least some of them are prooooobably? chosen based on the
> > used regulator type, to ensure it's always in HPM..
> 
> That's what set_mode() is for.  Like I say it's becoming less and less
> relevant though.
> 

set_mode() just applies the mode to the regulator_dev, so in cases where
you have multiple consumers of a regulator_dev things would break.

Further, there are numerous cases where we have multiple consumers each
needing a "low" mode, but their combined load requires a "high" mode.

set_load() and its aggregation of the inputs deals with both of these
issues.


Whether mode setting is becoming less relevant in our hardware, that I
don't have the definitive answer to.

> > That said, our drivers cover a wide variety of hardware, built on a
> > wide variety of process nodes, with different configurations, etc.,
> > so it's either polluting the DT, or polluting the driver with
> > per-compatible hardcoded data (and additional compatibles because
> > fallbacks wouldn't work most of the time)

If this is our reason for putting it in DeviceTree, then we should write
that in the commit message :)

> 
> That's really not a persuasive argument for adding a genric property
> that applies to all regulator consumers...
> 

I agree, even if we determine that this belongs in DT, because it needs
to be tweaked on a per-board basis, it's still only applicable to a
fraction of our device nodes.

Regards,
Bjorn

> My instinct with this stuff is generally to avoid putting it in the DT,
> we see far too many instances where someone's typed some numbers in
> wrongly or discovers the ability to drive the hardware harder and needs
> to tune the numbers - once something is ABI you're stuck just trusting
> the numbers.  That said I'm not going to stop you putting something
> specific to this driver in there, I just don't think this is a good idea
> as a generic property.



From conor at kernel.org  Mon Aug 11 09:12:02 2025
From: conor at kernel.org (Conor Dooley)
Date: Mon, 11 Aug 2025 17:12:02 +0100
Subject: [PATCH RESEND 0/2] dt-bindings: Drop 'db' suffix duplicating
 dtschema
In-Reply-To: <20250811-dt-bindings-db-v1-0-457301523bb5@linaro.org>
References: <20250811-dt-bindings-db-v1-0-457301523bb5@linaro.org>
Message-ID: <20250811-pretext-nurture-f26afcb71bc4@spud>

On Mon, Aug 11, 2025 at 03:54:02PM +0200, Krzysztof Kozlowski wrote:
> Resending because all dependencies are merged.
> 
> Please take individual patches via respective subsystems (phy, leds).
> 
> Previously:
> - Link to v1: https://lore.kernel.org/r/20250627-dt-bindings-db-v1-0-d5c7072acbee at linaro.org
> 
> Best regards,
> Krzysztof

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/20250811/19154a8d/attachment-0001.sig>

From broonie at kernel.org  Mon Aug 11 09:14:08 2025
From: broonie at kernel.org (Mark Brown)
Date: Mon, 11 Aug 2025 17:14:08 +0100
Subject: [PATCH V1 4/4] phy: qcom-qmp-ufs: read max-microamp values from
 device tree
In-Reply-To: <kwp3q4r5rzahzro5f6l6ml24vbiutyxokrhjsbtzcb5kvanx5e@elagxv6w5dq7>
References: <20250806154340.20122-5-quic_nitirawa@quicinc.com>
 <f368b6da-1aa3-4b8e-9106-3c29d4ab5c5e@oss.qualcomm.com>
 <fe2bc07c-8fe9-47fd-bcd7-c2f0ebbd596f@sirena.org.uk>
 <aed1de56-fafe-4ccc-b542-69400b574def@oss.qualcomm.com>
 <acf89420-743b-4178-ac05-d4ca492bfee3@sirena.org.uk>
 <599b8a4b-324a-4543-ba27-0451f05c3dfd@quicinc.com>
 <3aa82f65-4812-4bf0-9323-96f40824a004@sirena.org.uk>
 <8c7f8cfc-2090-449e-b6ec-688a0021bac4@oss.qualcomm.com>
 <14566f49-7f7b-4583-98b7-8a473054f7c3@sirena.org.uk>
 <kwp3q4r5rzahzro5f6l6ml24vbiutyxokrhjsbtzcb5kvanx5e@elagxv6w5dq7>
Message-ID: <81858c88-151a-46ea-9172-76d3052467e9@sirena.org.uk>

On Mon, Aug 11, 2025 at 10:50:27AM -0500, Bjorn Andersson wrote:
> On Thu, Aug 07, 2025 at 08:09:56PM +0100, Mark Brown wrote:
> > On Thu, Aug 07, 2025 at 07:43:15PM +0200, Konrad Dybcio wrote:

> > > I was never able to get a reliable source for those numbers myselfe
> > > either.. At least some of them are prooooobably? chosen based on the
> > > used regulator type, to ensure it's always in HPM..

> > That's what set_mode() is for.  Like I say it's becoming less and less
> > relevant though.

> set_mode() just applies the mode to the regulator_dev, so in cases where
> you have multiple consumers of a regulator_dev things would break.

> Further, there are numerous cases where we have multiple consumers each
> needing a "low" mode, but their combined load requires a "high" mode.

> set_load() and its aggregation of the inputs deals with both of these
> issues.

That sort of active mode management is not the suggestion above that all
this stuff is just intended to force the regulator to always be in high
power mode.  If that's the goal then like I say just use set_mode() and
directly express it.

> Whether mode setting is becoming less relevant in our hardware, that I
> don't have the definitive answer to.

I rather get the impression that nobody understands what any of this
stuff is actually trying to accomplish in these systems and is just
copying things around from older code or BSPs, I'm not entirely
convinced it's actually doing anything useful in modern systems.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-phy/attachments/20250811/0d84853d/attachment-0001.sig>

From andersson at kernel.org  Mon Aug 11 11:41:10 2025
From: andersson at kernel.org (Bjorn Andersson)
Date: Mon, 11 Aug 2025 13:41:10 -0500
Subject: [PATCH v9 0/2] pci: qcom: Add QCS615 PCIe support
In-Reply-To: <20250725112346.614316-1-ziyue.zhang@oss.qualcomm.com>
References: <20250725112346.614316-1-ziyue.zhang@oss.qualcomm.com>
Message-ID: <175493766101.138281.16774900398360513894.b4-ty@kernel.org>


On Fri, 25 Jul 2025 19:23:44 +0800, Ziyue Zhang wrote:
> This series adds document, phy, configs support for PCIe in QCS615.
> 
> This series depend on the dt-bindings change
> https://lore.kernel.org/all/20250521-topic-8150_pcie_drop_clocks-v1-0-3d42e84f6453 at oss.qualcomm.com/
> 
> 

Applied, thanks!

[1/2] arm64: dts: qcom: qcs615: enable pcie
      commit: 718cc7542a000e2911c8d18878ba2eac5f29e744
[2/2] arm64: dts: qcom: qcs615-ride: Enable PCIe interface
      commit: 414be2b5a79de8694db1e26a3ea63a2aee5957ad

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


From neil.armstrong at linaro.org  Mon Aug 11 12:04:46 2025
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Mon, 11 Aug 2025 21:04:46 +0200
Subject: [PATCH v4 0/6] arm64: qcom: allow up to 4 lanes for the Type-C
 DisplayPort Altmode
In-Reply-To: <20250807-topic-4ln_dp_respin-v4-0-43272d6eca92@oss.qualcomm.com>
References: <20250807-topic-4ln_dp_respin-v4-0-43272d6eca92@oss.qualcomm.com>
Message-ID: <1ab2f4f0-94e5-413b-a87b-190b288b5f32@linaro.org>

On 07/08/2025 18:33, Konrad Dybcio wrote:
> Register a typec mux in order to change the PHY mode on the Type-C
> mux events depending on the mode and the svid when in Altmode setup.
> 
> The DisplayPort phy should be left enabled if is still powered on
> by the DRM DisplayPort controller, so bail out until the DisplayPort
> PHY is not powered off.
> 
> The Type-C Mode/SVID only changes on plug/unplug, and USB SAFE states
> will be set in between of USB-Only, Combo and DisplayPort Only so
> this will leave enough time to the DRM DisplayPort controller to
> turn of the DisplayPort PHY.
> 
> The patchset also includes bindings changes and DT changes.
> 
> This has been successfully tested on an SM8550 board, but the
> Thinkpad X13s deserved testing between non-PD USB, non-PD DisplayPort,
> PD USB Hubs and PD Altmode Dongles to make sure the switch works
> as expected.
> 
> The DisplayPort 4 lanes setup can be check with:
> $ cat /sys/kernel/debug/dri/ae01000.display-controller/DP-1/dp_debug
> 	name = msm_dp
> 	drm_dp_link
> 		rate = 540000
> 		num_lanes = 4
> ...
> 
> This patchset depends on [1] to allow broadcasting the type-c mode
> to the PHY, otherwise the PHY will keep the combo state while the
> retimer would setup the 4 lanes in DP mode.
> 
> [1] https://lore.kernel.org/all/20240527-topic-sm8x50-upstream-retimer-broadcast-mode-v1-0-79ec91381aba at linaro.org/
> 
> Changes in v4:
> - Default to USB3_ONLY if there's no DP SVID (Dmitry)
> - Pick up tags, dropped T-bys due to the above change
> - Add missing submitter's sign-off on some patches
> - The odd 4-lane-DP + USB2 case remains unhandled for now, but it's
>    not a huge deal, see:
>    <c2f2ba36-1a25-450e-99b9-79aa4fd4913d at linaro.org>
> - Link to v3: https://lore.kernel.org/r/20250527-topic-4ln_dp_respin-v3-0-f9a0763ec289 at oss.qualcomm.com
> Changes in v3:
> - Take the series from Neil
> - Rebase
> - Rename many variables
> - Test on X1E & X13s
> - Apply a number of small cosmetic/codestyle changes
> - Remove some unused variables
> - Some smaller bugfixes
> - Link to v2: https://lore.kernel.org/lkml/20240527-topic-sm8x50-upstream-phy-combo-typec-mux-v2-0-a03e68d7b8fc at linaro.org/
> Changes in v2:
> - Reference usb-switch.yaml in bindings patch
> - Fix switch/case indenting
> - Check svid for USB_TYPEC_DP_SID
> - Fix X13s patch subject
> - Update SM8650 patch to enable 4 lanes on HDK aswell
> - Link to v1: https://lore.kernel.org/r/20240229-topic-sm8x50-upstream-phy-combo-typec-mux-v1-0-07e24a231840 at linaro.org
> 
> Signed-off-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
> ---
> Konrad Dybcio (1):
>        phy: qcom: qmp-combo: Rename 'mode' to 'phy_mode'
> 
> Neil Armstrong (5):
>        dt-bindings: phy: qcom,sc8280xp-qmp-usb43dp: Reference usb-switch.yaml to allow mode-switch
>        phy: qcom: qmp-combo: store DP phy power state
>        phy: qcom: qmp-combo: introduce QMPPHY_MODE
>        phy: qcom: qmp-combo: register a typec mux to change the QMPPHY_MODE
>        arm64: dts: qcom: sc8280xp-lenovo-thinkpad-x13: Set up 4-lane DP
> 
>   .../phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml         |   7 +-
>   .../dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts     |   6 +-
>   drivers/phy/qualcomm/phy-qcom-qmp-combo.c          | 179 +++++++++++++++++++--
>   3 files changed, 170 insertions(+), 22 deletions(-)
> ---
> base-commit: 442d93313caebc8ccd6d53f4572c50732a95bc48
> change-id: 20250527-topic-4ln_dp_respin-c6924a8825ce
> 
> Best regards,

Tested-by: Neil Armstrong <neil.armstrong at linaro.org> # on Lenovo Thinkpad T14S

Successfully got 4 lanes working with an USB-C to DP adapter with either orientation:
	dp_link:
		test_requested = 512
		num_lanes = 4
		bw_code = 20
		lclk = 540000000
		v_level = 2
		p_level = 0

And 2 lanes is still working.

I'll test on SM8550/SM8650 later this week.

Thanks,
Neil


From quic_nitirawa at quicinc.com  Mon Aug 11 12:48:58 2025
From: quic_nitirawa at quicinc.com (Nitin Rawat)
Date: Tue, 12 Aug 2025 01:18:58 +0530
Subject: [PATCH V1 4/4] phy: qcom-qmp-ufs: read max-microamp values from
 device tree
In-Reply-To: <kwp3q4r5rzahzro5f6l6ml24vbiutyxokrhjsbtzcb5kvanx5e@elagxv6w5dq7>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
 <20250806154340.20122-5-quic_nitirawa@quicinc.com>
 <f368b6da-1aa3-4b8e-9106-3c29d4ab5c5e@oss.qualcomm.com>
 <fe2bc07c-8fe9-47fd-bcd7-c2f0ebbd596f@sirena.org.uk>
 <aed1de56-fafe-4ccc-b542-69400b574def@oss.qualcomm.com>
 <acf89420-743b-4178-ac05-d4ca492bfee3@sirena.org.uk>
 <599b8a4b-324a-4543-ba27-0451f05c3dfd@quicinc.com>
 <3aa82f65-4812-4bf0-9323-96f40824a004@sirena.org.uk>
 <8c7f8cfc-2090-449e-b6ec-688a0021bac4@oss.qualcomm.com>
 <14566f49-7f7b-4583-98b7-8a473054f7c3@sirena.org.uk>
 <kwp3q4r5rzahzro5f6l6ml24vbiutyxokrhjsbtzcb5kvanx5e@elagxv6w5dq7>
Message-ID: <d072b19d-bc01-45c8-8cf3-bceb53ca9b2c@quicinc.com>



On 8/11/2025 9:20 PM, Bjorn Andersson wrote:
> On Thu, Aug 07, 2025 at 08:09:56PM +0100, Mark Brown wrote:
>> On Thu, Aug 07, 2025 at 07:43:15PM +0200, Konrad Dybcio wrote:
>>> On 8/7/25 7:26 PM, Mark Brown wrote:
>>
>>>> Note that that's specifying OPPs which is different...
>>
>>> The microamp properties are in the top-level, not under OPP if
>>> that's what you meant
>>
>> I mean the OPPs use case is an existing well known one for dumping stuff
>> into DT.
>>
>>>> That doesn't mean that it's a good idea to put that information in the
>>>> DT, nor if it is sensible to put in DT does it mean that it's a good
>>>> idea to define a generic property that applies to all regulator
>>>> consumers which is what I now think Konrad is proposing.
>>
>>> Yeah, that's what I had in mind
>>
>>> I was never able to get a reliable source for those numbers myselfe
>>> either.. At least some of them are prooooobably? chosen based on the
>>> used regulator type, to ensure it's always in HPM..
>>
>> That's what set_mode() is for.  Like I say it's becoming less and less
>> relevant though.
>>
> 
> set_mode() just applies the mode to the regulator_dev, so in cases where
> you have multiple consumers of a regulator_dev things would break.
> 
> Further, there are numerous cases where we have multiple consumers each
> needing a "low" mode, but their combined load requires a "high" mode.
> 
> set_load() and its aggregation of the inputs deals with both of these
> issues.
> 
> 
> Whether mode setting is becoming less relevant in our hardware, that I
> don't have the definitive answer to.
> 
>>> That said, our drivers cover a wide variety of hardware, built on a
>>> wide variety of process nodes, with different configurations, etc.,
>>> so it's either polluting the DT, or polluting the driver with
>>> per-compatible hardcoded data (and additional compatibles because
>>> fallbacks wouldn't work most of the time)
> 
> If this is our reason for putting it in DeviceTree, then we should write
> that in the commit message :)
> 
>>
>> That's really not a persuasive argument for adding a genric property
>> that applies to all regulator consumers...
>>
> 
> I agree, even if we determine that this belongs in DT, because it needs
> to be tweaked on a per-board basis, it's still only applicable to a
> fraction of our device nodes.

Hi Bjorn & Mark,

I had a follow-up discussion with the PHY designer to confirm whether 
this value could vary at the board level. Based on their response, it's 
a fixed value for the SoC and remains consistent across different 
boards. Therefore, I'm comfortable removing it from the device tree and 
using hardcoded, per-compatible data in the driver.

The only concern is that this approach may lead to driver bloat over 
time, as more SoCs are added and each requires its own hardcoded 
configuration.

Regards,
Nitin






> 
> Regards,
> Bjorn
> 
>> My instinct with this stuff is generally to avoid putting it in the DT,
>> we see far too many instances where someone's typed some numbers in
>> wrongly or discovers the ability to drive the hardware harder and needs
>> to tune the numbers - once something is ABI you're stuck just trusting
>> the numbers.  That said I'm not going to stop you putting something
>> specific to this driver in there, I just don't think this is a good idea
>> as a generic property.
> 



From quic_nitirawa at quicinc.com  Mon Aug 11 12:49:23 2025
From: quic_nitirawa at quicinc.com (Nitin Rawat)
Date: Tue, 12 Aug 2025 01:19:23 +0530
Subject: [PATCH V1 4/4] phy: qcom-qmp-ufs: read max-microamp values from
 device tree
In-Reply-To: <5nsglhsnqdx4l44r36zmxumcpbbwhns4432hm3lvttsgyjaknb@feobdhpzzo65>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
 <20250806154340.20122-5-quic_nitirawa@quicinc.com>
 <5nsglhsnqdx4l44r36zmxumcpbbwhns4432hm3lvttsgyjaknb@feobdhpzzo65>
Message-ID: <331c5c34-9bf7-4c1f-97cb-e78749c9f6b0@quicinc.com>



On 8/9/2025 1:00 PM, Dmitry Baryshkov wrote:
> On Wed, Aug 06, 2025 at 09:13:40PM +0530, Nitin Rawat wrote:
>> Add support in QMP PHY driver to read optional vdda-phy-max-microamp
>> and vdda-pll-max-microamp properties from the device tree.
>>
>> These properties define the expected maximum current (in microamps) for
>> each supply. The driver uses this information to configure regulators
>> more accurately and ensure they operate in the correct mode based on
>> client load requirements.
> 
> What defines those load values? Are they actually dependent on the
> platform? On the SoC? On the board design? On the UFS gear?

Hi Dmitry,

These load values are defined at the SoC level, although they may vary 
depending on the UFS gear. However, the peak value per power grid is 
determined by the maximum gear supported by the controller.

In summary, the value is SoC-specific and does not depend on board-level 
variations. Based on this, I'm comfortable hardcoding per-compatible 
data directly in the driver instead of relying on the device tree.

Thanks,
Nitin


> 
>>
>> If the property is not present, the driver defaults load to
>> `QMP_VREG_UNUSED`.
>>
>> Signed-off-by: Nitin Rawat <quic_nitirawa at quicinc.com>
>> ---
>>   drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 22 +++++++++++++++++++---
>>   1 file changed, 19 insertions(+), 3 deletions(-)
>>
> 



From quic_nitirawa at quicinc.com  Mon Aug 11 12:55:02 2025
From: quic_nitirawa at quicinc.com (Nitin Rawat)
Date: Tue, 12 Aug 2025 01:25:02 +0530
Subject: [PATCH V1 2/4] arm64: dts: qcom: sm8750: add max-microamp for UFS
 PHY and PLL supplies
In-Reply-To: <rh3qxu2rijpjswfash3rpmmh6sw47l3b6j5p5upti6zffknasz@cywwm3fypghd>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
 <20250806154340.20122-3-quic_nitirawa@quicinc.com>
 <20250808-calm-boa-of-swiftness-a4a7ce@kuoka>
 <9af71063-0629-4ccc-bc76-3fb588677bf4@oss.qualcomm.com>
 <292907f3-25d6-40d9-be6e-b6b83e646d73@kernel.org>
 <5e32be05-0dbd-4d6f-879d-8ce97fb430ba@quicinc.com>
 <rh3qxu2rijpjswfash3rpmmh6sw47l3b6j5p5upti6zffknasz@cywwm3fypghd>
Message-ID: <89ab7e51-f82e-465a-aa22-1ccb8e7a0f6d@quicinc.com>



On 8/9/2025 4:37 PM, Manivannan Sadhasivam wrote:
> On Fri, Aug 08, 2025 at 08:49:45PM GMT, Nitin Rawat wrote:
>>
>>
>> On 8/8/2025 3:09 PM, Krzysztof Kozlowski wrote:
>>> On 08/08/2025 10:58, Konrad Dybcio wrote:
>>>> On 8/8/25 9:29 AM, Krzysztof Kozlowski wrote:
>>>>> On Wed, Aug 06, 2025 at 09:13:38PM +0530, Nitin Rawat wrote:
>>>>>> Add `vdda-phy-max-microamp` and `vdda-pll-max-microamp` properties to
>>>>>> the UFS PHY node in the device tree.
>>>>>>
>>>>>> These properties define the maximum current (in microamps) expected
>>>>>> from the PHY and PLL regulators. This allows the PHY driver to
>>>>>> configure regulator load accurately and ensure proper regulator
>>>>>> mode based on load requirements.
>>>>>
>>>>> That's not the property of phy, but regulator.
>>>>>
>>>>> Also reasoning is here incomplete - you just post downstream code. :/
>>>>
>>>> The reason for this change is good, but perhaps not explained clearly
>>>>
>>>> All of these values refer to the maximum current draw that needs to be
>>>> allocated on a shared voltage supply for this peripheral (because the
>>>
>>>
>>> It sounds very different than how much it can be drawn. How much can be
>>> drawn is the property of the regulator. The regulator knows how much
>>> current it can support.
>>
>> Consumers are aware of their dynamic load requirements, which can vary at
>> runtime?this awareness is not reciprocal. The power grid is designed based
>> on the collective load requirements of all clients sharing the same power
>> rail.
>>
>> Since regulators can operate in multiple modes for power optimization, each
>> consumer is expected to vote for its runtime power needs. These votes help
>> the regulator framework maintain the regulator in the appropriate mode,
>> ensuring stable and efficient operation across all clients.
>>
>>
>> Stability issues can arise if each consumer does not vote for its own load
>> requirement.
>> For example, consider a scenario where a single regulator is shared by two
>> consumers.
>>
>> If the first client requests low-power mode by voting for zero or a minimal
>> load to regulator framework during its driver's LPM sequence, and the second
>> client (e.g., UFS PHY) has not voted for its own load requirement through
>> the regulator framework, the regulator may transition to low-power mode.
>> This can lead to issues for the second client, which expects a higher power
>> state to operate correctly.
>>
> 
> I think we all agree on consumers setting the load for shared regulators, but
> the naming and description of the DT property is what causing confusion here.
> There is no way the consumers can set the *max* current draw for a shared
> regulator. They can only request load as per their requirement. But the max
> current draw is a regulator constraint.

To avoid confusion with regulator-level constraints, I'm open to 
renaming the property vdda-phy-max-microamp to something more 
descriptive, such as vdda-phy-client-peak-load-microamp or 
vdda-phy-peak-load-microamp. Along with updating the description, this 
would better reflect the property's actual intent: to specify the 
maximum current a client may draw during peak operation, rather than 
implying it defines the regulator?s maximum capability.


Having said that, I had a follow-up discussion with the PHY designer to 
confirm whether this value could vary at the board level. Based on their 
response, it's a fixed value for the SoC and does not change across 
different boards(atleast for now). Therefore, I can remove from device 
tree and replaced with hardcoded, per-compatible data in the driver.

> 
>>
>>>
>>>
>>>> supply's capabilities change depending on the maximum potential load
>>>> at any given time, which the regulator driver must be aware of)
>>>>
>>>> This is a property of a regulator *consumer*, i.e. if we had a chain
>>>> of LEDs hanging off of this supply, we'd need to specify NUM_LEDS *
>>>> MAX_CURR under the "led chain" device, to make sure that if the
>>>> aggregated current requirements go over a certain threshold (which is
>>>> unknown to Linux and hidden in RPMh fw), the regulator can be
>>>> reconfigured to allow for a higher current draw (likely at some
>>>> downgrade to efficiency)
>>>
>>>
>>> The problem is that rationale is downstream. Instead I want to see some
>>> reason: e.g. datasheets, spec, type of UFS device (that was the argument
>>> in the driver patch discussion).
>>
>>
>> The PHY load requirements for consumers such as UFS, USB, PCIe are defined
>> by Qualcomm?s PHY IP and are well-documented in Qualcomm?s datasheets and
>> power grid documentation. These values can depending on the process or
>> technology node, board design, and even the chip foundry used.
>>
>> As a result, the load values can differ across SoCs or may be even
>> board(unlikely though) due to variations in any of these parameters.
>>
> 
> Okay. This goes into the commit message and possibly some part of it to property
> description also.




> 
> - Mani
> 



From andersson at kernel.org  Mon Aug 11 16:27:08 2025
From: andersson at kernel.org (Bjorn Andersson)
Date: Mon, 11 Aug 2025 18:27:08 -0500
Subject: (subset) [PATCH v2 1/1] arm64: dts: qcom: qcs615: Set LDO12A regulator to HPM to avoid boot hang
In-Reply-To: <20250717072746.987298-1-quic_ziyuzhan@quicinc.com>
References: <20250717072746.987298-1-quic_ziyuzhan@quicinc.com>
Message-ID: <175495482442.157244.678684703517788074.b4-ty@kernel.org>


On Thu, 17 Jul 2025 15:27:46 +0800, Ziyue Zhang wrote:
> On certain platforms (e.g., QCS615), consumers of LDO12A?such as PCIe,
> UFS, and eMMC?may draw more than 10mA of current during boot. This can
> exceed the regulator's limit in Low Power Mode (LPM), triggering current
> limit protection and causing the system to hang.
> 
> To address this, there are two possible approaches:
> a) Set the regulator's initial mode to High Performance Mode (HPM) in
>    the device tree.
> b) Keep the default LPM setting and have each consumer driver explicitly
>    set its current load.
> 
> [...]

Applied, thanks!

[1/1] arm64: dts: qcom: qcs615: Set LDO12A regulator to HPM to avoid boot hang
      commit: fba47ba8c8a8ffa9d8ad1836396837a998bb5153

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


From andersson at kernel.org  Mon Aug 11 16:27:11 2025
From: andersson at kernel.org (Bjorn Andersson)
Date: Mon, 11 Aug 2025 18:27:11 -0500
Subject: (subset) [PATCH v1 1/1] arm64: dts: qcom: qcs615: Set LDO12A regulator to HPM to avoid boot hang
In-Reply-To: <20250716030601.1705364-1-ziyue.zhang@oss.qualcomm.com>
References: <20250716030601.1705364-1-ziyue.zhang@oss.qualcomm.com>
Message-ID: <175495482457.157244.16977167154606922012.b4-ty@kernel.org>


On Wed, 16 Jul 2025 11:06:01 +0800, Ziyue Zhang wrote:
> On certain platforms (e.g., QCS615), consumers of LDO12A?such as PCIe,
> UFS, and eMMC?may draw more than 10mA of current during boot. This can
> exceed the regulator's limit in Low Power Mode (LPM), triggering current
> limit protection and causing the system to hang.
> 
> To address this, there are two possible approaches:
> a) Set the regulator's initial mode to High Performance Mode (HPM) in
>    the device tree.
> b) Keep the default LPM setting and have each consumer driver explicitly
>    set its current load.
> 
> [...]

Applied, thanks!

[1/1] arm64: dts: qcom: qcs615: Set LDO12A regulator to HPM to avoid boot hang
      commit: fba47ba8c8a8ffa9d8ad1836396837a998bb5153

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


From andersson at kernel.org  Mon Aug 11 20:04:52 2025
From: andersson at kernel.org (Bjorn Andersson)
Date: Mon, 11 Aug 2025 22:04:52 -0500
Subject: (subset) [PATCH v7 0/3] pci: qcom: drop unrelated clock and add link_down reset for sa8775p
In-Reply-To: <20250725102231.3608298-1-ziyue.zhang@oss.qualcomm.com>
References: <20250725102231.3608298-1-ziyue.zhang@oss.qualcomm.com>
Message-ID: <175496788924.165980.4310613357045244026.b4-ty@kernel.org>


On Fri, 25 Jul 2025 18:22:28 +0800, Ziyue Zhang wrote:
> This series drop gcc_aux_clock in pcie phy, the pcie aux clock should
> be gcc_phy_aux_clock. And sa8775p platform support link_down reset in
> hardware, so add it for both pcie0 and pcie1 to provide a better user
> experience.
> 
> Have follwing changes:
>   - Update pcie phy bindings for sa8775p.
>   - Document link_down reset.
>   - Remove aux clock from pcie phy.
>   - Add link_down reset for pcie.
> 
> [...]

Applied, thanks!

[2/3] arm64: dts: qcom: sa8775p: remove aux clock from pcie phy
      commit: d41fb878adf64ef5dc4b4c25419e875483f62fe2
[3/3] arm64: dts: qcom: sa8775p: add link_down reset for pcie
      commit: f0370265b1d7fc169956927aa62c3abc375743b5

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


From shradha.t at samsung.com  Mon Aug 11 08:46:27 2025
From: shradha.t at samsung.com (Shradha Todi)
Date: Mon, 11 Aug 2025 21:16:27 +0530
Subject: [PATCH v3 01/12] PCI: exynos: Remove unused MACROs in exynos PCIe
 file
In-Reply-To: <20250811154638.95732-1-shradha.t@samsung.com>
References: <20250811154638.95732-1-shradha.t@samsung.com>
	<CGME20250811154655epcas5p211bd14152fa48635fc5c1daceb963e71@epcas5p2.samsung.com>
Message-ID: <20250811154638.95732-2-shradha.t@samsung.com>

Some MACROs are defined in the exynos PCIe file but are
not used anywhere within the file. Remove such unused
MACROs.

Suggested-by: Hrishikesh Dileep <hrishikesh.d at samsung.com>
Signed-off-by: Shradha Todi <shradha.t at samsung.com>
---
 drivers/pci/controller/dwc/pci-exynos.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-exynos.c b/drivers/pci/controller/dwc/pci-exynos.c
index 1f0e98d07109..f9140d1f1d19 100644
--- a/drivers/pci/controller/dwc/pci-exynos.c
+++ b/drivers/pci/controller/dwc/pci-exynos.c
@@ -31,8 +31,6 @@
 #define IRQ_INTB_ASSERT			BIT(2)
 #define IRQ_INTC_ASSERT			BIT(4)
 #define IRQ_INTD_ASSERT			BIT(6)
-#define PCIE_IRQ_LEVEL			0x004
-#define PCIE_IRQ_SPECIAL		0x008
 #define PCIE_IRQ_EN_PULSE		0x00c
 #define PCIE_IRQ_EN_LEVEL		0x010
 #define PCIE_IRQ_EN_SPECIAL		0x014
-- 
2.49.0



From shradha.t at samsung.com  Mon Aug 11 08:46:28 2025
From: shradha.t at samsung.com (Shradha Todi)
Date: Mon, 11 Aug 2025 21:16:28 +0530
Subject: [PATCH v3 02/12] PCI: exynos: Change macro names to exynos specific
In-Reply-To: <20250811154638.95732-1-shradha.t@samsung.com>
References: <20250811154638.95732-1-shradha.t@samsung.com>
	<CGME20250811154659epcas5p1874791c7ce4e26a2bd36e24a7be55f51@epcas5p1.samsung.com>
Message-ID: <20250811154638.95732-3-shradha.t@samsung.com>

Prefix macro names in exynos file with the term "EXYNOS" as the current
macro names seem to be generic to PCIe.

Signed-off-by: Shradha Todi <shradha.t at samsung.com>
---
 drivers/pci/controller/dwc/pci-exynos.c | 112 ++++++++++++------------
 1 file changed, 56 insertions(+), 56 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-exynos.c b/drivers/pci/controller/dwc/pci-exynos.c
index f9140d1f1d19..30d12ff9b0c6 100644
--- a/drivers/pci/controller/dwc/pci-exynos.c
+++ b/drivers/pci/controller/dwc/pci-exynos.c
@@ -26,28 +26,28 @@
 #define to_exynos_pcie(x)	dev_get_drvdata((x)->dev)
 
 /* PCIe ELBI registers */
-#define PCIE_IRQ_PULSE			0x000
-#define IRQ_INTA_ASSERT			BIT(0)
-#define IRQ_INTB_ASSERT			BIT(2)
-#define IRQ_INTC_ASSERT			BIT(4)
-#define IRQ_INTD_ASSERT			BIT(6)
-#define PCIE_IRQ_EN_PULSE		0x00c
-#define PCIE_IRQ_EN_LEVEL		0x010
-#define PCIE_IRQ_EN_SPECIAL		0x014
-#define PCIE_SW_WAKE			0x018
-#define PCIE_BUS_EN			BIT(1)
-#define PCIE_CORE_RESET			0x01c
-#define PCIE_CORE_RESET_ENABLE		BIT(0)
-#define PCIE_STICKY_RESET		0x020
-#define PCIE_NONSTICKY_RESET		0x024
-#define PCIE_APP_INIT_RESET		0x028
-#define PCIE_APP_LTSSM_ENABLE		0x02c
-#define PCIE_ELBI_RDLH_LINKUP		0x074
-#define PCIE_ELBI_XMLH_LINKUP		BIT(4)
-#define PCIE_ELBI_LTSSM_ENABLE		0x1
-#define PCIE_ELBI_SLV_AWMISC		0x11c
-#define PCIE_ELBI_SLV_ARMISC		0x120
-#define PCIE_ELBI_SLV_DBI_ENABLE	BIT(21)
+#define EXYNOS_PCIE_IRQ_PULSE			0x000
+#define EXYNOS_IRQ_INTA_ASSERT			BIT(0)
+#define EXYNOS_IRQ_INTB_ASSERT			BIT(2)
+#define EXYNOS_IRQ_INTC_ASSERT			BIT(4)
+#define EXYNOS_IRQ_INTD_ASSERT			BIT(6)
+#define EXYNOS_PCIE_IRQ_EN_PULSE		0x00c
+#define EXYNOS_PCIE_IRQ_EN_LEVEL		0x010
+#define EXYNOS_PCIE_IRQ_EN_SPECIAL		0x014
+#define EXYNOS_PCIE_SW_WAKE			0x018
+#define EXYNOS_PCIE_BUS_EN			BIT(1)
+#define EXYNOS_PCIE_CORE_RESET			0x01c
+#define EXYNOS_PCIE_CORE_RESET_ENABLE		BIT(0)
+#define EXYNOS_PCIE_STICKY_RESET		0x020
+#define EXYNOS_PCIE_NONSTICKY_RESET		0x024
+#define EXYNOS_PCIE_APP_INIT_RESET		0x028
+#define EXYNOS_PCIE_APP_LTSSM_ENABLE		0x02c
+#define EXYNOS_PCIE_ELBI_RDLH_LINKUP		0x074
+#define EXYNOS_PCIE_ELBI_XMLH_LINKUP		BIT(4)
+#define EXYNOS_PCIE_ELBI_LTSSM_ENABLE		0x1
+#define EXYNOS_PCIE_ELBI_SLV_AWMISC		0x11c
+#define EXYNOS_PCIE_ELBI_SLV_ARMISC		0x120
+#define EXYNOS_PCIE_ELBI_SLV_DBI_ENABLE		BIT(21)
 
 struct exynos_pcie {
 	struct dw_pcie			pci;
@@ -71,49 +71,49 @@ static void exynos_pcie_sideband_dbi_w_mode(struct exynos_pcie *ep, bool on)
 {
 	u32 val;
 
-	val = exynos_pcie_readl(ep->elbi_base, PCIE_ELBI_SLV_AWMISC);
+	val = exynos_pcie_readl(ep->elbi_base, EXYNOS_PCIE_ELBI_SLV_AWMISC);
 	if (on)
-		val |= PCIE_ELBI_SLV_DBI_ENABLE;
+		val |= EXYNOS_PCIE_ELBI_SLV_DBI_ENABLE;
 	else
-		val &= ~PCIE_ELBI_SLV_DBI_ENABLE;
-	exynos_pcie_writel(ep->elbi_base, val, PCIE_ELBI_SLV_AWMISC);
+		val &= ~EXYNOS_PCIE_ELBI_SLV_DBI_ENABLE;
+	exynos_pcie_writel(ep->elbi_base, val, EXYNOS_PCIE_ELBI_SLV_AWMISC);
 }
 
 static void exynos_pcie_sideband_dbi_r_mode(struct exynos_pcie *ep, bool on)
 {
 	u32 val;
 
-	val = exynos_pcie_readl(ep->elbi_base, PCIE_ELBI_SLV_ARMISC);
+	val = exynos_pcie_readl(ep->elbi_base, EXYNOS_PCIE_ELBI_SLV_ARMISC);
 	if (on)
-		val |= PCIE_ELBI_SLV_DBI_ENABLE;
+		val |= EXYNOS_PCIE_ELBI_SLV_DBI_ENABLE;
 	else
-		val &= ~PCIE_ELBI_SLV_DBI_ENABLE;
-	exynos_pcie_writel(ep->elbi_base, val, PCIE_ELBI_SLV_ARMISC);
+		val &= ~EXYNOS_PCIE_ELBI_SLV_DBI_ENABLE;
+	exynos_pcie_writel(ep->elbi_base, val, EXYNOS_PCIE_ELBI_SLV_ARMISC);
 }
 
 static void exynos_pcie_assert_core_reset(struct exynos_pcie *ep)
 {
 	u32 val;
 
-	val = exynos_pcie_readl(ep->elbi_base, PCIE_CORE_RESET);
-	val &= ~PCIE_CORE_RESET_ENABLE;
-	exynos_pcie_writel(ep->elbi_base, val, PCIE_CORE_RESET);
-	exynos_pcie_writel(ep->elbi_base, 0, PCIE_STICKY_RESET);
-	exynos_pcie_writel(ep->elbi_base, 0, PCIE_NONSTICKY_RESET);
+	val = exynos_pcie_readl(ep->elbi_base, EXYNOS_PCIE_CORE_RESET);
+	val &= ~EXYNOS_PCIE_CORE_RESET_ENABLE;
+	exynos_pcie_writel(ep->elbi_base, val, EXYNOS_PCIE_CORE_RESET);
+	exynos_pcie_writel(ep->elbi_base, 0, EXYNOS_PCIE_STICKY_RESET);
+	exynos_pcie_writel(ep->elbi_base, 0, EXYNOS_PCIE_NONSTICKY_RESET);
 }
 
 static void exynos_pcie_deassert_core_reset(struct exynos_pcie *ep)
 {
 	u32 val;
 
-	val = exynos_pcie_readl(ep->elbi_base, PCIE_CORE_RESET);
-	val |= PCIE_CORE_RESET_ENABLE;
+	val = exynos_pcie_readl(ep->elbi_base, EXYNOS_PCIE_CORE_RESET);
+	val |= EXYNOS_PCIE_CORE_RESET_ENABLE;
 
-	exynos_pcie_writel(ep->elbi_base, val, PCIE_CORE_RESET);
-	exynos_pcie_writel(ep->elbi_base, 1, PCIE_STICKY_RESET);
-	exynos_pcie_writel(ep->elbi_base, 1, PCIE_NONSTICKY_RESET);
-	exynos_pcie_writel(ep->elbi_base, 1, PCIE_APP_INIT_RESET);
-	exynos_pcie_writel(ep->elbi_base, 0, PCIE_APP_INIT_RESET);
+	exynos_pcie_writel(ep->elbi_base, val, EXYNOS_PCIE_CORE_RESET);
+	exynos_pcie_writel(ep->elbi_base, 1, EXYNOS_PCIE_STICKY_RESET);
+	exynos_pcie_writel(ep->elbi_base, 1, EXYNOS_PCIE_NONSTICKY_RESET);
+	exynos_pcie_writel(ep->elbi_base, 1, EXYNOS_PCIE_APP_INIT_RESET);
+	exynos_pcie_writel(ep->elbi_base, 0, EXYNOS_PCIE_APP_INIT_RESET);
 }
 
 static int exynos_pcie_start_link(struct dw_pcie *pci)
@@ -121,21 +121,21 @@ static int exynos_pcie_start_link(struct dw_pcie *pci)
 	struct exynos_pcie *ep = to_exynos_pcie(pci);
 	u32 val;
 
-	val = exynos_pcie_readl(ep->elbi_base, PCIE_SW_WAKE);
-	val &= ~PCIE_BUS_EN;
-	exynos_pcie_writel(ep->elbi_base, val, PCIE_SW_WAKE);
+	val = exynos_pcie_readl(ep->elbi_base, EXYNOS_PCIE_SW_WAKE);
+	val &= ~EXYNOS_PCIE_BUS_EN;
+	exynos_pcie_writel(ep->elbi_base, val, EXYNOS_PCIE_SW_WAKE);
 
 	/* assert LTSSM enable */
-	exynos_pcie_writel(ep->elbi_base, PCIE_ELBI_LTSSM_ENABLE,
-			  PCIE_APP_LTSSM_ENABLE);
+	exynos_pcie_writel(ep->elbi_base, EXYNOS_PCIE_ELBI_LTSSM_ENABLE,
+			  EXYNOS_PCIE_APP_LTSSM_ENABLE);
 	return 0;
 }
 
 static void exynos_pcie_clear_irq_pulse(struct exynos_pcie *ep)
 {
-	u32 val = exynos_pcie_readl(ep->elbi_base, PCIE_IRQ_PULSE);
+	u32 val = exynos_pcie_readl(ep->elbi_base, EXYNOS_PCIE_IRQ_PULSE);
 
-	exynos_pcie_writel(ep->elbi_base, val, PCIE_IRQ_PULSE);
+	exynos_pcie_writel(ep->elbi_base, val, EXYNOS_PCIE_IRQ_PULSE);
 }
 
 static irqreturn_t exynos_pcie_irq_handler(int irq, void *arg)
@@ -148,12 +148,12 @@ static irqreturn_t exynos_pcie_irq_handler(int irq, void *arg)
 
 static void exynos_pcie_enable_irq_pulse(struct exynos_pcie *ep)
 {
-	u32 val = IRQ_INTA_ASSERT | IRQ_INTB_ASSERT |
-		  IRQ_INTC_ASSERT | IRQ_INTD_ASSERT;
+	u32 val = EXYNOS_IRQ_INTA_ASSERT | EXYNOS_IRQ_INTB_ASSERT |
+		  EXYNOS_IRQ_INTC_ASSERT | EXYNOS_IRQ_INTD_ASSERT;
 
-	exynos_pcie_writel(ep->elbi_base, val, PCIE_IRQ_EN_PULSE);
-	exynos_pcie_writel(ep->elbi_base, 0, PCIE_IRQ_EN_LEVEL);
-	exynos_pcie_writel(ep->elbi_base, 0, PCIE_IRQ_EN_SPECIAL);
+	exynos_pcie_writel(ep->elbi_base, val, EXYNOS_PCIE_IRQ_EN_PULSE);
+	exynos_pcie_writel(ep->elbi_base, 0, EXYNOS_PCIE_IRQ_EN_LEVEL);
+	exynos_pcie_writel(ep->elbi_base, 0, EXYNOS_PCIE_IRQ_EN_SPECIAL);
 }
 
 static u32 exynos_pcie_read_dbi(struct dw_pcie *pci, void __iomem *base,
@@ -210,9 +210,9 @@ static struct pci_ops exynos_pci_ops = {
 static bool exynos_pcie_link_up(struct dw_pcie *pci)
 {
 	struct exynos_pcie *ep = to_exynos_pcie(pci);
-	u32 val = exynos_pcie_readl(ep->elbi_base, PCIE_ELBI_RDLH_LINKUP);
+	u32 val = exynos_pcie_readl(ep->elbi_base, EXYNOS_PCIE_ELBI_RDLH_LINKUP);
 
-	return val & PCIE_ELBI_XMLH_LINKUP;
+	return val & EXYNOS_PCIE_ELBI_XMLH_LINKUP;
 }
 
 static int exynos_pcie_host_init(struct dw_pcie_rp *pp)
-- 
2.49.0



From shradha.t at samsung.com  Mon Aug 11 08:46:26 2025
From: shradha.t at samsung.com (Shradha Todi)
Date: Mon, 11 Aug 2025 21:16:26 +0530
Subject: [PATCH v3 00/12] Add PCIe support for Tesla FSD SoC
References: <CGME20250811154648epcas5p4e55cc82e0df7d44ea55e249fef63d5fa@epcas5p4.samsung.com>
Message-ID: <20250811154638.95732-1-shradha.t@samsung.com>

FSD platform has three instances of DesignWare based PCIe IP,
one is in FSYS0 block and other two in FSYS1 block.
This patch series add required DT binding, DT file modifications,
Controller driver support and PHY driver support for the same.

To keep single PCIe controller driver and PHY driver for all Samsung
manufactured SoC, we have made changes to Exynos files to extend
support for FSD platform and other Samsung manufactured SoCs which
shall be upstreamed soon.

First a version was posted as a separate driver file:
https://lore.kernel.org/lkml/20221121105210.68596-1-shradha.t at samsung.com/
This was rejected and request was made to add the support in exynos file
itself.

Then another patchset was posted to refactor existing exynos file:
https://lore.kernel.org/lkml/649a8d88-0504-5aa9-d167-d25d394f3f26 at linaro.org/T/
This requested some major changes

Taking both these reviews into consideration, I have posted a fresh
patchset where both changes to exynos framework and addition of new FSD
support is present.

v3:
 - Made separate DT bindings for Exynos5433 and FSD platforms as not
   much is shared
 - Moved all common changes to separate patch for controller and PHY
   and added FSD related changes on top
 - Removed alias method of differentiating between instances of PHY and
   added two separate compatibles.
 - Fixed smatch issues pointed out by Dan and other styling issues.

v2: https://lore.kernel.org/all/20250625165229.3458-1-shradha.t at samsung.com/ 
 - Reordered patches for removing unused MACROs and renaming them
 - Fixed all incomplete DT bindings
 - Modified PHY driver code to adopt better design
 - Removed patch to add alignment data in PCI endpoint test driver
 - Added dts changes in the patchset itself

v1: https://lore.kernel.org/lkml/20250518193152.63476-1-shradha.t at samsung.com/ 


*** BLURB HERE ***

Shradha Todi (12):
  PCI: exynos: Remove unused MACROs in exynos PCIe file
  PCI: exynos: Change macro names to exynos specific
  PCI: exynos: Reorder MACROs to maintain consistency
  PCI: exynos: Add platform device private data
  PCI: exynos: Add resource ops, soc variant and device mode
  dt-bindings: PCI: Split exynos host into two files
  dt-bindings: PCI: Add support for Tesla FSD SoC
  dt-bindings: phy: Add PCIe PHY support for FSD SoC
  phy: exynos: Add platform device private data
  phy: exynos: Add PCIe PHY support for FSD SoC
  PCI: exynos: Add support for Tesla FSD SoC
  arm64: dts: fsd: Add PCIe support for Tesla FSD SoC

 .../bindings/pci/samsung,exynos-pcie.yaml     |  70 +--
 .../bindings/pci/samsung,exynos5433-pcie.yaml |  89 +++
 .../bindings/pci/tesla,fsd-pcie-ep.yaml       |  91 +++
 .../bindings/pci/tesla,fsd-pcie.yaml          |  77 +++
 .../bindings/phy/samsung,exynos-pcie-phy.yaml |  27 +-
 arch/arm64/boot/dts/tesla/fsd-evb.dts         |  34 ++
 arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi    |  65 ++
 arch/arm64/boot/dts/tesla/fsd.dtsi            | 147 +++++
 drivers/pci/controller/dwc/pci-exynos.c       | 567 +++++++++++++++---
 drivers/phy/samsung/phy-exynos-pcie.c         | 295 ++++++++-
 10 files changed, 1300 insertions(+), 162 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/samsung,exynos5433-pcie.yaml
 create mode 100644 Documentation/devicetree/bindings/pci/tesla,fsd-pcie-ep.yaml
 create mode 100644 Documentation/devicetree/bindings/pci/tesla,fsd-pcie.yaml

-- 
2.49.0



From shradha.t at samsung.com  Mon Aug 11 08:46:29 2025
From: shradha.t at samsung.com (Shradha Todi)
Date: Mon, 11 Aug 2025 21:16:29 +0530
Subject: [PATCH v3 03/12] PCI: exynos: Reorder MACROs to maintain
 consistency
In-Reply-To: <20250811154638.95732-1-shradha.t@samsung.com>
References: <20250811154638.95732-1-shradha.t@samsung.com>
	<CGME20250811154707epcas5p20e96a10de3fffcaaf95861358811446c@epcas5p2.samsung.com>
Message-ID: <20250811154638.95732-4-shradha.t@samsung.com>

Exynos PCI file follows MACRO definition order where
register offset is defined in ascending order and each
bit field within the offset is defined right after offset
definition. Some MACROs are out of order and so reorder
those MACROs to maintain consistency.

Suggested-by: Hrishikesh Dileep <hrishikesh.d at samsung.com>
Signed-off-by: Shradha Todi <shradha.t at samsung.com>
---
 drivers/pci/controller/dwc/pci-exynos.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-exynos.c b/drivers/pci/controller/dwc/pci-exynos.c
index 30d12ff9b0c6..b4ec167b0583 100644
--- a/drivers/pci/controller/dwc/pci-exynos.c
+++ b/drivers/pci/controller/dwc/pci-exynos.c
@@ -27,11 +27,11 @@
 
 /* PCIe ELBI registers */
 #define EXYNOS_PCIE_IRQ_PULSE			0x000
+#define EXYNOS_PCIE_IRQ_EN_PULSE		0x00c
 #define EXYNOS_IRQ_INTA_ASSERT			BIT(0)
 #define EXYNOS_IRQ_INTB_ASSERT			BIT(2)
 #define EXYNOS_IRQ_INTC_ASSERT			BIT(4)
 #define EXYNOS_IRQ_INTD_ASSERT			BIT(6)
-#define EXYNOS_PCIE_IRQ_EN_PULSE		0x00c
 #define EXYNOS_PCIE_IRQ_EN_LEVEL		0x010
 #define EXYNOS_PCIE_IRQ_EN_SPECIAL		0x014
 #define EXYNOS_PCIE_SW_WAKE			0x018
@@ -42,9 +42,9 @@
 #define EXYNOS_PCIE_NONSTICKY_RESET		0x024
 #define EXYNOS_PCIE_APP_INIT_RESET		0x028
 #define EXYNOS_PCIE_APP_LTSSM_ENABLE		0x02c
+#define EXYNOS_PCIE_ELBI_LTSSM_ENABLE		0x1
 #define EXYNOS_PCIE_ELBI_RDLH_LINKUP		0x074
 #define EXYNOS_PCIE_ELBI_XMLH_LINKUP		BIT(4)
-#define EXYNOS_PCIE_ELBI_LTSSM_ENABLE		0x1
 #define EXYNOS_PCIE_ELBI_SLV_AWMISC		0x11c
 #define EXYNOS_PCIE_ELBI_SLV_ARMISC		0x120
 #define EXYNOS_PCIE_ELBI_SLV_DBI_ENABLE		BIT(21)
-- 
2.49.0



From shradha.t at samsung.com  Mon Aug 11 08:46:30 2025
From: shradha.t at samsung.com (Shradha Todi)
Date: Mon, 11 Aug 2025 21:16:30 +0530
Subject: [PATCH v3 04/12] PCI: exynos: Add platform device private data
In-Reply-To: <20250811154638.95732-1-shradha.t@samsung.com>
References: <20250811154638.95732-1-shradha.t@samsung.com>
	<CGME20250811154711epcas5p1847566b0216447ad0976472dddf096dd@epcas5p1.samsung.com>
Message-ID: <20250811154638.95732-5-shradha.t@samsung.com>

In order to extend this driver to all Samsung manufactured SoCs having
DWC PCIe controller, add private data structure which will hold platform
device specific information. It holds function ops like DWC host ops,
DWC generic ops, and PCI read/write ops which will be used as driver
data for different compatibles.

Suggested-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Shradha Todi <shradha.t at samsung.com>
---
 drivers/pci/controller/dwc/pci-exynos.c | 32 ++++++++++++++++++++-----
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-exynos.c b/drivers/pci/controller/dwc/pci-exynos.c
index b4ec167b0583..c830b20d54f0 100644
--- a/drivers/pci/controller/dwc/pci-exynos.c
+++ b/drivers/pci/controller/dwc/pci-exynos.c
@@ -49,9 +49,16 @@
 #define EXYNOS_PCIE_ELBI_SLV_ARMISC		0x120
 #define EXYNOS_PCIE_ELBI_SLV_DBI_ENABLE		BIT(21)
 
+struct samsung_pcie_pdata {
+	struct pci_ops				*pci_ops;
+	const struct dw_pcie_ops		*dwc_ops;
+	const struct dw_pcie_host_ops		*host_ops;
+};
+
 struct exynos_pcie {
 	struct dw_pcie			pci;
 	void __iomem			*elbi_base;
+	const struct samsung_pcie_pdata	*pdata;
 	struct clk_bulk_data		*clks;
 	struct phy			*phy;
 	struct regulator_bulk_data	supplies[2];
@@ -220,7 +227,7 @@ static int exynos_pcie_host_init(struct dw_pcie_rp *pp)
 	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
 	struct exynos_pcie *ep = to_exynos_pcie(pci);
 
-	pp->bridge->ops = &exynos_pci_ops;
+	pp->bridge->ops = ep->pdata->pci_ops;
 
 	exynos_pcie_assert_core_reset(ep);
 
@@ -268,7 +275,7 @@ static int exynos_add_pcie_port(struct exynos_pcie *ep,
 	return 0;
 }
 
-static const struct dw_pcie_ops dw_pcie_ops = {
+static const struct dw_pcie_ops exynos_dw_pcie_ops = {
 	.read_dbi = exynos_pcie_read_dbi,
 	.write_dbi = exynos_pcie_write_dbi,
 	.link_up = exynos_pcie_link_up,
@@ -279,6 +286,7 @@ static int exynos_pcie_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct exynos_pcie *ep;
+	const struct samsung_pcie_pdata *pdata;
 	struct device_node *np = dev->of_node;
 	int ret;
 
@@ -286,8 +294,11 @@ static int exynos_pcie_probe(struct platform_device *pdev)
 	if (!ep)
 		return -ENOMEM;
 
+	pdata = of_device_get_match_data(dev);
+
+	ep->pdata = pdata;
 	ep->pci.dev = dev;
-	ep->pci.ops = &dw_pcie_ops;
+	ep->pci.ops = pdata->dwc_ops;
 
 	ep->phy = devm_of_phy_get(dev, np, NULL);
 	if (IS_ERR(ep->phy))
@@ -363,9 +374,9 @@ static int exynos_pcie_resume_noirq(struct device *dev)
 		return ret;
 
 	/* exynos_pcie_host_init controls ep->phy */
-	exynos_pcie_host_init(pp);
+	ep->pdata->host_ops->init(pp);
 	dw_pcie_setup_rc(pp);
-	exynos_pcie_start_link(pci);
+	ep->pdata->dwc_ops->start_link(pci);
 	return dw_pcie_wait_for_link(pci);
 }
 
@@ -374,8 +385,17 @@ static const struct dev_pm_ops exynos_pcie_pm_ops = {
 				  exynos_pcie_resume_noirq)
 };
 
+static const struct samsung_pcie_pdata exynos_5433_pcie_rc_pdata = {
+	.dwc_ops		= &exynos_dw_pcie_ops,
+	.pci_ops		= &exynos_pci_ops,
+	.host_ops		= &exynos_pcie_host_ops,
+};
+
 static const struct of_device_id exynos_pcie_of_match[] = {
-	{ .compatible = "samsung,exynos5433-pcie", },
+	{
+		.compatible = "samsung,exynos5433-pcie",
+		.data = (void *) &exynos_5433_pcie_rc_pdata,
+	},
 	{ },
 };
 
-- 
2.49.0



From shradha.t at samsung.com  Mon Aug 11 08:46:31 2025
From: shradha.t at samsung.com (Shradha Todi)
Date: Mon, 11 Aug 2025 21:16:31 +0530
Subject: [PATCH v3 05/12] PCI: exynos: Add resource ops, soc variant and
 device mode
In-Reply-To: <20250811154638.95732-1-shradha.t@samsung.com>
References: <20250811154638.95732-1-shradha.t@samsung.com>
	<CGME20250811154716epcas5p44980091d5273073b9bf2031572c38376@epcas5p4.samsung.com>
Message-ID: <20250811154638.95732-6-shradha.t@samsung.com>

Some resources might differ based on platforms and we need platform
specific functions to initialize or alter them. For better code
re-usability, making a separate res_ops which will hold all such
function pointers or other resource specific data. Include ops like
 - init_regulator (initialize the regulator data)
 - pcie_irq_handler (interrupt handler for PCIe)
 - set_device_mode (set device mode to EP or RC)

Some operations maybe specific to certain SoCs and not applicable
to others. For such use cases, adding an SoC variant data field
which can be used to distinguish between the variants.

Some SoCs may have dual-role PCIe controller which can work as
RC or EP. Add device_mode to store the role and take decisions
accordingly.

Make enable/disable of regulator and initialization of IRQ as
common functions to be used by all Samsung SoCs.

Suggested-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Shradha Todi <shradha.t at samsung.com>
---
 drivers/pci/controller/dwc/pci-exynos.c | 143 +++++++++++++++++++-----
 1 file changed, 116 insertions(+), 27 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-exynos.c b/drivers/pci/controller/dwc/pci-exynos.c
index c830b20d54f0..ef1f42236575 100644
--- a/drivers/pci/controller/dwc/pci-exynos.c
+++ b/drivers/pci/controller/dwc/pci-exynos.c
@@ -49,10 +49,18 @@
 #define EXYNOS_PCIE_ELBI_SLV_ARMISC		0x120
 #define EXYNOS_PCIE_ELBI_SLV_DBI_ENABLE		BIT(21)
 
+/* to store different SoC variants of Samsung */
+enum samsung_pcie_variants {
+	EXYNOS_5433,
+};
+
 struct samsung_pcie_pdata {
 	struct pci_ops				*pci_ops;
 	const struct dw_pcie_ops		*dwc_ops;
 	const struct dw_pcie_host_ops		*host_ops;
+	const struct samsung_res_ops		*res_ops;
+	unsigned int				soc_variant;
+	enum dw_pcie_device_mode		device_mode;
 };
 
 struct exynos_pcie {
@@ -61,7 +69,14 @@ struct exynos_pcie {
 	const struct samsung_pcie_pdata	*pdata;
 	struct clk_bulk_data		*clks;
 	struct phy			*phy;
-	struct regulator_bulk_data	supplies[2];
+	struct regulator_bulk_data	*supplies;
+	int				supplies_cnt;
+};
+
+struct samsung_res_ops {
+	int (*init_regulator)(struct exynos_pcie *ep);
+	irqreturn_t (*pcie_irq_handler)(int irq, void *arg);
+	void (*set_device_mode)(struct exynos_pcie *ep);
 };
 
 static void exynos_pcie_writel(void __iomem *base, u32 val, u32 reg)
@@ -74,6 +89,31 @@ static u32 exynos_pcie_readl(void __iomem *base, u32 reg)
 	return readl(base + reg);
 }
 
+static int samsung_regulator_enable(struct exynos_pcie *ep)
+{
+	int ret;
+
+	if (ep->supplies_cnt == 0)
+		return 0;
+
+	ret = regulator_bulk_enable(ep->supplies_cnt, ep->supplies);
+
+	return ret;
+}
+
+static void samsung_regulator_disable(struct exynos_pcie *ep)
+{
+	struct device *dev = ep->pci.dev;
+	int ret;
+
+	if (ep->supplies_cnt == 0)
+		return;
+
+	ret = regulator_bulk_disable(ep->supplies_cnt, ep->supplies);
+	if (ret)
+		dev_warn(dev, "failed to disable regulators: %d\n", ret);
+}
+
 static void exynos_pcie_sideband_dbi_w_mode(struct exynos_pcie *ep, bool on)
 {
 	u32 val;
@@ -244,7 +284,26 @@ static const struct dw_pcie_host_ops exynos_pcie_host_ops = {
 	.init = exynos_pcie_host_init,
 };
 
-static int exynos_add_pcie_port(struct exynos_pcie *ep,
+static int exynos_init_regulator(struct exynos_pcie *ep)
+{
+	struct device *dev = ep->pci.dev;
+	int ret = 0;
+
+	ep->supplies_cnt = 2;
+
+	ep->supplies = devm_kcalloc(dev, ep->supplies_cnt, sizeof(*ep->supplies), GFP_KERNEL);
+	if (!ep->supplies)
+		return -ENOMEM;
+
+	ep->supplies[0].supply = "vdd18";
+	ep->supplies[1].supply = "vdd10";
+
+	ret = devm_regulator_bulk_get(dev, ep->supplies_cnt, ep->supplies);
+
+	return ret;
+}
+
+static int samsung_irq_init(struct exynos_pcie *ep,
 				       struct platform_device *pdev)
 {
 	struct dw_pcie *pci = &ep->pci;
@@ -256,22 +315,15 @@ static int exynos_add_pcie_port(struct exynos_pcie *ep,
 	if (pp->irq < 0)
 		return pp->irq;
 
-	ret = devm_request_irq(dev, pp->irq, exynos_pcie_irq_handler,
+	ret = devm_request_irq(dev, pp->irq, ep->pdata->res_ops->pcie_irq_handler,
 			       IRQF_SHARED, "exynos-pcie", ep);
 	if (ret) {
 		dev_err(dev, "failed to request irq\n");
 		return ret;
 	}
 
-	pp->ops = &exynos_pcie_host_ops;
 	pp->msi_irq[0] = -ENODEV;
 
-	ret = dw_pcie_host_init(pp);
-	if (ret) {
-		dev_err(dev, "failed to initialize host\n");
-		return ret;
-	}
-
 	return 0;
 }
 
@@ -282,6 +334,11 @@ static const struct dw_pcie_ops exynos_dw_pcie_ops = {
 	.start_link = exynos_pcie_start_link,
 };
 
+static const struct samsung_res_ops exynos_res_ops_data = {
+	.init_regulator		= exynos_init_regulator,
+	.pcie_irq_handler	= exynos_pcie_irq_handler,
+};
+
 static int exynos_pcie_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -313,28 +370,46 @@ static int exynos_pcie_probe(struct platform_device *pdev)
 	if (ret < 0)
 		return ret;
 
-	ep->supplies[0].supply = "vdd18";
-	ep->supplies[1].supply = "vdd10";
-	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ep->supplies),
-				      ep->supplies);
-	if (ret)
-		return ret;
+	if (pdata->res_ops && pdata->res_ops->init_regulator) {
+		ret = ep->pdata->res_ops->init_regulator(ep);
+		if (ret)
+			return ret;
+	}
 
-	ret = regulator_bulk_enable(ARRAY_SIZE(ep->supplies), ep->supplies);
+	ret = samsung_regulator_enable(ep);
 	if (ret)
 		return ret;
 
 	platform_set_drvdata(pdev, ep);
 
-	ret = exynos_add_pcie_port(ep, pdev);
-	if (ret < 0)
-		goto fail_probe;
+	if (pdata->res_ops && pdata->res_ops->set_device_mode)
+		pdata->res_ops->set_device_mode(ep);
+
+	switch (ep->pdata->device_mode) {
+	case DW_PCIE_RC_TYPE:
+		ret = samsung_irq_init(ep, pdev);
+		if (ret)
+			goto fail_regulator;
+
+		ep->pci.pp.ops = pdata->host_ops;
+
+		ret = dw_pcie_host_init(&ep->pci.pp);
+		if (ret < 0)
+			goto fail_phy_init;
+
+		break;
+	default:
+		dev_err(dev, "invalid device type\n");
+		ret = -EINVAL;
+		goto fail_regulator;
+	}
 
 	return 0;
 
-fail_probe:
+fail_phy_init:
 	phy_exit(ep->phy);
-	regulator_bulk_disable(ARRAY_SIZE(ep->supplies), ep->supplies);
+fail_regulator:
+	samsung_regulator_disable(ep);
 
 	return ret;
 }
@@ -343,21 +418,29 @@ static void exynos_pcie_remove(struct platform_device *pdev)
 {
 	struct exynos_pcie *ep = platform_get_drvdata(pdev);
 
+	if (ep->pdata->device_mode == DW_PCIE_EP_TYPE)
+		return;
 	dw_pcie_host_deinit(&ep->pci.pp);
-	exynos_pcie_assert_core_reset(ep);
+	if (ep->pdata->soc_variant == EXYNOS_5433)
+		exynos_pcie_assert_core_reset(ep);
 	phy_power_off(ep->phy);
 	phy_exit(ep->phy);
-	regulator_bulk_disable(ARRAY_SIZE(ep->supplies), ep->supplies);
+	samsung_regulator_disable(ep);
 }
 
 static int exynos_pcie_suspend_noirq(struct device *dev)
 {
 	struct exynos_pcie *ep = dev_get_drvdata(dev);
+	struct dw_pcie *pci = &ep->pci;
 
-	exynos_pcie_assert_core_reset(ep);
+	if (ep->pdata->device_mode == DW_PCIE_EP_TYPE)
+		return 0;
+
+	if (ep->pdata->soc_variant == EXYNOS_5433)
+		exynos_pcie_assert_core_reset(ep);
 	phy_power_off(ep->phy);
 	phy_exit(ep->phy);
-	regulator_bulk_disable(ARRAY_SIZE(ep->supplies), ep->supplies);
+	samsung_regulator_disable(ep);
 
 	return 0;
 }
@@ -369,7 +452,10 @@ static int exynos_pcie_resume_noirq(struct device *dev)
 	struct dw_pcie_rp *pp = &pci->pp;
 	int ret;
 
-	ret = regulator_bulk_enable(ARRAY_SIZE(ep->supplies), ep->supplies);
+	if (ep->pdata->device_mode == DW_PCIE_EP_TYPE)
+		return 0;
+
+	ret = samsung_regulator_enable(ep);
 	if (ret)
 		return ret;
 
@@ -389,6 +475,9 @@ static const struct samsung_pcie_pdata exynos_5433_pcie_rc_pdata = {
 	.dwc_ops		= &exynos_dw_pcie_ops,
 	.pci_ops		= &exynos_pci_ops,
 	.host_ops		= &exynos_pcie_host_ops,
+	.res_ops		= &exynos_res_ops_data,
+	.soc_variant		= EXYNOS_5433,
+	.device_mode		= DW_PCIE_RC_TYPE,
 };
 
 static const struct of_device_id exynos_pcie_of_match[] = {
-- 
2.49.0



From shradha.t at samsung.com  Mon Aug 11 08:46:32 2025
From: shradha.t at samsung.com (Shradha Todi)
Date: Mon, 11 Aug 2025 21:16:32 +0530
Subject: [PATCH v3 06/12] dt-bindings: PCI: Split exynos host into two files
In-Reply-To: <20250811154638.95732-1-shradha.t@samsung.com>
References: <20250811154638.95732-1-shradha.t@samsung.com>
	<CGME20250811154721epcas5p26c9e2880ca55a470f595d914b4030745@epcas5p2.samsung.com>
Message-ID: <20250811154638.95732-7-shradha.t@samsung.com>

The current Exynos PCIe yaml binding file is hard to reuse by
other Samsung SoCs. Refactoring it by:
 - Moving common Samsung PCIe properties into samsung,exynos-pcie.yaml
 - Creating a dedicated samsung,exynos5433-pcie.yaml file for properties
   and constraints specific to the Exynos5433 SoC

Signed-off-by: Shradha Todi <shradha.t at samsung.com>
---
 .../bindings/pci/samsung,exynos-pcie.yaml     | 70 +--------------
 .../bindings/pci/samsung,exynos5433-pcie.yaml | 89 +++++++++++++++++++
 2 files changed, 91 insertions(+), 68 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/samsung,exynos5433-pcie.yaml

diff --git a/Documentation/devicetree/bindings/pci/samsung,exynos-pcie.yaml b/Documentation/devicetree/bindings/pci/samsung,exynos-pcie.yaml
index f20ed7e709f7..fd0b97b30821 100644
--- a/Documentation/devicetree/bindings/pci/samsung,exynos-pcie.yaml
+++ b/Documentation/devicetree/bindings/pci/samsung,exynos-pcie.yaml
@@ -11,7 +11,7 @@ maintainers:
   - Jaehoon Chung <jh80.chung at samsung.com>
 
 description: |+
-  Exynos5433 SoC PCIe host controller is based on the Synopsys DesignWare
+  Samsung SoCs PCIe host controller is based on the Synopsys DesignWare
   PCIe IP and thus inherits all the common properties defined in
   snps,dw-pcie.yaml.
 
@@ -19,9 +19,6 @@ allOf:
   - $ref: /schemas/pci/snps,dw-pcie.yaml#
 
 properties:
-  compatible:
-    const: samsung,exynos5433-pcie
-
   reg:
     items:
       - description: Data Bus Interface (DBI) registers.
@@ -37,83 +34,20 @@ properties:
   interrupts:
     maxItems: 1
 
-  clocks:
-    items:
-      - description: PCIe bridge clock
-      - description: PCIe bus clock
-
-  clock-names:
-    items:
-      - const: pcie
-      - const: pcie_bus
-
   phys:
     maxItems: 1
 
-  vdd10-supply:
-    description:
-      Phandle to a regulator that provides 1.0V power to the PCIe block.
-
-  vdd18-supply:
-    description:
-      Phandle to a regulator that provides 1.8V power to the PCIe block.
-
-  num-lanes:
-    const: 1
-
-  num-viewport:
-    const: 3
-
 required:
   - reg
   - reg-names
   - interrupts
   - "#address-cells"
   - "#size-cells"
-  - "#interrupt-cells"
-  - interrupt-map
-  - interrupt-map-mask
   - ranges
-  - bus-range
   - device_type
   - num-lanes
-  - num-viewport
   - clocks
   - clock-names
   - phys
-  - vdd10-supply
-  - vdd18-supply
-
-unevaluatedProperties: false
-
-examples:
-  - |
-    #include <dt-bindings/interrupt-controller/irq.h>
-    #include <dt-bindings/interrupt-controller/arm-gic.h>
-    #include <dt-bindings/clock/exynos5433.h>
 
-    pcie: pcie at 15700000 {
-        compatible = "samsung,exynos5433-pcie";
-        reg = <0x15700000 0x1000>, <0x156b0000 0x1000>, <0x0c000000 0x1000>;
-        reg-names = "dbi", "elbi", "config";
-        #address-cells = <3>;
-        #size-cells = <2>;
-        #interrupt-cells = <1>;
-        device_type = "pci";
-        interrupts = <GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>;
-        clocks = <&cmu_fsys CLK_PCIE>, <&cmu_fsys CLK_PCLK_PCIE_PHY>;
-        clock-names = "pcie", "pcie_bus";
-        phys = <&pcie_phy>;
-        pinctrl-0 = <&pcie_bus &pcie_wlanen>;
-        pinctrl-names = "default";
-        num-lanes = <1>;
-        num-viewport = <3>;
-        bus-range = <0x00 0xff>;
-        ranges = <0x81000000 0 0	  0x0c001000 0 0x00010000>,
-                 <0x82000000 0 0x0c011000 0x0c011000 0 0x03feefff>;
-        vdd10-supply = <&ldo6_reg>;
-        vdd18-supply = <&ldo7_reg>;
-        interrupt-map-mask = <0 0 0 0>;
-        interrupt-map = <0 0 0 0 &gic GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>;
-    };
-...
+additionalProperties: true
diff --git a/Documentation/devicetree/bindings/pci/samsung,exynos5433-pcie.yaml b/Documentation/devicetree/bindings/pci/samsung,exynos5433-pcie.yaml
new file mode 100644
index 000000000000..1fb2c32899c4
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/samsung,exynos5433-pcie.yaml
@@ -0,0 +1,89 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/samsung,exynos5433-pcie.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos5433 SoC PCIe Host Controller
+
+maintainers:
+  - Marek Szyprowski <m.szyprowski at samsung.com>
+  - Jaehoon Chung <jh80.chung at samsung.com>
+
+description:
+  Exynos5433 SoCs PCIe host controller inherits all the
+  common properties defined in samsung,exynos-pcie.yaml
+
+allOf:
+  - $ref: /schemas/pci/samsung,exynos-pcie.yaml#
+
+properties:
+  compatible:
+    const: samsung,exynos5433-pcie
+
+  clocks:
+    items:
+      - description: PCIe bridge clock
+      - description: PCIe bus clock
+
+  clock-names:
+    items:
+      - const: pcie
+      - const: pcie_bus
+
+  num-lanes:
+    const: 1
+
+  num-viewport:
+    const: 3
+
+  vdd10-supply:
+    description:
+      phandle to a regulator that provides 1.0v power to the pcie block
+
+  vdd18-supply:
+    description:
+      phandle to a regulator that provides 1.8v power to the pcie block
+
+required:
+  - "#interrupt-cells"
+  - interrupt-map
+  - interrupt-map-mask
+  - bus-range
+  - num-viewport
+  - vdd10-supply
+  - vdd18-supply
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/exynos5433.h>
+
+    pcie: pcie at 15700000 {
+        compatible = "samsung,exynos5433-pcie";
+        reg = <0x15700000 0x1000>, <0x156b0000 0x1000>, <0x0c000000 0x1000>;
+        reg-names = "dbi", "elbi", "config";
+        #address-cells = <3>;
+        #size-cells = <2>;
+        #interrupt-cells = <1>;
+        device_type = "pci";
+        interrupts = <GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&cmu_fsys CLK_PCIE>, <&cmu_fsys CLK_PCLK_PCIE_PHY>;
+        clock-names = "pcie", "pcie_bus";
+        phys = <&pcie_phy>;
+        pinctrl-0 = <&pcie_bus &pcie_wlanen>;
+        pinctrl-names = "default";
+        num-lanes = <1>;
+        num-viewport = <3>;
+        bus-range = <0x00 0xff>;
+        ranges = <0x81000000 0 0	  0x0c001000 0 0x00010000>,
+                 <0x82000000 0 0x0c011000 0x0c011000 0 0x03feefff>;
+        vdd10-supply = <&ldo6_reg>;
+        vdd18-supply = <&ldo7_reg>;
+        interrupt-map-mask = <0 0 0 0>;
+        interrupt-map = <0 0 0 0 &gic GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>;
+    };
+...
-- 
2.49.0



From shradha.t at samsung.com  Mon Aug 11 08:46:33 2025
From: shradha.t at samsung.com (Shradha Todi)
Date: Mon, 11 Aug 2025 21:16:33 +0530
Subject: [PATCH v3 07/12] dt-bindings: PCI: Add support for Tesla FSD SoC
In-Reply-To: <20250811154638.95732-1-shradha.t@samsung.com>
References: <20250811154638.95732-1-shradha.t@samsung.com>
	<CGME20250811154725epcas5p428fa3370a32bc2b664a4fd8260078097@epcas5p4.samsung.com>
Message-ID: <20250811154638.95732-8-shradha.t@samsung.com>

Add Tesla FSD SoC support for both RC and EP.

Signed-off-by: Shradha Todi <shradha.t at samsung.com>
---
 .../bindings/pci/tesla,fsd-pcie-ep.yaml       | 91 +++++++++++++++++++
 .../bindings/pci/tesla,fsd-pcie.yaml          | 77 ++++++++++++++++
 2 files changed, 168 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/tesla,fsd-pcie-ep.yaml
 create mode 100644 Documentation/devicetree/bindings/pci/tesla,fsd-pcie.yaml

diff --git a/Documentation/devicetree/bindings/pci/tesla,fsd-pcie-ep.yaml b/Documentation/devicetree/bindings/pci/tesla,fsd-pcie-ep.yaml
new file mode 100644
index 000000000000..8dfe0720e6ab
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/tesla,fsd-pcie-ep.yaml
@@ -0,0 +1,91 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/tesla,fsd-pcie-ep.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Tesla FSD SoC series PCIe Endpoint Controller
+
+maintainers:
+  - Shradha Todi <shradha.t at samsung.com>
+
+description:
+  Tesla FSD SoCs PCIe endpoint controller is based on the Synopsys DesignWare
+  PCIe IP and thus inherits all the common properties defined in
+  snps,dw-pcie-ep.yaml
+
+allOf:
+  - $ref: /schemas/pci/snps,dw-pcie-ep.yaml#
+
+properties:
+  compatible:
+    const: tesla,fsd-pcie-ep
+
+  reg:
+    maxItems: 4
+
+  reg-names:
+    items:
+      - const: elbi
+      - const: dbi
+      - const: dbi2
+      - const: addr_space
+
+  clocks:
+    maxItems: 4
+
+  clock-names:
+    items:
+      - const: aux
+      - const: dbi
+      - const: mstr
+      - const: slv
+
+  num-lanes:
+    maximum: 4
+
+  phys:
+    maxItems: 1
+
+  samsung,syscon-pcie:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: phandle for system control registers, used to
+                 control signals at system level
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - clocks
+  - clock-names
+  - num-lanes
+  - phys
+  - samsung,syscon-pcie
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/fsd-clk.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    bus {
+        #address-cells = <2>;
+        #size-cells = <2>;
+        pcieep0: pcie-ep at 16a00000 {
+            compatible = "tesla,fsd-pcie-ep";
+            reg = <0x0 0x168b0000 0x0 0x1000>,
+                  <0x0 0x16a00000 0x0 0x2000>,
+                  <0x0 0x16a01000 0x0 0x80>,
+                  <0x0 0x17000000 0x0 0xff0000>;
+            reg-names = "elbi", "dbi", "dbi2", "addr_space";
+            clocks = <&clock_fsys1 PCIE_LINK0_IPCLKPORT_AUX_ACLK>,
+                     <&clock_fsys1 PCIE_LINK0_IPCLKPORT_DBI_ACLK>,
+                     <&clock_fsys1 PCIE_LINK0_IPCLKPORT_MSTR_ACLK>,
+                     <&clock_fsys1 PCIE_LINK0_IPCLKPORT_SLV_ACLK>;
+            clock-names = "aux", "dbi", "mstr", "slv";
+            num-lanes = <4>;
+            phys = <&pciephy1>;
+            samsung,syscon-pcie = <&sysreg_fsys1 0x50c>;
+        };
+    };
+...
diff --git a/Documentation/devicetree/bindings/pci/tesla,fsd-pcie.yaml b/Documentation/devicetree/bindings/pci/tesla,fsd-pcie.yaml
new file mode 100644
index 000000000000..533870ab1d73
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/tesla,fsd-pcie.yaml
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/tesla,fsd-pcie.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Tesla FSD SoC series PCIe Host Controller
+
+maintainers:
+  - Shradha Todi <shradha.t at samsung.com>
+
+description:
+  Tesla FSD SoCs PCIe host controller inherits all the common
+  properties defined in samsung,exynos-pcie.yaml
+
+allOf:
+  - $ref: /schemas/pci/samsung,exynos-pcie.yaml#
+
+properties:
+  compatible:
+    const: tesla,fsd-pcie
+
+  clocks:
+    maxItems: 4
+
+  clock-names:
+    items:
+      - const: aux
+      - const: dbi
+      - const: mstr
+      - const: slv
+
+  num-lanes:
+    maximum: 4
+
+  samsung,syscon-pcie:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: phandle for system control registers, used to
+                 control signals at system level
+
+required:
+  - samsung,syscon-pcie
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/fsd-clk.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        pcierc1: pcie at 16b00000 {
+            compatible = "tesla,fsd-pcie";
+            reg = <0x0 0x16b00000 0x0 0x2000>,
+                  <0x0 0x168c0000 0x0 0x1000>,
+                  <0x0 0x18000000 0x0 0x1000>;
+            reg-names = "dbi", "elbi", "config";
+            ranges =  <0x82000000 0x0 0x18001000 0x0 0x18001000 0x0 0xffefff>;
+            clocks = <&clock_fsys1 PCIE_LINK1_IPCLKPORT_AUX_ACLK>,
+                     <&clock_fsys1 PCIE_LINK1_IPCLKPORT_DBI_ACLK>,
+                     <&clock_fsys1 PCIE_LINK1_IPCLKPORT_MSTR_ACLK>,
+                     <&clock_fsys1 PCIE_LINK1_IPCLKPORT_SLV_ACLK>;
+            clock-names = "aux", "dbi", "mstr", "slv";
+            #address-cells = <3>;
+            #size-cells = <2>;
+            dma-coherent;
+            device_type = "pci";
+            interrupts = <GIC_SPI 117 IRQ_TYPE_EDGE_RISING>;
+            num-lanes = <4>;
+            phys = <&pciephy1>;
+            samsung,syscon-pcie = <&sysreg_fsys1 0x510>;
+        };
+    };
+...
-- 
2.49.0



From shradha.t at samsung.com  Mon Aug 11 08:46:34 2025
From: shradha.t at samsung.com (Shradha Todi)
Date: Mon, 11 Aug 2025 21:16:34 +0530
Subject: [PATCH v3 08/12] dt-bindings: phy: Add PCIe PHY support for FSD SoC
In-Reply-To: <20250811154638.95732-1-shradha.t@samsung.com>
References: <20250811154638.95732-1-shradha.t@samsung.com>
	<CGME20250811154729epcas5p456ddb0d1ba34b992204f54724b57a401@epcas5p4.samsung.com>
Message-ID: <20250811154638.95732-9-shradha.t@samsung.com>

Since Tesla FSD SoC uses Samsung PCIe PHY, add support in
exynos PCIe PHY bindings.

In Tesla FSD SoC, the two PHY instances, although having identical
hardware design and register maps, are placed in different locations
(Placement and routing) inside the SoC and have distinct
PHY-to-Controller topologies. (One instance is connected to two PCIe
controllers, while the other is connected to only one). As a result,
they experience different analog environments, including varying
channel losses and noise profiles.

Since these PHYs lack internal adaptation mechanisms and f/w based
tuning, manual register programming is required for analog tuning.
To ensure optimal signal integrity, it is essential to use different
register values for each PHY instance, despite their identical hardware
design. This is because the same register values may not be suitable
for both instances due to their differing environments and topologies.

Due to this, we are using two PHY compatibles for different PHY
instances.

Signed-off-by: Shradha Todi <shradha.t at samsung.com>
---
 .../bindings/phy/samsung,exynos-pcie-phy.yaml | 27 +++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/samsung,exynos-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,exynos-pcie-phy.yaml
index 41df8bb08ff7..6295472696db 100644
--- a/Documentation/devicetree/bindings/phy/samsung,exynos-pcie-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/samsung,exynos-pcie-phy.yaml
@@ -15,10 +15,14 @@ properties:
     const: 0
 
   compatible:
-    const: samsung,exynos5433-pcie-phy
+    enum:
+      - samsung,exynos5433-pcie-phy
+      - tesla,fsd-pcie-phy0
+      - tesla,fsd-pcie-phy1
 
   reg:
-    maxItems: 1
+    minItems: 1
+    maxItems: 2
 
   samsung,pmu-syscon:
     $ref: /schemas/types.yaml#/definitions/phandle
@@ -30,6 +34,25 @@ properties:
     description: phandle for FSYS sysreg interface, used to control
                  sysreg registers bits for PCIe PHY
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - tesla,fsd-pcie-phy0
+              - tesla,fsd-pcie-phy1
+    then:
+      properties:
+        reg:
+          items:
+            - description: PHY
+            - description: PCS
+    else:
+      properties:
+        reg:
+          maxItems: 1
+
 required:
   - "#phy-cells"
   - compatible
-- 
2.49.0



From shradha.t at samsung.com  Mon Aug 11 08:46:35 2025
From: shradha.t at samsung.com (Shradha Todi)
Date: Mon, 11 Aug 2025 21:16:35 +0530
Subject: [PATCH v3 09/12] phy: exynos: Add platform device private data
In-Reply-To: <20250811154638.95732-1-shradha.t@samsung.com>
References: <20250811154638.95732-1-shradha.t@samsung.com>
	<CGME20250811154734epcas5p1ed075fa71285a5c34c2d319bb01c98ac@epcas5p1.samsung.com>
Message-ID: <20250811154638.95732-10-shradha.t@samsung.com>

Currently, the exynos PCIe PHY driver supports only single
phy ops making it unusable for other platforms. Add the phy_ops
as platform specific device data so as to extend this driver
to support all platforms using Samsung PHY.

Signed-off-by: Shradha Todi <shradha.t at samsung.com>
---
 drivers/phy/samsung/phy-exynos-pcie.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/samsung/phy-exynos-pcie.c b/drivers/phy/samsung/phy-exynos-pcie.c
index 53c9230c2907..022222a0212a 100644
--- a/drivers/phy/samsung/phy-exynos-pcie.c
+++ b/drivers/phy/samsung/phy-exynos-pcie.c
@@ -136,6 +136,7 @@ static const struct phy_ops exynos5433_phy_ops = {
 static const struct of_device_id exynos_pcie_phy_match[] = {
 	{
 		.compatible = "samsung,exynos5433-pcie-phy",
+		.data = &exynos5433_phy_ops,
 	},
 	{},
 };
@@ -146,6 +147,11 @@ static int exynos_pcie_phy_probe(struct platform_device *pdev)
 	struct exynos_pcie_phy *exynos_phy;
 	struct phy *generic_phy;
 	struct phy_provider *phy_provider;
+	const struct phy_ops *drv_data;
+
+	drv_data = of_device_get_match_data(dev);
+	if (!drv_data)
+		return -ENODEV;
 
 	exynos_phy = devm_kzalloc(dev, sizeof(*exynos_phy), GFP_KERNEL);
 	if (!exynos_phy)
@@ -169,7 +175,7 @@ static int exynos_pcie_phy_probe(struct platform_device *pdev)
 		return PTR_ERR(exynos_phy->fsysreg);
 	}
 
-	generic_phy = devm_phy_create(dev, dev->of_node, &exynos5433_phy_ops);
+	generic_phy = devm_phy_create(dev, dev->of_node, drv_data);
 	if (IS_ERR(generic_phy)) {
 		dev_err(dev, "failed to create PHY\n");
 		return PTR_ERR(generic_phy);
-- 
2.49.0



From shradha.t at samsung.com  Mon Aug 11 08:46:36 2025
From: shradha.t at samsung.com (Shradha Todi)
Date: Mon, 11 Aug 2025 21:16:36 +0530
Subject: [PATCH v3 10/12] phy: exynos: Add PCIe PHY support for FSD SoC
In-Reply-To: <20250811154638.95732-1-shradha.t@samsung.com>
References: <20250811154638.95732-1-shradha.t@samsung.com>
	<CGME20250811154738epcas5p1d1202f799c4d950c5d5e7f45e39a51e7@epcas5p1.samsung.com>
Message-ID: <20250811154638.95732-11-shradha.t@samsung.com>

Add PCIe PHY support for Tesla FSD SoC.

Signed-off-by: Shradha Todi <shradha.t at samsung.com>
---
 drivers/phy/samsung/phy-exynos-pcie.c | 287 ++++++++++++++++++++++++++
 1 file changed, 287 insertions(+)

diff --git a/drivers/phy/samsung/phy-exynos-pcie.c b/drivers/phy/samsung/phy-exynos-pcie.c
index 022222a0212a..5a55a22f9661 100644
--- a/drivers/phy/samsung/phy-exynos-pcie.c
+++ b/drivers/phy/samsung/phy-exynos-pcie.c
@@ -34,9 +34,105 @@
 /* PMU PCIE PHY isolation control */
 #define EXYNOS5433_PMU_PCIE_PHY_OFFSET		0x730
 
+/* FSD: PCIe PHY common registers */
+#define FSD_PCIE_PHY_TRSV_CMN_REG03	0x000c
+#define FSD_PCIE_PHY_TRSV_CMN_REG01E	0x0078
+#define FSD_PCIE_PHY_TRSV_CMN_REG02D	0x00b4
+#define FSD_PCIE_PHY_TRSV_CMN_REG031	0x00c4
+#define FSD_PCIE_PHY_TRSV_CMN_REG036	0x00d8
+#define FSD_PCIE_PHY_TRSV_CMN_REG05F	0x017c
+#define FSD_PCIE_PHY_TRSV_CMN_REG060	0x0180
+#define FSD_PCIE_PHY_TRSV_CMN_REG062	0x0188
+#define FSD_PCIE_PHY_TRSV_CMN_REG061	0x0184
+#define FSD_PCIE_PHY_AGG_BIF_RESET	0x0200
+#define FSD_PCIE_PHY_AGG_BIF_CLOCK	0x0208
+#define FSD_PCIE_PHY_CMN_RESET		0x0228
+
+/* FSD: PCIe PHY lane registers */
+#define FSD_PCIE_LANE_OFFSET		0x0400
+#define FSD_PCIE_NUM_LANES		0x4
+
+#define FSD_PCIE_PHY_TRSV_REG001_LN_N	0x0404
+#define FSD_PCIE_PHY_TRSV_REG002_LN_N	0x0408
+#define FSD_PCIE_PHY_TRSV_REG005_LN_N	0x0414
+#define FSD_PCIE_PHY_TRSV_REG006_LN_N	0x0418
+#define FSD_PCIE_PHY_TRSV_REG007_LN_N	0x041c
+#define FSD_PCIE_PHY_TRSV_REG009_LN_N	0x0424
+#define FSD_PCIE_PHY_TRSV_REG00A_LN_N	0x0428
+#define FSD_PCIE_PHY_TRSV_REG00C_LN_N	0x0430
+#define FSD_PCIE_PHY_TRSV_REG012_LN_N	0x0448
+#define FSD_PCIE_PHY_TRSV_REG013_LN_N	0x044c
+#define FSD_PCIE_PHY_TRSV_REG014_LN_N	0x0450
+#define FSD_PCIE_PHY_TRSV_REG015_LN_N	0x0454
+#define FSD_PCIE_PHY_TRSV_REG016_LN_N	0x0458
+#define FSD_PCIE_PHY_TRSV_REG018_LN_N	0x0460
+#define FSD_PCIE_PHY_TRSV_REG020_LN_N	0x0480
+#define FSD_PCIE_PHY_TRSV_REG026_LN_N	0x0498
+#define FSD_PCIE_PHY_TRSV_REG029_LN_N	0x04a4
+#define FSD_PCIE_PHY_TRSV_REG031_LN_N	0x04c4
+#define FSD_PCIE_PHY_TRSV_REG036_LN_N	0x04d8
+#define FSD_PCIE_PHY_TRSV_REG039_LN_N	0x04e4
+#define FSD_PCIE_PHY_TRSV_REG03B_LN_N	0x04ec
+#define FSD_PCIE_PHY_TRSV_REG03C_LN_N	0x04f0
+#define FSD_PCIE_PHY_TRSV_REG03E_LN_N	0x04f8
+#define FSD_PCIE_PHY_TRSV_REG03F_LN_N	0x04fc
+#define FSD_PCIE_PHY_TRSV_REG043_LN_N	0x050c
+#define FSD_PCIE_PHY_TRSV_REG044_LN_N	0x0510
+#define FSD_PCIE_PHY_TRSV_REG046_LN_N	0x0518
+#define FSD_PCIE_PHY_TRSV_REG048_LN_N	0x0520
+#define FSD_PCIE_PHY_TRSV_REG049_LN_N	0x0524
+#define FSD_PCIE_PHY_TRSV_REG04E_LN_N	0x0538
+#define FSD_PCIE_PHY_TRSV_REG052_LN_N	0x0548
+#define FSD_PCIE_PHY_TRSV_REG068_LN_N	0x05a0
+#define FSD_PCIE_PHY_TRSV_REG069_LN_N	0x05a4
+#define FSD_PCIE_PHY_TRSV_REG06A_LN_N	0x05a8
+#define FSD_PCIE_PHY_TRSV_REG06B_LN_N	0x05ac
+#define FSD_PCIE_PHY_TRSV_REG07B_LN_N	0x05ec
+#define FSD_PCIE_PHY_TRSV_REG083_LN_N	0x060c
+#define FSD_PCIE_PHY_TRSV_REG084_LN_N	0x0610
+#define FSD_PCIE_PHY_TRSV_REG086_LN_N	0x0618
+#define FSD_PCIE_PHY_TRSV_REG087_LN_N	0x061c
+#define FSD_PCIE_PHY_TRSV_REG08B_LN_N	0x062c
+#define FSD_PCIE_PHY_TRSV_REG09C_LN_N	0x0670
+#define FSD_PCIE_PHY_TRSV_REG09D_LN_N	0x0674
+#define FSD_PCIE_PHY_TRSV_REG09E_LN_N	0x0678
+#define FSD_PCIE_PHY_TRSV_REG09F_LN_N	0x067c
+#define FSD_PCIE_PHY_TRSV_REG0A2_LN_N	0x0688
+#define FSD_PCIE_PHY_TRSV_REG0A4_LN_N	0x0690
+#define FSD_PCIE_PHY_TRSV_REG0CE_LN_N	0x0738
+#define FSD_PCIE_PHY_TRSV_REG0FC_LN_N	0x07f0
+#define FSD_PCIE_PHY_TRSV_REG0FD_LN_N	0x07f4
+#define FSD_PCIE_PHY_TRSV_REG0FE_LN_N	0x07f8
+#define FSD_PCIE_PHY_TRSV_REG0CE_LN_1	0x0b38
+#define FSD_PCIE_PHY_TRSV_REG0CE_LN_2	0x0f38
+#define FSD_PCIE_PHY_TRSV_REG0CE_LN_3	0x1338
+
+/* FSD: PCIe PCS registers */
+#define FSD_PCIE_PCS_BRF_0		0x0004
+#define FSD_PCIE_PCS_BRF_1		0x0804
+#define FSD_PCIE_PCS_CLK		0x0180
+
+/* FSD: PCIe SYSREG registers */
+#define FSD_PCIE_SYSREG_PHY_0_CON			0x042c
+#define FSD_PCIE_SYSREG_PHY_0_CON_MASK			0x03ff
+#define FSD_PCIE_SYSREG_PHY_0_REF_SEL			(0x2 << 0)
+#define FSD_PCIE_SYSREG_PHY_0_REF_SEL_MASK		0x3
+#define FSD_PCIE_SYSREG_PHY_0_AUX_EN			BIT(4)
+#define FSD_PCIE_SYSREG_PHY_0_CMN_RSTN			BIT(8)
+#define FSD_PCIE_SYSREG_PHY_0_INIT_RSTN			BIT(9)
+
+#define FSD_PCIE_SYSREG_PHY_1_CON			0x0500
+#define FSD_PCIE_SYSREG_PHY_1_CON_MASK			0x01ff
+#define FSD_PCIE_SYSREG_PHY_1_REF_SEL			(0x2 << 4)
+#define FSD_PCIE_SYSREG_PHY_1_REF_SEL_MASK		0x30
+#define FSD_PCIE_SYSREG_PHY_1_AUX_EN			BIT(0)
+#define FSD_PCIE_SYSREG_PHY_1_CMN_RSTN			BIT(1)
+#define FSD_PCIE_SYSREG_PHY_1_INIT_RSTN			BIT(3)
+
 /* For Exynos pcie phy */
 struct exynos_pcie_phy {
 	void __iomem *base;
+	void __iomem *pcs_base;
 	struct regmap *pmureg;
 	struct regmap *fsysreg;
 };
@@ -133,11 +229,200 @@ static const struct phy_ops exynos5433_phy_ops = {
 	.owner		= THIS_MODULE,
 };
 
+static void fsd_pcie_phy_writel(struct exynos_pcie_phy *phy_ctrl, u32 offset, u32 val)
+{
+	void __iomem *phy_base = phy_ctrl->base;
+	u32 i;
+
+	for (i = 0; i < FSD_PCIE_NUM_LANES; i++)
+		writel(val, phy_base + (offset + i * FSD_PCIE_LANE_OFFSET));
+}
+
+static int fsd_pcie_phy0_reset(struct phy *phy)
+{
+	struct exynos_pcie_phy *phy_ctrl = phy_get_drvdata(phy);
+
+	writel(0x1, phy_ctrl->pcs_base + FSD_PCIE_PCS_CLK);
+
+	regmap_update_bits(phy_ctrl->fsysreg, FSD_PCIE_SYSREG_PHY_0_CON,
+			FSD_PCIE_SYSREG_PHY_0_CON_MASK, 0x0);
+	regmap_update_bits(phy_ctrl->fsysreg, FSD_PCIE_SYSREG_PHY_0_CON,
+		FSD_PCIE_SYSREG_PHY_0_AUX_EN, FSD_PCIE_SYSREG_PHY_0_AUX_EN);
+	regmap_update_bits(phy_ctrl->fsysreg, FSD_PCIE_SYSREG_PHY_0_CON,
+		FSD_PCIE_SYSREG_PHY_0_REF_SEL_MASK, FSD_PCIE_SYSREG_PHY_0_REF_SEL);
+	regmap_update_bits(phy_ctrl->fsysreg, FSD_PCIE_SYSREG_PHY_0_CON,
+		FSD_PCIE_SYSREG_PHY_0_INIT_RSTN, FSD_PCIE_SYSREG_PHY_0_INIT_RSTN);
+
+	return 0;
+}
+
+static int fsd_pcie_phy1_reset(struct phy *phy)
+{
+	struct exynos_pcie_phy *phy_ctrl = phy_get_drvdata(phy);
+
+	writel(0x1, phy_ctrl->pcs_base + FSD_PCIE_PCS_CLK);
+
+	regmap_update_bits(phy_ctrl->fsysreg, FSD_PCIE_SYSREG_PHY_1_CON,
+			FSD_PCIE_SYSREG_PHY_1_CON_MASK, 0x0);
+	regmap_update_bits(phy_ctrl->fsysreg, FSD_PCIE_SYSREG_PHY_1_CON,
+		FSD_PCIE_SYSREG_PHY_1_AUX_EN, FSD_PCIE_SYSREG_PHY_1_AUX_EN);
+	regmap_update_bits(phy_ctrl->fsysreg, FSD_PCIE_SYSREG_PHY_1_CON,
+		FSD_PCIE_SYSREG_PHY_1_REF_SEL_MASK, FSD_PCIE_SYSREG_PHY_1_REF_SEL);
+	regmap_update_bits(phy_ctrl->fsysreg, FSD_PCIE_SYSREG_PHY_1_CON,
+		FSD_PCIE_SYSREG_PHY_1_INIT_RSTN, FSD_PCIE_SYSREG_PHY_1_INIT_RSTN);
+
+	return 0;
+}
+
+static int fsd_pcie_phy0_init(struct phy *phy)
+{
+	struct exynos_pcie_phy *phy_ctrl = phy_get_drvdata(phy);
+	void __iomem *pbase = phy_ctrl->base;
+
+	fsd_pcie_phy0_reset(phy);
+
+	writel(0x00, phy_ctrl->pcs_base + FSD_PCIE_PCS_BRF_0);
+	writel(0x00, phy_ctrl->pcs_base + FSD_PCIE_PCS_BRF_1);
+	writel(0x00, pbase + FSD_PCIE_PHY_AGG_BIF_RESET);
+	writel(0x00, pbase + FSD_PCIE_PHY_AGG_BIF_CLOCK);
+
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG07B_LN_N, 0x20);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG052_LN_N, 0x00);
+	writel(0x11, pbase + FSD_PCIE_PHY_TRSV_CMN_REG05F);
+	writel(0x23, pbase + FSD_PCIE_PHY_TRSV_CMN_REG060);
+	writel(0x0, pbase + FSD_PCIE_PHY_TRSV_CMN_REG062);
+	writel(0x15, pbase + FSD_PCIE_PHY_TRSV_CMN_REG03);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG0CE_LN_N, 0x8);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG039_LN_N, 0xf);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG03B_LN_N, 0x13);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG03C_LN_N, 0xf6);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG044_LN_N, 0x57);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG03E_LN_N, 0x10);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG03F_LN_N, 0x04);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG043_LN_N, 0x11);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG049_LN_N, 0x6f);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG04E_LN_N, 0x18);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG068_LN_N, 0x1f);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG069_LN_N, 0xc);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG06B_LN_N, 0x78);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG083_LN_N, 0xa);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG084_LN_N, 0x80);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG086_LN_N, 0xff);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG087_LN_N, 0x3c);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG09D_LN_N, 0x7c);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG09E_LN_N, 0x33);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG09F_LN_N, 0x33);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG001_LN_N, 0x3f);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG002_LN_N, 0x1c);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG005_LN_N, 0x2b);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG006_LN_N, 0x3);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG007_LN_N, 0x0c);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG009_LN_N, 0x10);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG00A_LN_N, 0x1);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG00C_LN_N, 0x93);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG012_LN_N, 0x1);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG013_LN_N, 0x0);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG014_LN_N, 0x70);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG015_LN_N, 0x0);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG016_LN_N, 0x70);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG0FC_LN_N, 0x80);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG0FD_LN_N, 0x0);
+
+	regmap_update_bits(phy_ctrl->fsysreg, FSD_PCIE_SYSREG_PHY_0_CON,
+		FSD_PCIE_SYSREG_PHY_0_CMN_RSTN, FSD_PCIE_SYSREG_PHY_0_CMN_RSTN);
+
+	return 0;
+}
+
+static int fsd_pcie_phy1_init(struct phy *phy)
+{
+	struct exynos_pcie_phy *phy_ctrl = phy_get_drvdata(phy);
+	void __iomem *pbase = phy_ctrl->base;
+
+	fsd_pcie_phy1_reset(phy);
+
+	writel(0x2, pbase + FSD_PCIE_PHY_CMN_RESET);
+
+	writel(0x00, phy_ctrl->pcs_base + FSD_PCIE_PCS_BRF_0);
+	writel(0x00, phy_ctrl->pcs_base + FSD_PCIE_PCS_BRF_1);
+	writel(0x00, pbase + FSD_PCIE_PHY_AGG_BIF_RESET);
+	writel(0x00, pbase + FSD_PCIE_PHY_AGG_BIF_CLOCK);
+
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG07B_LN_N, 0x20);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG052_LN_N, 0x00);
+	writel(0xaa, pbase + FSD_PCIE_PHY_TRSV_CMN_REG01E);
+	writel(0x28, pbase + FSD_PCIE_PHY_TRSV_CMN_REG02D);
+	writel(0x28, pbase + FSD_PCIE_PHY_TRSV_CMN_REG031);
+	writel(0x21, pbase + FSD_PCIE_PHY_TRSV_CMN_REG036);
+	writel(0x12, pbase + FSD_PCIE_PHY_TRSV_CMN_REG05F);
+	writel(0x23, pbase + FSD_PCIE_PHY_TRSV_CMN_REG060);
+	writel(0x0, pbase + FSD_PCIE_PHY_TRSV_CMN_REG061);
+	writel(0x0, pbase + FSD_PCIE_PHY_TRSV_CMN_REG062);
+	writel(0x15, pbase + FSD_PCIE_PHY_TRSV_CMN_REG03);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG039_LN_N, 0xf);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG03B_LN_N, 0x13);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG03C_LN_N, 0x66);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG044_LN_N, 0x57);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG03E_LN_N, 0x10);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG03F_LN_N, 0x44);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG043_LN_N, 0x11);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG046_LN_N, 0xef);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG048_LN_N, 0x06);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG049_LN_N, 0xaf);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG04E_LN_N, 0x28);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG068_LN_N, 0x1f);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG069_LN_N, 0xc);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG06A_LN_N, 0x8);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG06B_LN_N, 0x78);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG083_LN_N, 0xa);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG084_LN_N, 0x80);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG087_LN_N, 0x30);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG08B_LN_N, 0xa0);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG09C_LN_N, 0xf7);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG09E_LN_N, 0x33);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG0A2_LN_N, 0xfa);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG0A4_LN_N, 0xf2);
+	writel(0x8, pbase + FSD_PCIE_PHY_TRSV_REG0CE_LN_N);
+	writel(0x9, pbase + FSD_PCIE_PHY_TRSV_REG0CE_LN_1);
+	writel(0x9, pbase + FSD_PCIE_PHY_TRSV_REG0CE_LN_2);
+	writel(0x9, pbase + FSD_PCIE_PHY_TRSV_REG0CE_LN_3);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG0FE_LN_N, 0x33);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG001_LN_N, 0x3f);
+	fsd_pcie_phy_writel(phy_ctrl, FSD_PCIE_PHY_TRSV_REG005_LN_N, 0x2b);
+
+	writel(0x3, pbase + FSD_PCIE_PHY_CMN_RESET);
+
+	regmap_update_bits(phy_ctrl->fsysreg, FSD_PCIE_SYSREG_PHY_1_CON,
+		FSD_PCIE_SYSREG_PHY_1_CMN_RSTN, FSD_PCIE_SYSREG_PHY_1_CMN_RSTN);
+
+	return 0;
+}
+
+static const struct phy_ops fsd_phy0_ops = {
+	.init		= fsd_pcie_phy0_init,
+	.reset		= fsd_pcie_phy0_reset,
+	.owner		= THIS_MODULE,
+};
+
+static const struct phy_ops fsd_phy1_ops = {
+	.init		= fsd_pcie_phy1_init,
+	.reset		= fsd_pcie_phy1_reset,
+	.owner		= THIS_MODULE,
+};
+
 static const struct of_device_id exynos_pcie_phy_match[] = {
 	{
 		.compatible = "samsung,exynos5433-pcie-phy",
 		.data = &exynos5433_phy_ops,
 	},
+	{
+		.compatible = "tesla,fsd-pcie-phy0",
+		.data = &fsd_phy0_ops,
+	},
+	{
+		.compatible = "tesla,fsd-pcie-phy1",
+		.data = &fsd_phy1_ops,
+	},
 	{},
 };
 
@@ -181,6 +466,8 @@ static int exynos_pcie_phy_probe(struct platform_device *pdev)
 		return PTR_ERR(generic_phy);
 	}
 
+	exynos_phy->pcs_base = devm_platform_ioremap_resource(pdev, 1);
+
 	phy_set_drvdata(generic_phy, exynos_phy);
 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
 
-- 
2.49.0



From shradha.t at samsung.com  Mon Aug 11 08:46:37 2025
From: shradha.t at samsung.com (Shradha Todi)
Date: Mon, 11 Aug 2025 21:16:37 +0530
Subject: [PATCH v3 11/12] PCI: exynos: Add support for Tesla FSD SoC
In-Reply-To: <20250811154638.95732-1-shradha.t@samsung.com>
References: <20250811154638.95732-1-shradha.t@samsung.com>
	<CGME20250811154742epcas5p3276c7c053bedc526d9ce370dda83e195@epcas5p3.samsung.com>
Message-ID: <20250811154638.95732-12-shradha.t@samsung.com>

Add host and endpoint controller driver support for FSD SoC.

Signed-off-by: Shradha Todi <shradha.t at samsung.com>
---
 drivers/pci/controller/dwc/pci-exynos.c | 278 ++++++++++++++++++++++++
 1 file changed, 278 insertions(+)

diff --git a/drivers/pci/controller/dwc/pci-exynos.c b/drivers/pci/controller/dwc/pci-exynos.c
index ef1f42236575..9aabfecdc147 100644
--- a/drivers/pci/controller/dwc/pci-exynos.c
+++ b/drivers/pci/controller/dwc/pci-exynos.c
@@ -18,6 +18,8 @@
 #include <linux/platform_device.h>
 #include <linux/phy/phy.h>
 #include <linux/regulator/consumer.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
 #include <linux/mod_devicetable.h>
 #include <linux/module.h>
 
@@ -49,15 +51,35 @@
 #define EXYNOS_PCIE_ELBI_SLV_ARMISC		0x120
 #define EXYNOS_PCIE_ELBI_SLV_DBI_ENABLE		BIT(21)
 
+#define FSD_IRQ2_STS				0x008
+#define FSD_IRQ_MSI_ENABLE			BIT(17)
+#define FSD_IRQ2_EN				0x018
+#define FSD_PCIE_APP_LTSSM_ENABLE		0x054
+#define FSD_PCIE_LTSSM_ENABLE			0x1
+#define FSD_PCIE_DEVICE_TYPE			0x080
+#define FSD_DEVICE_TYPE_RC			0x4
+#define FSD_DEVICE_TYPE_EP			0x0
+#define FSD_PCIE_CXPL_DEBUG_00_31		0x2c8
+
 /* to store different SoC variants of Samsung */
 enum samsung_pcie_variants {
+	FSD,
 	EXYNOS_5433,
 };
 
+/* Values to be written to SYSREG to view DBI space as CDM/DBI2/IATU/DMA */
+enum fsd_pcie_addr_type {
+	ADDR_TYPE_DBI = 0x0,
+	ADDR_TYPE_DBI2 = 0x12,
+	ADDR_TYPE_ATU = 0x36,
+	ADDR_TYPE_DMA = 0x3f,
+};
+
 struct samsung_pcie_pdata {
 	struct pci_ops				*pci_ops;
 	const struct dw_pcie_ops		*dwc_ops;
 	const struct dw_pcie_host_ops		*host_ops;
+	const struct dw_pcie_ep_ops		*ep_ops;
 	const struct samsung_res_ops		*res_ops;
 	unsigned int				soc_variant;
 	enum dw_pcie_device_mode		device_mode;
@@ -67,6 +89,8 @@ struct exynos_pcie {
 	struct dw_pcie			pci;
 	void __iomem			*elbi_base;
 	const struct samsung_pcie_pdata	*pdata;
+	struct regmap			*sysreg;
+	unsigned int			sysreg_offset;
 	struct clk_bulk_data		*clks;
 	struct phy			*phy;
 	struct regulator_bulk_data	*supplies;
@@ -334,11 +358,201 @@ static const struct dw_pcie_ops exynos_dw_pcie_ops = {
 	.start_link = exynos_pcie_start_link,
 };
 
+static void fsd_pcie_stop_link(struct dw_pcie *pci)
+{
+	u32 val;
+	struct exynos_pcie *ep = to_exynos_pcie(pci);
+
+	val = readl(ep->elbi_base + FSD_PCIE_APP_LTSSM_ENABLE);
+	val &= ~FSD_PCIE_LTSSM_ENABLE;
+	writel(val, ep->elbi_base + FSD_PCIE_APP_LTSSM_ENABLE);
+}
+
+static int fsd_pcie_start_link(struct dw_pcie *pci)
+{
+	struct exynos_pcie *ep = to_exynos_pcie(pci);
+	struct dw_pcie_ep *dw_ep = &pci->ep;
+
+	if (dw_pcie_link_up(pci))
+		return 0;
+
+	writel(FSD_PCIE_LTSSM_ENABLE, ep->elbi_base + FSD_PCIE_APP_LTSSM_ENABLE);
+
+	/* no need to wait for link in case of host as core files take care */
+	if (ep->pdata->device_mode == DW_PCIE_RC_TYPE)
+		return 0;
+
+	/* check if the link is up or not in case of EP */
+	if (!dw_pcie_wait_for_link(pci)) {
+		dw_pcie_ep_linkup(dw_ep);
+		return 0;
+	}
+
+	return -ETIMEDOUT;
+}
+
+static irqreturn_t fsd_pcie_irq_handler(int irq, void *arg)
+{
+	u32 val;
+	struct exynos_pcie *ep = arg;
+	struct dw_pcie *pci = &ep->pci;
+	struct dw_pcie_rp *pp = &pci->pp;
+
+	val = readl(ep->elbi_base + FSD_IRQ2_STS);
+	if ((val & FSD_IRQ_MSI_ENABLE) == FSD_IRQ_MSI_ENABLE) {
+		val &= FSD_IRQ_MSI_ENABLE;
+		writel(val, ep->elbi_base + FSD_IRQ2_STS);
+		dw_handle_msi_irq(pp);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static void fsd_pcie_msi_init(struct exynos_pcie *ep)
+{
+	int val;
+
+	val = readl(ep->elbi_base + FSD_IRQ2_EN);
+	val |= FSD_IRQ_MSI_ENABLE;
+	writel(val, ep->elbi_base + FSD_IRQ2_EN);
+}
+
+static void __iomem *fsd_atu_setting(struct dw_pcie *pci, void __iomem *base)
+{
+	struct exynos_pcie *ep = to_exynos_pcie(pci);
+
+	if (base >= pci->atu_base) {
+		regmap_write(ep->sysreg, ep->sysreg_offset, ADDR_TYPE_ATU);
+		return (base - DEFAULT_DBI_ATU_OFFSET);
+	} else if (base == pci->dbi_base) {
+		regmap_write(ep->sysreg, ep->sysreg_offset, ADDR_TYPE_DBI);
+	} else if (base == pci->dbi_base2) {
+		regmap_write(ep->sysreg, ep->sysreg_offset, ADDR_TYPE_DBI2);
+	}
+
+	return base;
+}
+
+static u32 fsd_pcie_read_dbi(struct dw_pcie *pci, void __iomem *base,
+				u32 reg, size_t size)
+{
+	void __iomem *addr;
+	u32 val;
+
+	addr = fsd_atu_setting(pci, base);
+	dw_pcie_read(addr + reg, size, &val);
+
+	return val;
+}
+
+static void fsd_pcie_write_dbi(struct dw_pcie *pci, void __iomem *base,
+				u32 reg, size_t size, u32 val)
+{
+	void __iomem *addr;
+
+	addr = fsd_atu_setting(pci, base);
+	dw_pcie_write(addr + reg, size, val);
+}
+
+static void fsd_pcie_write_dbi2(struct dw_pcie *pci, void __iomem *base,
+				u32 reg, size_t size, u32 val)
+{
+	struct exynos_pcie *ep = to_exynos_pcie(pci);
+
+	fsd_atu_setting(pci, base);
+	dw_pcie_write(pci->dbi_base + reg, size, val);
+	regmap_write(ep->sysreg, ep->sysreg_offset, ADDR_TYPE_DBI);
+}
+
+static bool fsd_pcie_link_up(struct dw_pcie *pci)
+{
+	u32 val;
+	struct exynos_pcie *ep = to_exynos_pcie(pci);
+
+	val = readl(ep->elbi_base + FSD_PCIE_CXPL_DEBUG_00_31);
+	val &= PORT_LOGIC_LTSSM_STATE_MASK;
+
+	return (val == PORT_LOGIC_LTSSM_STATE_L0);
+}
+
+static int fsd_pcie_host_init(struct dw_pcie_rp *pp)
+{
+	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+	struct exynos_pcie *ep = to_exynos_pcie(pci);
+
+	phy_init(ep->phy);
+	fsd_pcie_msi_init(ep);
+
+	return 0;
+}
+
+static const struct dw_pcie_host_ops fsd_pcie_host_ops = {
+	.init = fsd_pcie_host_init,
+};
+
+static int fsd_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
+				 unsigned int type, u16 interrupt_num)
+{
+	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+
+	switch (type) {
+	case PCI_IRQ_INTX:
+		return dw_pcie_ep_raise_intx_irq(ep, func_no);
+	case PCI_IRQ_MSIX:
+		dev_err(pci->dev, "EP does not support MSI-X\n");
+		return -EINVAL;
+	case PCI_IRQ_MSI:
+		return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num);
+	default:
+		dev_err(pci->dev, "UNKNOWN IRQ type\n");
+	}
+
+	return 0;
+}
+
+static const struct pci_epc_features fsd_pcie_epc_features = {
+	.linkup_notifier = false,
+	.msi_capable = true,
+	.msix_capable = false,
+};
+
+static const struct pci_epc_features *fsd_pcie_get_features(struct dw_pcie_ep *ep)
+{
+	return &fsd_pcie_epc_features;
+}
+
+static const struct dw_pcie_ep_ops fsd_ep_ops = {
+	.raise_irq	= fsd_pcie_raise_irq,
+	.get_features	= fsd_pcie_get_features,
+};
+
+static void fsd_set_device_mode(struct exynos_pcie *ep)
+{
+	if (ep->pdata->device_mode == DW_PCIE_RC_TYPE)
+		writel(FSD_DEVICE_TYPE_RC, ep->elbi_base + FSD_PCIE_DEVICE_TYPE);
+	else
+		writel(FSD_DEVICE_TYPE_EP, ep->elbi_base + FSD_PCIE_DEVICE_TYPE);
+}
+
+static const struct dw_pcie_ops fsd_dw_pcie_ops = {
+	.read_dbi	= fsd_pcie_read_dbi,
+	.write_dbi	= fsd_pcie_write_dbi,
+	.write_dbi2	= fsd_pcie_write_dbi2,
+	.start_link	= fsd_pcie_start_link,
+	.stop_link	= fsd_pcie_stop_link,
+	.link_up	= fsd_pcie_link_up,
+};
+
 static const struct samsung_res_ops exynos_res_ops_data = {
 	.init_regulator		= exynos_init_regulator,
 	.pcie_irq_handler	= exynos_pcie_irq_handler,
 };
 
+static const struct samsung_res_ops fsd_res_ops_data = {
+	.pcie_irq_handler	= fsd_pcie_irq_handler,
+	.set_device_mode	= fsd_set_device_mode,
+};
+
 static int exynos_pcie_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -361,6 +575,26 @@ static int exynos_pcie_probe(struct platform_device *pdev)
 	if (IS_ERR(ep->phy))
 		return PTR_ERR(ep->phy);
 
+	if (ep->pdata->soc_variant == FSD) {
+		ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(36));
+		if (ret)
+			return ret;
+
+		ep->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
+				"samsung,syscon-pcie");
+		if (IS_ERR(ep->sysreg)) {
+			dev_err(dev, "sysreg regmap lookup failed.\n");
+			return PTR_ERR(ep->sysreg);
+		}
+
+		ret = of_property_read_u32_index(dev->of_node, "samsung,syscon-pcie", 1,
+						 &ep->sysreg_offset);
+		if (ret) {
+			dev_err(dev, "couldn't get the register offset for syscon!\n");
+			return ret;
+		}
+	}
+
 	/* External Local Bus interface (ELBI) registers */
 	ep->elbi_base = devm_platform_ioremap_resource_byname(pdev, "elbi");
 	if (IS_ERR(ep->elbi_base))
@@ -397,6 +631,22 @@ static int exynos_pcie_probe(struct platform_device *pdev)
 		if (ret < 0)
 			goto fail_phy_init;
 
+		break;
+	case DW_PCIE_EP_TYPE:
+		phy_init(ep->phy);
+
+		ep->pci.ep.ops = pdata->ep_ops;
+
+		ret = dw_pcie_ep_init(&ep->pci.ep);
+		if (ret < 0)
+			goto fail_phy_init;
+
+		ret = dw_pcie_ep_init_registers(&ep->pci.ep);
+		if (ret)
+			goto fail_phy_init;
+
+		pci_epc_init_notify(ep->pci.ep.epc);
+
 		break;
 	default:
 		dev_err(dev, "invalid device type\n");
@@ -436,6 +686,9 @@ static int exynos_pcie_suspend_noirq(struct device *dev)
 	if (ep->pdata->device_mode == DW_PCIE_EP_TYPE)
 		return 0;
 
+	if (ep->pdata->dwc_ops->stop_link)
+		ep->pdata->dwc_ops->stop_link(pci);
+
 	if (ep->pdata->soc_variant == EXYNOS_5433)
 		exynos_pcie_assert_core_reset(ep);
 	phy_power_off(ep->phy);
@@ -471,6 +724,23 @@ static const struct dev_pm_ops exynos_pcie_pm_ops = {
 				  exynos_pcie_resume_noirq)
 };
 
+
+static const struct samsung_pcie_pdata fsd_hw3_pcie_rc_pdata = {
+	.dwc_ops		= &fsd_dw_pcie_ops,
+	.host_ops		= &fsd_pcie_host_ops,
+	.res_ops		= &fsd_res_ops_data,
+	.soc_variant		= FSD,
+	.device_mode		= DW_PCIE_RC_TYPE,
+};
+
+static const struct samsung_pcie_pdata fsd_hw3_pcie_ep_pdata = {
+	.dwc_ops		= &fsd_dw_pcie_ops,
+	.ep_ops			= &fsd_ep_ops,
+	.res_ops		= &fsd_res_ops_data,
+	.soc_variant		= FSD,
+	.device_mode		= DW_PCIE_EP_TYPE,
+};
+
 static const struct samsung_pcie_pdata exynos_5433_pcie_rc_pdata = {
 	.dwc_ops		= &exynos_dw_pcie_ops,
 	.pci_ops		= &exynos_pci_ops,
@@ -485,6 +755,14 @@ static const struct of_device_id exynos_pcie_of_match[] = {
 		.compatible = "samsung,exynos5433-pcie",
 		.data = (void *) &exynos_5433_pcie_rc_pdata,
 	},
+	{
+		.compatible = "tesla,fsd-pcie",
+		.data = (void *) &fsd_hw3_pcie_rc_pdata,
+	},
+	{
+		.compatible = "tesla,fsd-pcie-ep",
+		.data = (void *) &fsd_hw3_pcie_ep_pdata,
+	},
 	{ },
 };
 
-- 
2.49.0



From shradha.t at samsung.com  Mon Aug 11 08:46:38 2025
From: shradha.t at samsung.com (Shradha Todi)
Date: Mon, 11 Aug 2025 21:16:38 +0530
Subject: [PATCH v3 12/12] arm64: dts: fsd: Add PCIe support for Tesla FSD
 SoC
In-Reply-To: <20250811154638.95732-1-shradha.t@samsung.com>
References: <20250811154638.95732-1-shradha.t@samsung.com>
	<CGME20250811154746epcas5p261ba0c811f9dd8748f8f241b76be6525@epcas5p2.samsung.com>
Message-ID: <20250811154638.95732-13-shradha.t@samsung.com>

Add the support for PCIe controller driver and phy driver for Tesla FSD.
It includes support for both RC and EP.

Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Shradha Todi <shradha.t at samsung.com>
---
 arch/arm64/boot/dts/tesla/fsd-evb.dts      |  34 +++++
 arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi |  65 +++++++++
 arch/arm64/boot/dts/tesla/fsd.dtsi         | 147 +++++++++++++++++++++
 3 files changed, 246 insertions(+)

diff --git a/arch/arm64/boot/dts/tesla/fsd-evb.dts b/arch/arm64/boot/dts/tesla/fsd-evb.dts
index 9ff22e1c8723..1b63c5d72d19 100644
--- a/arch/arm64/boot/dts/tesla/fsd-evb.dts
+++ b/arch/arm64/boot/dts/tesla/fsd-evb.dts
@@ -130,3 +130,37 @@ &serial_0 {
 &ufs {
 	status = "okay";
 };
+
+&pcierc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie1_clkreq>, <&pcie1_wake>, <&pcie1_preset>,
+			<&pcie0_slot1>;
+};
+
+&pcieep2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie1_clkreq>, <&pcie1_wake>, <&pcie1_preset>,
+			<&pcie0_slot1>;
+};
+
+&pcierc0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie0_clkreq>, <&pcie0_wake0>, <&pcie0_preset0>,
+			 <&pcie0_slot0>;
+};
+
+&pcieep0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie0_clkreq>, <&pcie0_wake0>, <&pcie0_preset0>,
+			 <&pcie0_slot0>;
+};
+
+&pcierc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie0_clkreq>, <&pcie0_wake1>, <&pcie0_preset0>;
+};
+
+&pcieep1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie0_clkreq>, <&pcie0_wake1>, <&pcie0_preset0>;
+};
diff --git a/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
index 6f4658f57453..fa99aa4b9906 100644
--- a/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
@@ -120,6 +120,27 @@ eth0_mdio: eth0-mdio-pins {
 		samsung,pin-pud = <FSD_PIN_PULL_NONE>;
 		samsung,pin-drv = <FSD_PIN_DRV_LV4>;
 	};
+
+	pcie1_clkreq: pcie1-clkreq-pins {
+		samsung,pins = "gpf6-0";
+		samsung,pin-function = <FSD_PIN_FUNC_2>;
+		samsung,pin-pud = <FSD_PIN_PULL_UP>;
+		samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+	};
+
+	pcie1_wake: pcie1-wake-pins {
+		samsung,pins = "gpf6-1";
+		samsung,pin-function = <FSD_PIN_FUNC_2>;
+		samsung,pin-pud = <FSD_PIN_PULL_UP>;
+		samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+	};
+
+	pcie1_preset: pcie1-preset-pins {
+		samsung,pins = "gpf6-2";
+		samsung,pin-function = <FSD_PIN_FUNC_2>;
+		samsung,pin-pud = <FSD_PIN_PULL_UP>;
+		samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+	};
 };
 
 &pinctrl_peric {
@@ -493,6 +514,50 @@ eth1_mdio: eth1-mdio-pins {
 		samsung,pin-pud = <FSD_PIN_PULL_UP>;
 		samsung,pin-drv = <FSD_PIN_DRV_LV4>;
 	};
+
+	pcie0_clkreq: pcie0-clkreq-pins {
+		samsung,pins = "gpc8-0";
+		samsung,pin-function = <FSD_PIN_FUNC_2>;
+		samsung,pin-pud = <FSD_PIN_PULL_UP>;
+		samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+	};
+
+	pcie0_wake0: pcie0-wake0-pins {
+		samsung,pins = "gpc8-1";
+		samsung,pin-function = <FSD_PIN_FUNC_2>;
+		samsung,pin-pud = <FSD_PIN_PULL_UP>;
+		samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+	};
+
+	pcie0_preset0: pcie0-preset0-pins {
+		samsung,pins = "gpc8-2";
+		samsung,pin-function = <FSD_PIN_FUNC_2>;
+		samsung,pin-pud = <FSD_PIN_PULL_UP>;
+		samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+	};
+
+	pcie0_wake1: pcie0-wake1-pins {
+		samsung,pins = "gpc8-3";
+		samsung,pin-function = <FSD_PIN_FUNC_2>;
+		samsung,pin-pud = <FSD_PIN_PULL_UP>;
+		samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+	};
+
+	pcie0_slot0: pcie0-gpio22-pins {
+		samsung,pins = "gpg2-6";
+		samsung,pin-function = <FSD_PIN_FUNC_OUTPUT>;
+		samsung,pin-pud = <FSD_PIN_PULL_UP>;
+		samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+		samsung,pin-val = <1>;
+	};
+
+	pcie0_slot1: pcie0-gpio23-pins {
+		samsung,pins = "gpg2-7";
+		samsung,pin-function = <FSD_PIN_FUNC_OUTPUT>;
+		samsung,pin-pud = <FSD_PIN_PULL_UP>;
+		samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+		samsung,pin-val = <1>;
+	};
 };
 
 &pinctrl_pmu {
diff --git a/arch/arm64/boot/dts/tesla/fsd.dtsi b/arch/arm64/boot/dts/tesla/fsd.dtsi
index a5ebb3f9b18f..8ed8d2131855 100644
--- a/arch/arm64/boot/dts/tesla/fsd.dtsi
+++ b/arch/arm64/boot/dts/tesla/fsd.dtsi
@@ -1009,6 +1009,16 @@ ethernet1: ethernet at 14300000 {
 			status = "disabled";
 		};
 
+		pciephy0: pcie-phy at 15080000 {
+			compatible = "tesla,fsd-pcie-phy0";
+			reg = <0x0 0x15080000 0x0 0x2000>,
+			      <0x0 0x150a0000 0x0 0x1000>;
+			#phy-cells = <0>;
+			samsung,pmu-syscon = <&pmu_system_controller>;
+			samsung,fsys-sysreg = <&sysreg_fsys0>;
+			status = "disabled";
+		};
+
 		ufs: ufs at 15120000 {
 			compatible = "tesla,fsd-ufs";
 			reg = <0x0 0x15120000 0x0 0x200>,  /* 0: HCI standard */
@@ -1057,6 +1067,143 @@ ethernet0: ethernet at 15300000 {
 			iommus = <&smmu_fsys0 0x0 0x1>;
 			status = "disabled";
 		};
+
+		pcierc2: pcie at 15400000 {
+			compatible = "tesla,fsd-pcie";
+			reg = <0x0 0x15400000 0x0 0x2000>,
+			      <0x0 0x15090000 0x0 0x1000>,
+			      <0x0 0x15800000 0x0 0x1000>;
+			reg-names = "dbi", "elbi", "config";
+			ranges =  <0x82000000 0 0x15801000 0 0x15801000 0 0xffefff>;
+			clocks = <&clock_fsys0 PCIE_SUBCTRL_INST0_AUX_CLK_SOC>,
+				 <&clock_fsys0 PCIE_SUBCTRL_INST0_DBI_ACLK_SOC>,
+				 <&clock_fsys0 PCIE_SUBCTRL_INST0_MSTR_ACLK_SOC>,
+				 <&clock_fsys0 PCIE_SUBCTRL_INST0_SLV_ACLK_SOC>;
+			clock-names = "aux", "dbi", "mstr", "slv";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			dma-coherent;
+			device_type = "pci";
+			interrupts = <GIC_SPI 93 IRQ_TYPE_EDGE_RISING>;
+			num-lanes = <4>;
+			phys = <&pciephy0>;
+			iommu-map = <0x0 &smmu_fsys0 0x4 0x10000>;
+			iommu-map-mask = <0x0>;
+			samsung,syscon-pcie = <&sysreg_fsys0 0x434>;
+			status = "disabled";
+		};
+
+		pcieep2: pcie-ep at 15400000 {
+			compatible = "tesla,fsd-pcie-ep";
+			reg = <0x0 0x15090000 0x0 0x1000>,
+			      <0x0 0x15400000 0x0 0x2000>,
+			      <0x0 0x15402000 0x0 0x80>,
+			      <0x0 0x15800000 0x0 0xff0000>;
+			reg-names = "elbi", "dbi", "dbi2", "addr_space";
+			clocks = <&clock_fsys0 PCIE_SUBCTRL_INST0_AUX_CLK_SOC>,
+				 <&clock_fsys0 PCIE_SUBCTRL_INST0_DBI_ACLK_SOC>,
+				 <&clock_fsys0 PCIE_SUBCTRL_INST0_MSTR_ACLK_SOC>,
+				 <&clock_fsys0 PCIE_SUBCTRL_INST0_SLV_ACLK_SOC>;
+			clock-names = "aux", "dbi", "mstr", "slv";
+			num-lanes = <4>;
+			phys = <&pciephy0>;
+			samsung,syscon-pcie = <&sysreg_fsys0 0x434>;
+			status = "disabled";
+		};
+
+		pciephy1: pcie-phy at 16880000 {
+			compatible = "tesla,fsd-pcie-phy1";
+			reg = <0x0 0x16880000 0x0 0x2000>,
+			      <0x0 0x16860000 0x0 0x1000>;
+			#phy-cells = <0>;
+			samsung,pmu-syscon = <&pmu_system_controller>;
+			samsung,fsys-sysreg = <&sysreg_fsys1>;
+			status = "disabled";
+		};
+
+		pcierc0: pcie at 16a00000 {
+			compatible = "tesla,fsd-pcie";
+			reg = <0x0 0x16a00000 0x0 0x2000>,
+			      <0x0 0x168b0000 0x0 0x1000>,
+			      <0x0 0x17000000 0x0 0x1000>;
+			reg-names = "dbi", "elbi", "config";
+			ranges =  <0x82000000 0 0x17001000 0 0x17001000 0 0xffefff>;
+			clocks = <&clock_fsys1 PCIE_LINK0_IPCLKPORT_AUX_ACLK>,
+				 <&clock_fsys1 PCIE_LINK0_IPCLKPORT_DBI_ACLK>,
+				 <&clock_fsys1 PCIE_LINK0_IPCLKPORT_MSTR_ACLK>,
+				 <&clock_fsys1 PCIE_LINK0_IPCLKPORT_SLV_ACLK>;
+			clock-names = "aux", "dbi", "mstr", "slv";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			dma-coherent;
+			device_type = "pci";
+			interrupts = <GIC_SPI 115 IRQ_TYPE_EDGE_RISING>;
+			num-lanes = <4>;
+			phys = <&pciephy1>;
+			iommu-map = <0x0 &smmu_imem 0x0 0x10000>;
+			iommu-map-mask = <0x0>;
+			samsung,syscon-pcie = <&sysreg_fsys1 0x50c>;
+			status = "disabled";
+		};
+
+		pcieep0: pcie-ep at 16a00000 {
+			compatible = "tesla,fsd-pcie-ep";
+			reg = <0x0 0x168b0000 0x0 0x1000>,
+			      <0x0 0x16a00000 0x0 0x2000>,
+			      <0x0 0x16a02000 0x0 0x80>,
+			      <0x0 0x17000000 0x0 0xff0000>;
+			reg-names = "elbi", "dbi", "dbi2", "addr_space";
+			clocks = <&clock_fsys1 PCIE_LINK0_IPCLKPORT_AUX_ACLK>,
+				 <&clock_fsys1 PCIE_LINK0_IPCLKPORT_DBI_ACLK>,
+				 <&clock_fsys1 PCIE_LINK0_IPCLKPORT_MSTR_ACLK>,
+				 <&clock_fsys1 PCIE_LINK0_IPCLKPORT_SLV_ACLK>;
+			clock-names = "aux", "dbi", "mstr", "slv";
+			num-lanes = <4>;
+			phys = <&pciephy1>;
+			samsung,syscon-pcie = <&sysreg_fsys1 0x50c>;
+			status = "disabled";
+		};
+
+		pcierc1: pcie at 16b00000 {
+			compatible = "tesla,fsd-pcie";
+			reg = <0x0 0x16b00000 0x0 0x2000>,
+			      <0x0 0x168c0000 0x0 0x1000>,
+			      <0x0 0x18000000 0x0 0x1000>;
+			reg-names = "dbi", "elbi", "config";
+			ranges =  <0x82000000 0 0x18001000 0 0x18001000 0 0xffefff>;
+			clocks = <&clock_fsys1 PCIE_LINK1_IPCLKPORT_AUX_ACLK>,
+				 <&clock_fsys1 PCIE_LINK1_IPCLKPORT_DBI_ACLK>,
+				 <&clock_fsys1 PCIE_LINK1_IPCLKPORT_MSTR_ACLK>,
+				 <&clock_fsys1 PCIE_LINK1_IPCLKPORT_SLV_ACLK>;
+			clock-names = "aux", "dbi", "mstr", "slv";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			dma-coherent;
+			device_type = "pci";
+			interrupts = <GIC_SPI 117 IRQ_TYPE_EDGE_RISING>;
+			num-lanes = <4>;
+			phys = <&pciephy1>;
+			samsung,syscon-pcie = <&sysreg_fsys1 0x510>;
+			status = "disabled";
+		};
+
+		pcieep1: pcie-ep at 16b00000 {
+			compatible = "tesla,fsd-pcie-ep";
+			reg = <0x0 0x168c0000 0x0 0x1000>,
+			      <0x0 0x16b00000 0x0 0x2000>,
+			      <0x0 0x16b02000 0x0 0x80>,
+			      <0x0 0x18000000 0x0 0xff0000>;
+			reg-names = "elbi", "dbi", "dbi2", "addr_space";
+			clocks = <&clock_fsys1 PCIE_LINK1_IPCLKPORT_AUX_ACLK>,
+				 <&clock_fsys1 PCIE_LINK1_IPCLKPORT_DBI_ACLK>,
+				 <&clock_fsys1 PCIE_LINK1_IPCLKPORT_MSTR_ACLK>,
+				 <&clock_fsys1 PCIE_LINK1_IPCLKPORT_SLV_ACLK>;
+			clock-names = "aux", "dbi", "mstr", "slv";
+			num-lanes = <4>;
+			phys = <&pciephy1>;
+			samsung,syscon-pcie = <&sysreg_fsys1 0x510>;
+			status = "disabled";
+		};
 	};
 };
 
-- 
2.49.0



From jai.luthra at ideasonboard.com  Mon Aug 11 22:47:56 2025
From: jai.luthra at ideasonboard.com (Jai Luthra)
Date: Tue, 12 Aug 2025 11:17:56 +0530
Subject: [PATCH] phy: cadence: cdns-dphy-rx: Add runtime PM support
In-Reply-To: <20250224-cdns_phy_pm-v1-1-0fe2c544cc87@ideasonboard.com>
References: <20250224-cdns_phy_pm-v1-1-0fe2c544cc87@ideasonboard.com>
Message-ID: <175497767648.8696.3021844845686596634@freya>

Hi Vinod, Kishon,

Quoting Jai Luthra (2025-02-24 18:10:05)
> Enable runtime power management for the device. The PHY framework
> handles calling pm_runtime_(get|put)_sync when powering on/off this
> device.
> 

Can this patch get picked for the next merge window?

The CSI PM series is already reviewed [1], and it would be good to have
runtime PM for cameras working in 6.18, which needs both the PHY and CSI
IPs to be powered off.

[1]: https://lore.kernel.org/linux-media/20250224-ti_csi_pm-v1-0-8f8c29ef646d at ideasonboard.com/

> Signed-off-by: Jai Luthra <jai.luthra at ideasonboard.com>
> ---
>  drivers/phy/cadence/cdns-dphy-rx.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/phy/cadence/cdns-dphy-rx.c b/drivers/phy/cadence/cdns-dphy-rx.c
> index 7729cf80a9bd892c3e5db6cdbdc4ece9ada2d99f..3ac80141189c4c8c350b678998e5dec7a15c3892 100644
> --- a/drivers/phy/cadence/cdns-dphy-rx.c
> +++ b/drivers/phy/cadence/cdns-dphy-rx.c
> @@ -12,6 +12,7 @@
>  #include <linux/phy/phy.h>
>  #include <linux/phy/phy-mipi-dphy.h>
>  #include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
>  #include <linux/sys_soc.h>
>  
>  #define DPHY_PMA_CMN(reg)              (reg)
> @@ -265,7 +266,7 @@ static int cdns_dphy_rx_probe(struct platform_device *pdev)
>                 return PTR_ERR(provider);
>         }
>  
> -       return 0;
> +       return devm_pm_runtime_enable(dev);
>  }
>  
>  static const struct of_device_id cdns_dphy_rx_of_match[] = {
> 
> ---
> base-commit: d082ecbc71e9e0bf49883ee4afd435a77a5101b6
> change-id: 20250224-cdns_phy_pm-b2b7d472835d
> 
> Best regards,
> -- 
> Jai Luthra <jai.luthra at ideasonboard.com>
> 

Thanks,
Jai


From devarsht at ti.com  Mon Aug 11 23:02:17 2025
From: devarsht at ti.com (devarsh)
Date: Tue, 12 Aug 2025 11:32:17 +0530
Subject: [PATCH 0/2] phy: cdns-dphy: hs-clk improvement and a cleanup
In-Reply-To: <aJM0WPVDUkte9E_D@vaman>
References: <20250723-cdns-dphy-hs-clk-rate-fix-v1-0-d4539d44cbe7@ideasonboard.com>
 <cc0e4cf5-1bd9-4ae3-a130-0483dbfc6335@ideasonboard.com>
 <aJM0WPVDUkte9E_D@vaman>
Message-ID: <cac3d853-11aa-481b-90bb-aeb2cd4608f8@ti.com>

Hi Vinod, Kishon,

On 06/08/25 16:24, Vinod Koul wrote:
> On 05-08-25, 15:03, Tomi Valkeinen wrote:
>> Hi Vinod, Kishon,
>>
>> On 23/07/2025 13:01, Tomi Valkeinen wrote:
>>> A cdns-dphy improvement to return the actual hs clock rate, and a
>>> cleanup to remove leftover code.
>>>
>>> These were part of a Cadence DSI series:
>>>
>>> https://lore.kernel.org/all/20250618-cdns-dsi-impro-v4-0-862c841dbe02%40ideasonboard.com/
>>>
>>> but are now separately here for easier merging.
>>>
>>> Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
>>> ---
>>> Tomi Valkeinen (2):
>>>       phy: cdns-dphy: Store hs_clk_rate and return it
>>>       phy: cdns-dphy: Remove leftover code
>>>
>>>  drivers/phy/cadence/cdns-dphy.c | 24 +++++++++---------------
>>>  1 file changed, 9 insertions(+), 15 deletions(-)
>>> ---
>>> base-commit: 89be9a83ccf1f88522317ce02f854f30d6115c41
>>> change-id: 20250723-cdns-dphy-hs-clk-rate-fix-a8857a5789dd
>>
>> Is this good to merge, and if so, do you have any estimate when? While
>> this is independent from the DSI series, I'd rather push the DSI series
>> into drm-misc about the same time, so both would appear in linux-next
>> relatively together.
> 
> I will start taking patches after merge window closes next monday, so
> next week should be a good estimate

On top of this series [1], we have the cadence DPHY fixes for fixing PLL
lockup timeout [2] and one more patch which enables lower resolutions
[3], both have been reviewed and tested too.

Would it be possible for you too merge all 3 together in below order ?

[1]:
https://lore.kernel.org/all/cc0e4cf5-1bd9-4ae3-a130-0483dbfc6335 at ideasonboard.com/
[2]: https://lore.kernel.org/all/20250704125915.1224738-1-devarsht at ti.com/
[3]: https://lore.kernel.org/all/20250807052002.717807-1-h-shenoy at ti.com/

Kindly let us know if anything required from our side.

Regards
Devarsh



From krzk at kernel.org  Mon Aug 11 23:32:03 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 12 Aug 2025 08:32:03 +0200
Subject: [PATCH v3 06/12] dt-bindings: PCI: Split exynos host into two
 files
In-Reply-To: <20250811154638.95732-7-shradha.t@samsung.com>
References: <20250811154638.95732-1-shradha.t@samsung.com>
 <CGME20250811154721epcas5p26c9e2880ca55a470f595d914b4030745@epcas5p2.samsung.com>
 <20250811154638.95732-7-shradha.t@samsung.com>
Message-ID: <4a47b758-5c20-4e30-bc61-206acd48bdd0@kernel.org>

On 11/08/2025 17:46, Shradha Todi wrote:
> The current Exynos PCIe yaml binding file is hard to reuse by
> other Samsung SoCs. Refactoring it by:
>  - Moving common Samsung PCIe properties into samsung,exynos-pcie.yaml
>  - Creating a dedicated samsung,exynos5433-pcie.yaml file for properties
>    and constraints specific to the Exynos5433 SoC
> 
> Signed-off-by: Shradha Todi <shradha.t at samsung.com>
> ---
>  .../bindings/pci/samsung,exynos-pcie.yaml     | 70 +--------------
>  .../bindings/pci/samsung,exynos5433-pcie.yaml | 89 +++++++++++++++++++
>  2 files changed, 91 insertions(+), 68 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/pci/samsung,exynos5433-pcie.yaml
> 
> diff --git a/Documentation/devicetree/bindings/pci/samsung,exynos-pcie.yaml b/Documentation/devicetree/bindings/pci/samsung,exynos-pcie.yaml
> index f20ed7e709f7..fd0b97b30821 100644
> --- a/Documentation/devicetree/bindings/pci/samsung,exynos-pcie.yaml
> +++ b/Documentation/devicetree/bindings/pci/samsung,exynos-pcie.yaml
> @@ -11,7 +11,7 @@ maintainers:
>    - Jaehoon Chung <jh80.chung at samsung.com>
>  
>  description: |+
> -  Exynos5433 SoC PCIe host controller is based on the Synopsys DesignWare
> +  Samsung SoCs PCIe host controller is based on the Synopsys DesignWare
>    PCIe IP and thus inherits all the common properties defined in
>    snps,dw-pcie.yaml.
>  
> @@ -19,9 +19,6 @@ allOf:
>    - $ref: /schemas/pci/snps,dw-pcie.yaml#
>  
>  properties:
> -  compatible:
> -    const: samsung,exynos5433-pcie
> -
>    reg:
>      items:
>        - description: Data Bus Interface (DBI) registers.


So the only common part left here is reg and phy? I don't think such
common file brings any value.


Best regards,
Krzysztof


From krzk at kernel.org  Mon Aug 11 23:37:02 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 12 Aug 2025 08:37:02 +0200
Subject: [PATCH v3 07/12] dt-bindings: PCI: Add support for Tesla FSD SoC
In-Reply-To: <20250811154638.95732-8-shradha.t@samsung.com>
References: <20250811154638.95732-1-shradha.t@samsung.com>
 <CGME20250811154725epcas5p428fa3370a32bc2b664a4fd8260078097@epcas5p4.samsung.com>
 <20250811154638.95732-8-shradha.t@samsung.com>
Message-ID: <9e065582-9349-4f39-88b5-048d333ab8d7@kernel.org>

On 11/08/2025 17:46, Shradha Todi wrote:
> +
> +  clocks:
> +    maxItems: 4
> +
> +  clock-names:
> +    items:
> +      - const: aux
> +      - const: dbi
> +      - const: mstr
> +      - const: slv
> +
> +  num-lanes:
> +    maximum: 4
> +
> +  phys:
> +    maxItems: 1
> +
> +  samsung,syscon-pcie:
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    description: phandle for system control registers, used to
> +                 control signals at system level

What is "system level"? and what are these "signals" being controlled?


> +
> +required:
> +  - compatible
> +  - reg
> +  - reg-names
> +  - clocks
> +  - clock-names
> +  - num-lanes
> +  - phys
> +  - samsung,syscon-pcie
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/fsd-clk.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    bus {
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +        pcieep0: pcie-ep at 16a00000 {
> +            compatible = "tesla,fsd-pcie-ep";
> +            reg = <0x0 0x168b0000 0x0 0x1000>,
> +                  <0x0 0x16a00000 0x0 0x2000>,
> +                  <0x0 0x16a01000 0x0 0x80>,
> +                  <0x0 0x17000000 0x0 0xff0000>;
> +            reg-names = "elbi", "dbi", "dbi2", "addr_space";
> +            clocks = <&clock_fsys1 PCIE_LINK0_IPCLKPORT_AUX_ACLK>,
> +                     <&clock_fsys1 PCIE_LINK0_IPCLKPORT_DBI_ACLK>,
> +                     <&clock_fsys1 PCIE_LINK0_IPCLKPORT_MSTR_ACLK>,
> +                     <&clock_fsys1 PCIE_LINK0_IPCLKPORT_SLV_ACLK>;
> +            clock-names = "aux", "dbi", "mstr", "slv";
> +            num-lanes = <4>;
> +            phys = <&pciephy1>;
> +            samsung,syscon-pcie = <&sysreg_fsys1 0x50c>;
> +        };
> +    };
> +...
> diff --git a/Documentation/devicetree/bindings/pci/tesla,fsd-pcie.yaml b/Documentation/devicetree/bindings/pci/tesla,fsd-pcie.yaml
> new file mode 100644
> index 000000000000..533870ab1d73
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/tesla,fsd-pcie.yaml
> @@ -0,0 +1,77 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pci/tesla,fsd-pcie.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Tesla FSD SoC series PCIe Host Controller
> +
> +maintainers:
> +  - Shradha Todi <shradha.t at samsung.com>
> +
> +description:
> +  Tesla FSD SoCs PCIe host controller inherits all the common
> +  properties defined in samsung,exynos-pcie.yaml
> +
> +allOf:
> +  - $ref: /schemas/pci/samsung,exynos-pcie.yaml#
> +
> +properties:
> +  compatible:
> +    const: tesla,fsd-pcie
> +
> +  clocks:
> +    maxItems: 4
> +
> +  clock-names:
> +    items:
> +      - const: aux
> +      - const: dbi
> +      - const: mstr
> +      - const: slv
> +
> +  num-lanes:
> +    maximum: 4
> +
> +  samsung,syscon-pcie:
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    description: phandle for system control registers, used to
> +                 control signals at system level
> +
> +required:
> +  - samsung,syscon-pcie

clocks are required, compatible as well.

Missing supplies, both as properties and required. PCI devices do not
work without power.

> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/fsd-clk.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> +    soc {
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +
> +        pcierc1: pcie at 16b00000 {
> +            compatible = "tesla,fsd-pcie";
> +            reg = <0x0 0x16b00000 0x0 0x2000>,
> +                  <0x0 0x168c0000 0x0 0x1000>,
> +                  <0x0 0x18000000 0x0 0x1000>;
> +            reg-names = "dbi", "elbi", "config";
> +            ranges =  <0x82000000 0x0 0x18001000 0x0 0x18001000 0x0 0xffefff>;

Misaligned. Follow closely DTS coding style.

> +            clocks = <&clock_fsys1 PCIE_LINK1_IPCLKPORT_AUX_ACLK>,
> +                     <&clock_fsys1 PCIE_LINK1_IPCLKPORT_DBI_ACLK>,
> +                     <&clock_fsys1 PCIE_LINK1_IPCLKPORT_MSTR_ACLK>,
> +                     <&clock_fsys1 PCIE_LINK1_IPCLKPORT_SLV_ACLK>;
> +            clock-names = "aux", "dbi", "mstr", "slv";
> +            #address-cells = <3>;
> +            #size-cells = <2>;
> +            dma-coherent;
> +            device_type = "pci";
> +            interrupts = <GIC_SPI 117 IRQ_TYPE_EDGE_RISING>;
> +            num-lanes = <4>;
> +            phys = <&pciephy1>;
> +            samsung,syscon-pcie = <&sysreg_fsys1 0x510>;

Incomplete, missing supplies.

> +        };
> +    };
> +...


Best regards,
Krzysztof


From krzk at kernel.org  Mon Aug 11 23:43:43 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 12 Aug 2025 08:43:43 +0200
Subject: [PATCH v3 12/12] arm64: dts: fsd: Add PCIe support for Tesla FSD
 SoC
In-Reply-To: <20250811154638.95732-13-shradha.t@samsung.com>
References: <20250811154638.95732-1-shradha.t@samsung.com>
 <CGME20250811154746epcas5p261ba0c811f9dd8748f8f241b76be6525@epcas5p2.samsung.com>
 <20250811154638.95732-13-shradha.t@samsung.com>
Message-ID: <b22f9381-1835-463a-8daa-97835b159f78@kernel.org>

On 11/08/2025 17:46, Shradha Todi wrote:
> Add the support for PCIe controller driver and phy driver for Tesla FSD.
> It includes support for both RC and EP.
> 
> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
> Signed-off-by: Shradha Todi <shradha.t at samsung.com>
> ---
>  arch/arm64/boot/dts/tesla/fsd-evb.dts      |  34 +++++
>  arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi |  65 +++++++++
>  arch/arm64/boot/dts/tesla/fsd.dtsi         | 147 +++++++++++++++++++++
>  3 files changed, 246 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/tesla/fsd-evb.dts b/arch/arm64/boot/dts/tesla/fsd-evb.dts
> index 9ff22e1c8723..1b63c5d72d19 100644
> --- a/arch/arm64/boot/dts/tesla/fsd-evb.dts
> +++ b/arch/arm64/boot/dts/tesla/fsd-evb.dts
> @@ -130,3 +130,37 @@ &serial_0 {
>  &ufs {
>  	status = "okay";
>  };
> +
> +&pcierc2 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pcie1_clkreq>, <&pcie1_wake>, <&pcie1_preset>,
> +			<&pcie0_slot1>;
> +};
> +
> +&pcieep2 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pcie1_clkreq>, <&pcie1_wake>, <&pcie1_preset>,
> +			<&pcie0_slot1>;
> +};
> +
> +&pcierc0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pcie0_clkreq>, <&pcie0_wake0>, <&pcie0_preset0>,
> +			 <&pcie0_slot0>;
> +};
> +
> +&pcieep0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pcie0_clkreq>, <&pcie0_wake0>, <&pcie0_preset0>,
> +			 <&pcie0_slot0>;
> +};
> +
> +&pcierc1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pcie0_clkreq>, <&pcie0_wake1>, <&pcie0_preset0>;
> +};
> +
> +&pcieep1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pcie0_clkreq>, <&pcie0_wake1>, <&pcie0_preset0>;


All these are pointless, because the node is disabled. The board level
should be complete, so also supplies and enabling the device.

Best regards,
Krzysztof


From ziyue.zhang at oss.qualcomm.com  Tue Aug 12 01:30:26 2025
From: ziyue.zhang at oss.qualcomm.com (Ziyue Zhang)
Date: Tue, 12 Aug 2025 16:30:26 +0800
Subject: [PATCH v10 0/5] pci: qcom: Add QCS8300 PCIe support
In-Reply-To: <20250811071131.982983-1-ziyue.zhang@oss.qualcomm.com>
References: <20250811071131.982983-1-ziyue.zhang@oss.qualcomm.com>
Message-ID: <dc3dda22-34d3-4254-ba60-9037f3ccb368@oss.qualcomm.com>


On 8/11/2025 3:11 PM, Ziyue Zhang wrote:
> This series depend on the sa8775p gcc_aux_clock and link_down reset change
> https://lore.kernel.org/all/20250725102231.3608298-2-ziyue.zhang at oss.qualcomm.com/
>
> This series adds document, phy, configs support for PCIe in QCS8300.
> It also adds 'link_down' reset for sa8775p.
>
> Have follwing changes:
> 	- Add dedicated schema for the PCIe controllers found on QCS8300.
> 	- Add compatible for qcs8300 platform.
> 	- Add configurations in devicetree for PCIe0, including registers, clocks, interrupts and phy setting sequence.
> 	- Add configurations in devicetree for PCIe1, including registers, clocks, interrupts and phy setting sequence.
>
> Signed-off-by: Krishna chaitanya chundru <quic_krichai at quicinc.com>
> Signed-off-by: Ziyue Zhang <quic_ziyuzhan at quicinc.com>
> ---
> Changes in v10:
> - Update PHY max_items (Johan)
> - Link to v9: https://lore.kernel.org/all/20250725104037.4054070-1-ziyue.zhang at oss.qualcomm.com/
>
> Changes in v9:
> - Fix DTB error (Vinod)
> - Link to v8: https://lore.kernel.org/all/20250714081529.3847385-1-ziyue.zhang at oss.qualcomm.com/
>
> Changes in v8:
> - rebase sc8280xp-qmp-pcie-phy change to solve conflicts.
> - Add Fixes tag to phy change (Johan)
> - Link to v7: https://lore.kernel.org/all/20250625092539.762075-1-quic_ziyuzhan at quicinc.com/
>
> Changes in v7:
> - rebase qcs8300-ride.dtsi change to solve conflicts.
> - Link to v6: https://lore.kernel.org/all/20250529035635.4162149-1-quic_ziyuzhan at quicinc.com/
>
> Changes in v6:
> - move the qcs8300 and sa8775p phy compatibility entry into the list of PHYs that require six clocks
> - Update QCS8300 and sa8775p phy dt, remove aux clock.
> - Fixed compile error found by kernel test robot
> - Link to v5: https://lore.kernel.org/all/20250507031019.4080541-1-quic_ziyuzhan at quicinc.com/
>
> Changes in v5:
> - Add QCOM PCIe controller version in commit msg (Mani)
> - Modify platform dts change subject (Dmitry)
> - Fixed compile error found by kernel test robot
> - Link to v4: https://lore.kernel.org/linux-phy/20241220055239.2744024-1-quic_ziyuzhan at quicinc.com/
>
> Changes in v4:
> - Add received tag
> - Fixed compile error found by kernel test robot
> - Link to v3: https://lore.kernel.org/lkml/202412211301.bQO6vXpo-lkp at intel.com/T/#mdd63e5be39acbf879218aef91c87b12d4540e0f7
>
> Changes in v3:
> - Add received tag(Rob & Dmitry)
> - Update pcie_phy in gcc node to soc dtsi(Dmitry & Konrad)
> - remove pcieprot0 node(Konrad & Mani)
> - Fix format comments(Konrad)
> - Update base-commit to tag: next-20241213(Bjorn)
> - Corrected of_device_id.data from 1.9.0 to 1.34.0.
> - Link to v2: https://lore.kernel.org/all/20241128081056.1361739-1-quic_ziyuzhan at quicinc.com/
>
> Changes in v2:
> - Fix some format comments and match the style in x1e80100(Konrad)
> - Add global interrupt for PCIe0 and PCIe1(Konrad)
> - split the soc dtsi and the platform dts into two changes(Konrad)
> - Link to v1: https://lore.kernel.org/all/20241114095409.2682558-1-quic_ziyuzhan at quicinc.com/
>
> Ziyue Zhang (5):
>    dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Update pcie phy bindings
>      for qcs8300
>    arm64: dts: qcom: qcs8300: enable pcie0
>    arm64: dts: qcom: qcs8300-ride: enable pcie0 interface
>    arm64: dts: qcom: qcs8300: enable pcie1
>    arm64: dts: qcom: qcs8300-ride: enable pcie1 interface
>
>   .../phy/qcom,sc8280xp-qmp-pcie-phy.yaml       |  17 +-
>   arch/arm64/boot/dts/qcom/qcs8300-ride.dts     |  80 +++++
>   arch/arm64/boot/dts/qcom/qcs8300.dtsi         | 296 +++++++++++++++++-
>   3 files changed, 376 insertions(+), 17 deletions(-)
>
>
> base-commit: e2622a23e8405644c7188af39d4c1bd2b405bb27
Hi Maintainers,

It seems the patches get reviewed tag for a long time, can you give this

series further comment or help me to merge them ?
Thanks very much.

BRs
Ziyue


From ziyue.zhang at oss.qualcomm.com  Tue Aug 12 01:31:29 2025
From: ziyue.zhang at oss.qualcomm.com (Ziyue Zhang)
Date: Tue, 12 Aug 2025 16:31:29 +0800
Subject: [PATCH v7 1/3] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy:
 Update pcie phy bindings
In-Reply-To: <20250725102231.3608298-2-ziyue.zhang@oss.qualcomm.com>
References: <20250725102231.3608298-1-ziyue.zhang@oss.qualcomm.com>
 <20250725102231.3608298-2-ziyue.zhang@oss.qualcomm.com>
Message-ID: <e9c9005f-dab3-4bed-999d-9a7563f5f2cd@oss.qualcomm.com>


On 7/25/2025 6:22 PM, Ziyue Zhang wrote:
> The gcc_aux_clk is required by the PCIe controller but not by the PCIe
> PHY. In PCIe PHY, the source of aux_clk used in low-power mode should
> be gcc_phy_aux_clk. Hence, remove gcc_aux_clk and replace it with
> gcc_phy_aux_clk.
>
> Fixes: fd2d4e4c1986 ("dt-bindings: phy: qcom,qmp: Add sa8775p QMP PCIe PHY")
> Signed-off-by: Ziyue Zhang <ziyue.zhang at oss.qualcomm.com>
> Acked-by: Rob Herring (Arm) <robh 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 a1ae8c7988c8..b6f140bf5b3b 100644
> --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
> +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
> @@ -176,6 +176,8 @@ allOf:
>           compatible:
>             contains:
>               enum:
> +              - qcom,sa8775p-qmp-gen4x2-pcie-phy
> +              - qcom,sa8775p-qmp-gen4x4-pcie-phy
>                 - qcom,sc8280xp-qmp-gen3x1-pcie-phy
>                 - qcom,sc8280xp-qmp-gen3x2-pcie-phy
>                 - qcom,sc8280xp-qmp-gen3x4-pcie-phy
> @@ -197,8 +199,6 @@ allOf:
>             contains:
>               enum:
>                 - qcom,qcs8300-qmp-gen4x2-pcie-phy
> -              - qcom,sa8775p-qmp-gen4x2-pcie-phy
> -              - qcom,sa8775p-qmp-gen4x4-pcie-phy
>       then:
>         properties:
>           clocks:
Hi Maintainers,

It seems the patche get reviewed tag for a long time, can you give this

series further comment or help me to merge them ?
Thanks very much.

BRs
Ziyue


From ziyue.zhang at oss.qualcomm.com  Tue Aug 12 01:32:43 2025
From: ziyue.zhang at oss.qualcomm.com (Ziyue Zhang)
Date: Tue, 12 Aug 2025 16:32:43 +0800
Subject: [PATCH v4 0/3] Add Equalization Settings for 8.0 GT/s and Add
 PCIe Lane Equalization Preset Properties for 8.0 GT/s and 16.0 GT/s
In-Reply-To: <20250714082110.3890821-1-ziyue.zhang@oss.qualcomm.com>
References: <20250714082110.3890821-1-ziyue.zhang@oss.qualcomm.com>
Message-ID: <23e28eba-3c7e-439e-88d8-998decd2b285@oss.qualcomm.com>


On 7/14/2025 4:21 PM, Ziyue Zhang wrote:
> This series adds add equalization settings for 8.0 GT/s, and add PCIe lane equalization
> preset properties for 8.0 GT/s and 16.0 GT/s for sa8775p ride platform, which fix AER
> errors.
>
> While equalization settings for 16 GT/s have already been set, this update adds the
> required equalization settings for PCIe operating at 8.0 GT/s, including the
> configuration of shadow registers, ensuring optimal performance and stability.
>
> The DT change for sa8775p add PCIe lane equalization preset properties for 8 GT/s
> and 16 GT/s data rates used in lane equalization procedure.
>
> Signed-off-by: Ziyue Zhang <ziyue.zhang at oss.qualcomm.com>
>
> Changes in v4:
> - Bail out early if the link speed > 16 GT/s and use pci->max_link_speed directly (Mani)
> - Fix the build warning. (Bjorn)
> - Link to v3: https://lore.kernel.org/all/8ccd3731-8dbc-4972-a79a-ba78e90ec4a8 at quicinc.com/
>
> Changes in v3:
> - Delte TODO tag and warn print in pcie-qcom-common.c. (Bjorn)
> - Refined the commit message for better readability. (Bjorn)
> - Link to v2: https://lore.kernel.org/all/20250611100319.464803-1-quic_ziyuzhan at quicinc.com/
>
> Changes in v2:
> - Update code in pcie-qcom-common.c make it easier to read. (Neil)
> - Fix the compile error.
> - Link to v1: https://lore.kernel.org/all/20250604091946.1890602-1-quic_ziyuzhan at quicinc.com
>
>
> Ziyue Zhang (3):
>    PCI: qcom: Add equalization settings for 8.0 GT/s
>    PCI: qcom: fix macro typo for CURSOR
>    arm64: dts: qcom: sa8775p: Add PCIe lane equalization preset
>      properties
>
>   arch/arm64/boot/dts/qcom/sa8775p.dtsi         |  6 +++
>   drivers/pci/controller/dwc/pcie-designware.h  |  5 +-
>   drivers/pci/controller/dwc/pcie-qcom-common.c | 54 ++++++++++---------
>   drivers/pci/controller/dwc/pcie-qcom-common.h |  2 +-
>   drivers/pci/controller/dwc/pcie-qcom-ep.c     |  6 +--
>   drivers/pci/controller/dwc/pcie-qcom.c        |  6 +--
>   6 files changed, 45 insertions(+), 34 deletions(-)
>
>
> base-commit: 58ba80c4740212c29a1cf9b48f588e60a7612209
Hi Maintainers,

It seems the patches get reviewed tag for a long time, can you give this

series further comment or help me to merge them ?
Thanks very much.

BRs
Ziyue


From krzk at kernel.org  Tue Aug 12 01:33:00 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 12 Aug 2025 10:33:00 +0200
Subject: [PATCH v10 0/5] pci: qcom: Add QCS8300 PCIe support
In-Reply-To: <dc3dda22-34d3-4254-ba60-9037f3ccb368@oss.qualcomm.com>
References: <20250811071131.982983-1-ziyue.zhang@oss.qualcomm.com>
 <dc3dda22-34d3-4254-ba60-9037f3ccb368@oss.qualcomm.com>
Message-ID: <2b4fd0fb-ecab-4a10-bead-c78fa5e6d436@kernel.org>

On 12/08/2025 10:30, Ziyue Zhang wrote:
> 
> On 8/11/2025 3:11 PM, Ziyue Zhang wrote:
>> This series depend on the sa8775p gcc_aux_clock and link_down reset change
>> https://lore.kernel.org/all/20250725102231.3608298-2-ziyue.zhang at oss.qualcomm.com/
>>
>> This series adds document, phy, configs support for PCIe in QCS8300.
>> It also adds 'link_down' reset for sa8775p.
>>
>> Have follwing changes:
>> 	- Add dedicated schema for the PCIe controllers found on QCS8300.
>> 	- Add compatible for qcs8300 platform.
>> 	- Add configurations in devicetree for PCIe0, including registers, clocks, interrupts and phy setting sequence.
>> 	- Add configurations in devicetree for PCIe1, including registers, clocks, interrupts and phy setting sequence.
>>
>> Signed-off-by: Krishna chaitanya chundru <quic_krichai at quicinc.com>
>> Signed-off-by: Ziyue Zhang <quic_ziyuzhan at quicinc.com>
>> ---
>> Changes in v10:
>> - Update PHY max_items (Johan)
>> - Link to v9: https://lore.kernel.org/all/20250725104037.4054070-1-ziyue.zhang at oss.qualcomm.com/
>>
>> Changes in v9:
>> - Fix DTB error (Vinod)
>> - Link to v8: https://lore.kernel.org/all/20250714081529.3847385-1-ziyue.zhang at oss.qualcomm.com/
>>
>> Changes in v8:
>> - rebase sc8280xp-qmp-pcie-phy change to solve conflicts.
>> - Add Fixes tag to phy change (Johan)
>> - Link to v7: https://lore.kernel.org/all/20250625092539.762075-1-quic_ziyuzhan at quicinc.com/
>>
>> Changes in v7:
>> - rebase qcs8300-ride.dtsi change to solve conflicts.
>> - Link to v6: https://lore.kernel.org/all/20250529035635.4162149-1-quic_ziyuzhan at quicinc.com/
>>
>> Changes in v6:
>> - move the qcs8300 and sa8775p phy compatibility entry into the list of PHYs that require six clocks
>> - Update QCS8300 and sa8775p phy dt, remove aux clock.
>> - Fixed compile error found by kernel test robot
>> - Link to v5: https://lore.kernel.org/all/20250507031019.4080541-1-quic_ziyuzhan at quicinc.com/
>>
>> Changes in v5:
>> - Add QCOM PCIe controller version in commit msg (Mani)
>> - Modify platform dts change subject (Dmitry)
>> - Fixed compile error found by kernel test robot
>> - Link to v4: https://lore.kernel.org/linux-phy/20241220055239.2744024-1-quic_ziyuzhan at quicinc.com/
>>
>> Changes in v4:
>> - Add received tag
>> - Fixed compile error found by kernel test robot
>> - Link to v3: https://lore.kernel.org/lkml/202412211301.bQO6vXpo-lkp at intel.com/T/#mdd63e5be39acbf879218aef91c87b12d4540e0f7
>>
>> Changes in v3:
>> - Add received tag(Rob & Dmitry)
>> - Update pcie_phy in gcc node to soc dtsi(Dmitry & Konrad)
>> - remove pcieprot0 node(Konrad & Mani)
>> - Fix format comments(Konrad)
>> - Update base-commit to tag: next-20241213(Bjorn)
>> - Corrected of_device_id.data from 1.9.0 to 1.34.0.
>> - Link to v2: https://lore.kernel.org/all/20241128081056.1361739-1-quic_ziyuzhan at quicinc.com/
>>
>> Changes in v2:
>> - Fix some format comments and match the style in x1e80100(Konrad)
>> - Add global interrupt for PCIe0 and PCIe1(Konrad)
>> - split the soc dtsi and the platform dts into two changes(Konrad)
>> - Link to v1: https://lore.kernel.org/all/20241114095409.2682558-1-quic_ziyuzhan at quicinc.com/
>>
>> Ziyue Zhang (5):
>>    dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Update pcie phy bindings
>>      for qcs8300
>>    arm64: dts: qcom: qcs8300: enable pcie0
>>    arm64: dts: qcom: qcs8300-ride: enable pcie0 interface
>>    arm64: dts: qcom: qcs8300: enable pcie1
>>    arm64: dts: qcom: qcs8300-ride: enable pcie1 interface
>>
>>   .../phy/qcom,sc8280xp-qmp-pcie-phy.yaml       |  17 +-
>>   arch/arm64/boot/dts/qcom/qcs8300-ride.dts     |  80 +++++
>>   arch/arm64/boot/dts/qcom/qcs8300.dtsi         | 296 +++++++++++++++++-
>>   3 files changed, 376 insertions(+), 17 deletions(-)
>>
>>
>> base-commit: e2622a23e8405644c7188af39d4c1bd2b405bb27
> Hi Maintainers,
> 
> It seems the patches get reviewed tag for a long time, can you give this
> 
> series further comment or help me to merge them ?
> Thanks very much.

Can you NOT ping after one day? It is not really acceptable.

Best regards,
Krzysztof


From mitltlatltl at gmail.com  Tue Aug 12 02:39:56 2025
From: mitltlatltl at gmail.com (Pengyu Luo)
Date: Tue, 12 Aug 2025 17:39:56 +0800
Subject: [PATCH] phy: qualcomm: phy-qcom-eusb2-repeater: fix override properties
Message-ID: <20250812093957.32235-1-mitltlatltl@gmail.com>

property "qcom,tune-usb2-preem" is for EUSB2_TUNE_USB2_PREEM
property "qcom,tune-usb2-amplitude" is for EUSB2_TUNE_IUSB2

The downstream correspondence is as follows:
EUSB2_TUNE_USB2_PREEM: Tx pre-emphasis tuning
EUSB2_TUNE_IUSB2: HS trasmit amplitude
EUSB2_TUNE_SQUELCH_U: Squelch detection threshold
EUSB2_TUNE_HSDISC: HS disconnect threshold
EUSB2_TUNE_EUSB_SLEW: slew rate

Fixes: 31bc94de7602 ("phy: qualcomm: phy-qcom-eusb2-repeater: Don't zero-out registers")
Signed-off-by: Pengyu Luo <mitltlatltl at gmail.com>
---
 drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
index d7493c229..3709fba42 100644
--- a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
+++ b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
@@ -127,13 +127,13 @@ static int eusb2_repeater_init(struct phy *phy)
 			     rptr->cfg->init_tbl[i].value);
 
 	/* Override registers from devicetree values */
-	if (!of_property_read_u8(np, "qcom,tune-usb2-amplitude", &val))
+	if (!of_property_read_u8(np, "qcom,tune-usb2-preem", &val))
 		regmap_write(regmap, base + EUSB2_TUNE_USB2_PREEM, val);
 
 	if (!of_property_read_u8(np, "qcom,tune-usb2-disc-thres", &val))
 		regmap_write(regmap, base + EUSB2_TUNE_HSDISC, val);
 
-	if (!of_property_read_u8(np, "qcom,tune-usb2-preem", &val))
+	if (!of_property_read_u8(np, "qcom,tune-usb2-amplitude", &val))
 		regmap_write(regmap, base + EUSB2_TUNE_IUSB2, val);
 
 	/* Wait for status OK */
-- 
2.50.1



From konrad.dybcio at oss.qualcomm.com  Tue Aug 12 02:44:21 2025
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Tue, 12 Aug 2025 11:44:21 +0200
Subject: [PATCH] phy: qualcomm: phy-qcom-eusb2-repeater: fix override
 properties
In-Reply-To: <20250812093957.32235-1-mitltlatltl@gmail.com>
References: <20250812093957.32235-1-mitltlatltl@gmail.com>
Message-ID: <c3d192d4-934b-4fe3-9b1a-8405cddbc668@oss.qualcomm.com>

On 8/12/25 11:39 AM, Pengyu Luo wrote:
> property "qcom,tune-usb2-preem" is for EUSB2_TUNE_USB2_PREEM
> property "qcom,tune-usb2-amplitude" is for EUSB2_TUNE_IUSB2
> 
> The downstream correspondence is as follows:
> EUSB2_TUNE_USB2_PREEM: Tx pre-emphasis tuning
> EUSB2_TUNE_IUSB2: HS trasmit amplitude
> EUSB2_TUNE_SQUELCH_U: Squelch detection threshold
> EUSB2_TUNE_HSDISC: HS disconnect threshold
> EUSB2_TUNE_EUSB_SLEW: slew rate

The commit message is a bit.. dry.. but I suppose it conveys what
the problem is
> 
> Fixes: 31bc94de7602 ("phy: qualcomm: phy-qcom-eusb2-repeater: Don't zero-out registers")
> Signed-off-by: Pengyu Luo <mitltlatltl at gmail.com>
> ---

Reviewed-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>

Konrad



From luca.weiss at fairphone.com  Tue Aug 12 03:13:39 2025
From: luca.weiss at fairphone.com (Luca Weiss)
Date: Tue, 12 Aug 2025 12:13:39 +0200
Subject: [PATCH] phy: qualcomm: phy-qcom-eusb2-repeater: fix override
 properties
In-Reply-To: <20250812093957.32235-1-mitltlatltl@gmail.com>
References: <20250812093957.32235-1-mitltlatltl@gmail.com>
Message-ID: <DC0DBER6477Q.143SU9KXEI6FN@fairphone.com>

On Tue Aug 12, 2025 at 11:39 AM CEST, Pengyu Luo wrote:
> property "qcom,tune-usb2-preem" is for EUSB2_TUNE_USB2_PREEM
> property "qcom,tune-usb2-amplitude" is for EUSB2_TUNE_IUSB2
>
> The downstream correspondence is as follows:
> EUSB2_TUNE_USB2_PREEM: Tx pre-emphasis tuning
> EUSB2_TUNE_IUSB2: HS trasmit amplitude
> EUSB2_TUNE_SQUELCH_U: Squelch detection threshold
> EUSB2_TUNE_HSDISC: HS disconnect threshold
> EUSB2_TUNE_EUSB_SLEW: slew rate
>
> Fixes: 31bc94de7602 ("phy: qualcomm: phy-qcom-eusb2-repeater: Don't zero-out registers")

Oh, not sure how this happened. Thanks for catching this, I do see the
problem in my original commit.

Reviewed-by: Luca Weiss <luca.weiss at fairphone.com>

Regards
Luca

> Signed-off-by: Pengyu Luo <mitltlatltl at gmail.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
> index d7493c229..3709fba42 100644
> --- a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
> +++ b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
> @@ -127,13 +127,13 @@ static int eusb2_repeater_init(struct phy *phy)
>  			     rptr->cfg->init_tbl[i].value);
>  
>  	/* Override registers from devicetree values */
> -	if (!of_property_read_u8(np, "qcom,tune-usb2-amplitude", &val))
> +	if (!of_property_read_u8(np, "qcom,tune-usb2-preem", &val))
>  		regmap_write(regmap, base + EUSB2_TUNE_USB2_PREEM, val);
>  
>  	if (!of_property_read_u8(np, "qcom,tune-usb2-disc-thres", &val))
>  		regmap_write(regmap, base + EUSB2_TUNE_HSDISC, val);
>  
> -	if (!of_property_read_u8(np, "qcom,tune-usb2-preem", &val))
> +	if (!of_property_read_u8(np, "qcom,tune-usb2-amplitude", &val))
>  		regmap_write(regmap, base + EUSB2_TUNE_IUSB2, val);
>  
>  	/* Wait for status OK */



From vkoul at kernel.org  Tue Aug 12 03:33:27 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Tue, 12 Aug 2025 16:03:27 +0530
Subject: [PATCH v10 1/5] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy:
 Update pcie phy bindings for qcs8300
In-Reply-To: <20250811071131.982983-2-ziyue.zhang@oss.qualcomm.com>
References: <20250811071131.982983-1-ziyue.zhang@oss.qualcomm.com>
 <20250811071131.982983-2-ziyue.zhang@oss.qualcomm.com>
Message-ID: <aJsYd7tAi4CdOfZ9@vaman>

On 11-08-25, 15:11, Ziyue Zhang wrote:
> The gcc_aux_clk is not required by the PCIe PHY on qcs8300 and is not
> specified in the device tree node. Hence, move the qcs8300 phy
> compatibility entry into the list of PHYs that require six clocks.
> 
> Removed the phy_aux clock from the PCIe PHY binding as it is no longer
> used by any instance.

This does not apply on phy tree, please rebase

-- 
~Vinod


From dmitry.baryshkov at oss.qualcomm.com  Tue Aug 12 03:52:08 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Tue, 12 Aug 2025 13:52:08 +0300
Subject: [PATCH V1 2/4] arm64: dts: qcom: sm8750: add max-microamp for
 UFS PHY and PLL supplies
In-Reply-To: <89ab7e51-f82e-465a-aa22-1ccb8e7a0f6d@quicinc.com>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
 <20250806154340.20122-3-quic_nitirawa@quicinc.com>
 <20250808-calm-boa-of-swiftness-a4a7ce@kuoka>
 <9af71063-0629-4ccc-bc76-3fb588677bf4@oss.qualcomm.com>
 <292907f3-25d6-40d9-be6e-b6b83e646d73@kernel.org>
 <5e32be05-0dbd-4d6f-879d-8ce97fb430ba@quicinc.com>
 <rh3qxu2rijpjswfash3rpmmh6sw47l3b6j5p5upti6zffknasz@cywwm3fypghd>
 <89ab7e51-f82e-465a-aa22-1ccb8e7a0f6d@quicinc.com>
Message-ID: <ljythvl2yfilcnmgdwt2cyyefxmgl54osll5e76qn7njadhgqq@rwrl3dy6ykt3>

On Tue, Aug 12, 2025 at 01:25:02AM +0530, Nitin Rawat wrote:
> 
> 
> On 8/9/2025 4:37 PM, Manivannan Sadhasivam wrote:
> > On Fri, Aug 08, 2025 at 08:49:45PM GMT, Nitin Rawat wrote:
> > > 
> > > 
> > > On 8/8/2025 3:09 PM, Krzysztof Kozlowski wrote:
> > > > On 08/08/2025 10:58, Konrad Dybcio wrote:
> > > > > On 8/8/25 9:29 AM, Krzysztof Kozlowski wrote:
> > > > > > On Wed, Aug 06, 2025 at 09:13:38PM +0530, Nitin Rawat wrote:
> > > > > > > Add `vdda-phy-max-microamp` and `vdda-pll-max-microamp` properties to
> > > > > > > the UFS PHY node in the device tree.
> > > > > > > 
> > > > > > > These properties define the maximum current (in microamps) expected
> > > > > > > from the PHY and PLL regulators. This allows the PHY driver to
> > > > > > > configure regulator load accurately and ensure proper regulator
> > > > > > > mode based on load requirements.
> > > > > > 
> > > > > > That's not the property of phy, but regulator.
> > > > > > 
> > > > > > Also reasoning is here incomplete - you just post downstream code. :/
> > > > > 
> > > > > The reason for this change is good, but perhaps not explained clearly
> > > > > 
> > > > > All of these values refer to the maximum current draw that needs to be
> > > > > allocated on a shared voltage supply for this peripheral (because the
> > > > 
> > > > 
> > > > It sounds very different than how much it can be drawn. How much can be
> > > > drawn is the property of the regulator. The regulator knows how much
> > > > current it can support.
> > > 
> > > Consumers are aware of their dynamic load requirements, which can vary at
> > > runtime?this awareness is not reciprocal. The power grid is designed based
> > > on the collective load requirements of all clients sharing the same power
> > > rail.
> > > 
> > > Since regulators can operate in multiple modes for power optimization, each
> > > consumer is expected to vote for its runtime power needs. These votes help
> > > the regulator framework maintain the regulator in the appropriate mode,
> > > ensuring stable and efficient operation across all clients.
> > > 
> > > 
> > > Stability issues can arise if each consumer does not vote for its own load
> > > requirement.
> > > For example, consider a scenario where a single regulator is shared by two
> > > consumers.
> > > 
> > > If the first client requests low-power mode by voting for zero or a minimal
> > > load to regulator framework during its driver's LPM sequence, and the second
> > > client (e.g., UFS PHY) has not voted for its own load requirement through
> > > the regulator framework, the regulator may transition to low-power mode.
> > > This can lead to issues for the second client, which expects a higher power
> > > state to operate correctly.
> > > 
> > 
> > I think we all agree on consumers setting the load for shared regulators, but
> > the naming and description of the DT property is what causing confusion here.
> > There is no way the consumers can set the *max* current draw for a shared
> > regulator. They can only request load as per their requirement. But the max
> > current draw is a regulator constraint.
> 
> To avoid confusion with regulator-level constraints, I'm open to renaming
> the property vdda-phy-max-microamp to something more descriptive, such as
> vdda-phy-client-peak-load-microamp or vdda-phy-peak-load-microamp. Along
> with updating the description, this would better reflect the property's
> actual intent: to specify the maximum current a client may draw during peak
> operation, rather than implying it defines the regulator?s maximum
> capability.

Move them into the driver please.

> 
> 
> Having said that, I had a follow-up discussion with the PHY designer to
> confirm whether this value could vary at the board level. Based on their
> response, it's a fixed value for the SoC and does not change across
> different boards(atleast for now). Therefore, I can remove from device tree
> and replaced with hardcoded, per-compatible data in the driver.
> 
> > 
> > > 
> > > > 
> > > > 
> > > > > supply's capabilities change depending on the maximum potential load
> > > > > at any given time, which the regulator driver must be aware of)
> > > > > 
> > > > > This is a property of a regulator *consumer*, i.e. if we had a chain
> > > > > of LEDs hanging off of this supply, we'd need to specify NUM_LEDS *
> > > > > MAX_CURR under the "led chain" device, to make sure that if the
> > > > > aggregated current requirements go over a certain threshold (which is
> > > > > unknown to Linux and hidden in RPMh fw), the regulator can be
> > > > > reconfigured to allow for a higher current draw (likely at some
> > > > > downgrade to efficiency)
> > > > 
> > > > 
> > > > The problem is that rationale is downstream. Instead I want to see some
> > > > reason: e.g. datasheets, spec, type of UFS device (that was the argument
> > > > in the driver patch discussion).
> > > 
> > > 
> > > The PHY load requirements for consumers such as UFS, USB, PCIe are defined
> > > by Qualcomm?s PHY IP and are well-documented in Qualcomm?s datasheets and
> > > power grid documentation. These values can depending on the process or
> > > technology node, board design, and even the chip foundry used.
> > > 
> > > As a result, the load values can differ across SoCs or may be even
> > > board(unlikely though) due to variations in any of these parameters.
> > > 
> > 
> > Okay. This goes into the commit message and possibly some part of it to property
> > description also.
> 
> 
> 
> 
> > 
> > - Mani
> > 
> 

-- 
With best wishes
Dmitry


From yizhijiao2025 at 163.com  Tue Aug 12 04:38:06 2025
From: yizhijiao2025 at 163.com (yizhijiao2025 at 163.com)
Date: Tue, 12 Aug 2025 19:38:06 +0800
Subject: =?UTF-8?Q?=E5=9B=9E=E5=A4=8D:_=5BPATCH_V1_2/4=5D_arm64:_dts:_q?=
	=?UTF-8?Q?com:_sm8750:_add_max-microamp_fo?=
	=?UTF-8?Q?r_UFS_PHY_and_PLL_supplies?=
In-Reply-To: <ljythvl2yfilcnmgdwt2cyyefxmgl54osll5e76qn7njadhgqq@rwrl3dy6ykt3>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com> <20250806154340.20122-3-quic_nitirawa@quicinc.com> <20250808-calm-boa-of-swiftness-a4a7ce@kuoka> <9af71063-0629-4ccc-bc76-3fb588677bf4@oss.qualcomm.com> <292907f3-25d6-40d9-be6e-b6b83e646d73@kernel.org> <5e32be05-0dbd-4d6f-879d-8ce97fb430ba@quicinc.com> <rh3qxu2rijpjswfash3rpmmh6sw47l3b6j5p5upti6zffknasz@cywwm3fypghd> <89ab7e51-f82e-465a-aa22-1ccb8e7a0f6d@quicinc.com> <ljythvl2yfilcnmgdwt2cyyefxmgl54osll5e76qn7njadhgqq@rwrl3dy6ykt3>
Message-ID: <006d01dc0b7d$929184a0$b7b48de0$@163.com>



-----????-----
???: linux-arm-msm+bounces-68747-yizhijiao2025=163.com at vger.kernel.org <linux-arm-msm+bounces-68747-yizhijiao2025=163.com at vger.kernel.org> ?? Dmitry Baryshkov
????: 2025?8?12? 18:52
???: Nitin Rawat <quic_nitirawa at quicinc.com>
??: Manivannan Sadhasivam <mani at kernel.org>; Krzysztof Kozlowski <krzk at kernel.org>; Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>; vkoul at kernel.org; kishon at kernel.org; conor+dt at kernel.org; bvanassche at acm.org; andersson at kernel.org; neil.armstrong at linaro.org; konradybcio at kernel.org; krzk+dt at kernel.org; linux-arm-msm at vger.kernel.org; linux-phy at lists.infradead.org; linux-kernel at vger.kernel.org; devicetree at vger.kernel.org
??: Re: [PATCH V1 2/4] arm64: dts: qcom: sm8750: add max-microamp for UFS PHY and PLL supplies

On Tue, Aug 12, 2025 at 01:25:02AM +0530, Nitin Rawat wrote:
> 
> 
> On 8/9/2025 4:37 PM, Manivannan Sadhasivam wrote:
> > On Fri, Aug 08, 2025 at 08:49:45PM GMT, Nitin Rawat wrote:
> > > 
> > > 
> > > On 8/8/2025 3:09 PM, Krzysztof Kozlowski wrote:
> > > > On 08/08/2025 10:58, Konrad Dybcio wrote:
> > > > > On 8/8/25 9:29 AM, Krzysztof Kozlowski wrote:
> > > > > > On Wed, Aug 06, 2025 at 09:13:38PM +0530, Nitin Rawat wrote:
> > > > > > > Add `vdda-phy-max-microamp` and `vdda-pll-max-microamp` 
> > > > > > > properties to the UFS PHY node in the device tree.
> > > > > > > 
> > > > > > > These properties define the maximum current (in microamps) 
> > > > > > > expected from the PHY and PLL regulators. This allows the 
> > > > > > > PHY driver to configure regulator load accurately and 
> > > > > > > ensure proper regulator mode based on load requirements.
> > > > > > 
> > > > > > That's not the property of phy, but regulator.
> > > > > > 
> > > > > > Also reasoning is here incomplete - you just post downstream 
> > > > > > code. :/
> > > > > 
> > > > > The reason for this change is good, but perhaps not explained 
> > > > > clearly
> > > > > 
> > > > > All of these values refer to the maximum current draw that 
> > > > > needs to be allocated on a shared voltage supply for this 
> > > > > peripheral (because the
> > > > 
> > > > 
> > > > It sounds very different than how much it can be drawn. How much 
> > > > can be drawn is the property of the regulator. The regulator 
> > > > knows how much current it can support.
> > > 
> > > Consumers are aware of their dynamic load requirements, which can 
> > > vary at runtime?this awareness is not reciprocal. The power grid 
> > > is designed based on the collective load requirements of all 
> > > clients sharing the same power rail.
> > > 
> > > Since regulators can operate in multiple modes for power 
> > > optimization, each consumer is expected to vote for its runtime 
> > > power needs. These votes help the regulator framework maintain the 
> > > regulator in the appropriate mode, ensuring stable and efficient operation across all clients.
> > > 
> > > 
> > > Stability issues can arise if each consumer does not vote for its 
> > > own load requirement.
> > > For example, consider a scenario where a single regulator is 
> > > shared by two consumers.
> > > 
> > > If the first client requests low-power mode by voting for zero or 
> > > a minimal load to regulator framework during its driver's LPM 
> > > sequence, and the second client (e.g., UFS PHY) has not voted for 
> > > its own load requirement through the regulator framework, the regulator may transition to low-power mode.
> > > This can lead to issues for the second client, which expects a 
> > > higher power state to operate correctly.
> > > 
> > 
> > I think we all agree on consumers setting the load for shared 
> > regulators, but the naming and description of the DT property is what causing confusion here.
> > There is no way the consumers can set the *max* current draw for a 
> > shared regulator. They can only request load as per their 
> > requirement. But the max current draw is a regulator constraint.
> 
> To avoid confusion with regulator-level constraints, I'm open to 
> renaming the property vdda-phy-max-microamp to something more 
> descriptive, such as vdda-phy-client-peak-load-microamp or 
> vdda-phy-peak-load-microamp. Along with updating the description, this 
> would better reflect the property's actual intent: to specify the 
> maximum current a client may draw during peak operation, rather than 
> implying it defines the regulator?s maximum capability.

Move them into the driver please.

> 
> 
> Having said that, I had a follow-up discussion with the PHY designer 
> to confirm whether this value could vary at the board level. Based on 
> their response, it's a fixed value for the SoC and does not change 
> across different boards(atleast for now). Therefore, I can remove from 
> device tree and replaced with hardcoded, per-compatible data in the driver.
> 
> > 
> > > 
> > > > 
> > > > 
> > > > > supply's capabilities change depending on the maximum 
> > > > > potential load at any given time, which the regulator driver 
> > > > > must be aware of)
> > > > > 
> > > > > This is a property of a regulator *consumer*, i.e. if we had a 
> > > > > chain of LEDs hanging off of this supply, we'd need to specify 
> > > > > NUM_LEDS * MAX_CURR under the "led chain" device, to make sure 
> > > > > that if the aggregated current requirements go over a certain 
> > > > > threshold (which is unknown to Linux and hidden in RPMh fw), 
> > > > > the regulator can be reconfigured to allow for a higher 
> > > > > current draw (likely at some downgrade to efficiency)
> > > > 
> > > > 
> > > > The problem is that rationale is downstream. Instead I want to 
> > > > see some
> > > > reason: e.g. datasheets, spec, type of UFS device (that was the 
> > > > argument in the driver patch discussion).
> > > 
> > > 
> > > The PHY load requirements for consumers such as UFS, USB, PCIe are 
> > > defined by Qualcomm?s PHY IP and are well-documented in Qualcomm?s 
> > > datasheets and power grid documentation. These values can 
> > > depending on the process or technology node, board design, and even the chip foundry used.
> > > 
> > > As a result, the load values can differ across SoCs or may be even 
> > > board(unlikely though) due to variations in any of these parameters.
> > > 
> > 
> > Okay. This goes into the commit message and possibly some part of it 
> > to property description also.
> 
> 
> 
> 
> > 
> > - Mani
> > 
> 

--
With best wishes
Dmitry



From neil.armstrong at linaro.org  Tue Aug 12 06:39:00 2025
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Tue, 12 Aug 2025 15:39:00 +0200
Subject: [PATCH 2/2] phy: qcom-mipi-csi2: Add a CSI2 MIPI D-PHY driver
In-Reply-To: <20250710-x1e-csi2-phy-v1-2-74acbb5b162b@linaro.org>
References: <20250710-x1e-csi2-phy-v1-0-74acbb5b162b@linaro.org>
 <20250710-x1e-csi2-phy-v1-2-74acbb5b162b@linaro.org>
Message-ID: <d7949778-73c4-4575-8db3-a3724f75eb38@linaro.org>

On 10/07/2025 18:16, Bryan O'Donoghue wrote:
> Add a new MIPI CSI2 driver in D-PHY mode initially. The entire set of
> existing CAMSS CSI PHY init sequences are imported in order to save time
> and effort in later patches.
> 
> In-line with other PHY drivers the process node name is omitted from the
> compat string while the soc name is included.
> 
> At the moment we follow the assignment of lane positions - the bitmap of
> physical input lanes to logical lane numbers as a linear list per the
> existing DPHY @lanes data-member.
> 
> This is fine for us in upstream since we also map the lanes contiguously
> but, our hardware can support different lane mappings so we should in the
> future extend out the DPHY structure to capture the mapping.
> 
> The Qualcomm 3PH class of PHYs can do both D-PHY and C-PHY mode. For now only
> D-PHY is supported.
> 
> In porting some of the logic over from camss-csiphy*.c to here its also
> possible to rationalise some of the code.
> 
> In particular use of regulator_bulk and clk_bulk as well as dropping the
> seemingly useless and unused interrupt handler.
> 
> The PHY sequences and a lot of the logic that goes with them are well proven
> in CAMSS and mature so the main thing to watch out for here is how to get
> the right sequencing of regulators, clocks and register-writes.
> 
> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
> ---
>   MAINTAINERS                                        |  11 +
>   drivers/phy/qualcomm/Kconfig                       |  11 +
>   drivers/phy/qualcomm/Makefile                      |   6 +
>   drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c | 491 +++++++++++++++++++++
>   drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c     | 281 ++++++++++++
>   drivers/phy/qualcomm/phy-qcom-mipi-csi2.h          | 101 +++++
>   6 files changed, 901 insertions(+)
> 
>
<snip>

> +const struct mipi_csi2phy_clk_freq zero = { 0 };
> +
> +const struct mipi_csi2phy_clk_freq dphy_4nm_x1e_csiphy = {
> +	.freq = {
> +		300000000, 400000000, 480000000
> +	},
> +	.num_freq = 3,
> +};
> +
> +const struct mipi_csi2phy_clk_freq dphy_4nm_x1e_csiphy_timer = {
> +	.freq = {
> +		266666667, 400000000
> +	},
> +	.num_freq = 2,
> +};
> +
> +const struct mipi_csi2phy_soc_cfg mipi_csi2_dphy_4nm_x1e = {
> +	.ops = &phy_qcom_mipi_csi2_ops_3ph_1_0,
> +	.reg_info = {
> +		.init_seq = lane_regs_x1e80100,
> +		.lane_array_size = ARRAY_SIZE(lane_regs_x1e80100),
> +		.offset = 0x1000,
> +		.generation = GEN2,
> +	},
> +	.supply_names = (const char *[]){
> +		"vdda-0p8",
> +		"vdda-1p2"
> +	},
> +	.num_supplies = 2,
> +	.clk_names = (const char *[]) {
> +		"camnoc_axi",
> +		"cpas_ahb",
> +		"csiphy",
> +		"csiphy_timer"
> +	},
> +	.num_clk = 4,
> +	.clk_freq = {
> +		zero,

It seems clang doesn't like this at all:
drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c:486:3: error: initializer element is not a compile-time constant
                 zero,
                 ^~~~
1 error generated.

> +		zero,
> +		dphy_4nm_x1e_csiphy,
> +		dphy_4nm_x1e_csiphy_timer,
> +	},
> +};
<snip>



From krishna.chundru at oss.qualcomm.com  Tue Aug 12 06:56:43 2025
From: krishna.chundru at oss.qualcomm.com (Krishna Chaitanya Chundru)
Date: Tue, 12 Aug 2025 19:26:43 +0530
Subject: [PATCH v2 0/2] arm64: dts: qcom: sc7280: Add PCIe0 node
Message-ID: <20250812-sc7280-v2-0-814e36121af0@oss.qualcomm.com>

Add PCIe dtsi node for PCIe0 controller on sc7280 platform.
SC7280 PCIe0 PHY is functionally compatible with the SM8250 Gen3 x1 PCIe
PHY. To reflect this compatibility, update the binding schema to include
qcom,sc7280-qmp-gen3x1-pcie-phy using enum within a oneOf block, while
retaining qcom,sm8250-qmp-gen3x1-pcie-phy as a const.

Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
---
Changes from v1:
- Rebased to the latest code
- Added new compatible for pcie0 phy (Krzysztof)
- Fix the name of the pinctrl state of PCIe side band signals(Krzysztof)
Link to v1: https://lore.kernel.org/all/1690540760-20191-1-git-send-email-quic_krichai at quicinc.com/

---
Krishna Chaitanya Chundru (2):
      dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Document SC7280 PCIe0 phy
      arm64: dts: qcom: sc7280: Add PCIe0 node

 .../bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml   |  69 +++++----
 arch/arm64/boot/dts/qcom/sc7280.dtsi               | 170 ++++++++++++++++++++-
 2 files changed, 206 insertions(+), 33 deletions(-)
---
base-commit: c30a13538d9f8b2a60b2f6b26abe046dea10aa12
change-id: 20250809-sc7280-2dedf8ecad04

Best regards,
-- 
Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>



From krishna.chundru at oss.qualcomm.com  Tue Aug 12 06:56:44 2025
From: krishna.chundru at oss.qualcomm.com (Krishna Chaitanya Chundru)
Date: Tue, 12 Aug 2025 19:26:44 +0530
Subject: [PATCH v2 1/2] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy:
 Document SC7280 PCIe0 phy
In-Reply-To: <20250812-sc7280-v2-0-814e36121af0@oss.qualcomm.com>
References: <20250812-sc7280-v2-0-814e36121af0@oss.qualcomm.com>
Message-ID: <20250812-sc7280-v2-1-814e36121af0@oss.qualcomm.com>

SC7280 PCIe0 PHY is functionally compatible with the SM8250 Gen3 x1 PCIe
PHY. To reflect this compatibility, update the binding schema to include
qcom,sc7280-qmp-gen3x1-pcie-phy using enum within a oneOf block, while
retaining qcom,sm8250-qmp-gen3x1-pcie-phy as a const.

Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
---
 .../bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml   | 69 ++++++++++++----------
 1 file changed, 37 insertions(+), 32 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 a1ae8c7988c891a11f6872e58d25e9d04abb41ce..1e08e26892f7b769b75bb905377d30a301e6631c 100644
--- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
@@ -15,38 +15,43 @@ description:
 
 properties:
   compatible:
-    enum:
-      - qcom,qcs615-qmp-gen3x1-pcie-phy
-      - qcom,qcs8300-qmp-gen4x2-pcie-phy
-      - qcom,sa8775p-qmp-gen4x2-pcie-phy
-      - qcom,sa8775p-qmp-gen4x4-pcie-phy
-      - qcom,sar2130p-qmp-gen3x2-pcie-phy
-      - qcom,sc8180x-qmp-pcie-phy
-      - qcom,sc8280xp-qmp-gen3x1-pcie-phy
-      - qcom,sc8280xp-qmp-gen3x2-pcie-phy
-      - qcom,sc8280xp-qmp-gen3x4-pcie-phy
-      - qcom,sdm845-qhp-pcie-phy
-      - qcom,sdm845-qmp-pcie-phy
-      - qcom,sdx55-qmp-pcie-phy
-      - qcom,sdx65-qmp-gen4x2-pcie-phy
-      - qcom,sm8150-qmp-gen3x1-pcie-phy
-      - qcom,sm8150-qmp-gen3x2-pcie-phy
-      - qcom,sm8250-qmp-gen3x1-pcie-phy
-      - qcom,sm8250-qmp-gen3x2-pcie-phy
-      - qcom,sm8250-qmp-modem-pcie-phy
-      - qcom,sm8350-qmp-gen3x1-pcie-phy
-      - qcom,sm8350-qmp-gen3x2-pcie-phy
-      - qcom,sm8450-qmp-gen3x1-pcie-phy
-      - qcom,sm8450-qmp-gen4x2-pcie-phy
-      - qcom,sm8550-qmp-gen3x2-pcie-phy
-      - 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
-      - qcom,x1e80100-qmp-gen4x4-pcie-phy
-      - qcom,x1e80100-qmp-gen4x8-pcie-phy
-      - qcom,x1p42100-qmp-gen4x4-pcie-phy
+    oneOf:
+      - items:
+          - const: qcom,sc7280-qmp-gen3x1-pcie-phy
+          - const: qcom,sm8250-qmp-gen3x1-pcie-phy
+      - items:
+          - enum:
+              - qcom,qcs615-qmp-gen3x1-pcie-phy
+              - qcom,qcs8300-qmp-gen4x2-pcie-phy
+              - qcom,sa8775p-qmp-gen4x2-pcie-phy
+              - qcom,sa8775p-qmp-gen4x4-pcie-phy
+              - qcom,sar2130p-qmp-gen3x2-pcie-phy
+              - qcom,sc8180x-qmp-pcie-phy
+              - qcom,sc8280xp-qmp-gen3x1-pcie-phy
+              - qcom,sc8280xp-qmp-gen3x2-pcie-phy
+              - qcom,sc8280xp-qmp-gen3x4-pcie-phy
+              - qcom,sdm845-qhp-pcie-phy
+              - qcom,sdm845-qmp-pcie-phy
+              - qcom,sdx55-qmp-pcie-phy
+              - qcom,sdx65-qmp-gen4x2-pcie-phy
+              - qcom,sm8150-qmp-gen3x1-pcie-phy
+              - qcom,sm8150-qmp-gen3x2-pcie-phy
+              - qcom,sm8250-qmp-gen3x1-pcie-phy
+              - qcom,sm8250-qmp-gen3x2-pcie-phy
+              - qcom,sm8250-qmp-modem-pcie-phy
+              - qcom,sm8350-qmp-gen3x1-pcie-phy
+              - qcom,sm8350-qmp-gen3x2-pcie-phy
+              - qcom,sm8450-qmp-gen3x1-pcie-phy
+              - qcom,sm8450-qmp-gen4x2-pcie-phy
+              - qcom,sm8550-qmp-gen3x2-pcie-phy
+              - 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
+              - qcom,x1e80100-qmp-gen4x4-pcie-phy
+              - qcom,x1e80100-qmp-gen4x8-pcie-phy
+              - qcom,x1p42100-qmp-gen4x4-pcie-phy
 
   reg:
     minItems: 1

-- 
2.34.1



From krishna.chundru at oss.qualcomm.com  Tue Aug 12 06:56:45 2025
From: krishna.chundru at oss.qualcomm.com (Krishna Chaitanya Chundru)
Date: Tue, 12 Aug 2025 19:26:45 +0530
Subject: [PATCH v2 2/2] arm64: dts: qcom: sc7280: Add PCIe0 node
In-Reply-To: <20250812-sc7280-v2-0-814e36121af0@oss.qualcomm.com>
References: <20250812-sc7280-v2-0-814e36121af0@oss.qualcomm.com>
Message-ID: <20250812-sc7280-v2-2-814e36121af0@oss.qualcomm.com>

Add PCIe dtsi node for PCIe0 controller on sc7280 platform.

Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/sc7280.dtsi | 170 ++++++++++++++++++++++++++++++++++-
 1 file changed, 169 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi
index 64a2abd3010018e94eb50c534a509d6b4cf2473b..b0f688ce1c285888c05ed718e58dfafd51e2c1cf 100644
--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
@@ -970,7 +970,7 @@ gcc: clock-controller at 100000 {
 			reg = <0 0x00100000 0 0x1f0000>;
 			clocks = <&rpmhcc RPMH_CXO_CLK>,
 				 <&rpmhcc RPMH_CXO_CLK_A>, <&sleep_clk>,
-				 <0>, <&pcie1_phy>,
+				 <&pcie0_phy>, <&pcie1_phy>,
 				 <&ufs_mem_phy 0>, <&ufs_mem_phy 1>, <&ufs_mem_phy 2>,
 				 <&usb_1_qmpphy QMP_USB43DP_USB3_PIPE_CLK>;
 			clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk",
@@ -2200,6 +2200,149 @@ wifi: wifi at 17a10040 {
 			qcom,smem-state-names = "wlan-smp2p-out";
 		};
 
+		pcie0: pci at 1c00000 {
+			device_type = "pci";
+			compatible = "qcom,pcie-sc7280";
+			reg = <0x0 0x01c00000 0x0 0x3000>,
+			      <0x0 0x60000000 0x0 0xf1d>,
+			      <0x0 0x60000f20 0x0 0xa8>,
+			      <0x0 0x60001000 0x0 0x1000>,
+			      <0x0 0x60100000 0x0 0x100000>;
+			reg-names = "parf",
+				    "dbi",
+				    "elbi",
+				    "atu",
+				    "config";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			ranges = <0x01000000 0x0 0x00000000 0x0 0x60200000 0x0 0x100000>,
+				 <0x02000000 0x0 0x60300000 0x0 0x60300000 0x0 0x3d00000>;
+			bus-range = <0x00 0xff>;
+
+			dma-coherent;
+
+			linux,pci-domain = <0>;
+			num-lanes = <1>;
+
+			interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 140 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 0 149 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 2 &intc 0 0 0 150 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 3 &intc 0 0 0 151 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 4 &intc 0 0 0 152 IRQ_TYPE_LEVEL_HIGH>;
+
+			clocks = <&gcc GCC_PCIE_0_PIPE_CLK>,
+				 <&gcc GCC_PCIE_0_PIPE_CLK_SRC>,
+				 <&pcie0_phy>,
+				 <&rpmhcc RPMH_CXO_CLK>,
+				 <&gcc GCC_PCIE_0_AUX_CLK>,
+				 <&gcc GCC_PCIE_0_CFG_AHB_CLK>,
+				 <&gcc GCC_PCIE_0_MSTR_AXI_CLK>,
+				 <&gcc GCC_PCIE_0_SLV_AXI_CLK>,
+				 <&gcc GCC_PCIE_0_SLV_Q2A_AXI_CLK>,
+				 <&gcc GCC_AGGRE_NOC_PCIE_TBU_CLK>,
+				 <&gcc GCC_DDRSS_PCIE_SF_CLK>,
+				 <&gcc GCC_AGGRE_NOC_PCIE_CENTER_SF_AXI_CLK>,
+				 <&gcc GCC_AGGRE_NOC_PCIE_0_AXI_CLK>;
+
+			clock-names = "pipe",
+				      "pipe_mux",
+				      "phy_pipe",
+				      "ref",
+				      "aux",
+				      "cfg",
+				      "bus_master",
+				      "bus_slave",
+				      "slave_q2a",
+				      "tbu",
+				      "ddrss_sf_tbu",
+				      "aggre0",
+				      "aggre1";
+
+			assigned-clocks = <&gcc GCC_PCIE_0_AUX_CLK>;
+			assigned-clock-rates = <19200000>;
+
+			interconnects = <&aggre1_noc MASTER_PCIE_0 QCOM_ICC_TAG_ALWAYS
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+					<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &cnoc2 SLAVE_PCIE_0 QCOM_ICC_TAG_ACTIVE_ONLY>;
+			interconnect-names = "pcie-mem",
+					     "cpu-pcie";
+
+			iommu-map = <0x0 &apps_smmu 0x1c00 0x1>,
+				   <0x100 &apps_smmu 0x1c01 0x1>;
+
+			resets = <&gcc GCC_PCIE_0_BCR>;
+			reset-names = "pci";
+
+			power-domains = <&gcc GCC_PCIE_0_GDSC>;
+
+			phys = <&pcie0_phy>;
+			phy-names = "pciephy";
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&pcie0_clkreq_n>, <&pcie0_reset_n>, <&pcie0_wake_n>;
+
+			status = "disabled";
+
+			pcie at 0 {
+				device_type = "pci";
+				reg = <0x0 0x0 0x0 0x0 0x0>;
+				bus-range = <0x01 0xff>;
+
+				#address-cells = <3>;
+				#size-cells = <2>;
+				ranges;
+			};
+		};
+
+		pcie0_phy: phy at 1c06000 {
+			compatible = "qcom,sc7280-qmp-gen3x1-pcie-phy", "qcom,sm8250-qmp-gen3x1-pcie-phy";
+			reg = <0 0x01c06000 0 0x1000>;
+			clocks = <&gcc GCC_PCIE_0_AUX_CLK>,
+				 <&gcc GCC_PCIE_0_CFG_AHB_CLK>,
+				 <&gcc GCC_PCIE_CLKREF_EN>,
+				 <&gcc GCC_PCIE0_PHY_RCHNG_CLK>,
+				 <&gcc GCC_PCIE_0_PIPE_CLK>;
+			clock-names = "aux",
+				      "cfg_ahb",
+				      "ref",
+				      "refgen",
+				      "pipe";
+
+			clock-output-names = "pcie_0_pipe_clk";
+			#clock-cells = <0>;
+
+			#phy-cells = <0>;
+
+			resets = <&gcc GCC_PCIE_0_PHY_BCR>;
+			reset-names = "phy";
+
+			assigned-clocks = <&gcc GCC_PCIE0_PHY_RCHNG_CLK>;
+			assigned-clock-rates = <100000000>;
+
+			status = "disabled";
+		};
+
 		pcie1: pcie at 1c08000 {
 			compatible = "qcom,pcie-sc7280";
 			reg = <0 0x01c08000 0 0x3000>,
@@ -5285,6 +5428,31 @@ mi2s1_ws: mi2s1-ws-state {
 				function = "mi2s1_ws";
 			};
 
+			pcie0_reset_n: pcie0-reset-n-state {
+				pins = "gpio87";
+				function = "gpio";
+
+				drive-strength = <16>;
+				output-low;
+				bias-disable;
+			};
+
+			pcie0_wake_n: pcie0-wake-n-state {
+				pins = "gpio89";
+				function = "gpio";
+
+				drive-strength = <2>;
+				bias-pull-up;
+			};
+
+			pcie0_clkreq_n: pcie0-clkreq-n-state {
+				pins = "gpio88";
+				function = "pcie0_clkreqn";
+
+				bias-pull-up;
+				drive-strength = <2>;
+			};
+
 			pcie1_clkreq_n: pcie1-clkreq-n-state {
 				pins = "gpio79";
 				function = "pcie1_clkreqn";

-- 
2.34.1



From krzk at kernel.org  Tue Aug 12 07:04:33 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 12 Aug 2025 16:04:33 +0200
Subject: [PATCH v2 2/2] arm64: dts: qcom: sc7280: Add PCIe0 node
In-Reply-To: <20250812-sc7280-v2-2-814e36121af0@oss.qualcomm.com>
References: <20250812-sc7280-v2-0-814e36121af0@oss.qualcomm.com>
 <20250812-sc7280-v2-2-814e36121af0@oss.qualcomm.com>
Message-ID: <9a68f046-176a-4b10-af73-1a0dd849d5cd@kernel.org>

On 12/08/2025 15:56, Krishna Chaitanya Chundru wrote:
> Add PCIe dtsi node for PCIe0 controller on sc7280 platform.
> 
> Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
> ---
>  arch/arm64/boot/dts/qcom/sc7280.dtsi | 170 ++++++++++++++++++++++++++++++++++-
>  1 file changed, 169 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi
> index 64a2abd3010018e94eb50c534a509d6b4cf2473b..b0f688ce1c285888c05ed718e58dfafd51e2c1cf 100644
> --- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
> @@ -970,7 +970,7 @@ gcc: clock-controller at 100000 {
>  			reg = <0 0x00100000 0 0x1f0000>;
>  			clocks = <&rpmhcc RPMH_CXO_CLK>,
>  				 <&rpmhcc RPMH_CXO_CLK_A>, <&sleep_clk>,
> -				 <0>, <&pcie1_phy>,
> +				 <&pcie0_phy>, <&pcie1_phy>,
>  				 <&ufs_mem_phy 0>, <&ufs_mem_phy 1>, <&ufs_mem_phy 2>,
>  				 <&usb_1_qmpphy QMP_USB43DP_USB3_PIPE_CLK>;
>  			clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk",
> @@ -2200,6 +2200,149 @@ wifi: wifi at 17a10040 {
>  			qcom,smem-state-names = "wlan-smp2p-out";
>  		};
>  
> +		pcie0: pci at 1c00000 {
> +			device_type = "pci";
> +			compatible = "qcom,pcie-sc7280";

This was already sent and reviewed by Bjorn. Please don't duplicate the
work.

Or implement entire feedback given on that other patchset.

Best regards,
Krzysztof


From vkoul at kernel.org  Tue Aug 12 07:15:16 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Tue, 12 Aug 2025 19:45:16 +0530
Subject: [PATCH v5 2/6] phy: exynos5-usbdrd: support HS phy for
 ExynosAutov920
In-Reply-To: <20250805115216.3798121-3-pritam.sutar@samsung.com>
References: <20250805115216.3798121-1-pritam.sutar@samsung.com>
 <CGME20250805114310epcas5p459aa232884d22501f5fefe42f239fecc@epcas5p4.samsung.com>
 <20250805115216.3798121-3-pritam.sutar@samsung.com>
Message-ID: <aJtMdHcidETZyiIp@vaman>

On 05-08-25, 17:22, Pritam Manohar Sutar wrote:
> Enable UTMI+ phy support for this SoC which is very similar to what
> the existing Exynos850 supports.
> 
> Add required change in phy driver to support HS phy for this SoC.
> 
> Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
> ---
>  drivers/phy/samsung/phy-exynos5-usbdrd.c    | 123 ++++++++++++++++++++
>  include/linux/soc/samsung/exynos-regs-pmu.h |   2 +
>  2 files changed, 125 insertions(+)
> 
> diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
> index dd660ebe8045..5400dd23e500 100644
> --- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
> +++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
> @@ -2054,6 +2054,126 @@ static const struct exynos5_usbdrd_phy_drvdata exynos990_usbdrd_phy = {
>  	.n_regulators		= ARRAY_SIZE(exynos5_regulator_names),
>  };
>  
> +static int exynosautov920_usbdrd_phy_init(struct phy *phy)
> +{
> +	struct phy_usb_instance *inst = phy_get_drvdata(phy);
> +	struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
> +	int ret;
> +
> +	ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks);
> +	if (ret)
> +		return ret;
> +
> +	/* Bypass PHY isol */
> +	inst->phy_cfg->phy_isol(inst, false);
> +
> +	/* UTMI or PIPE3 specific init */
> +	inst->phy_cfg->phy_init(phy_drd);
> +
> +	clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks);
> +
> +	return 0;
> +}
> +
> +static int exynosautov920_usbdrd_phy_exit(struct phy *phy)
> +{
> +	struct phy_usb_instance *inst = phy_get_drvdata(phy);
> +	struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
> +	int ret = 0;

Superfluous init..

> +
> +	ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks);
> +	if (ret)
> +		return ret;
> +
> +	exynos850_usbdrd_phy_exit(phy);
> +
> +	/* enable PHY isol */
> +	inst->phy_cfg->phy_isol(inst, true);
> +
> +	clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks);
> +
> +	return 0;
> +}
> +
> +static int exynosautov920_usbdrd_phy_power_on(struct phy *phy)
> +{
> +	int ret;
> +	struct phy_usb_instance *inst = phy_get_drvdata(phy);
> +	struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);

Reverse chrsitmas tree pls

-- 
~Vinod


From vkoul at kernel.org  Tue Aug 12 07:18:00 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Tue, 12 Aug 2025 19:48:00 +0530
Subject: [PATCH v5 4/6] phy: exynos5-usbdrd: support HS combo phy for
 ExynosAutov920
In-Reply-To: <20250805115216.3798121-5-pritam.sutar@samsung.com>
References: <20250805115216.3798121-1-pritam.sutar@samsung.com>
 <CGME20250805114316epcas5p49b78db499c2e37a1fe68f4b2f0be62a7@epcas5p4.samsung.com>
 <20250805115216.3798121-5-pritam.sutar@samsung.com>
Message-ID: <aJtNGGjKy762BLcX@vaman>

On 05-08-25, 17:22, Pritam Manohar Sutar wrote:
> Support UTMI+ combo phy for this SoC which is somewhat simmilar to
> what the existing Exynos850 support does. The difference is that
> some register offsets and bit fields are defferent from Exynos850.
> 
> Add required change in phy driver to support combo HS phy for this SoC.
> 
> Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
> ---
>  drivers/phy/samsung/phy-exynos5-usbdrd.c | 210 +++++++++++++++++++++++
>  1 file changed, 210 insertions(+)
> 
> diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
> index 5400dd23e500..c22f4de7d094 100644
> --- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
> +++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
> @@ -41,6 +41,13 @@
>  #define EXYNOS2200_CLKRST_LINK_PCLK_SEL		BIT(1)
>  
>  #define EXYNOS2200_DRD_UTMI			0x10
> +
> +/* ExynosAutov920 bits */
> +#define UTMICTL_FORCE_UTMI_SUSPEND		BIT(13)
> +#define UTMICTL_FORCE_UTMI_SLEEP		BIT(12)
> +#define UTMICTL_FORCE_DPPULLDOWN		BIT(9)
> +#define UTMICTL_FORCE_DMPULLDOWN		BIT(8)
> +
>  #define EXYNOS2200_UTMI_FORCE_VBUSVALID		BIT(1)
>  #define EXYNOS2200_UTMI_FORCE_BVALID		BIT(0)
>  
> @@ -250,6 +257,22 @@
>  #define EXYNOS850_DRD_HSP_TEST			0x5c
>  #define HSP_TEST_SIDDQ				BIT(24)
>  
> +#define EXYNOSAUTOV920_DRD_HSP_CLKRST		0x100
> +#define HSPCLKRST_PHY20_SW_PORTRESET		BIT(3)
> +#define HSPCLKRST_PHY20_SW_POR			BIT(1)
> +#define HSPCLKRST_PHY20_SW_POR_SEL		BIT(0)
> +
> +#define EXYNOSAUTOV920_DRD_HSPCTL		0x104
> +#define HSPCTRL_VBUSVLDEXTSEL			BIT(13)
> +#define HSPCTRL_VBUSVLDEXT			BIT(12)
> +#define HSPCTRL_EN_UTMISUSPEND			BIT(9)
> +#define HSPCTRL_COMMONONN			BIT(8)
> +
> +#define EXYNOSAUTOV920_DRD_HSP_TEST		0x10c
> +
> +#define EXYNOSAUTOV920_DRD_HSPPLLTUNE		0x110
> +#define HSPPLLTUNE_FSEL				GENMASK(18, 16)
> +
>  /* Exynos9 - GS101 */
>  #define EXYNOS850_DRD_SECPMACTL			0x48
>  #define SECPMACTL_PMA_ROPLL_REF_CLK_SEL		GENMASK(13, 12)
> @@ -2054,6 +2077,139 @@ static const struct exynos5_usbdrd_phy_drvdata exynos990_usbdrd_phy = {
>  	.n_regulators		= ARRAY_SIZE(exynos5_regulator_names),
>  };
>  
> +static void
> +exynosautov920_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd)
> +{
> +	void __iomem *reg_phy = phy_drd->reg_phy;
> +	u32 reg;
> +
> +	/*
> +	 * Disable HWACG (hardware auto clock gating control). This
> +	 * forces QACTIVE signal in Q-Channel interface to HIGH level,
> +	 * to make sure the PHY clock is not gated by the hardware.
> +	 */
> +	reg = readl(reg_phy + EXYNOS850_DRD_LINKCTRL);
> +	reg |= LINKCTRL_FORCE_QACT;
> +	writel(reg, reg_phy + EXYNOS850_DRD_LINKCTRL);

maybe add a read-modify-write helper, this is user a lot here

> +
> +	/* De-assert link reset */
> +	reg = readl(reg_phy + EXYNOS2200_DRD_CLKRST);
> +	reg &= ~CLKRST_LINK_SW_RST;
> +	writel(reg, reg_phy + EXYNOS2200_DRD_CLKRST);
> +
> +	/* Set PHY POR High */
> +	reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSP_CLKRST);
> +	reg |= HSPCLKRST_PHY20_SW_POR | HSPCLKRST_PHY20_SW_POR_SEL;
> +	writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSP_CLKRST);
> +
> +	/* Enable UTMI+ */
> +	reg = readl(reg_phy + EXYNOS2200_DRD_UTMI);
> +	reg &= ~(UTMICTL_FORCE_UTMI_SUSPEND | UTMICTL_FORCE_UTMI_SLEEP |
> +		UTMICTL_FORCE_DPPULLDOWN | UTMICTL_FORCE_DMPULLDOWN);
> +	writel(reg, reg_phy + EXYNOS2200_DRD_UTMI);
> +
> +	/* set phy clock & control HS phy */
> +	reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSPCTL);
> +	reg |= HSPCTRL_EN_UTMISUSPEND | HSPCTRL_COMMONONN;
> +	writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSPCTL);
> +
> +	fsleep(100);
> +
> +	/* Set VBUS Valid and DP-Pull up control by VBUS pad usage */
> +	reg = readl(reg_phy + EXYNOS850_DRD_LINKCTRL);
> +	reg |= FIELD_PREP_CONST(LINKCTRL_BUS_FILTER_BYPASS, 0xf);
> +	writel(reg, reg_phy + EXYNOS850_DRD_LINKCTRL);
> +
> +	reg = readl(reg_phy + EXYNOS2200_DRD_UTMI);
> +	reg |= EXYNOS2200_UTMI_FORCE_VBUSVALID | EXYNOS2200_UTMI_FORCE_BVALID;
> +	writel(reg, reg_phy + EXYNOS2200_DRD_UTMI);
> +
> +	reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSPCTL);
> +	reg |= HSPCTRL_VBUSVLDEXTSEL | HSPCTRL_VBUSVLDEXT;
> +	writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSPCTL);
> +
> +	/* Setting FSEL for refference clock */
> +	reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSPPLLTUNE);
> +	reg &= ~HSPPLLTUNE_FSEL;

Empty line here please

> +	switch (phy_drd->extrefclk) {
> +	case EXYNOS5_FSEL_50MHZ:
> +		reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 7);
> +		break;
> +	case EXYNOS5_FSEL_26MHZ:
> +		reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 6);
> +		break;
> +	case EXYNOS5_FSEL_24MHZ:
> +		reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 2);
> +		break;
> +	case EXYNOS5_FSEL_20MHZ:
> +		reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 1);
> +		break;
> +	case EXYNOS5_FSEL_19MHZ2:
> +		reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 0);
> +		break;
> +	default:
> +		dev_warn(phy_drd->dev, "unsupported ref clk: %#.2x\n",
> +			 phy_drd->extrefclk);

but we still continue?
-- 
~Vinod


From vkoul at kernel.org  Tue Aug 12 07:21:34 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Tue, 12 Aug 2025 19:51:34 +0530
Subject: [PATCH v5 6/6] phy: exynos5-usbdrd: support SS combo phy for
 ExynosAutov920
In-Reply-To: <20250805115216.3798121-7-pritam.sutar@samsung.com>
References: <20250805115216.3798121-1-pritam.sutar@samsung.com>
 <CGME20250805114323epcas5p39bf73c5e0a9382ff54b1832724804cc9@epcas5p3.samsung.com>
 <20250805115216.3798121-7-pritam.sutar@samsung.com>
Message-ID: <aJtN7uVUV3YhfY5-@vaman>

On 05-08-25, 17:22, Pritam Manohar Sutar wrote:
> Add required change in phy driver to support combo SS phy for this SoC.
> 
> Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
> ---
>  drivers/phy/samsung/phy-exynos5-usbdrd.c    | 327 +++++++++++++++++++-
>  include/linux/soc/samsung/exynos-regs-pmu.h |   1 +
>  2 files changed, 324 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
> index c22f4de7d094..1108f0c07755 100644
> --- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
> +++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
> @@ -273,6 +273,36 @@
>  #define EXYNOSAUTOV920_DRD_HSPPLLTUNE		0x110
>  #define HSPPLLTUNE_FSEL				GENMASK(18, 16)
>  
> +/* ExynosAutov920 phy usb31drd port reg */
> +#define EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL	0x000
> +#define PHY_RST_CTRL_PIPE_LANE0_RESET_N_OVRD_EN	BIT(5)
> +#define PHY_RST_CTRL_PIPE_LANE0_RESET_N		BIT(4)
> +#define PHY_RST_CTRL_PHY_RESET_OVRD_EN		BIT(1)
> +#define PHY_RST_CTRL_PHY_RESET			BIT(0)
> +
> +#define EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0	0x0004
> +#define PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR		GENMASK(31, 16)
> +#define PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK		BIT(8)
> +#define PHY_CR_PARA_CON0_PHY0_CR_PARA_ACK		BIT(4)
> +#define PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL		BIT(0)
> +
> +#define EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON1	0x0008
> +
> +#define EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2	0x000c
> +#define PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_EN		BIT(0)
> +#define PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_DATA		GENMASK(31, 16)
> +
> +#define EXYNOSAUTOV920_USB31DRD_PHY_CONFIG0	0x100
> +#define PHY_CONFIG0_PHY0_PMA_PWR_STABLE		BIT(14)
> +#define PHY_CONFIG0_PHY0_PCS_PWR_STABLE		BIT(13)
> +#define PHY_CONFIG0_PHY0_ANA_PWR_EN		BIT(1)
> +
> +#define EXYNOSAUTOV920_USB31DRD_PHY_CONFIG7	0x11c
> +#define PHY_CONFIG7_PHY_TEST_POWERDOWN		BIT(24)
> +
> +#define EXYNOSAUTOV920_USB31DRD_PHY_CONFIG4	0x110
> +#define PHY_CONFIG4_PIPE_RX0_SRIS_MODE_EN	BIT(2)
> +
>  /* Exynos9 - GS101 */
>  #define EXYNOS850_DRD_SECPMACTL			0x48
>  #define SECPMACTL_PMA_ROPLL_REF_CLK_SEL		GENMASK(13, 12)
> @@ -2077,6 +2107,253 @@ static const struct exynos5_usbdrd_phy_drvdata exynos990_usbdrd_phy = {
>  	.n_regulators		= ARRAY_SIZE(exynos5_regulator_names),
>  };
>  
> +static void
> +exynosautov920_usb31drd_cr_clk(struct exynos5_usbdrd_phy *phy_drd, bool high)
> +{
> +	void __iomem *reg_phy = phy_drd->reg_phy;
> +	u32 reg = 0;

again..

> +
> +	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
> +	if (high)
> +		reg |= PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK;
> +	else
> +		reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK;
> +
> +	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
> +	fsleep(1);
> +}
> +
> +static void
> +exynosautov920_usb31drd_port_phy_ready(struct exynos5_usbdrd_phy *phy_drd)
> +{
> +	struct device *dev = phy_drd->dev;
> +	void __iomem *reg_phy = phy_drd->reg_phy;
> +	static const unsigned int timeout_us = 20000;
> +	static const unsigned int sleep_us = 40;
> +	u32 reg = 0;

here too

> +	int err;
> +
> +	/* Clear cr_para_con */
> +	reg &= ~(PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK |
> +			PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR);
> +	reg |= PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL;
> +	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
> +	writel(0x0, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON1);
> +	writel(0x0, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2);
> +
> +	exynosautov920_usb31drd_cr_clk(phy_drd, true);
> +	exynosautov920_usb31drd_cr_clk(phy_drd, false);
> +
> +	/*
> +	 * The maximum time from phy reset de-assertion to de-assertion of
> +	 * tx/rx_ack can be as high as 5ms in fast simulation mode.
> +	 * Time to phy ready is < 20ms
> +	 */
> +	err = readl_poll_timeout(reg_phy +
> +				EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0,
> +			reg, !(reg & PHY_CR_PARA_CON0_PHY0_CR_PARA_ACK),
> +			sleep_us, timeout_us);
> +	if (err)
> +		dev_err(dev, "timed out waiting for rx/tx_ack: %#.8x\n", reg);
> +
> +	reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK;
> +	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
> +}
> +
> +static void
> +exynosautov920_usb31drd_cr_write(struct exynos5_usbdrd_phy *phy_drd,
> +				 u16 addr, u16 data)
> +{
> +	struct device *dev = phy_drd->dev;
> +	void __iomem *reg_phy = phy_drd->reg_phy;
> +	u32 cnt = 0;
> +	u32 reg = 0;

this one, former is okay

> +
> +	/* Pre Clocking */
> +	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
> +	reg |= PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL;
> +	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
> +
> +	/*
> +	 * tx clks must be available prior to assertion of tx req.
> +	 * tx pstate p2 to p0 transition directly is not permitted.
> +	 * tx clk ready must be asserted synchronously on tx clk prior
> +	 * to internal transmit clk alignment sequence in the phy
> +	 * when entering from p2 to p1 to p0.
> +	 */
> +	do {
> +		exynosautov920_usb31drd_cr_clk(phy_drd, true);
> +		exynosautov920_usb31drd_cr_clk(phy_drd, false);
> +		cnt++;
> +	} while (cnt < 15);
> +
> +	reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL;
> +	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
> +
> +	/*
> +	 * tx data path is active when tx lane is in p0 state
> +	 * and tx data en asserted. enable cr_para_wr_en.
> +	 */
> +	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2);
> +	reg &= ~PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_DATA;
> +	reg |= FIELD_PREP(PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_DATA, data) |
> +		PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_EN;
> +	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2);
> +
> +	/* write addr */
> +	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
> +	reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR;
> +	reg |= FIELD_PREP(PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR, addr) |
> +		PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK |
> +		PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL;
> +	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
> +
> +	/* check cr_para_ack*/
> +	cnt = 0;
> +	do {
> +		/*
> +		 * data symbols are captured by phy on rising edge of the
> +		 * tx_clk when tx data enabled.
> +		 * completion of the write cycle is acknowledged by assertion
> +		 * of the cr_para_ack.
> +		 */
> +		exynosautov920_usb31drd_cr_clk(phy_drd, true);
> +		reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
> +		if ((reg & PHY_CR_PARA_CON0_PHY0_CR_PARA_ACK))
> +			break;
> +
> +		exynosautov920_usb31drd_cr_clk(phy_drd, false);
> +
> +		/*
> +		 * wait for minimum of 10 cr_para_clk cycles after phy reset
> +		 * is negated, before accessing control regs to allow for
> +		 * internal resets.
> +		 */
> +		cnt++;
> +	} while (cnt < 10);
> +
> +	if (cnt == 10)
> +		dev_dbg(dev, "CR write failed to 0x%04x\n", addr);

Not error?
-- 
~Vinod


From bryan.odonoghue at linaro.org  Tue Aug 12 08:05:38 2025
From: bryan.odonoghue at linaro.org (Bryan O'Donoghue)
Date: Tue, 12 Aug 2025 16:05:38 +0100
Subject: [PATCH 2/2] phy: qcom-mipi-csi2: Add a CSI2 MIPI D-PHY driver
In-Reply-To: <d7949778-73c4-4575-8db3-a3724f75eb38@linaro.org>
References: <20250710-x1e-csi2-phy-v1-0-74acbb5b162b@linaro.org>
 <20250710-x1e-csi2-phy-v1-2-74acbb5b162b@linaro.org>
 <d7949778-73c4-4575-8db3-a3724f75eb38@linaro.org>
Message-ID: <16e4883a-a056-46c3-a7c7-a87ff5da89a1@linaro.org>

On 12/08/2025 14:39, neil.armstrong at linaro.org wrote:
>> +??? .clk_freq = {
>> +??????? zero,
> 
> It seems clang doesn't like this at all:
> drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c:486:3: error: 
> initializer element is not a compile-time constant
>  ??????????????? zero,
>  ??????????????? ^~~~
> 1 error generated.

Weirdly I compile with clang..

thx though

---
bod


From vkoul at kernel.org  Tue Aug 12 08:49:59 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Tue, 12 Aug 2025 21:19:59 +0530
Subject: [PATCH 05/11] phy: rockchip: inno-usb2: Add support for RK3528
In-Reply-To: <20250723122323.2344916-6-jonas@kwiboo.se>
References: <20250723122323.2344916-1-jonas@kwiboo.se>
 <20250723122323.2344916-6-jonas@kwiboo.se>
Message-ID: <aJtip49r8R3-2XXi@vaman>

On 23-07-25, 12:23, Jonas Karlman wrote:
> From: Jianwei Zheng <jianwei.zheng at rock-chips.com>

Please do not send encrypted emails over public mail lists

> 
> The RK3528 has a single USB2PHY with a otg and host port.
> 
> Add support for the RK3528 variant of USB2PHY.
> 
> PHY tuning for RK3528:
> 
> - Turn off differential receiver in suspend mode to save power
>   consumption.
> 
> - Set HS eye-height to 400mV instead of default 450mV.
> 
> - Choose the Tx fs/ls data as linestate from TX driver for otg port
>   which uses dwc3 controller to improve fs/ls devices compatibility with
>   long cables.
> 
> This is based on vendor kernel linux-stan-6.1-rkr5 tag.
> 
> Signed-off-by: Jianwei Zheng <jianwei.zheng at rock-chips.com>
> Signed-off-by: Jonas Karlman <jonas at kwiboo.se>
> ---
>  drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 74 +++++++++++++++++++
>  1 file changed, 74 insertions(+)
> 
> diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> index cd1a02b990ef..b8950d9f9e97 100644
> --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> @@ -1507,6 +1507,28 @@ static int rk3128_usb2phy_tuning(struct rockchip_usb2phy *rphy)
>  				BIT(2) << BIT_WRITEABLE_SHIFT | 0);
>  }
>  
> +static int rk3528_usb2phy_tuning(struct rockchip_usb2phy *rphy)
> +{
> +	int ret = 0;

Superfluous init

> +
> +	/* Turn off otg port differential receiver in suspend mode */
> +	ret |= regmap_write(rphy->phy_base, 0x30, BIT(18) | 0x0000);
> +
> +	/* Turn off host port differential receiver in suspend mode */
> +	ret |= regmap_write(rphy->phy_base, 0x430, BIT(18) | 0x0000);
> +
> +	/* Set otg port HS eye height to 400mv (default is 450mv) */
> +	ret |= regmap_write(rphy->phy_base, 0x30, GENMASK(22, 20) | 0x0000);
> +
> +	/* Set host port HS eye height to 400mv (default is 450mv) */
> +	ret |= regmap_write(rphy->phy_base, 0x430, GENMASK(22, 20) | 0x0000);
> +
> +	/* Choose the Tx fs/ls data as linestate from TX driver for otg port */
> +	ret |= regmap_write(rphy->phy_base, 0x94, GENMASK(22, 19) | 0x0018);

No error checking?

-- 
~Vinod


From neil.armstrong at linaro.org  Tue Aug 12 09:08:41 2025
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Tue, 12 Aug 2025 18:08:41 +0200
Subject: [PATCH 2/2] phy: qcom-mipi-csi2: Add a CSI2 MIPI D-PHY driver
In-Reply-To: <16e4883a-a056-46c3-a7c7-a87ff5da89a1@linaro.org>
References: <20250710-x1e-csi2-phy-v1-0-74acbb5b162b@linaro.org>
 <20250710-x1e-csi2-phy-v1-2-74acbb5b162b@linaro.org>
 <d7949778-73c4-4575-8db3-a3724f75eb38@linaro.org>
 <16e4883a-a056-46c3-a7c7-a87ff5da89a1@linaro.org>
Message-ID: <8b8207bf-e841-4033-8356-dffa2c2e2d25@linaro.org>

On 12/08/2025 17:05, Bryan O'Donoghue wrote:
> On 12/08/2025 14:39, neil.armstrong at linaro.org wrote:
>>> +??? .clk_freq = {
>>> +??????? zero,
>>
>> It seems clang doesn't like this at all:
>> drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c:486:3: error: initializer element is not a compile-time constant
>> ???????????????? zero,
>> ???????????????? ^~~~
>> 1 error generated.
> 
> Weirdly I compile with clang..

The tuxmake log is available at https://storage.tuxsuite.com/public/linaro/neil.armstrong/builds/31Boss31K6meeYAxqhJUZo8yhwK/build.log

It uses clang-16

Neil

> 
> thx though
> 
> ---
> bod



From stephan.gerhold at linaro.org  Tue Aug 12 09:30:19 2025
From: stephan.gerhold at linaro.org (Stephan Gerhold)
Date: Tue, 12 Aug 2025 18:30:19 +0200
Subject: [PATCH] phy: qcom: qmp-pcie: Fix PHY initialization when powered
 down by firmware
Message-ID: <20250812-phy-qcom-qmp-pcie-nocsr-fix-v1-1-9a7d0a5d2b46@linaro.org>

Commit 0cc22f5a861c ("phy: qcom: qmp-pcie: Add PHY register retention
support") added support for using the "no_csr" reset to skip configuration
of the PHY if the init sequence was already applied by the boot firmware.
The expectation is that the PHY is only turned on/off by using the "no_csr"
reset, instead of powering it down and re-programming it after a full
reset.

The boot firmware on X1E does not fully conform to this expectation: If the
PCIe3 link fails to come up (e.g. because no PCIe card is inserted), the
firmware powers down the PHY using the QPHY_PCS_POWER_DOWN_CONTROL
register. The QPHY_START_CTRL register is kept as-is, so the driver assumes
the PHY is already initialized and skips the configuration/power up
sequence. The PHY won't come up again without clearing the
QPHY_PCS_POWER_DOWN_CONTROL, so eventually initialization fails:

  qcom-qmp-pcie-phy 1be0000.phy: phy initialization timed-out
  phy phy-1be0000.phy.0: phy poweron failed --> -110
  qcom-pcie 1bd0000.pcie: cannot initialize host
  qcom-pcie 1bd0000.pcie: probe with driver qcom-pcie failed with error -110

This can be reliably reproduced on the X1E CRD, QCP and Devkit when no card
is inserted for PCIe3.

Fix this by checking the QPHY_PCS_POWER_DOWN_CONTROL register in addition
to QPHY_START_CTRL. If the PHY is powered down with the register, it
doesn't conform to the expectations for using the "no_csr" reset, so we
fully re-initialize with the normal reset sequence.

Cc: stable at vger.kernel.org
Fixes: 0cc22f5a861c ("phy: qcom: qmp-pcie: Add PHY register retention support")
Signed-off-by: Stephan Gerhold <stephan.gerhold at linaro.org>
---
 drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index 95830dcfdec9b1f68fd55d1cc3c102985cfafcc1..6a469a8f5ae7eba6e4d1d702efaae1c658c4321e 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -4339,10 +4339,12 @@ static int qmp_pcie_init(struct phy *phy)
 	struct qmp_pcie *qmp = phy_get_drvdata(phy);
 	const struct qmp_phy_cfg *cfg = qmp->cfg;
 	void __iomem *pcs = qmp->pcs;
-	bool phy_initialized = !!(readl(pcs + cfg->regs[QPHY_START_CTRL]));
 	int ret;
 
-	qmp->skip_init = qmp->nocsr_reset && phy_initialized;
+	qmp->skip_init = qmp->nocsr_reset &&
+		readl(pcs + cfg->regs[QPHY_START_CTRL]) &&
+		readl(pcs + cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL]);
+
 	/*
 	 * We need to check the existence of init sequences in two cases:
 	 * 1. The PHY doesn't support no_csr reset.

---
base-commit: 8f5ae30d69d7543eee0d70083daf4de8fe15d585
change-id: 20250812-phy-qcom-qmp-pcie-nocsr-fix-1603106294cd

Best regards,
-- 
Stephan Gerhold <stephan.gerhold at linaro.org>



From vkoul at kernel.org  Tue Aug 12 09:40:16 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Tue, 12 Aug 2025 22:10:16 +0530
Subject: [PATCH] phy: qualcomm: phy-qcom-eusb2-repeater: fix override
 properties
In-Reply-To: <20250812093957.32235-1-mitltlatltl@gmail.com>
References: <20250812093957.32235-1-mitltlatltl@gmail.com>
Message-ID: <175501681673.633066.704631034138052201.b4-ty@kernel.org>


On Tue, 12 Aug 2025 17:39:56 +0800, Pengyu Luo wrote:
> property "qcom,tune-usb2-preem" is for EUSB2_TUNE_USB2_PREEM
> property "qcom,tune-usb2-amplitude" is for EUSB2_TUNE_IUSB2
> 
> The downstream correspondence is as follows:
> EUSB2_TUNE_USB2_PREEM: Tx pre-emphasis tuning
> EUSB2_TUNE_IUSB2: HS trasmit amplitude
> EUSB2_TUNE_SQUELCH_U: Squelch detection threshold
> EUSB2_TUNE_HSDISC: HS disconnect threshold
> EUSB2_TUNE_EUSB_SLEW: slew rate
> 
> [...]

Applied, thanks!

[1/1] phy: qualcomm: phy-qcom-eusb2-repeater: fix override properties
      commit: 942e47ab228c7dd27c2ae043c17e7aab2028082c

Best regards,
-- 
~Vinod




From vkoul at kernel.org  Tue Aug 12 09:40:20 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Tue, 12 Aug 2025 22:10:20 +0530
Subject: [PATCH] dt-bindings: phy: marvell,comphy-cp110: Fix clock and
 child node constraints
In-Reply-To: <20250806200138.1366189-1-robh@kernel.org>
References: <20250806200138.1366189-1-robh@kernel.org>
Message-ID: <175501682042.633066.13384009290495512266.b4-ty@kernel.org>


On Wed, 06 Aug 2025 15:01:37 -0500, Rob Herring (Arm) wrote:
> In converting marvell,comphy-cp110 to schema, the constraints for clocks on
> marvell,comphy-a3700 are wrong, the maximum number of child nodes are wrong,
> and the phy nodes may have a 'connector' child node:
> 
> phy at 18300 (marvell,comphy-a3700): clock-names: False schema does not allow ['xtal']
> phy at 120000 (marvell,comphy-cp110): 'phy at 3', 'phy at 4', 'phy at 5' do not match any of the regexes: '^phy@[0-2]$', '^pinctrl-[0-9]+$'
> phy at 120000 (marvell,comphy-cp110): phy at 2: 'connector' does not match any of the regexes: '^pinctrl-[0-9]+$'
> 
> [...]

Applied, thanks!

[1/1] dt-bindings: phy: marvell,comphy-cp110: Fix clock and child node constraints
      commit: 5cfdfc623835d40664f642b75a56d9934f24c5ff

Best regards,
-- 
~Vinod




From vkoul at kernel.org  Tue Aug 12 09:40:23 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Tue, 12 Aug 2025 22:10:23 +0530
Subject: [PATCH 0/3] phy: fix device leaks at unbind
In-Reply-To: <20250724131206.2211-1-johan@kernel.org>
References: <20250724131206.2211-1-johan@kernel.org>
Message-ID: <175501682357.633066.13503601845975199477.b4-ty@kernel.org>


On Thu, 24 Jul 2025 15:12:03 +0200, Johan Hovold wrote:
> This series fixes device leaks due to failure to drop the reference
> taken by of_find_device_by_node().
> 
> Johan
> 
> Johan Hovold (3):
>   phy: tegra: xusb: fix device and OF node leak at probe
>   phy: ti: omap-usb2: fix device leak at unbind
>   phy: ti-pipe3: fix device leak at unbind
> 
> [...]

Applied, thanks!

[1/3] phy: tegra: xusb: fix device and OF node leak at probe
      commit: bca065733afd1e3a89a02f05ffe14e966cd5f78e
[2/3] phy: ti: omap-usb2: fix device leak at unbind
      commit: 64961557efa1b98f375c0579779e7eeda1a02c42
[3/3] phy: ti-pipe3: fix device leak at unbind
      commit: e19bcea99749ce8e8f1d359f68ae03210694ad56

Best regards,
-- 
~Vinod




From vkoul at kernel.org  Tue Aug 12 09:40:26 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Tue, 12 Aug 2025 22:10:26 +0530
Subject: (subset) [PATCH v7 0/3] pci: qcom: drop unrelated clock and
 add link_down reset for sa8775p
In-Reply-To: <20250725102231.3608298-1-ziyue.zhang@oss.qualcomm.com>
References: <20250725102231.3608298-1-ziyue.zhang@oss.qualcomm.com>
Message-ID: <175501682675.633066.14367700051268770361.b4-ty@kernel.org>


On Fri, 25 Jul 2025 18:22:28 +0800, Ziyue Zhang wrote:
> This series drop gcc_aux_clock in pcie phy, the pcie aux clock should
> be gcc_phy_aux_clock. And sa8775p platform support link_down reset in
> hardware, so add it for both pcie0 and pcie1 to provide a better user
> experience.
> 
> Have follwing changes:
>   - Update pcie phy bindings for sa8775p.
>   - Document link_down reset.
>   - Remove aux clock from pcie phy.
>   - Add link_down reset for pcie.
> 
> [...]

Applied, thanks!

[1/3] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Update pcie phy bindings
      commit: aac1256a41cfbbaca12d6c0a5753d1e3b8d2d8bf

Best regards,
-- 
~Vinod




From vkoul at kernel.org  Tue Aug 12 09:41:25 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Tue, 12 Aug 2025 22:11:25 +0530
Subject: (subset) [PATCH RESEND 0/2] dt-bindings: Drop 'db' suffix
 duplicating dtschema
In-Reply-To: <20250811-dt-bindings-db-v1-0-457301523bb5@linaro.org>
References: <20250811-dt-bindings-db-v1-0-457301523bb5@linaro.org>
Message-ID: <175501688581.633310.2083661450340253592.b4-ty@kernel.org>


On Mon, 11 Aug 2025 15:54:02 +0200, Krzysztof Kozlowski wrote:
> Resending because all dependencies are merged.
> 
> Please take individual patches via respective subsystems (phy, leds).
> 
> Previously:
> - Link to v1: https://lore.kernel.org/r/20250627-dt-bindings-db-v1-0-d5c7072acbee at linaro.org
> 
> [...]

Applied, thanks!

[2/2] dt-bindings: phy: fsl,imx8mq-usb: Drop 'db' suffix duplicating dtschema
      commit: 78a474b5a31a25e0a77e50df42be925f7cb575e6

Best regards,
-- 
~Vinod




From vkoul at kernel.org  Tue Aug 12 09:41:35 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Tue, 12 Aug 2025 22:11:35 +0530
Subject: [PATCH] phy: cadence: cdns-dphy-rx: Add runtime PM support
In-Reply-To: <20250224-cdns_phy_pm-v1-1-0fe2c544cc87@ideasonboard.com>
References: <20250224-cdns_phy_pm-v1-1-0fe2c544cc87@ideasonboard.com>
Message-ID: <175501689535.633310.5617884055739697680.b4-ty@kernel.org>


On Mon, 24 Feb 2025 18:10:05 +0530, Jai Luthra wrote:
> Enable runtime power management for the device. The PHY framework
> handles calling pm_runtime_(get|put)_sync when powering on/off this
> device.
> 
> 

Applied, thanks!

[1/1] phy: cadence: cdns-dphy-rx: Add runtime PM support
      commit: a230d52c90cfb48f1f32d3957dc962165373895b

Best regards,
-- 
~Vinod




From vkoul at kernel.org  Tue Aug 12 09:41:37 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Tue, 12 Aug 2025 22:11:37 +0530
Subject: [PATCH] phy: ti: omap-usb2: enable compile testing
In-Reply-To: <20250724131623.2662-1-johan@kernel.org>
References: <20250724131623.2662-1-johan@kernel.org>
Message-ID: <175501689789.633310.16803003001477331009.b4-ty@kernel.org>


On Thu, 24 Jul 2025 15:16:23 +0200, Johan Hovold wrote:
> Nothing seems to prevent the driver from being built on non-TI platforms
> so enable compile testing for wider build coverage.
> 
> 

Applied, thanks!

[1/1] phy: ti: omap-usb2: enable compile testing
      commit: 8343cfb636261f36796fde0e79a858422eeb0207

Best regards,
-- 
~Vinod




From vkoul at kernel.org  Tue Aug 12 09:41:31 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Tue, 12 Aug 2025 22:11:31 +0530
Subject: [PATCH 0/2] phy: cdns-dphy: hs-clk improvement and a cleanup
In-Reply-To: <20250723-cdns-dphy-hs-clk-rate-fix-v1-0-d4539d44cbe7@ideasonboard.com>
References: <20250723-cdns-dphy-hs-clk-rate-fix-v1-0-d4539d44cbe7@ideasonboard.com>
Message-ID: <175501689198.633310.10908708738197218310.b4-ty@kernel.org>


On Wed, 23 Jul 2025 13:01:27 +0300, Tomi Valkeinen wrote:
> A cdns-dphy improvement to return the actual hs clock rate, and a
> cleanup to remove leftover code.
> 
> These were part of a Cadence DSI series:
> 
> https://lore.kernel.org/all/20250618-cdns-dsi-impro-v4-0-862c841dbe02%40ideasonboard.com/
> 
> [...]

Applied, thanks!

[1/2] phy: cdns-dphy: Store hs_clk_rate and return it
      commit: 7ac3644d1e82ae6c7ad3767a3f2594faffd12264
[2/2] phy: cdns-dphy: Remove leftover code
      commit: b659c5cc993767a42ad1a712dd357522099c5c37

Best regards,
-- 
~Vinod




From vkoul at kernel.org  Tue Aug 12 09:41:39 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Tue, 12 Aug 2025 22:11:39 +0530
Subject: (subset) [PATCH v5 0/6] Support RK3528 variant of Rockchip
 naneng-combphy
In-Reply-To: <20250728102947.38984-2-ziyao@disroot.org>
References: <20250728102947.38984-2-ziyao@disroot.org>
Message-ID: <175501689991.633310.3061565953624951232.b4-ty@kernel.org>


On Mon, 28 Jul 2025 10:29:42 +0000, Yao Zi wrote:
> Rockchip RK3528 ships a naneng-combphy that operates in either PCIe or
> USB 3.0 mode. It has a similar control logic to previous generations of
> naneng-combphy but an apparently different register layout.
> 
> This series prepares phy-rockchip-naneng-combphy.c for variants with a
> different register layout and add RK3528 support.
> 
> [...]

Applied, thanks!

[1/6] dt-bindings: soc: rockchip: Add RK3528 pipe-phy GRF syscon
      commit: d7122636eca216ea2876baae45483d17e40a55f6
[2/6] dt-bindings: phy: rockchip: naneng-combphy: Add power-domains property
      commit: 19bb2bfdfa5dc4a912e7e5e3432290204e998ac9
[3/6] dt-bindings: phy: rockchip: naneng-combphy: Add RK3528 variant
      commit: d9e0fd60d8d44b2cabd41f5e370e9d41edffe6e9
[4/6] phy: rockchip: naneng-combphy: Add SoC prefix to register definitions
      commit: 11f1896e60f61ca1948cb7920585a79ce5254c0c
[5/6] phy: rockchip: naneng-combphy: Add RK3528 support
      commit: aee07ee1b97d9a3825e8db609a1c76157218cc59

Best regards,
-- 
~Vinod




From vkoul at kernel.org  Tue Aug 12 09:41:45 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Tue, 12 Aug 2025 22:11:45 +0530
Subject: [PATCH 00/11] phy: drop unused module aliases
In-Reply-To: <20250724154823.15998-1-johan@kernel.org>
References: <20250724154823.15998-1-johan@kernel.org>
Message-ID: <175501690578.633310.16974700832772559803.b4-ty@kernel.org>


On Thu, 24 Jul 2025 17:48:12 +0200, Johan Hovold wrote:
> When fixing up some device leaks in the TI drivers I noticed that the
> commits introducing the leaks had also converted the drivers to only
> support OF probe.
> 
> This series drops the unused platform module alias from the PHY drivers
> that never have supported or no longer supports anything but OF probing.
> 
> [...]

Applied, thanks!

[01/11] phy: broadcom: brcm-sata: drop unused module alias
        commit: b4e1e9108c948896661ecf5c61a29f6086e53f38
[02/11] phy: broadcom: brcm-usb: drop unused module alias
        commit: 33e64f6e38b2dccbaba8c3533cd0c45e1245c205
[03/11] phy: cadence: Sierra: drop unused module alias
        commit: d81e02d02b5f0c0f53e6cfb8982489fdacd546b6
[04/11] phy: hisilicon: hi6220-usb: drop unused module alias
        commit: b4d4af09092b50b940b37892445f0ae5a007e888
[05/11] phy: qualcomm: ipq806x-usb: drop unused module alias
        commit: 8cbb931b8ac285cd1ec46f8764a91a627704ccab
[06/11] phy: samsung: exynos5-usbdrd: drop unused module alias
        commit: a4c3d8015f4298d90d4d145101dd04de8854e6f9
[07/11] phy: samsung: usb2: drop unused module alias
        commit: 7ee2e0347cc781f0f87777558218961c51ec6aba
[08/11] phy: ti: omap-usb2: drop unused module alias
        commit: 36d20c023bfe98eb999ec5ba4f051460f6080564
[09/11] phy: ti: ti-pipe3: drop unused module alias
        commit: e709cc0741e8f155a39174d97eb9ae9c0cba2623
[10/11] phy: ti: dm816x-usb: drop unused module alias
        commit: 00837ae34f6321f9b6c290f92eb369e7f9259d41
[11/11] phy: ti: omap-control: drop unused module alias
        commit: e04f91e1d881120ff97389960cf7c765d510213e

Best regards,
-- 
~Vinod




From vkoul at kernel.org  Tue Aug 12 09:41:53 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Tue, 12 Aug 2025 22:11:53 +0530
Subject: [PATCH] phy: rockchip: naneng-combphy: Enable U3 OTG port for
 RK3568
In-Reply-To: <20250723072324.2246498-1-jonas@kwiboo.se>
References: <20250723072324.2246498-1-jonas@kwiboo.se>
Message-ID: <175501691338.633310.6315313120573301384.b4-ty@kernel.org>


On Wed, 23 Jul 2025 07:23:22 +0000, Jonas Karlman wrote:
> The boot firmware may disable the U3 port early during boot and leave it
> up to the controller or PHY driver to re-enable U3 when needed.
> 
> The Rockchip USBDP PHY driver currently does this for RK3576 and RK3588,
> something the Rockchip Naneng Combo PHY driver never does for RK3568.
> This may result in USB 3.0 ports being limited to only using USB 2.0 or
> in special cases not working at all on RK3568.
> 
> [...]

Applied, thanks!

[1/1] phy: rockchip: naneng-combphy: Enable U3 OTG port for RK3568
      commit: 4e346666edcc0506d8f0e581de4280b85b0d3e98

Best regards,
-- 
~Vinod




From vkoul at kernel.org  Tue Aug 12 09:41:48 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Tue, 12 Aug 2025 22:11:48 +0530
Subject: [PATCH v2 0/4] Add support for eUSB2 repeater on PMIV0104
In-Reply-To: <20250709-sm7635-eusb-repeater-v2-0-b6eff075c097@fairphone.com>
References: <20250709-sm7635-eusb-repeater-v2-0-b6eff075c097@fairphone.com>
Message-ID: <175501690862.633310.534963018208999296.b4-ty@kernel.org>


On Wed, 09 Jul 2025 16:55:13 +0200, Luca Weiss wrote:
> Add a new property qcom,tune-res-fsdif for the eUSB2 repeater and add
> the compatible for the repeater on the PMIV0104 PMIC.
> 
> 

Applied, thanks!

[1/4] dt-bindings: phy: qcom,snps-eusb2-repeater: Document qcom,tune-res-fsdif
      commit: 47e9b6f601932899280f725b0fdbc4d4f85e2719
[2/4] phy: qualcomm: phy-qcom-eusb2-repeater: Support tune-res-fsdif prop
      commit: 8e086fe190b63ef1d0d31b300bfefb5d00217427
[3/4] dt-bindings: phy: qcom,snps-eusb2-repeater: Add compatible for PMIV0104
      commit: eb86c2ce4a89157da71d3a7953eac4dcde7d5527
[4/4] phy: qualcomm: phy-qcom-eusb2-repeater: Add support for PMIV0104
      commit: 8427a4ca85b36247cb2c055ec7507a78a19246ad

Best regards,
-- 
~Vinod




From andersson at kernel.org  Tue Aug 12 14:13:47 2025
From: andersson at kernel.org (Bjorn Andersson)
Date: Tue, 12 Aug 2025 16:13:47 -0500
Subject: (subset) [PATCH v5 0/2] Update PCIe PHY settings for QCS8300 and SA8775P
In-Reply-To: <20250617-update_phy-v5-0-2df83ed6a373@quicinc.com>
References: <20250617-update_phy-v5-0-2df83ed6a373@quicinc.com>
Message-ID: <175503322856.231048.14752083569105388831.b4-ty@kernel.org>


On Tue, 17 Jun 2025 17:08:18 +0530, Mrinmay Sarkar wrote:
> This Series is to update PCIe PHY settings as per latest
> hardware programming guide and remove max link speed dt
> property for SA8775P PCIe EP.
> 
> 

Applied, thanks!

[2/2] arm64: dts: qcom: sa8775p: Remove max link speed property for PCIe EP
      commit: d6111177f6504b013d0424657e131ae9a36ab5e2

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


From ziyue.zhang at oss.qualcomm.com  Tue Aug 12 18:31:36 2025
From: ziyue.zhang at oss.qualcomm.com (Ziyue Zhang)
Date: Wed, 13 Aug 2025 09:31:36 +0800
Subject: [PATCH v10 1/5] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy:
 Update pcie phy bindings for qcs8300
In-Reply-To: <aJsYd7tAi4CdOfZ9@vaman>
References: <20250811071131.982983-1-ziyue.zhang@oss.qualcomm.com>
 <20250811071131.982983-2-ziyue.zhang@oss.qualcomm.com>
 <aJsYd7tAi4CdOfZ9@vaman>
Message-ID: <cef1da96-f584-4100-a97d-640fa24e5f54@oss.qualcomm.com>


On 8/12/2025 6:33 PM, Vinod Koul wrote:
> On 11-08-25, 15:11, Ziyue Zhang wrote:
>> The gcc_aux_clk is not required by the PCIe PHY on qcs8300 and is not
>> specified in the device tree node. Hence, move the qcs8300 phy
>> compatibility entry into the list of PHYs that require six clocks.
>>
>> Removed the phy_aux clock from the PCIe PHY binding as it is no longer
>> used by any instance.
> This does not apply on phy tree, please rebase

Hi Vinod

This patch based on the patch you applied in 8.12.

dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Update pcie phy bindings
commit: aac1256a41cfbbaca12d6c0a5753d1e3b8d2d8bf

Can you try to apply it again ? Thanks

BRs
Ziyue



From konrad.dybcio at oss.qualcomm.com  Wed Aug 13 03:13:31 2025
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Wed, 13 Aug 2025 12:13:31 +0200
Subject: [PATCH] phy: qcom: qmp-pcie: Fix PHY initialization when powered
 down by firmware
In-Reply-To: <20250812-phy-qcom-qmp-pcie-nocsr-fix-v1-1-9a7d0a5d2b46@linaro.org>
References: <20250812-phy-qcom-qmp-pcie-nocsr-fix-v1-1-9a7d0a5d2b46@linaro.org>
Message-ID: <f44beed6-72c3-4e86-834b-ac522c786bc7@oss.qualcomm.com>

On 8/12/25 6:30 PM, Stephan Gerhold wrote:
> Commit 0cc22f5a861c ("phy: qcom: qmp-pcie: Add PHY register retention
> support") added support for using the "no_csr" reset to skip configuration
> of the PHY if the init sequence was already applied by the boot firmware.
> The expectation is that the PHY is only turned on/off by using the "no_csr"
> reset, instead of powering it down and re-programming it after a full
> reset.
> 
> The boot firmware on X1E does not fully conform to this expectation: If the
> PCIe3 link fails to come up (e.g. because no PCIe card is inserted), the
> firmware powers down the PHY using the QPHY_PCS_POWER_DOWN_CONTROL
> register. The QPHY_START_CTRL register is kept as-is, so the driver assumes
> the PHY is already initialized and skips the configuration/power up
> sequence. The PHY won't come up again without clearing the
> QPHY_PCS_POWER_DOWN_CONTROL, so eventually initialization fails:
> 
>   qcom-qmp-pcie-phy 1be0000.phy: phy initialization timed-out
>   phy phy-1be0000.phy.0: phy poweron failed --> -110
>   qcom-pcie 1bd0000.pcie: cannot initialize host
>   qcom-pcie 1bd0000.pcie: probe with driver qcom-pcie failed with error -110
> 
> This can be reliably reproduced on the X1E CRD, QCP and Devkit when no card
> is inserted for PCIe3.
> 
> Fix this by checking the QPHY_PCS_POWER_DOWN_CONTROL register in addition
> to QPHY_START_CTRL. If the PHY is powered down with the register, it
> doesn't conform to the expectations for using the "no_csr" reset, so we
> fully re-initialize with the normal reset sequence.
> 
> Cc: stable at vger.kernel.org
> Fixes: 0cc22f5a861c ("phy: qcom: qmp-pcie: Add PHY register retention support")
> Signed-off-by: Stephan Gerhold <stephan.gerhold at linaro.org>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
> index 95830dcfdec9b1f68fd55d1cc3c102985cfafcc1..6a469a8f5ae7eba6e4d1d702efaae1c658c4321e 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
> @@ -4339,10 +4339,12 @@ static int qmp_pcie_init(struct phy *phy)
>  	struct qmp_pcie *qmp = phy_get_drvdata(phy);
>  	const struct qmp_phy_cfg *cfg = qmp->cfg;
>  	void __iomem *pcs = qmp->pcs;
> -	bool phy_initialized = !!(readl(pcs + cfg->regs[QPHY_START_CTRL]));
>  	int ret;
>  
> -	qmp->skip_init = qmp->nocsr_reset && phy_initialized;
> +	qmp->skip_init = qmp->nocsr_reset &&
> +		readl(pcs + cfg->regs[QPHY_START_CTRL]) &&
> +		readl(pcs + cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL]);

I think it would be good to ensure the value matches platform config
expectations, i.e. !(val & cfg->pwrdn_ctrl)

Konrad


From stephan.gerhold at linaro.org  Wed Aug 13 05:04:00 2025
From: stephan.gerhold at linaro.org (Stephan Gerhold)
Date: Wed, 13 Aug 2025 14:04:00 +0200
Subject: [PATCH] phy: qcom: qmp-pcie: Fix PHY initialization when powered
 down by firmware
In-Reply-To: <f44beed6-72c3-4e86-834b-ac522c786bc7@oss.qualcomm.com>
References: <20250812-phy-qcom-qmp-pcie-nocsr-fix-v1-1-9a7d0a5d2b46@linaro.org>
 <f44beed6-72c3-4e86-834b-ac522c786bc7@oss.qualcomm.com>
Message-ID: <aJx_KjWFxeYE5U81@linaro.org>

On Wed, Aug 13, 2025 at 12:13:31PM +0200, Konrad Dybcio wrote:
> On 8/12/25 6:30 PM, Stephan Gerhold wrote:
> > Commit 0cc22f5a861c ("phy: qcom: qmp-pcie: Add PHY register retention
> > support") added support for using the "no_csr" reset to skip configuration
> > of the PHY if the init sequence was already applied by the boot firmware.
> > The expectation is that the PHY is only turned on/off by using the "no_csr"
> > reset, instead of powering it down and re-programming it after a full
> > reset.
> > 
> > The boot firmware on X1E does not fully conform to this expectation: If the
> > PCIe3 link fails to come up (e.g. because no PCIe card is inserted), the
> > firmware powers down the PHY using the QPHY_PCS_POWER_DOWN_CONTROL
> > register. The QPHY_START_CTRL register is kept as-is, so the driver assumes
> > the PHY is already initialized and skips the configuration/power up
> > sequence. The PHY won't come up again without clearing the
> > QPHY_PCS_POWER_DOWN_CONTROL, so eventually initialization fails:
> > 
> >   qcom-qmp-pcie-phy 1be0000.phy: phy initialization timed-out
> >   phy phy-1be0000.phy.0: phy poweron failed --> -110
> >   qcom-pcie 1bd0000.pcie: cannot initialize host
> >   qcom-pcie 1bd0000.pcie: probe with driver qcom-pcie failed with error -110
> > 
> > This can be reliably reproduced on the X1E CRD, QCP and Devkit when no card
> > is inserted for PCIe3.
> > 
> > Fix this by checking the QPHY_PCS_POWER_DOWN_CONTROL register in addition
> > to QPHY_START_CTRL. If the PHY is powered down with the register, it
> > doesn't conform to the expectations for using the "no_csr" reset, so we
> > fully re-initialize with the normal reset sequence.
> > 
> > Cc: stable at vger.kernel.org
> > Fixes: 0cc22f5a861c ("phy: qcom: qmp-pcie: Add PHY register retention support")
> > Signed-off-by: Stephan Gerhold <stephan.gerhold at linaro.org>
> > ---
> >  drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 6 ++++--
> >  1 file changed, 4 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
> > index 95830dcfdec9b1f68fd55d1cc3c102985cfafcc1..6a469a8f5ae7eba6e4d1d702efaae1c658c4321e 100644
> > --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
> > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
> > @@ -4339,10 +4339,12 @@ static int qmp_pcie_init(struct phy *phy)
> >  	struct qmp_pcie *qmp = phy_get_drvdata(phy);
> >  	const struct qmp_phy_cfg *cfg = qmp->cfg;
> >  	void __iomem *pcs = qmp->pcs;
> > -	bool phy_initialized = !!(readl(pcs + cfg->regs[QPHY_START_CTRL]));
> >  	int ret;
> >  
> > -	qmp->skip_init = qmp->nocsr_reset && phy_initialized;
> > +	qmp->skip_init = qmp->nocsr_reset &&
> > +		readl(pcs + cfg->regs[QPHY_START_CTRL]) &&
> > +		readl(pcs + cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL]);
> 
> I think it would be good to ensure the value matches platform config
> expectations, i.e. !(val & cfg->pwrdn_ctrl)
> 

I think ((val & cfg->pwrdn_ctrl) == cfg->pwrdn_ctrl) is what you want,
to check if all the bits we would set are actually set? That sounds
reasonable, I'll send a v2 with that soon.

I'll make the same change for QPHY_START_CTRL, to have it consistent
(checking for SERDES_START | PCS_START, which is what we would set).

Thanks,
Stephan


From konrad.dybcio at oss.qualcomm.com  Wed Aug 13 05:07:56 2025
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Wed, 13 Aug 2025 14:07:56 +0200
Subject: [PATCH] phy: qcom: qmp-pcie: Fix PHY initialization when powered
 down by firmware
In-Reply-To: <aJx_KjWFxeYE5U81@linaro.org>
References: <20250812-phy-qcom-qmp-pcie-nocsr-fix-v1-1-9a7d0a5d2b46@linaro.org>
 <f44beed6-72c3-4e86-834b-ac522c786bc7@oss.qualcomm.com>
 <aJx_KjWFxeYE5U81@linaro.org>
Message-ID: <3ad5abef-9fcd-4dbd-babd-3820f6915a52@oss.qualcomm.com>

On 8/13/25 2:04 PM, Stephan Gerhold wrote:
> On Wed, Aug 13, 2025 at 12:13:31PM +0200, Konrad Dybcio wrote:
>> On 8/12/25 6:30 PM, Stephan Gerhold wrote:
>>> Commit 0cc22f5a861c ("phy: qcom: qmp-pcie: Add PHY register retention
>>> support") added support for using the "no_csr" reset to skip configuration
>>> of the PHY if the init sequence was already applied by the boot firmware.
>>> The expectation is that the PHY is only turned on/off by using the "no_csr"
>>> reset, instead of powering it down and re-programming it after a full
>>> reset.
>>>
>>> The boot firmware on X1E does not fully conform to this expectation: If the
>>> PCIe3 link fails to come up (e.g. because no PCIe card is inserted), the
>>> firmware powers down the PHY using the QPHY_PCS_POWER_DOWN_CONTROL
>>> register. The QPHY_START_CTRL register is kept as-is, so the driver assumes
>>> the PHY is already initialized and skips the configuration/power up
>>> sequence. The PHY won't come up again without clearing the
>>> QPHY_PCS_POWER_DOWN_CONTROL, so eventually initialization fails:
>>>
>>>   qcom-qmp-pcie-phy 1be0000.phy: phy initialization timed-out
>>>   phy phy-1be0000.phy.0: phy poweron failed --> -110
>>>   qcom-pcie 1bd0000.pcie: cannot initialize host
>>>   qcom-pcie 1bd0000.pcie: probe with driver qcom-pcie failed with error -110
>>>
>>> This can be reliably reproduced on the X1E CRD, QCP and Devkit when no card
>>> is inserted for PCIe3.
>>>
>>> Fix this by checking the QPHY_PCS_POWER_DOWN_CONTROL register in addition
>>> to QPHY_START_CTRL. If the PHY is powered down with the register, it
>>> doesn't conform to the expectations for using the "no_csr" reset, so we
>>> fully re-initialize with the normal reset sequence.
>>>
>>> Cc: stable at vger.kernel.org
>>> Fixes: 0cc22f5a861c ("phy: qcom: qmp-pcie: Add PHY register retention support")
>>> Signed-off-by: Stephan Gerhold <stephan.gerhold at linaro.org>
>>> ---
>>>  drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 6 ++++--
>>>  1 file changed, 4 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
>>> index 95830dcfdec9b1f68fd55d1cc3c102985cfafcc1..6a469a8f5ae7eba6e4d1d702efaae1c658c4321e 100644
>>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
>>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
>>> @@ -4339,10 +4339,12 @@ static int qmp_pcie_init(struct phy *phy)
>>>  	struct qmp_pcie *qmp = phy_get_drvdata(phy);
>>>  	const struct qmp_phy_cfg *cfg = qmp->cfg;
>>>  	void __iomem *pcs = qmp->pcs;
>>> -	bool phy_initialized = !!(readl(pcs + cfg->regs[QPHY_START_CTRL]));
>>>  	int ret;
>>>  
>>> -	qmp->skip_init = qmp->nocsr_reset && phy_initialized;
>>> +	qmp->skip_init = qmp->nocsr_reset &&
>>> +		readl(pcs + cfg->regs[QPHY_START_CTRL]) &&
>>> +		readl(pcs + cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL]);
>>
>> I think it would be good to ensure the value matches platform config
>> expectations, i.e. !(val & cfg->pwrdn_ctrl)
>>
> 
> I think ((val & cfg->pwrdn_ctrl) == cfg->pwrdn_ctrl) is what you want,
> to check if all the bits we would set are actually set? That sounds
> reasonable, I'll send a v2 with that soon.

We can do that, currently the register (at least on 8750 that I randomly
checked) doesn't have any other bits..

> I'll make the same change for QPHY_START_CTRL, to have it consistent
> (checking for SERDES_START | PCS_START, which is what we would set).

Sounds reasonable

Konrad


From peter.griffin at linaro.org  Wed Aug 13 08:00:45 2025
From: peter.griffin at linaro.org (Peter Griffin)
Date: Wed, 13 Aug 2025 16:00:45 +0100
Subject: [PATCH v3 0/2] Add new phy_notify_state() api
Message-ID: <20250813-phy-notify-pmstate-v3-0-3bda59055dd3@linaro.org>

This series adds a new phy_notify_state() API to the phy subsystem. It is
designed to be used when some specific runtime configuration parameters
need to be changed when transitioning to the desired state which can't be
handled by phy_calibrate()or phy_power_{on|off}().

The first user of the new API is phy-samsung-ufs and phy-gs101-ufs which
need to issue some register writes when entering and exiting the hibern8
link state.

A separate patch will be sent for ufs-exynos driver to make use of this new
API in the hibern8 callbacks.

Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
---
Changes in v3:
- Rename API to phy_notify_state(). (Mani/Neil)
- Remove inline kerneldoc comment (Mani)
- s/phy/PHY (Mani)
- peripheral specific enums in phy.h (Vinod)

- Link to v2: https://lore.kernel.org/r/20250703-phy-notify-pmstate-v2-0-fc1690439117 at linaro.org

Changes in v2:
- Add new phy_notify_pmstate API() instead of using phy_set_mode() (Vinod)
- Link to v1: https://lore.kernel.org/r/20241002201555.3332138-1-peter.griffin at linaro.org

---
Peter Griffin (2):
      phy: add new phy_notify_state() api
      phy: samsung: gs101-ufs: Add .notify_phystate() & hibern8 enter/exit values

 drivers/phy/phy-core.c                | 25 +++++++++++++++++++++++
 drivers/phy/samsung/phy-gs101-ufs.c   | 28 ++++++++++++++++++++++++++
 drivers/phy/samsung/phy-samsung-ufs.c | 38 +++++++++++++++++++++++++++++++++++
 drivers/phy/samsung/phy-samsung-ufs.h |  7 +++++++
 include/linux/phy/phy.h               | 19 ++++++++++++++++++
 5 files changed, 117 insertions(+)
---
base-commit: 43c3c17f0c805882d1b48818b1085747a68c80ec
change-id: 20250703-phy-notify-pmstate-f02ba5582f65

Best regards,
-- 
Peter Griffin <peter.griffin at linaro.org>



From peter.griffin at linaro.org  Wed Aug 13 08:00:46 2025
From: peter.griffin at linaro.org (Peter Griffin)
Date: Wed, 13 Aug 2025 16:00:46 +0100
Subject: [PATCH v3 1/2] phy: add new phy_notify_state() api
In-Reply-To: <20250813-phy-notify-pmstate-v3-0-3bda59055dd3@linaro.org>
References: <20250813-phy-notify-pmstate-v3-0-3bda59055dd3@linaro.org>
Message-ID: <20250813-phy-notify-pmstate-v3-1-3bda59055dd3@linaro.org>

Add a new phy_notify_state() api that notifies and configures a phy for a
given state transition.

This is intended to be by phy drivers which need to do some runtime
configuration of parameters that can't be handled by phy_calibrate() or
phy_power_{on|off}().

The first usage of this API is in the Samsung UFS phy that needs to issue
some register writes when entering and exiting the hibernate link state.

Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
---
 drivers/phy/phy-core.c  | 25 +++++++++++++++++++++++++
 include/linux/phy/phy.h | 19 +++++++++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index 04a5a34e7a950ae94fae915673c25d476fc071c1..60be8af984bf06649ef00e695d0ed4ced597cdb9 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -520,6 +520,31 @@ int phy_notify_disconnect(struct phy *phy, int port)
 }
 EXPORT_SYMBOL_GPL(phy_notify_disconnect);
 
+/**
+ * phy_notify_state() - phy state notification
+ * @phy: the PHY returned by phy_get()
+ * @state: the PHY state
+ *
+ * Notify the PHY of a state transition. Used to notify and
+ * configure the PHY accordingly.
+ *
+ * Returns: %0 if successful, a negative error code otherwise
+ */
+int phy_notify_state(struct phy *phy, union phy_notify state)
+{
+	int ret;
+
+	if (!phy || !phy->ops->notify_phystate)
+		return 0;
+
+	mutex_lock(&phy->mutex);
+	ret = phy->ops->notify_phystate(phy, state);
+	mutex_unlock(&phy->mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(phy_notify_state);
+
 /**
  * phy_configure() - Changes the phy parameters
  * @phy: the phy returned by phy_get()
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index 13add0c2c40721fe9ca3f0350d13c035cd25af45..664d0864c3a5042949cb121e982368fe0a97827f 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -53,6 +53,15 @@ enum phy_media {
 	PHY_MEDIA_DAC,
 };
 
+enum phy_ufs_state {
+	PHY_UFS_HIBERN8_ENTER,
+	PHY_UFS_HIBERN8_EXIT,
+};
+
+union phy_notify {
+	enum phy_ufs_state ufs_state;
+};
+
 /**
  * union phy_configure_opts - Opaque generic phy configuration
  *
@@ -83,6 +92,7 @@ union phy_configure_opts {
  * @set_speed: set the speed of the phy (optional)
  * @reset: resetting the phy
  * @calibrate: calibrate the phy
+ * @notify_phystate: notify and configure the phy for a particular state
  * @release: ops to be performed while the consumer relinquishes the PHY
  * @owner: the module owner containing the ops
  */
@@ -132,6 +142,7 @@ struct phy_ops {
 	int	(*connect)(struct phy *phy, int port);
 	int	(*disconnect)(struct phy *phy, int port);
 
+	int	(*notify_phystate)(struct phy *phy, union phy_notify state);
 	void	(*release)(struct phy *phy);
 	struct module *owner;
 };
@@ -255,6 +266,7 @@ int phy_reset(struct phy *phy);
 int phy_calibrate(struct phy *phy);
 int phy_notify_connect(struct phy *phy, int port);
 int phy_notify_disconnect(struct phy *phy, int port);
+int phy_notify_state(struct phy *phy, union phy_notify state);
 static inline int phy_get_bus_width(struct phy *phy)
 {
 	return phy->attrs.bus_width;
@@ -412,6 +424,13 @@ static inline int phy_notify_disconnect(struct phy *phy, int index)
 	return -ENOSYS;
 }
 
+static inline int phy_notify_phystate(struct phy *phy, union phy_notify state)
+{
+	if (!phy)
+		return 0;
+	return -ENOSYS;
+}
+
 static inline int phy_configure(struct phy *phy,
 				union phy_configure_opts *opts)
 {

-- 
2.51.0.rc0.205.g4a044479a3-goog



From peter.griffin at linaro.org  Wed Aug 13 08:00:47 2025
From: peter.griffin at linaro.org (Peter Griffin)
Date: Wed, 13 Aug 2025 16:00:47 +0100
Subject: [PATCH v3 2/2] phy: samsung: gs101-ufs: Add .notify_phystate() &
 hibern8 enter/exit values
In-Reply-To: <20250813-phy-notify-pmstate-v3-0-3bda59055dd3@linaro.org>
References: <20250813-phy-notify-pmstate-v3-0-3bda59055dd3@linaro.org>
Message-ID: <20250813-phy-notify-pmstate-v3-2-3bda59055dd3@linaro.org>

Implement the .notify_phystate() callback and provide the gs101 specific
phy values that need to be programmed when entering and exiting the hibern8
state.

Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
---
 drivers/phy/samsung/phy-gs101-ufs.c   | 28 ++++++++++++++++++++++++++
 drivers/phy/samsung/phy-samsung-ufs.c | 38 +++++++++++++++++++++++++++++++++++
 drivers/phy/samsung/phy-samsung-ufs.h |  7 +++++++
 3 files changed, 73 insertions(+)

diff --git a/drivers/phy/samsung/phy-gs101-ufs.c b/drivers/phy/samsung/phy-gs101-ufs.c
index 17b798da5b5761f8e367599517d2d97bf0bb6b74..a15e1f453f7f3cecd6d3aa75217633ac4b6085d0 100644
--- a/drivers/phy/samsung/phy-gs101-ufs.c
+++ b/drivers/phy/samsung/phy-gs101-ufs.c
@@ -108,12 +108,39 @@ static const struct samsung_ufs_phy_cfg tensor_gs101_post_pwr_hs_config[] = {
 	END_UFS_PHY_CFG,
 };
 
+static const struct samsung_ufs_phy_cfg tensor_gs101_post_h8_enter[] = {
+	PHY_TRSV_REG_CFG_GS101(0x262, 0x08, PWR_MODE_ANY),
+	PHY_TRSV_REG_CFG_GS101(0x265, 0x0A, PWR_MODE_ANY),
+	PHY_COMN_REG_CFG(0x1, 0x8,  PWR_MODE_ANY),
+	PHY_COMN_REG_CFG(0x0, 0x86,  PWR_MODE_ANY),
+	PHY_COMN_REG_CFG(0x8, 0x60,  PWR_MODE_HS_ANY),
+	PHY_TRSV_REG_CFG_GS101(0x222, 0x08, PWR_MODE_HS_ANY),
+	PHY_TRSV_REG_CFG_GS101(0x246, 0x01, PWR_MODE_HS_ANY),
+	END_UFS_PHY_CFG,
+};
+
+static const struct samsung_ufs_phy_cfg tensor_gs101_pre_h8_exit[] = {
+	PHY_COMN_REG_CFG(0x0, 0xC6,  PWR_MODE_ANY),
+	PHY_COMN_REG_CFG(0x1, 0x0C,  PWR_MODE_ANY),
+	PHY_TRSV_REG_CFG_GS101(0x262, 0x00, PWR_MODE_ANY),
+	PHY_TRSV_REG_CFG_GS101(0x265, 0x00, PWR_MODE_ANY),
+	PHY_COMN_REG_CFG(0x8, 0xE0,  PWR_MODE_HS_ANY),
+	PHY_TRSV_REG_CFG_GS101(0x246, 0x03, PWR_MODE_HS_ANY),
+	PHY_TRSV_REG_CFG_GS101(0x222, 0x18, PWR_MODE_HS_ANY),
+	END_UFS_PHY_CFG,
+};
+
 static const struct samsung_ufs_phy_cfg *tensor_gs101_ufs_phy_cfgs[CFG_TAG_MAX] = {
 	[CFG_PRE_INIT]		= tensor_gs101_pre_init_cfg,
 	[CFG_PRE_PWR_HS]	= tensor_gs101_pre_pwr_hs_config,
 	[CFG_POST_PWR_HS]	= tensor_gs101_post_pwr_hs_config,
 };
 
+static const struct samsung_ufs_phy_cfg *tensor_gs101_hibern8_cfgs[] = {
+	[CFG_POST_HIBERN8_ENTER]	= tensor_gs101_post_h8_enter,
+	[CFG_PRE_HIBERN8_EXIT]		= tensor_gs101_pre_h8_exit,
+};
+
 static const char * const tensor_gs101_ufs_phy_clks[] = {
 	"ref_clk",
 };
@@ -170,6 +197,7 @@ static int gs101_phy_wait_for_cdr_lock(struct phy *phy, u8 lane)
 
 const struct samsung_ufs_phy_drvdata tensor_gs101_ufs_phy = {
 	.cfgs = tensor_gs101_ufs_phy_cfgs,
+	.cfgs_hibern8 = tensor_gs101_hibern8_cfgs,
 	.isol = {
 		.offset = TENSOR_GS101_PHY_CTRL,
 		.mask = TENSOR_GS101_PHY_CTRL_MASK,
diff --git a/drivers/phy/samsung/phy-samsung-ufs.c b/drivers/phy/samsung/phy-samsung-ufs.c
index f3cbe6b17b235bb181b3fae628d75822f0c9183a..192ea408f787bb31912a2c7dd90cc1b61c4237c4 100644
--- a/drivers/phy/samsung/phy-samsung-ufs.c
+++ b/drivers/phy/samsung/phy-samsung-ufs.c
@@ -217,6 +217,42 @@ static int samsung_ufs_phy_set_mode(struct phy *generic_phy,
 	return 0;
 }
 
+static int samsung_ufs_phy_notify_state(struct phy *phy,
+					union phy_notify state)
+{
+	struct samsung_ufs_phy *ufs_phy = get_samsung_ufs_phy(phy);
+	const struct samsung_ufs_phy_cfg *cfg;
+	int i, err;
+
+	if (!ufs_phy->cfgs_hibern8)
+		return 0;
+
+	if (state.ufs_state == PHY_UFS_HIBERN8_ENTER)
+		cfg = ufs_phy->cfgs_hibern8[CFG_POST_HIBERN8_ENTER];
+	else if (state.ufs_state == PHY_UFS_HIBERN8_EXIT)
+		cfg = ufs_phy->cfgs_hibern8[CFG_PRE_HIBERN8_EXIT];
+
+	for_each_phy_cfg(cfg) {
+		for_each_phy_lane(ufs_phy, i) {
+			samsung_ufs_phy_config(ufs_phy, cfg, i);
+		}
+	}
+
+	if (state.ufs_state == PHY_UFS_HIBERN8_EXIT) {
+		for_each_phy_lane(ufs_phy, i) {
+			if (ufs_phy->drvdata->wait_for_cdr) {
+				err = ufs_phy->drvdata->wait_for_cdr(phy, i);
+				if (err)
+					goto err_out;
+			}
+		}
+	}
+
+	return 0;
+err_out:
+	return err;
+}
+
 static int samsung_ufs_phy_exit(struct phy *phy)
 {
 	struct samsung_ufs_phy *ss_phy = get_samsung_ufs_phy(phy);
@@ -233,6 +269,7 @@ static const struct phy_ops samsung_ufs_phy_ops = {
 	.power_off	= samsung_ufs_phy_power_off,
 	.calibrate	= samsung_ufs_phy_calibrate,
 	.set_mode	= samsung_ufs_phy_set_mode,
+	.notify_phystate = samsung_ufs_phy_notify_state,
 	.owner          = THIS_MODULE,
 };
 
@@ -287,6 +324,7 @@ static int samsung_ufs_phy_probe(struct platform_device *pdev)
 	phy->dev = dev;
 	phy->drvdata = drvdata;
 	phy->cfgs = drvdata->cfgs;
+	phy->cfgs_hibern8 = drvdata->cfgs_hibern8;
 	memcpy(&phy->isol, &drvdata->isol, sizeof(phy->isol));
 
 	if (!of_property_read_u32_index(dev->of_node, "samsung,pmu-syscon", 1,
diff --git a/drivers/phy/samsung/phy-samsung-ufs.h b/drivers/phy/samsung/phy-samsung-ufs.h
index a28f148081d168344b47f2798b00cb098f0a8574..f2c2e744e5bae87c9cfcaa17f4a09456f134966a 100644
--- a/drivers/phy/samsung/phy-samsung-ufs.h
+++ b/drivers/phy/samsung/phy-samsung-ufs.h
@@ -92,6 +92,11 @@ enum {
 	CFG_TAG_MAX,
 };
 
+enum {
+	CFG_POST_HIBERN8_ENTER,
+	CFG_PRE_HIBERN8_EXIT,
+};
+
 struct samsung_ufs_phy_cfg {
 	u32 off_0;
 	u32 off_1;
@@ -108,6 +113,7 @@ struct samsung_ufs_phy_pmu_isol {
 
 struct samsung_ufs_phy_drvdata {
 	const struct samsung_ufs_phy_cfg **cfgs;
+	const struct samsung_ufs_phy_cfg **cfgs_hibern8;
 	struct samsung_ufs_phy_pmu_isol isol;
 	const char * const *clk_list;
 	int num_clks;
@@ -124,6 +130,7 @@ struct samsung_ufs_phy {
 	struct clk_bulk_data *clks;
 	const struct samsung_ufs_phy_drvdata *drvdata;
 	const struct samsung_ufs_phy_cfg * const *cfgs;
+	const struct samsung_ufs_phy_cfg * const *cfgs_hibern8;
 	struct samsung_ufs_phy_pmu_isol isol;
 	u8 lane_cnt;
 	int ufs_phy_state;

-- 
2.51.0.rc0.205.g4a044479a3-goog



From wsa+renesas at sang-engineering.com  Wed Aug 13 09:14:58 2025
From: wsa+renesas at sang-engineering.com (Wolfram Sang)
Date: Wed, 13 Aug 2025 18:14:58 +0200
Subject: [PATCH 12/21] phy: remove unneeded 'fast_io' parameter in regmap_config
In-Reply-To: <20250813161517.4746-1-wsa+renesas@sang-engineering.com>
References: <20250813161517.4746-1-wsa+renesas@sang-engineering.com>
Message-ID: <20250813161517.4746-13-wsa+renesas@sang-engineering.com>

When using MMIO with regmap, fast_io is implied. No need to set it
again.

Signed-off-by: Wolfram Sang <wsa+renesas at sang-engineering.com>
---
No dependencies, can be applied directly to the subsystem tree. Buildbot is
happy, too.

 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 1 -
 drivers/phy/rockchip/phy-rockchip-usbdp.c         | 1 -
 drivers/phy/ti/phy-am654-serdes.c                 | 1 -
 drivers/phy/ti/phy-j721e-wiz.c                    | 1 -
 4 files changed, 4 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index 79db57ee90d1..01bbf668e05e 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -795,7 +795,6 @@ static const struct regmap_config rk_hdptx_phy_regmap_config = {
 	.val_bits = 32,
 	.writeable_reg = rk_hdptx_phy_is_rw_reg,
 	.readable_reg = rk_hdptx_phy_is_rw_reg,
-	.fast_io = true,
 	.max_register = 0x18b4,
 };
 
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index c066cc0a7b4f..010e9d2d6fac 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -1430,7 +1430,6 @@ static const struct regmap_config rk_udphy_pma_regmap_cfg = {
 	.reg_bits = 32,
 	.reg_stride = 4,
 	.val_bits = 32,
-	.fast_io = true,
 	.max_register = 0x20dc,
 };
 
diff --git a/drivers/phy/ti/phy-am654-serdes.c b/drivers/phy/ti/phy-am654-serdes.c
index 431b223996e0..5b6c27aa7e8b 100644
--- a/drivers/phy/ti/phy-am654-serdes.c
+++ b/drivers/phy/ti/phy-am654-serdes.c
@@ -99,7 +99,6 @@ static const struct regmap_config serdes_am654_regmap_config = {
 	.reg_bits = 32,
 	.val_bits = 32,
 	.reg_stride = 4,
-	.fast_io = true,
 	.max_register = 0x1ffc,
 };
 
diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c
index ab2a4f2c0a5b..a8b440c6c46b 100644
--- a/drivers/phy/ti/phy-j721e-wiz.c
+++ b/drivers/phy/ti/phy-j721e-wiz.c
@@ -1319,7 +1319,6 @@ static const struct regmap_config wiz_regmap_config = {
 	.reg_bits = 32,
 	.val_bits = 32,
 	.reg_stride = 4,
-	.fast_io = true,
 };
 
 static struct wiz_data j721e_16g_data = {
-- 
2.47.2



From elder at riscstar.com  Wed Aug 13 11:46:54 2025
From: elder at riscstar.com (Alex Elder)
Date: Wed, 13 Aug 2025 13:46:54 -0500
Subject: [PATCH 0/6] Introduce SpacemiT K1 PCIe phy and host controller
Message-ID: <20250813184701.2444372-1-elder@riscstar.com>

This series introduces a PHY driver and a PCIe driver to support PCIe
on the SpacemiT K1 SoC.  The PCIe implementation is derived from a
Synopsys DesignWare PCIe IP.  The PHY driver supports one combination
PCIe/USB PHY as well as two PCIe-only PHYs.  The combo PHY port uses
one PCIe lane, and the other two ports each have two lanes.  All PCIe
ports operate at 5 GT/second.

The PCIe PHYs must be configured using a value that can only be
determined using the combo PHY, operating in PCIe mode.  To allow
that PHY to be used for USB, the calibration step is performed by
the PHY driver automatically at probe time.  Once this step is done,
the PHY can be used for either PCIe or USB.

					-Alex

Alex Elder (6):
  dt-bindings: phy: spacemit: add SpacemiT PCIe/combo PHY
  dt-bindings: phy: spacemit: introduce PCIe PHY
  dt-bindings: phy: spacemit: introduce PCIe root complex
  phy: spacemit: introduce PCIe/combo PHY
  PCI: spacemit: introduce SpacemiT PCIe host driver
  riscv: dts: spacemit: PCIe and PHY-related updates

 .../bindings/pci/spacemit,k1-pcie-rc.yaml     | 141 ++++
 .../bindings/phy/spacemit,k1-combo-phy.yaml   | 110 +++
 .../bindings/phy/spacemit,k1-pcie-phy.yaml    |  49 ++
 .../boot/dts/spacemit/k1-bananapi-f3.dts      |  28 +
 arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi  |  33 +
 arch/riscv/boot/dts/spacemit/k1.dtsi          | 169 +++++
 drivers/pci/controller/dwc/Kconfig            |  10 +
 drivers/pci/controller/dwc/Makefile           |   1 +
 drivers/pci/controller/dwc/pcie-k1.c          | 355 ++++++++++
 drivers/phy/Kconfig                           |  11 +
 drivers/phy/Makefile                          |   1 +
 drivers/phy/phy-spacemit-k1-pcie.c            | 639 ++++++++++++++++++
 12 files changed, 1547 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/spacemit,k1-pcie-rc.yaml
 create mode 100644 Documentation/devicetree/bindings/phy/spacemit,k1-combo-phy.yaml
 create mode 100644 Documentation/devicetree/bindings/phy/spacemit,k1-pcie-phy.yaml
 create mode 100644 drivers/pci/controller/dwc/pcie-k1.c
 create mode 100644 drivers/phy/phy-spacemit-k1-pcie.c


base-commit: 8f5ae30d69d7543eee0d70083daf4de8fe15d585
-- 
2.48.1



From elder at riscstar.com  Wed Aug 13 11:46:55 2025
From: elder at riscstar.com (Alex Elder)
Date: Wed, 13 Aug 2025 13:46:55 -0500
Subject: [PATCH 1/6] dt-bindings: phy: spacemit: add SpacemiT PCIe/combo PHY
In-Reply-To: <20250813184701.2444372-1-elder@riscstar.com>
References: <20250813184701.2444372-1-elder@riscstar.com>
Message-ID: <20250813184701.2444372-2-elder@riscstar.com>

Add the Device Tree binding for the PCIe/USB 3.0 combo PHY found in
the SpacemiT K1 SoC.  This is one of three PCIe PHYs, and is unusual
in that only the combo PHY can perform a calibration step needed to
determine settings used by the other two PCIe PHYs.

Calibration must be done with the combo PHY in PCIe mode, and to allow
this to occur independent of the eventual use for the PHY (PCIe or USB)
some PCIe-related properties must be supplied: clocks; resets; and a
syscon phandle.

Signed-off-by: Alex Elder <elder at riscstar.com>
---
 .../bindings/phy/spacemit,k1-combo-phy.yaml   | 110 ++++++++++++++++++
 1 file changed, 110 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/spacemit,k1-combo-phy.yaml

diff --git a/Documentation/devicetree/bindings/phy/spacemit,k1-combo-phy.yaml b/Documentation/devicetree/bindings/phy/spacemit,k1-combo-phy.yaml
new file mode 100644
index 0000000000000..ed78083a53231
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/spacemit,k1-combo-phy.yaml
@@ -0,0 +1,110 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/spacemit,k1-combo-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SpacemiT K1 PCIe/USB3 Combo PHY
+
+maintainers:
+  - Alex Elder <elder at riscstar.com>
+
+description:
+  Of the three PHYs on the SpacemiT K1 SoC capable of being used for
+  PCIe, one is a combo PHY that can also be configured for use by a
+  USB 3 controller.  Using PCIe or USB 3 is a board design decision.
+
+  The combo PHY is also the only PCIe PHY that is able to determine
+  PCIe calibration values to use, and this must be determined before
+  the other two PCIe PHYs can be used.  This calibration must be
+  performed with the combo PHY in PCIe mode, and is this is done
+  when the combo PHY is probed.
+
+  During normal operation, the PCIe or USB port driver is responsible
+  for ensuring all clocks needed by a PHY are enabled, and all resets
+  affecting the PHY are deasserted.  However, for the combo PHY to
+  perform calibration independent of whether it's later used for
+  PCIe or USB, all PCIe mode clocks and resets must be defined.
+
+properties:
+  compatible:
+    const: spacemit,k1-combo-phy
+
+  reg:
+    items:
+      - description: PHY control registers
+
+  clocks:
+    items:
+      - description: DWC PCIe Data Bus Interface (DBI) clock
+      - description: DWC PCIe application AXI-bus Master interface clock
+      - description: DWC PCIe application AXI-bus Slave interface clock.
+
+  clock-names:
+    items:
+      - const: dbi
+      - const: mstr
+      - const: slv
+
+  resets:
+    items:
+      - description: DWC PCIe Data Bus Interface (DBI) reset
+      - description: DWC PCIe application AXI-bus Master interface reset
+      - description: DWC PCIe application AXI-bus Slave interface reset.
+      - description: Global reset; must be deasserted for PHY to function
+
+  reset-names:
+    items:
+      - const: dbi
+      - const: mstr
+      - const: slv
+      - const: global
+
+  spacemit,syscon-pmu:
+    description:
+      PHandle that refers to the APMU system controller, whose
+      regmap is used in setting the mode
+    $ref: /schemas/types.yaml#/definitions/phandle
+
+  "#phy-cells":
+    const: 1
+    description:
+      The argument value (PHY_TYPE_PCIE or PHY_TYPE_USB3) determines
+      whether the PHY operates in PCIe or USB3 mode.
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+  - spacemit,syscon-pmu
+  - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/spacemit,k1-syscon.h>
+    combo_phy: phy at c0b10000 {
+        compatible = "spacemit,k1-combo-phy";
+        reg = <0xc0b10000 0x1000>;
+        clocks = <&syscon_apmu CLK_PCIE0_DBI>,
+                 <&syscon_apmu CLK_PCIE0_MASTER>,
+                 <&syscon_apmu CLK_PCIE0_SLAVE>;
+        clock-names = "dbi",
+                      "mstr",
+                      "slv";
+        resets = <&syscon_apmu RESET_PCIE0_DBI>,
+                 <&syscon_apmu RESET_PCIE0_MASTER>,
+                 <&syscon_apmu RESET_PCIE0_SLAVE>,
+                 <&syscon_apmu RESET_PCIE0_GLOBAL>;
+        reset-names = "dbi",
+                      "mstr",
+                      "slv",
+                      "global";
+        spacemit,syscon-pmu = <&syscon_apmu>;
+        #phy-cells = <1>;
+        status = "disabled";
+    };
-- 
2.48.1



From elder at riscstar.com  Wed Aug 13 11:46:56 2025
From: elder at riscstar.com (Alex Elder)
Date: Wed, 13 Aug 2025 13:46:56 -0500
Subject: [PATCH 2/6] dt-bindings: phy: spacemit: introduce PCIe PHY
In-Reply-To: <20250813184701.2444372-1-elder@riscstar.com>
References: <20250813184701.2444372-1-elder@riscstar.com>
Message-ID: <20250813184701.2444372-3-elder@riscstar.com>

Add the Device Tree binding for two PCIe PHYs present on the SpacemiT
K1 SoC.  These PHYs are dependent on a separate combo PHY, which
determines at probe time the calibration values used by the PCIe-only
PHYs.

Signed-off-by: Alex Elder <elder at riscstar.com>
---
 .../bindings/phy/spacemit,k1-pcie-phy.yaml    | 49 +++++++++++++++++++
 1 file changed, 49 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/spacemit,k1-pcie-phy.yaml

diff --git a/Documentation/devicetree/bindings/phy/spacemit,k1-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/spacemit,k1-pcie-phy.yaml
new file mode 100644
index 0000000000000..b0cbd231d9378
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/spacemit,k1-pcie-phy.yaml
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/spacemit,k1-pcie-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SpacemiT K1 PCIe PHY
+
+maintainers:
+  - Alex Elder <elder at riscstar.com>
+
+description:
+  There are two PHYs on the SpacemiT K1 SoC used for PCIe (only).
+  These PHYs must be configured using calibration values that are
+  determined by a third "combo PHY".  The combo PHY determines
+  these calibration values during probe so they can be used for
+  the two PCIe-only PHYs.
+
+  During normal operation, the PCIe port driver is responsible for
+  ensuring all clocks needed by a PHY are enabled, and all resets
+  affecting the PHY are deasserted.
+
+properties:
+  compatible:
+    const: spacemit,k1-pcie-phy
+
+  reg:
+    items:
+      - description: PHY control registers
+
+  "#phy-cells":
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/spacemit,k1-syscon.h>
+    pcie1_phy: phy at c0c10000 {
+        compatible = "spacemit,k1-pcie-phy";
+        reg = <0xc0c10000 0x1000>;
+        #phy-cells = <0>;
+        status = "disabled";
+    };
-- 
2.48.1



From elder at riscstar.com  Wed Aug 13 11:46:57 2025
From: elder at riscstar.com (Alex Elder)
Date: Wed, 13 Aug 2025 13:46:57 -0500
Subject: [PATCH 3/6] dt-bindings: phy: spacemit: introduce PCIe root complex
In-Reply-To: <20250813184701.2444372-1-elder@riscstar.com>
References: <20250813184701.2444372-1-elder@riscstar.com>
Message-ID: <20250813184701.2444372-4-elder@riscstar.com>

Add the Device Tree binding for the PCIe root complex found on the
SpacemiT K1 SoC.  This device is derived from the Synopsys Designware
PCIe IP.  It supports up to three PCIe ports operating at PCIe gen 2
link speeds (5 GT/sec).  One of the ports uses a combo PHY, which is
typically used to support a USB 3 port.

Signed-off-by: Alex Elder <elder at riscstar.com>
---
 .../bindings/pci/spacemit,k1-pcie-rc.yaml     | 141 ++++++++++++++++++
 1 file changed, 141 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/spacemit,k1-pcie-rc.yaml

diff --git a/Documentation/devicetree/bindings/pci/spacemit,k1-pcie-rc.yaml b/Documentation/devicetree/bindings/pci/spacemit,k1-pcie-rc.yaml
new file mode 100644
index 0000000000000..6bcca2f91a6fd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/spacemit,k1-pcie-rc.yaml
@@ -0,0 +1,141 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/spacemit,k1-pcie-rc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SpacemiT K1 PCI Express Root Complex
+
+maintainers:
+  - Alex Elder <elder at riscstar.com>
+
+description:
+  The SpacemiT K1 SoC PCIe root complex controller is based on the
+  Synopsys DesignWare PCIe IP.
+
+properties:
+  compatible:
+    const: spacemit,k1-pcie-rc.yaml
+
+  reg:
+    items:
+      - description: DesignWare PCIe registers
+      - description: ATU address space
+      - description: PCIe configuration space
+      - description: Link control registers
+
+  reg-names:
+    items:
+      - const: dbi
+      - const: atu
+      - const: config
+      - const: link
+
+  clocks:
+    items:
+      - description: DWC PCIe Data Bus Interface (DBI) clock
+      - description: DWC PCIe application AXI-bus Master interface clock
+      - description: DWC PCIe application AXI-bus Slave interface clock.
+
+  clock-names:
+    items:
+      - const: dbi
+      - const: mstr
+      - const: slv
+
+  resets:
+    items:
+      - description: DWC PCIe Data Bus Interface (DBI) reset
+      - description: DWC PCIe application AXI-bus Master interface reset
+      - description: DWC PCIe application AXI-bus Slave interface reset.
+      - description: Global reset; must be deasserted for PHY to function
+
+  reset-names:
+    items:
+      - const: dbi
+      - const: mstr
+      - const: slv
+      - const: global
+
+  interrupts-extended:
+    maxItems: 1
+
+  spacemit,syscon-pmu:
+    description:
+      PHandle that refers to the APMU system controller, whose
+      regmap is used in managing resets and link state.
+    $ref: /schemas/types.yaml#/definitions/phandle
+
+  device_type:
+    const: pci
+
+  max-link-speed:
+    const: 2
+
+  num-viewport:
+    const: 8
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+  - spacemit,syscon-pmu
+  - "#address-cells"
+  - "#size-cells"
+  - device_type
+  - max-link-speed
+  - bus-range
+  - num-viewport
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/spacemit,k1-syscon.h>
+    pcie0: pcie at ca000000 {
+        compatible = "spacemit,k1-pcie-rc";
+        reg = <0x0 0xca000000 0x0 0x00001000>,
+              <0x0 0xca300000 0x0 0x0001ff24>,
+              <0x0 0x8f000000 0x0 0x00002000>,
+              <0x0 0xc0b20000 0x0 0x00001000>;
+        reg-names = "dbi",
+                    "atu",
+                    "config",
+                    "link";
+
+        ranges = <0x01000000 0x8f002000 0x0 0x8f002000 0x0 0x100000>,
+                 <0x02000000 0x80000000 0x0 0x80000000 0x0 0x0f000000>;
+
+        clocks = <&syscon_apmu CLK_PCIE0_DBI>,
+                 <&syscon_apmu CLK_PCIE0_MASTER>,
+                 <&syscon_apmu CLK_PCIE0_SLAVE>;
+        clock-names = "dbi",
+                      "mstr",
+                      "slv";
+
+        resets = <&syscon_apmu RESET_PCIE0_DBI>,
+                 <&syscon_apmu RESET_PCIE0_MASTER>,
+                 <&syscon_apmu RESET_PCIE0_SLAVE>,
+                 <&syscon_apmu RESET_PCIE0_GLOBAL>;
+        reset-names = "dbi",
+                      "mstr",
+                      "slv",
+                      "global";
+
+        interrupts-extended = <&plic 141>;
+
+        spacemit,syscon-pmu = <&syscon_apmu 0x03cc>;
+
+        #address-cells = <3>;
+        #size-cells = <2>;
+
+        device_type = "pci";
+        max-link-speed = <2>;
+        bus-range = <0x00 0xff>;
+        num-viewport = <8>;
+
+        status = "disabled";
+    };
-- 
2.48.1



From elder at riscstar.com  Wed Aug 13 11:46:58 2025
From: elder at riscstar.com (Alex Elder)
Date: Wed, 13 Aug 2025 13:46:58 -0500
Subject: [PATCH 4/6] phy: spacemit: introduce PCIe/combo PHY
In-Reply-To: <20250813184701.2444372-1-elder@riscstar.com>
References: <20250813184701.2444372-1-elder@riscstar.com>
Message-ID: <20250813184701.2444372-5-elder@riscstar.com>

Introduce a driver that supports three PHYs found on the SpacemiT
K1 SoC.  The first PHY is a combo PHY that can be configured for
use for either USB 3 or PCIe.  The other two PHYs support PCIe
only.

All three PHYs must be programmed with an 8 bit receiver termination
value, which must be determined dynamically; only the combo PHY is
able to determine this value.  The combo PHY performs a special
calibration step at probe time to discover this, and that value is
used to program each PHY that operates in PCIe mode.  The combo
PHY must therefore be probed--first--if either of the PCIe-only
PHYs will be used.

During normal operation, the USB or PCIe driver using the PHY must
ensure clocks and resets are set up properly.  However clocks are
enabled and resets are de-asserted temporarily by this driver to
perform the calibration step on the combo PHY.

Tested-by: Junzhong Pan <panjunzhong at linux.spacemit.com>
Signed-off-by: Alex Elder <elder at riscstar.com>
---
 drivers/phy/Kconfig                |  11 +
 drivers/phy/Makefile               |   1 +
 drivers/phy/phy-spacemit-k1-pcie.c | 639 +++++++++++++++++++++++++++++
 3 files changed, 651 insertions(+)
 create mode 100644 drivers/phy/phy-spacemit-k1-pcie.c

diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 58c911e1b2d20..0fa343203f289 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -101,6 +101,17 @@ config PHY_NXP_PTN3222
 	  schemes. It supports all three USB 2.0 data rates: Low Speed, Full
 	  Speed and High Speed.
 
+config PHY_SPACEMIT_K1_PCIE
+	tristate "PCIe and combo PHY driver for the SpacemiT K1 SoC"
+	depends on ARCH_SPACEMIT || COMPILE_TEST
+	depends on HAS_IOMEM
+	depends on OF
+	select GENERIC_PHY
+	default ARCH_SPACEMIT
+	help
+	  Enable support for the PCIe and USB 3 combo PHY and two
+	  PCIe-only PHYs used in the SpacemiT K1 SoC.
+
 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 c670a8dac4680..20f0078e543c7 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_PHY_SNPS_EUSB2)		+= phy-snps-eusb2.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-$(CONFIG_PHY_SPACEMIT_K1_PCIE)	+= phy-spacemit-k1-pcie.o
 obj-y					+= allwinner/	\
 					   amlogic/	\
 					   broadcom/	\
diff --git a/drivers/phy/phy-spacemit-k1-pcie.c b/drivers/phy/phy-spacemit-k1-pcie.c
new file mode 100644
index 0000000000000..32dce53170fbb
--- /dev/null
+++ b/drivers/phy/phy-spacemit-k1-pcie.c
@@ -0,0 +1,639 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SpacemiT K1 PCIe and PCIe/USB 3 combo PHY driver
+ *
+ * Copyright (C) 2025 by RISCstar Solutions Corporation.  All rights reserved.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.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/reset.h>
+
+#include <dt-bindings/phy/phy.h>
+
+/*
+ * Three PCIe ports are supported in the SpacemiT K1 SoC, and this driver
+ * supports their PHYs.
+ *
+ * The PHY for PCIe port A is different from the PHYs for ports B and C:
+ * - It has one lane, while ports B and C have two
+ * - It is a combo PHY can be used for PCIe or USB 3
+ * - It can automatically calibrate PCIe TX and RX termination settings
+ *
+ * The PHY functionality for PCIe ports B and C is identical:
+ * - They have two PCIe lanes (but can be restricted to 1 via Device Tree)
+ * - They are used for PCIe only
+ * - They are configured using TX and RX values computed for port A
+ *
+ * A given board is designed to use the combo PHY for either PCIe or USB 3.
+ * Whether the combo PHY is configured for PCIe or USB 3 is specified in
+ * Device Tree using a phandle plus an argument.  The argument indicates
+ * the type (either PHY_TYPE_PCIE or PHY_TYPE_USB3).
+ *
+ * Each PHY depends on clocks and resets provided by the controller
+ * hardware (PCIe or USB) it is associated with.  The controller drivers
+ * are required to enable any clocks and de-assert any resets that affect
+ * PHY operation.
+ *
+ * PCIe PHYs must be programmed with RX and TX calibration values.  The
+ * combo PHY is the only one that can determine these values.  They are
+ * determined by temporarily enabling the combo PHY in PCIe mode at probe
+ * time (if necessary).  This calibration only needs to be done once, and
+ * when it has completed the TX and RX values are saved.
+ *
+ * To allow the combo PHY to be enabled for calibration, the resets and
+ * clocks it uses in PCIe mode must be supplied.
+ */
+
+struct k1_pcie_phy {
+	struct device *dev;		/* PHY provider device */
+	struct phy *phy;
+	void __iomem *regs;
+	u32 pcie_lanes;			/* Max unless limited by DT */
+	/* The remaining fields are only used for the combo PHY */
+	u32 type;			/* PHY_TYPE_PCIE or PHY_TYPE_USB3 */
+	struct regmap *pmu;
+};
+
+#define CALIBRATION_TIMEOUT		500000	/* microseconds */
+#define PLL_TIMEOUT			500000	/* microseconds */
+#define POLL_DELAY			500	/* microseconds */
+
+/* Selecting the combo PHY operating mode requires PMU regmap access */
+#define SYSCON_PMU			"spacemit,syscon-pmu"
+
+/* PMU space, for selecting between PCIe and USB3 mode on the combo PHY */
+
+#define PMUA_USB_PHY_CTRL0			0x0110
+#define COMBO_PHY_SEL			BIT(3)	/* 0: PCIe; 1: USB3 */
+
+#define PCIE_CLK_RES_CTRL			0x03cc
+#define PCIE_APP_HOLD_PHY_RST		BIT(30)
+
+/* PHY register space */
+
+/* Offset between lane 0 and lane 1 registers when there are two */
+#define PHY_LANE_OFFSET				0x0400
+
+#define PCIE_PU_ADDR_CLK_CFG			0x0008
+#define PLL_READY			BIT(0)		/* read-only */
+#define CFG_RXCLK_EN			BIT(3)
+#define CFG_TXCLK_EN			BIT(4)
+#define CFG_PCLK_EN			BIT(5)
+#define CFG_PIPE_PCLK_EN		BIT(6)
+#define CFG_INTERNAL_TIMER_ADJ		GENMASK(10, 7)
+#define TIMER_ADJ_USB		0x2
+#define TIMER_ADJ_PCIE		0x6
+#define CFG_SW_PHY_INIT_DONE		BIT(11)	/* We set after PLL config */
+
+#define PCIE_RC_DONE_STATUS			0x0018
+#define CFG_FORCE_RCV_RETRY		BIT(10)
+
+#define PCIE_RC_CAL_REG2			0x0020
+#define RC_CAL_TOGGLE			BIT(22)
+#define CLKSEL				GENMASK(31, 29)
+#define CLKSEL_24M		0x3
+
+#define PCIE_PU_PLL_1				0x0048
+#define REF_100_WSSC			BIT(12)	/* 1: input is 100MHz, SSC */
+#define FREF_SEL			GENMASK(15, 13)
+#define FREF_24M		0x1
+#define SSC_DEP_SEL			GENMASK(19, 16)
+#define SSC_DEP_NONE		0x0
+#define SSC_DEP_5000PPM		0xa
+#define SSC_MODE			GENMASK(21, 20)
+#define SSC_MODE_DOWN_SPREAD	0x3
+#define SSC_OFFSET			GENMASK(23, 22)
+#define SSC_OFFSET_0_PPM	0x0
+
+#define PCIE_PU_PLL_2				0x004c
+#define GEN_REF100			BIT(4)	/* 1: generate 100MHz clk */
+
+#define PCIE_RX_REG1				0x0050
+#define EN_RTERM			BIT(3)
+#define AFE_RTERM_REG			GENMASK(11, 8)
+
+#define PCIE_RX_REG2				0x0054
+#define RX_RTERM_SEL			BIT(5)	/* 0: use AFE_RTERM_REG value */
+
+#define PCIE_LTSSM_DIS_ENTRY			0x005c
+#define CFG_REFCLK_MODE			GENMASK(9, 8)
+#define RFCLK_MODE_DRIVER	0x1
+#define OVRD_REFCLK_MODE		BIT(10)	/* 1: use CFG_RFCLK_MODE */
+
+#define PCIE_TX_REG1				0x0064
+#define TX_RTERM_REG			GENMASK(15, 12)
+#define TX_RTERM_SEL			BIT(25)	/* 1: use TX_RTERM_REG */
+
+#define USB3_TEST_CTRL				0x0068
+
+#define PCIE_RCAL_RESULT			0x0084	/* Port A PHY only */
+#define RTERM_VALUE_RX			GENMASK(3, 0)
+#define RTERM_VALUE_TX			GENMASK(7, 4)
+#define R_TUNE_DONE			BIT(10)
+
+static u32 k1_phy_rterm = ~0;     /* Invalid initial value */
+
+/* Save the RX and TX receiver termination values */
+static void k1_phy_rterm_set(u32 val)
+{
+	k1_phy_rterm = val & (RTERM_VALUE_RX | RTERM_VALUE_TX);
+}
+
+static bool k1_phy_rterm_valid(void)
+{
+	/* Valid if no bits outside those we care about are set */
+	return !(k1_phy_rterm & ~(RTERM_VALUE_RX | RTERM_VALUE_TX));
+}
+
+static u32 k1_phy_rterm_rx(void)
+{
+	return FIELD_GET(RTERM_VALUE_RX, k1_phy_rterm);
+}
+
+static u32 k1_phy_rterm_tx(void)
+{
+	return FIELD_GET(RTERM_VALUE_TX, k1_phy_rterm);
+}
+
+/* Only the combo PHY has a PMU pointer defined */
+static bool k1_phy_port_a(struct k1_pcie_phy *k1_phy)
+{
+	return !!k1_phy->pmu;
+}
+
+/*
+ * Select PCIe or USB 3 mode for the combo PHY.  Return 1 if the bit
+ * was changed, 0 if it was not, or a negative error value otherwise.
+ */
+static int k1_combo_phy_sel(struct k1_pcie_phy *k1_phy, bool usb3)
+{
+	int ret;
+
+	ret = regmap_test_bits(k1_phy->pmu, PMUA_USB_PHY_CTRL0, COMBO_PHY_SEL);
+	if (ret < 0)
+		return ret;
+
+	/* If it's already in the desired state, we're done */
+	if (!!ret == usb3)
+		return 0;
+
+	/* Change the bit */
+	ret = regmap_assign_bits(k1_phy->pmu, PMUA_USB_PHY_CTRL0,
+				 COMBO_PHY_SEL, usb3);
+
+	return ret < 0 ? ret : 1;
+}
+
+static void k1_pcie_phy_init_pll(struct k1_pcie_phy *k1_phy,
+				 void __iomem *regs, bool pcie)
+{
+	void __iomem *virt;
+	u32 timer_adj;
+	u32 ssc_dep;
+	u32 val;
+
+	if (pcie) {
+		timer_adj = TIMER_ADJ_PCIE;
+		ssc_dep = SSC_DEP_NONE;
+	} else {
+		timer_adj = TIMER_ADJ_USB;
+		ssc_dep = SSC_DEP_5000PPM;
+	}
+
+	/*
+	 * Disable 100 MHz input reference with spread-spectrum
+	 * clocking and select the 24 MHz clock input frequency
+	 */
+	virt = k1_phy->regs + PCIE_PU_PLL_1;
+	val = readl(virt);
+	val &= ~REF_100_WSSC;
+
+	val &= ~FREF_SEL;
+	val |= FIELD_PREP(FREF_SEL, FREF_24M);
+
+	val &= ~SSC_DEP_SEL;
+	val |= FIELD_PREP(SSC_DEP_SEL, ssc_dep);
+
+	val &= ~SSC_MODE;
+	val |= FIELD_PREP(SSC_MODE, SSC_MODE_DOWN_SPREAD);
+
+	val &= ~SSC_OFFSET;
+	val |= FIELD_PREP(SSC_OFFSET, SSC_OFFSET_0_PPM);
+	writel(val, virt);
+
+	if (pcie) {
+		virt = regs + PCIE_PU_PLL_2;
+		val = readl(virt);
+		val |= GEN_REF100;	/* Enable 100 MHz PLL output clock */
+		writel(val, virt);
+	}
+
+	/* Enable clocks and mark PLL initialization done */
+	virt = regs + PCIE_PU_ADDR_CLK_CFG;
+	val = readl(virt);
+	val |= CFG_RXCLK_EN;
+	val |= CFG_TXCLK_EN;
+	val |= CFG_PCLK_EN;
+	val |= CFG_PIPE_PCLK_EN;
+
+	val &= ~CFG_INTERNAL_TIMER_ADJ;
+	val |= FIELD_PREP(CFG_INTERNAL_TIMER_ADJ, timer_adj);
+
+	val |= CFG_SW_PHY_INIT_DONE;
+	writel(val, virt);
+}
+
+static int k1_pcie_pll_lock(struct k1_pcie_phy *k1_phy, bool pcie)
+{
+	u32 val = pcie ? CFG_FORCE_RCV_RETRY : 0;
+	void __iomem *virt;
+
+	writel(val, k1_phy->regs + PCIE_RC_DONE_STATUS);
+
+	/*
+	 * Wait for indication the PHY PLL is locked.  Lanes for ports
+	 * B and C share a PLL, so it's enough to sample just lane 0.
+	 */
+	virt = k1_phy->regs + PCIE_PU_ADDR_CLK_CFG;	/* Lane 0 */
+
+	return readl_poll_timeout(virt, val, val & PLL_READY,
+				  POLL_DELAY, PLL_TIMEOUT);
+}
+
+static int k1_pcie_phy_init_pcie(struct k1_pcie_phy *k1_phy)
+{
+	u32 rx_rterm = k1_phy_rterm_rx();
+	u32 tx_rterm = k1_phy_rterm_tx();
+	void __iomem *virt;
+	void __iomem *regs;
+	u32 val;
+	int ret;
+	int i;
+
+	/* For the combo PHY, set PHY to PCIe mode */
+	if (k1_phy_port_a(k1_phy)) {
+		ret = k1_combo_phy_sel(k1_phy, false);
+		if (ret < 0)
+			return ret;
+	}
+
+	regs = k1_phy->regs;
+	for (i = 0; i < k1_phy->pcie_lanes; i++) {
+		virt = regs + PCIE_RX_REG1;
+		val = readl(virt);
+
+		/* Set RX analog front-end receiver termination value */
+		val &= ~AFE_RTERM_REG;
+		val |= FIELD_PREP(AFE_RTERM_REG, rx_rterm);
+
+		/* And enable refclock receiver termination */
+		val |= EN_RTERM;
+		writel(val, virt);
+
+		virt = regs + PCIE_RX_REG2;
+		val = readl(virt);
+		/* Use PCIE_RX_REG1 AFE_RTERM_REG value */
+		val &= ~RX_RTERM_SEL;
+		writel(val, virt);
+
+		virt = regs + PCIE_TX_REG1;
+		val = readl(virt);
+
+		/* Set TX driver termination value */
+		val &= ~TX_RTERM_REG;
+		val |= FIELD_PREP(TX_RTERM_REG, tx_rterm);
+
+		/* Use PCIE_TX_REG1 TX_RTERM_REG value */
+		val |= TX_RTERM_SEL;
+		writel(val, virt);
+
+		virt = regs + PCIE_RC_CAL_REG2;
+		val = readl(virt);
+
+		/* Set the input clock to 24 MHz, and clear RC_CAL_TOGGLE */
+		val &= CLKSEL;
+		val |= FIELD_PREP(CLKSEL, CLKSEL_24M);
+
+		val &= ~RC_CAL_TOGGLE;
+		writel(val, virt);
+		/* Trigger recalibration by setting RC_CAL_TOGGLE again */
+		val |= RC_CAL_TOGGLE;
+		writel(val, virt);
+
+		virt = regs + PCIE_LTSSM_DIS_ENTRY;
+		val = readl(virt);
+		/* Override the reference clock; set to refclk driver mode */
+		val |= OVRD_REFCLK_MODE;
+
+		val &= ~CFG_REFCLK_MODE;
+		val |= FIELD_PREP(CFG_REFCLK_MODE, RFCLK_MODE_DRIVER);
+
+		writel(val, virt);
+
+		k1_pcie_phy_init_pll(k1_phy, regs, true);
+
+		regs += PHY_LANE_OFFSET;	/* Next lane */
+	}
+
+	return k1_pcie_pll_lock(k1_phy, true);
+}
+
+/* Only called for combo PHY */
+static int k1_pcie_phy_init_usb3_host(struct k1_pcie_phy *k1_phy)
+{
+	int ret;
+
+	ret = k1_combo_phy_sel(k1_phy, true);
+	if (ret < 0)
+		return ret;
+
+	/* We're not doing any testing */
+	writel(0, k1_phy->regs + USB3_TEST_CTRL);
+
+	k1_pcie_phy_init_pll(k1_phy, k1_phy->regs, false);
+
+	return k1_pcie_pll_lock(k1_phy, false);
+}
+
+static int k1_pcie_phy_init(struct phy *phy)
+{
+	struct k1_pcie_phy *k1_phy = phy_get_drvdata(phy);
+
+	if (k1_phy_port_a(k1_phy) && k1_phy->type == PHY_TYPE_USB3)
+		return k1_pcie_phy_init_usb3_host(k1_phy);
+
+	return k1_pcie_phy_init_pcie(k1_phy);
+}
+
+static const struct phy_ops k1_pcie_phy_ops = {
+	.init		= k1_pcie_phy_init,
+	.owner		= THIS_MODULE,
+};
+
+/*
+ * Get values needed for calibrating PHYs operating in PCIe mode.  Only
+ * the combo PHY is able to do this, and its calibration values are used
+ * for configuring all PCIe PHYs.
+ *
+ * We always need to de-assert the (PCIe) global reset on the combo PHY,
+ * because the USB driver depends on it.  If used for PCIe, the driver
+ * will (also) de-assert this, but by leaving it de-asserted for the
+ * combo PHY, the USB driver doesn't have to do this.
+ * of this first.
+ *
+ * In addition, we guarantee the APP_HOLD_PHY_RESET bit is clear for the
+ * combo PHY, so the USB driver doesn't have to manage that either.  The
+ * PCIe driver is free to change this bit for normal operation.
+ *
+ * Calibration only needs to be done once.  It's possible calibration has
+ * already completed (e.g., it might have happened in the boot loader, or
+ * -EPROBE_DEFER might result in this function being called again).  So we
+ * check that early too, to avoid doing it more than once.
+ *
+ * Otherwise we temporarily power up the PHY, wait for the hardware to
+ * indicate calibration is done, grab the value, then shut the PHY down
+ * again.
+ */
+static int k1_pcie_combo_phy_calibrate(struct k1_pcie_phy *k1_phy)
+{
+	struct reset_control_bulk_data data[] = {
+		{ .id = "dbi", },
+		{ .id = "mstr", },
+		{ .id = "slv", },
+	};
+	size_t data_size = ARRAY_SIZE(data);
+	struct reset_control *global_reset;
+	struct device *dev = k1_phy->dev;
+	struct clk_bulk_data *clocks;
+	void __iomem *virt;
+	bool mode_changed;
+	u32 clock_count;
+	int ret = 0;
+	int val;
+
+	/* We always de-assert the global reset and leave it that way */
+	global_reset = devm_reset_control_get_shared_deasserted(dev, "global");
+	if (IS_ERR(global_reset))
+		return PTR_ERR(global_reset);
+
+	/*
+	 * We also guarantee the APP_HOLD_PHY_RESET bit is clear.  If an
+	 * error occurs we can't go on, but otherwise we can leave this
+	 * bit clear even if an error happens below.
+	 */
+	ret = regmap_assign_bits(k1_phy->pmu, PCIE_CLK_RES_CTRL,
+				 PCIE_APP_HOLD_PHY_RST, false);
+	if (ret < 0)
+		return ret;
+
+	/* If the receiver termination value is valid, nothing more to do */
+	if (k1_phy_rterm_valid())
+		return 0;
+
+	/* If the calibration already completed (e.g. by U-Boot), we're done */
+	virt = k1_phy->regs + PCIE_RCAL_RESULT;
+	val = readl(virt);
+	if (val & R_TUNE_DONE)
+		goto done;
+
+	/* Make sure the PHY is configured for PCIe */
+	ret = k1_combo_phy_sel(k1_phy, false);
+	if (ret < 0)
+		return ret;
+	mode_changed = ret > 0;
+
+	/* Get and enable all clocks */
+	ret = clk_bulk_get_all(dev, &clocks);
+	if (ret < 0)
+		return ret;
+	if (!ret)
+		return -ENOENT;
+	clock_count = ret;
+
+	ret = clk_bulk_prepare_enable(clock_count, clocks);
+	if (ret)
+		goto out_put_clocks;
+
+	/* Get the (not "global") PCIe application resets */
+	ret = reset_control_bulk_get_shared(dev, data_size, data);
+	if (ret)
+		goto out_disable_clocks;
+
+	/* De-assert the PCIe application resets */
+	ret = reset_control_bulk_deassert(data_size, data);
+	if (ret)
+		goto out_put_resets;
+
+	/*
+	 * This is the core activity here.  Wait for the hardware to
+	 * signal that it has completed calibration/tuning.  Once it
+	 * has, the register value will contain the values we'll
+	 * use to configure PCIe PHYs.
+	 */
+	ret = readl_poll_timeout(virt, val, val & R_TUNE_DONE,
+				 POLL_DELAY, CALIBRATION_TIMEOUT);
+
+	/* Clean up.  We're done with the resets and clocks */
+	reset_control_bulk_assert(data_size, data);
+out_put_resets:
+	reset_control_bulk_put(data_size, data);
+out_disable_clocks:
+	clk_bulk_disable_unprepare(clock_count, clocks);
+out_put_clocks:
+	clk_bulk_put_all(clock_count, clocks);
+
+	/* If we changed the mode, restore the original state */
+	if (mode_changed)
+		(void)k1_combo_phy_sel(k1_phy, true);
+done:
+	/* If we got the value without timing out, set k1_phy_rterm */
+	if (!ret)
+		k1_phy_rterm_set(val);
+
+	return ret;
+}
+
+static struct phy *
+k1_pcie_combo_phy_xlate(struct device *dev, const struct of_phandle_args *args)
+{
+	struct k1_pcie_phy *k1_phy = dev_get_drvdata(dev);
+	u32 type;
+
+	/* The argument specifying the PHY mode is required */
+	if (args->args_count != 1)
+		return ERR_PTR(-EINVAL);
+
+	/* We only support PCIe and USB3 mode */
+	type = args->args[0];
+	if (type != PHY_TYPE_PCIE && type != PHY_TYPE_USB3)
+		return ERR_PTR(-EINVAL);
+
+	/* This PHY can only be used once */
+	if (k1_phy->type != PHY_NONE)
+		return ERR_PTR(-EBUSY);
+
+	k1_phy->type = type;
+
+	return k1_phy->phy;
+}
+
+/* Use the maximum number of PCIe lanes unless limited by Device Tree */
+static u32 k1_pcie_num_lanes(struct k1_pcie_phy *k1_phy, bool port_a)
+{
+	struct device *dev = k1_phy->dev;
+	u32 count = 0;
+	u32 max;
+	int ret;
+
+	ret = of_property_read_u32(dev_of_node(dev), "num-lanes", &count);
+	if (count == 1)
+		return 1;
+
+	if (count == 2 && !port_a)
+		return 2;
+
+	max = port_a ? 1 : 2;
+	if (ret != -EINVAL)
+		dev_warn(dev, "bad lane count %u for port; using %u\n",
+			 count, max);
+
+	return max;
+}
+
+static int k1_pcie_combo_phy_probe(struct k1_pcie_phy *k1_phy)
+{
+	struct device *dev = k1_phy->dev;
+	struct regmap *regmap;
+	int ret;
+
+	/* Setting the PHY mode requires access to the PMU regmap */
+	regmap = syscon_regmap_lookup_by_phandle(dev_of_node(dev), SYSCON_PMU);
+	if (IS_ERR(regmap))
+		return dev_err_probe(dev, PTR_ERR(regmap),
+				     "error getting PMU\n");
+	k1_phy->pmu = regmap;
+
+	ret = k1_pcie_combo_phy_calibrate(k1_phy);
+	if (ret)
+		return dev_err_probe(dev, ret, "calibration failed\n");
+
+	/* Needed by k1_pcie_combo_phy_xlate(), which also sets k1_phy->type */
+	dev_set_drvdata(dev, k1_phy);
+
+	return 0;
+}
+
+static int k1_pcie_phy_probe(struct platform_device *pdev)
+{
+	struct phy *(*xlate)(struct device *, const struct of_phandle_args *);
+	struct device *dev = &pdev->dev;
+	struct phy_provider *provider;
+	struct k1_pcie_phy *k1_phy;
+	bool probing_port_a;
+	int ret;
+
+	xlate = of_device_get_match_data(dev);
+	probing_port_a = xlate == k1_pcie_combo_phy_xlate;
+
+	/* Only the combo PHY can calibrate, so it must probe first */
+	if (!k1_phy_rterm_valid() && !probing_port_a)
+		return -EPROBE_DEFER;
+
+	k1_phy = devm_kzalloc(dev, sizeof(*k1_phy), GFP_KERNEL);
+	if (!k1_phy)
+		return -ENOMEM;
+	k1_phy->dev = dev;
+
+	k1_phy->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(k1_phy->regs))
+		return dev_err_probe(dev, PTR_ERR(k1_phy->regs),
+				     "error mapping registers\n");
+
+	k1_phy->pcie_lanes = k1_pcie_num_lanes(k1_phy, probing_port_a);
+
+	if (probing_port_a) {
+		ret = k1_pcie_combo_phy_probe(k1_phy);
+		if (ret)
+			return dev_err_probe(dev, ret,
+					     "error probing combo phy\n");
+	}
+
+	k1_phy->phy = devm_phy_create(dev, NULL, &k1_pcie_phy_ops);
+	if (IS_ERR(k1_phy->phy))
+		return dev_err_probe(dev, PTR_ERR(k1_phy->phy),
+				     "error creating phy\n");
+	phy_set_drvdata(k1_phy->phy, k1_phy);
+
+	provider = devm_of_phy_provider_register(dev, xlate);
+	if (IS_ERR(provider))
+		return dev_err_probe(dev, PTR_ERR(provider),
+				     "error registering provider\n");
+	return 0;
+}
+
+static const struct of_device_id k1_pcie_phy_of_match[] = {
+	{ .compatible = "spacemit,k1-combo-phy", k1_pcie_combo_phy_xlate, },
+	{ .compatible = "spacemit,k1-pcie-phy", of_phy_simple_xlate, },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, k1_pcie_phy_of_match);
+
+static struct platform_driver k1_pcie_phy_driver = {
+	.probe	= k1_pcie_phy_probe,
+	.driver = {
+		.of_match_table	= k1_pcie_phy_of_match,
+		.name = "k1-pcie-phy",
+	}
+};
+module_platform_driver(k1_pcie_phy_driver);
+
+MODULE_DESCRIPTION("SpacemiT K1 PCIe 3.0 and USB 3 PHY driver");
+MODULE_LICENSE("GPL");
-- 
2.48.1



From elder at riscstar.com  Wed Aug 13 11:46:59 2025
From: elder at riscstar.com (Alex Elder)
Date: Wed, 13 Aug 2025 13:46:59 -0500
Subject: [PATCH 5/6] PCI: spacemit: introduce SpacemiT PCIe host driver
In-Reply-To: <20250813184701.2444372-1-elder@riscstar.com>
References: <20250813184701.2444372-1-elder@riscstar.com>
Message-ID: <20250813184701.2444372-6-elder@riscstar.com>

Introduce a driver for the PCIe root complex found in the SpacemiT
K1 SoC.  The hardware is derived from the Synopsys DesignWare PCIe IP.
The driver supports three PCIe ports that operate at PCIe v2 transfer
rates (5 GT/sec).  The first port uses a combo PHY, which may be
configured for use for USB 3 instead.

Signed-off-by: Alex Elder <elder at riscstar.com>
---
 drivers/pci/controller/dwc/Kconfig   |  10 +
 drivers/pci/controller/dwc/Makefile  |   1 +
 drivers/pci/controller/dwc/pcie-k1.c | 355 +++++++++++++++++++++++++++
 3 files changed, 366 insertions(+)
 create mode 100644 drivers/pci/controller/dwc/pcie-k1.c

diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
index ff6b6d9e18ecf..ca5782c041ce8 100644
--- a/drivers/pci/controller/dwc/Kconfig
+++ b/drivers/pci/controller/dwc/Kconfig
@@ -492,4 +492,14 @@ config PCIE_VISCONTI_HOST
 	  Say Y here if you want PCIe controller support on Toshiba Visconti SoC.
 	  This driver supports TMPV7708 SoC.
 
+config PCIE_K1
+	bool "SpacemiT K1 host mode PCIe controller"
+	depends on ARCH_SPACEMIT || COMPILE_TEST
+	depends on PCI && OF && HAS_IOMEM
+	select PCIE_DW_HOST
+	default ARCH_SPACEMIT
+	help
+	  Enables support for the PCIe controller in the K1 SoC operating
+	  in host mode.
+
 endmenu
diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile
index 6919d27798d13..62d9d4e7dd4d3 100644
--- a/drivers/pci/controller/dwc/Makefile
+++ b/drivers/pci/controller/dwc/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_PCIE_UNIPHIER) += pcie-uniphier.o
 obj-$(CONFIG_PCIE_UNIPHIER_EP) += pcie-uniphier-ep.o
 obj-$(CONFIG_PCIE_VISCONTI_HOST) += pcie-visconti.o
 obj-$(CONFIG_PCIE_RCAR_GEN4) += pcie-rcar-gen4.o
+obj-$(CONFIG_PCIE_K1) += pcie-k1.o
 
 # The following drivers are for devices that use the generic ACPI
 # pci_root.c driver but don't support standard ECAM config access.
diff --git a/drivers/pci/controller/dwc/pcie-k1.c b/drivers/pci/controller/dwc/pcie-k1.c
new file mode 100644
index 0000000000000..e9b1df3428d16
--- /dev/null
+++ b/drivers/pci/controller/dwc/pcie-k1.c
@@ -0,0 +1,355 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SpacemiT K1 PCIe host driver
+ *
+ * Copyright (C) 2025 by RISCstar Solutions Corporation.  All rights reserved.
+ * Copyright (c) 2023, spacemit Corporation.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/gfp.h>
+#include <linux/irq.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mod_devicetable.h>
+#include <linux/of.h>
+#include <linux/pci.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/types.h>
+
+#include "pcie-designware.h"
+
+#define K1_PCIE_VENDOR_ID	0x201f
+#define K1_PCIE_DEVICE_ID	0x0001
+
+/* Offsets and field definitions of link management registers */
+
+#define K1_PHY_AHB_IRQ_EN			0x0000
+#define PCIE_INTERRUPT_EN		BIT(0)
+
+#define K1_PHY_AHB_LINK_STS			0x0004
+#define SMLH_LINK_UP			BIT(1)
+#define RDLH_LINK_UP			BIT(12)
+
+#define INTR_ENABLE				0x0014
+#define MSI_CTRL_INT			BIT(11)
+
+/* Offsets and field definitions for PMU registers */
+
+#define PCIE_CLK_RESET_CONTROL			0x0000
+#define LTSSM_EN			BIT(6)
+#define PCIE_AUX_PWR_DET		BIT(9)
+#define PCIE_RC_PERST			BIT(12)	/* 0: PERST# high; 1: low */
+#define APP_HOLD_PHY_RST		BIT(30)
+#define DEVICE_TYPE_RC			BIT(31)	/* 0: endpoint; 1: RC */
+
+#define PCIE_CONTROL_LOGIC			0x0004
+#define PCIE_SOFT_RESET			BIT(0)
+
+struct k1_pcie {
+	struct dw_pcie pci;
+	void __iomem *link;
+	struct regmap *pmu;
+	u32 pmu_off;
+	struct phy *phy;
+	struct reset_control *global_reset;
+};
+
+#define to_k1_pcie(dw_pcie)	dev_get_drvdata((dw_pcie)->dev)
+
+static int k1_pcie_toggle_soft_reset(struct k1_pcie *k1)
+{
+	u32 offset = k1->pmu_off + PCIE_CONTROL_LOGIC;
+	const u32 mask = PCIE_SOFT_RESET;
+	int ret;
+
+	ret = regmap_set_bits(k1->pmu, offset, mask);
+	if (ret)
+		return ret;
+
+	mdelay(2);
+
+	return regmap_clear_bits(k1->pmu, offset, mask);
+}
+
+/* Enable app clocks, deassert app resets */
+static int k1_pcie_app_enable(struct k1_pcie *k1)
+{
+	struct dw_pcie *pci = &k1->pci;
+	u32 clock_count;
+	u32 reset_count;
+	int ret;
+
+	clock_count = ARRAY_SIZE(pci->app_clks);
+	ret = clk_bulk_prepare_enable(clock_count, pci->app_clks);
+	if (ret)
+		return ret;
+
+	reset_count = ARRAY_SIZE(pci->app_rsts);
+	ret = reset_control_bulk_deassert(reset_count, pci->app_rsts);
+	if (ret)
+		goto err_disable_clks;
+
+	ret = reset_control_deassert(k1->global_reset);
+	if (ret)
+		goto err_assert_resets;
+
+	return 0;
+
+err_assert_resets:
+	(void)reset_control_bulk_assert(reset_count, pci->app_rsts);
+err_disable_clks:
+	clk_bulk_disable_unprepare(clock_count, pci->app_clks);
+
+	return ret;
+}
+
+/* Disable app clocks, assert app resets */
+static void k1_pcie_app_disable(struct k1_pcie *k1)
+{
+	struct dw_pcie *pci = &k1->pci;
+	u32 count;
+	int ret;
+
+	(void)reset_control_assert(k1->global_reset);
+
+	count = ARRAY_SIZE(pci->app_rsts);
+	ret = reset_control_bulk_assert(count, pci->app_rsts);
+	if (ret)
+		dev_err(pci->dev, "app reset assert failed (%d)\n", ret);
+
+	count = ARRAY_SIZE(pci->app_clks);
+	clk_bulk_disable_unprepare(count, pci->app_clks);
+}
+
+static int k1_pcie_init(struct dw_pcie_rp *pp)
+{
+	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+	struct k1_pcie *k1 = to_k1_pcie(pci);
+	u32 offset;
+	u32 mask;
+	int ret;
+
+	ret = k1_pcie_toggle_soft_reset(k1);
+	if (ret)
+		goto err_app_disable;
+
+	ret = k1_pcie_app_enable(k1);
+	if (ret)
+		return ret;
+
+	ret = phy_init(k1->phy);
+	if (ret)
+		goto err_app_disable;
+
+	/* Set the PCI vendor and device ID */
+	dw_pcie_dbi_ro_wr_en(pci);
+	dw_pcie_writew_dbi(pci, PCI_VENDOR_ID, K1_PCIE_VENDOR_ID);
+	dw_pcie_writew_dbi(pci, PCI_DEVICE_ID, K1_PCIE_DEVICE_ID);
+	dw_pcie_dbi_ro_wr_dis(pci);
+
+	/*
+	 * Put the port in root complex mode, record that Vaux is present.
+	 * Assert fundamental reset (drive PERST# low).
+	 */
+	offset = k1->pmu_off + PCIE_CLK_RESET_CONTROL;
+	mask = DEVICE_TYPE_RC | PCIE_AUX_PWR_DET;
+	mask |= PCIE_RC_PERST;
+	ret = regmap_set_bits(k1->pmu, offset, mask);
+	if (ret)
+		goto err_phy_exit;
+
+	/* Wait the PCIe-mandated 100 msec before deasserting PERST# */
+	mdelay(100);
+
+	ret = regmap_clear_bits(k1->pmu, offset, PCIE_RC_PERST);
+	if (!ret)
+		return 0;	/* Success! */
+
+err_phy_exit:
+	(void)phy_exit(k1->phy);
+err_app_disable:
+	k1_pcie_app_disable(k1);
+
+	return ret;
+}
+
+/* Silently ignore any errors */
+static void k1_pcie_deinit(struct dw_pcie_rp *pp)
+{
+	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+	struct k1_pcie *k1 = to_k1_pcie(pci);
+
+	/* Re-assert fundamental reset (drive PERST# low) */
+	(void)regmap_set_bits(k1->pmu, k1->pmu_off + PCIE_CLK_RESET_CONTROL,
+			      PCIE_RC_PERST);
+
+	(void)phy_exit(k1->phy);
+
+	k1_pcie_app_disable(k1);
+}
+
+static const struct dw_pcie_host_ops k1_pcie_host_ops = {
+	.init		= k1_pcie_init,
+	.deinit		= k1_pcie_deinit,
+};
+
+static void k1_pcie_enable_interrupts(struct k1_pcie *k1)
+{
+	void __iomem *virt;
+	u32 val;
+
+	/* Enable the MSI interrupt */
+	writel(MSI_CTRL_INT, k1->link + INTR_ENABLE);
+
+	/* Top-level interrupt enable */
+	virt = k1->link + K1_PHY_AHB_IRQ_EN;
+	val = readl(virt);
+	val |= PCIE_INTERRUPT_EN;
+	writel(val, virt);
+}
+
+static void k1_pcie_disable_interrupts(struct k1_pcie *k1)
+{
+	void __iomem *virt;
+	u32 val;
+
+	virt = k1->link + K1_PHY_AHB_IRQ_EN;
+	val = readl(virt);
+	val &= ~PCIE_INTERRUPT_EN;
+	writel(val, virt);
+
+	writel(0, k1->link + INTR_ENABLE);
+}
+
+static bool k1_pcie_link_up(struct dw_pcie *pci)
+{
+	struct k1_pcie *k1 = to_k1_pcie(pci);
+	u32 val;
+
+	val = readl(k1->link + K1_PHY_AHB_LINK_STS);
+
+	return (val & RDLH_LINK_UP) && (val & SMLH_LINK_UP);
+}
+
+static int k1_pcie_start_link(struct dw_pcie *pci)
+{
+	struct k1_pcie *k1 = to_k1_pcie(pci);
+	int ret;
+
+	/* Stop holding the PHY in reset, and enable link training */
+	ret = regmap_update_bits(k1->pmu, k1->pmu_off + PCIE_CLK_RESET_CONTROL,
+				 APP_HOLD_PHY_RST | LTSSM_EN, LTSSM_EN);
+	if (ret)
+		return ret;
+
+	k1_pcie_enable_interrupts(k1);
+
+	return 0;
+}
+
+static void k1_pcie_stop_link(struct dw_pcie *pci)
+{
+	struct k1_pcie *k1 = to_k1_pcie(pci);
+	int ret;
+
+	k1_pcie_disable_interrupts(k1);
+
+	/* Disable the link and hold the PHY in reset */
+	ret = regmap_update_bits(k1->pmu, k1->pmu_off + PCIE_CLK_RESET_CONTROL,
+				 APP_HOLD_PHY_RST | LTSSM_EN, APP_HOLD_PHY_RST);
+	if (ret)
+		dev_err(pci->dev, "disable LTSSM failed (%d)\n", ret);
+}
+
+static const struct dw_pcie_ops k1_pcie_ops = {
+	.link_up	= k1_pcie_link_up,
+	.start_link	= k1_pcie_start_link,
+	.stop_link	= k1_pcie_stop_link,
+};
+
+static int k1_pcie_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct dw_pcie_rp *pp;
+	struct dw_pcie *pci;
+	struct k1_pcie *k1;
+	int ret;
+
+	k1 = devm_kzalloc(dev, sizeof(*k1), GFP_KERNEL);
+	if (!k1)
+		return -ENOMEM;
+	dev_set_drvdata(dev, k1);
+
+	k1->pmu = syscon_regmap_lookup_by_phandle_args(dev_of_node(dev),
+						       "spacemit,syscon-pmu",
+						       1, &k1->pmu_off);
+	if (IS_ERR(k1->pmu))
+		return dev_err_probe(dev, PTR_ERR(k1->pmu),
+				     "lookup PMU regmap failed\n");
+
+	k1->link = devm_platform_ioremap_resource_byname(pdev, "link");
+	if (!k1->link)
+		return dev_err_probe(dev, -ENOMEM, "map link regs failed\n");
+
+	k1->global_reset = devm_reset_control_get_shared(dev, "global");
+	if (IS_ERR(k1->global_reset))
+		return dev_err_probe(dev, PTR_ERR(k1->global_reset),
+				     "get global reset failed\n");
+
+	/* Hold the PHY in reset until we start the link */
+	ret = regmap_set_bits(k1->pmu, k1->pmu_off + PCIE_CLK_RESET_CONTROL,
+			      APP_HOLD_PHY_RST);
+	if (ret)
+		return dev_err_probe(dev, ret, "hold PHY in reset failed\n");
+
+	k1->phy = devm_phy_get(dev, NULL);
+	if (IS_ERR(k1->phy))
+		return dev_err_probe(dev, PTR_ERR(k1->phy), "get PHY failed\n");
+
+	pci = &k1->pci;
+	dw_pcie_cap_set(pci, REQ_RES);
+	pci->dev = dev;
+	pci->ops = &k1_pcie_ops;
+
+	pp = &pci->pp;
+	pp->num_vectors = MAX_MSI_IRQS;
+	pp->ops = &k1_pcie_host_ops;
+
+	ret = dw_pcie_host_init(pp);
+	if (ret)
+		return dev_err_probe(dev, ret, "host init failed\n");
+
+	return 0;
+}
+
+static void k1_pcie_remove(struct platform_device *pdev)
+{
+	struct k1_pcie *k1 = dev_get_drvdata(&pdev->dev);
+	struct dw_pcie_rp *pp = &k1->pci.pp;
+
+	dw_pcie_host_deinit(pp);
+}
+
+static const struct of_device_id k1_pcie_of_match_table[] = {
+	{ .compatible = "spacemit,k1-pcie-rc", },
+	{ },
+};
+
+static struct platform_driver k1_pcie_driver = {
+	.probe	= k1_pcie_probe,
+	.remove	= k1_pcie_remove,
+	.driver = {
+		.name			= "k1-dwc-pcie",
+		.of_match_table		= k1_pcie_of_match_table,
+		.suppress_bind_attrs	= true,
+	},
+};
+module_platform_driver(k1_pcie_driver);
-- 
2.48.1



From elder at riscstar.com  Wed Aug 13 11:47:00 2025
From: elder at riscstar.com (Alex Elder)
Date: Wed, 13 Aug 2025 13:47:00 -0500
Subject: [PATCH 6/6] riscv: dts: spacemit: PCIe and PHY-related updates
In-Reply-To: <20250813184701.2444372-1-elder@riscstar.com>
References: <20250813184701.2444372-1-elder@riscstar.com>
Message-ID: <20250813184701.2444372-7-elder@riscstar.com>

Define PCIe and PHY-related Device Tree nodes for the SpacemiT K1 SoC.

Enable the combo PHY and the two PCIe-only PHYs on the Banana Pi BPI-F3
board.  The combo PHY is used for USB on this board, and that will be
enabled when USB 3 support is accepted.

Signed-off-by: Alex Elder <elder at riscstar.com>
---
 .../boot/dts/spacemit/k1-bananapi-f3.dts      |  28 +++
 arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi  |  33 ++++
 arch/riscv/boot/dts/spacemit/k1.dtsi          | 169 ++++++++++++++++++
 3 files changed, 230 insertions(+)

diff --git a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
index fe22c747c5012..1c75e38b1fab9 100644
--- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
+++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
@@ -40,6 +40,34 @@ &emmc {
 	status = "okay";
 };
 
+&combo_phy {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie0_3_cfg>;
+	status = "okay";
+};
+
+&pcie1_phy {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie1_3_cfg>;
+	status = "okay";
+};
+
+&pcie2_phy {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie2_4_cfg>;
+	status = "okay";
+};
+
+&pcie1 {
+	phys = <&pcie1_phy>;
+	status = "okay";
+};
+
+&pcie2 {
+	phys = <&pcie2_phy>;
+	status = "okay";
+};
+
 &uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart0_2_cfg>;
diff --git a/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi b/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi
index 3810557374228..e7dbecd7389b7 100644
--- a/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi
+++ b/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi
@@ -21,6 +21,39 @@ uart0-2-pins {
 		};
 	};
 
+	pcie0_3_cfg: pcie0-3-cfg {
+		pcie0-3-pins {
+			pinmux = <K1_PADCONF(54, 3)>,	/* PERST# */
+				 <K1_PADCONF(55, 3)>,	/* WAKE */
+				 <K1_PADCONF(53, 3)>;	/* CLKREQ# */
+
+			bias-pull-up = <0>;
+			drive-strength = <21>;
+		};
+	};
+
+	pcie1_3_cfg: pcie1-3-cfg {
+		pcie1-3-pins {
+			pinmux = <K1_PADCONF(59, 4)>,	/* PERST# */
+				 <K1_PADCONF(60, 4)>,	/* WAKE */
+				 <K1_PADCONF(61, 4)>;	/* CLKREQ# */
+
+			bias-pull-up = <0>;
+			drive-strength = <21>;
+		};
+	};
+
+	pcie2_4_cfg: pcie2-4-cfg {
+		pcie2-4-pins {
+			pinmux = <K1_PADCONF(62, 4)>,	/* PERST# */
+				 <K1_PADCONF(112, 3)>,	/* WAKE */
+				 <K1_PADCONF(117, 4)>;	/* CLKREQ# */
+
+			bias-pull-up = <0>;
+			drive-strength = <21>;
+		};
+	};
+
 	pwm14_1_cfg: pwm14-1-cfg {
 		pwm14-1-pins {
 			pinmux = <K1_PADCONF(44, 4)>;
diff --git a/arch/riscv/boot/dts/spacemit/k1.dtsi b/arch/riscv/boot/dts/spacemit/k1.dtsi
index abde8bb07c95c..6343f6e95284d 100644
--- a/arch/riscv/boot/dts/spacemit/k1.dtsi
+++ b/arch/riscv/boot/dts/spacemit/k1.dtsi
@@ -4,6 +4,8 @@
  */
 
 #include <dt-bindings/clock/spacemit,k1-syscon.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/phy/phy.h>
 
 /dts-v1/;
 / {
@@ -358,6 +360,42 @@ syscon_rcpu2: system-controller at c0888000 {
 			#reset-cells = <1>;
 		};
 
+		combo_phy: phy at c0b10000 {
+			compatible = "spacemit,k1-combo-phy";
+			reg = <0x0 0xc0b10000 0x0 0x1000>;
+			clocks = <&syscon_apmu CLK_PCIE0_DBI>,
+				 <&syscon_apmu CLK_PCIE0_MASTER>,
+				 <&syscon_apmu CLK_PCIE0_SLAVE>;
+			clock-names = "dbi",
+				      "mstr",
+				      "slv";
+			resets = <&syscon_apmu RESET_PCIE0_DBI>,
+				 <&syscon_apmu RESET_PCIE0_MASTER>,
+				 <&syscon_apmu RESET_PCIE0_SLAVE>,
+				 <&syscon_apmu RESET_PCIE0_GLOBAL>;
+			reset-names = "dbi",
+				      "mstr",
+				      "slv",
+				      "global";
+			spacemit,syscon-pmu = <&syscon_apmu>;
+			#phy-cells = <1>;
+			status = "disabled";
+		};
+
+		pcie1_phy: phy at c0c10000 {
+			compatible = "spacemit,k1-pcie-phy";
+			reg = <0x0 0xc0c10000 0x0 0x1000>;
+			#phy-cells = <0>;
+			status = "disabled";
+		};
+
+		pcie2_phy: phy at c0d10000 {
+			compatible = "spacemit,k1-pcie-phy";
+			reg = <0x0 0xc0d10000 0x0 0x1000>;
+			#phy-cells = <0>;
+			status = "disabled";
+		};
+
 		syscon_apbc: system-controller at d4015000 {
 			compatible = "spacemit,k1-syscon-apbc";
 			reg = <0x0 0xd4015000 0x0 0x1000>;
@@ -814,6 +852,137 @@ pcie-bus {
 			#size-cells = <2>;
 			dma-ranges = <0x0 0x00000000 0x0 0x00000000 0x0 0x80000000>,
 				     <0x0 0xb8000000 0x1 0x38000000 0x3 0x48000000>;
+			pcie0: pcie at ca000000 {
+				compatible = "spacemit,k1-pcie-rc";
+				reg = <0x0 0xca000000 0x0 0x00001000>,
+				      <0x0 0xca300000 0x0 0x0001ff24>,
+				      <0x0 0x8f000000 0x0 0x00002000>,
+				      <0x0 0xc0b20000 0x0 0x00001000>;
+				reg-names = "dbi",
+					    "atu",
+					    "config",
+					    "link";
+				spacemit,syscon-pmu = <&syscon_apmu 0x03cc>;
+
+				ranges = <0x01000000 0x0 0x8f002000 0 0x8f002000 0x0 0x100000>,
+					 <0x02000000 0x0 0x80000000 0 0x80000000 0x0 0x0f000000>;
+
+				clocks = <&syscon_apmu CLK_PCIE0_DBI>,
+					 <&syscon_apmu CLK_PCIE0_MASTER>,
+					 <&syscon_apmu CLK_PCIE0_SLAVE>;
+				clock-names = "dbi",
+					      "mstr",
+					      "slv";
+
+				resets = <&syscon_apmu RESET_PCIE0_DBI>,
+					 <&syscon_apmu RESET_PCIE0_MASTER>,
+					 <&syscon_apmu RESET_PCIE0_SLAVE>,
+					 <&syscon_apmu RESET_PCIE0_GLOBAL>;
+				reset-names = "dbi",
+					      "mstr",
+					      "slv",
+					      "global";
+
+				interrupts-extended = <&plic 141>;
+
+				#address-cells = <3>;
+				#size-cells = <2>;
+
+				device_type = "pci";
+				max-link-speed = <2>;
+				bus-range = <0x00 0xff>;
+				num-viewport = <8>;
+
+				status = "disabled";
+			};
+
+			pcie1: pcie at ca400000 {
+				compatible = "spacemit,k1-pcie-rc";
+				reg = <0x0 0xca400000 0x0 0x00001000>,
+				      <0x0 0xca700000 0x0 0x0001ff24>,
+				      <0x0 0x9f000000 0x0 0x00002000>,
+				      <0x0 0xc0c20000 0x0 0x00001000>;
+				reg-names = "dbi",
+					    "atu",
+					    "config",
+					    "link";
+				spacemit,syscon-pmu = <&syscon_apmu 0x3d4>;
+
+				ranges = <0x01000000 0x0 0x9f002000 0 0x9f002000 0x0 0x100000>,
+					 <0x02000000 0x0 0x90000000 0 0x90000000 0x0 0x0f000000>;
+				clocks = <&syscon_apmu CLK_PCIE1_DBI>,
+					 <&syscon_apmu CLK_PCIE1_MASTER>,
+					 <&syscon_apmu CLK_PCIE1_SLAVE>;
+				clock-names = "dbi",
+					      "mstr",
+					      "slv";
+
+				resets = <&syscon_apmu RESET_PCIE1_DBI>,
+					 <&syscon_apmu RESET_PCIE1_MASTER>,
+					 <&syscon_apmu RESET_PCIE1_SLAVE>,
+					 <&syscon_apmu RESET_PCIE1_GLOBAL>;
+				reset-names = "dbi",
+					      "mstr",
+					      "slv",
+					      "global";
+
+				interrupts-extended = <&plic 142>;
+
+				#address-cells = <3>;
+				#size-cells = <2>;
+
+				device_type = "pci";
+				max-link-speed = <2>;
+				bus-range = <0x00 0xff>;
+				num-viewport = <8>;
+
+				status = "disabled";
+			};
+
+			pcie2: pcie at ca800000 {
+				compatible = "spacemit,k1-pcie-rc";
+				reg = <0x0 0xca800000 0x0 0x00001000>,
+				      <0x0 0xcab00000 0x0 0x0001ff24>,
+				      <0x0 0xb7000000 0x0 0x00002000>,
+				      <0x0 0xc0d20000 0x0 0x00001000>;
+				reg-names = "dbi",
+					    "atu",
+					    "config",
+					    "link";
+
+				spacemit,syscon-pmu = <&syscon_apmu 0x3dc>;
+
+				ranges = <0x01000000 0x0 0xb7002000 0 0xb7002000 0x0 0x100000>,
+					 <0x42000000 0x0 0xa0000000 0 0xa0000000 0x0 0x10000000>,
+					 <0x02000000 0x0 0xb0000000 0 0xb0000000 0x0 0x7000000>;
+				clocks = <&syscon_apmu CLK_PCIE2_DBI>,
+					 <&syscon_apmu CLK_PCIE2_MASTER>,
+					 <&syscon_apmu CLK_PCIE2_SLAVE>;
+				clock-names = "dbi",
+					      "mstr",
+					      "slv";
+
+				resets = <&syscon_apmu RESET_PCIE2_DBI>,
+					 <&syscon_apmu RESET_PCIE2_MASTER>,
+					 <&syscon_apmu RESET_PCIE2_SLAVE>,
+					 <&syscon_apmu RESET_PCIE2_GLOBAL>;
+				reset-names = "dbi",
+					      "mstr",
+					      "slv",
+					      "global";
+
+				interrupts-extended = <&plic 143>;
+
+				#address-cells = <3>;
+				#size-cells = <2>;
+
+				device_type = "pci";
+				max-link-speed = <2>;
+				bus-range = <0x00 0xff>;
+				num-viewport = <8>;
+
+				status = "disabled";
+			};
 		};
 
 		storage-bus {
-- 
2.48.1



From quic_nitirawa at quicinc.com  Wed Aug 13 13:47:04 2025
From: quic_nitirawa at quicinc.com (Nitin Rawat)
Date: Thu, 14 Aug 2025 02:17:04 +0530
Subject: [PATCH V1 2/4] arm64: dts: qcom: sm8750: add max-microamp for UFS
 PHY and PLL supplies
In-Reply-To: <ljythvl2yfilcnmgdwt2cyyefxmgl54osll5e76qn7njadhgqq@rwrl3dy6ykt3>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
 <20250806154340.20122-3-quic_nitirawa@quicinc.com>
 <20250808-calm-boa-of-swiftness-a4a7ce@kuoka>
 <9af71063-0629-4ccc-bc76-3fb588677bf4@oss.qualcomm.com>
 <292907f3-25d6-40d9-be6e-b6b83e646d73@kernel.org>
 <5e32be05-0dbd-4d6f-879d-8ce97fb430ba@quicinc.com>
 <rh3qxu2rijpjswfash3rpmmh6sw47l3b6j5p5upti6zffknasz@cywwm3fypghd>
 <89ab7e51-f82e-465a-aa22-1ccb8e7a0f6d@quicinc.com>
 <ljythvl2yfilcnmgdwt2cyyefxmgl54osll5e76qn7njadhgqq@rwrl3dy6ykt3>
Message-ID: <4e996a17-c996-4194-b57d-128e7d05e8ad@quicinc.com>



On 8/12/2025 4:22 PM, Dmitry Baryshkov wrote:
> On Tue, Aug 12, 2025 at 01:25:02AM +0530, Nitin Rawat wrote:
>>
>>
>> On 8/9/2025 4:37 PM, Manivannan Sadhasivam wrote:
>>> On Fri, Aug 08, 2025 at 08:49:45PM GMT, Nitin Rawat wrote:
>>>>
>>>>
>>>> On 8/8/2025 3:09 PM, Krzysztof Kozlowski wrote:
>>>>> On 08/08/2025 10:58, Konrad Dybcio wrote:
>>>>>> On 8/8/25 9:29 AM, Krzysztof Kozlowski wrote:
>>>>>>> On Wed, Aug 06, 2025 at 09:13:38PM +0530, Nitin Rawat wrote:
>>>>>>>> Add `vdda-phy-max-microamp` and `vdda-pll-max-microamp` properties to
>>>>>>>> the UFS PHY node in the device tree.
>>>>>>>>
>>>>>>>> These properties define the maximum current (in microamps) expected
>>>>>>>> from the PHY and PLL regulators. This allows the PHY driver to
>>>>>>>> configure regulator load accurately and ensure proper regulator
>>>>>>>> mode based on load requirements.
>>>>>>>
>>>>>>> That's not the property of phy, but regulator.
>>>>>>>
>>>>>>> Also reasoning is here incomplete - you just post downstream code. :/
>>>>>>
>>>>>> The reason for this change is good, but perhaps not explained clearly
>>>>>>
>>>>>> All of these values refer to the maximum current draw that needs to be
>>>>>> allocated on a shared voltage supply for this peripheral (because the
>>>>>
>>>>>
>>>>> It sounds very different than how much it can be drawn. How much can be
>>>>> drawn is the property of the regulator. The regulator knows how much
>>>>> current it can support.
>>>>
>>>> Consumers are aware of their dynamic load requirements, which can vary at
>>>> runtime?this awareness is not reciprocal. The power grid is designed based
>>>> on the collective load requirements of all clients sharing the same power
>>>> rail.
>>>>
>>>> Since regulators can operate in multiple modes for power optimization, each
>>>> consumer is expected to vote for its runtime power needs. These votes help
>>>> the regulator framework maintain the regulator in the appropriate mode,
>>>> ensuring stable and efficient operation across all clients.
>>>>
>>>>
>>>> Stability issues can arise if each consumer does not vote for its own load
>>>> requirement.
>>>> For example, consider a scenario where a single regulator is shared by two
>>>> consumers.
>>>>
>>>> If the first client requests low-power mode by voting for zero or a minimal
>>>> load to regulator framework during its driver's LPM sequence, and the second
>>>> client (e.g., UFS PHY) has not voted for its own load requirement through
>>>> the regulator framework, the regulator may transition to low-power mode.
>>>> This can lead to issues for the second client, which expects a higher power
>>>> state to operate correctly.
>>>>
>>>
>>> I think we all agree on consumers setting the load for shared regulators, but
>>> the naming and description of the DT property is what causing confusion here.
>>> There is no way the consumers can set the *max* current draw for a shared
>>> regulator. They can only request load as per their requirement. But the max
>>> current draw is a regulator constraint.
>>
>> To avoid confusion with regulator-level constraints, I'm open to renaming
>> the property vdda-phy-max-microamp to something more descriptive, such as
>> vdda-phy-client-peak-load-microamp or vdda-phy-peak-load-microamp. Along
>> with updating the description, this would better reflect the property's
>> actual intent: to specify the maximum current a client may draw during peak
>> operation, rather than implying it defines the regulator?s maximum
>> capability.
> 
> Move them into the driver please.

Sure Dmitry. I?ll will take care of this in next patchset.

Thanks,
Nitin


> 
>>
>>
>> Having said that, I had a follow-up discussion with the PHY designer to
>> confirm whether this value could vary at the board level. Based on their
>> response, it's a fixed value for the SoC and does not change across
>> different boards(atleast for now). Therefore, I can remove from device tree
>> and replaced with hardcoded, per-compatible data in the driver.
>>
>>>
>>>>
>>>>>
>>>>>
>>>>>> supply's capabilities change depending on the maximum potential load
>>>>>> at any given time, which the regulator driver must be aware of)
>>>>>>
>>>>>> This is a property of a regulator *consumer*, i.e. if we had a chain
>>>>>> of LEDs hanging off of this supply, we'd need to specify NUM_LEDS *
>>>>>> MAX_CURR under the "led chain" device, to make sure that if the
>>>>>> aggregated current requirements go over a certain threshold (which is
>>>>>> unknown to Linux and hidden in RPMh fw), the regulator can be
>>>>>> reconfigured to allow for a higher current draw (likely at some
>>>>>> downgrade to efficiency)
>>>>>
>>>>>
>>>>> The problem is that rationale is downstream. Instead I want to see some
>>>>> reason: e.g. datasheets, spec, type of UFS device (that was the argument
>>>>> in the driver patch discussion).
>>>>
>>>>
>>>> The PHY load requirements for consumers such as UFS, USB, PCIe are defined
>>>> by Qualcomm?s PHY IP and are well-documented in Qualcomm?s datasheets and
>>>> power grid documentation. These values can depending on the process or
>>>> technology node, board design, and even the chip foundry used.
>>>>
>>>> As a result, the load values can differ across SoCs or may be even
>>>> board(unlikely though) due to variations in any of these parameters.
>>>>
>>>
>>> Okay. This goes into the commit message and possibly some part of it to property
>>> description also.
>>
>>
>>
>>
>>>
>>> - Mani
>>>
>>
> 



From robh at kernel.org  Wed Aug 13 13:49:12 2025
From: robh at kernel.org (Rob Herring (Arm))
Date: Wed, 13 Aug 2025 15:49:12 -0500
Subject: [PATCH 3/6] dt-bindings: phy: spacemit: introduce PCIe root
 complex
In-Reply-To: <20250813184701.2444372-4-elder@riscstar.com>
References: <20250813184701.2444372-1-elder@riscstar.com>
 <20250813184701.2444372-4-elder@riscstar.com>
Message-ID: <175511815210.798605.10564052572461813362.robh@kernel.org>


On Wed, 13 Aug 2025 13:46:57 -0500, Alex Elder wrote:
> Add the Device Tree binding for the PCIe root complex found on the
> SpacemiT K1 SoC.  This device is derived from the Synopsys Designware
> PCIe IP.  It supports up to three PCIe ports operating at PCIe gen 2
> link speeds (5 GT/sec).  One of the ports uses a combo PHY, which is
> typically used to support a USB 3 port.
> 
> Signed-off-by: Alex Elder <elder at riscstar.com>
> ---
>  .../bindings/pci/spacemit,k1-pcie-rc.yaml     | 141 ++++++++++++++++++
>  1 file changed, 141 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pci/spacemit,k1-pcie-rc.yaml
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/pci/spacemit,k1-pcie-rc.example.dtb: /example-0/pcie at ca000000: failed to match any schema with compatible: ['spacemit,k1-pcie-rc']

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20250813184701.2444372-4-elder at riscstar.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 quic_nitirawa at quicinc.com  Wed Aug 13 14:01:21 2025
From: quic_nitirawa at quicinc.com (Nitin Rawat)
Date: Thu, 14 Aug 2025 02:31:21 +0530
Subject: [PATCH V1 4/4] phy: qcom-qmp-ufs: read max-microamp values from
 device tree
In-Reply-To: <d072b19d-bc01-45c8-8cf3-bceb53ca9b2c@quicinc.com>
References: <20250806154340.20122-1-quic_nitirawa@quicinc.com>
 <20250806154340.20122-5-quic_nitirawa@quicinc.com>
 <f368b6da-1aa3-4b8e-9106-3c29d4ab5c5e@oss.qualcomm.com>
 <fe2bc07c-8fe9-47fd-bcd7-c2f0ebbd596f@sirena.org.uk>
 <aed1de56-fafe-4ccc-b542-69400b574def@oss.qualcomm.com>
 <acf89420-743b-4178-ac05-d4ca492bfee3@sirena.org.uk>
 <599b8a4b-324a-4543-ba27-0451f05c3dfd@quicinc.com>
 <3aa82f65-4812-4bf0-9323-96f40824a004@sirena.org.uk>
 <8c7f8cfc-2090-449e-b6ec-688a0021bac4@oss.qualcomm.com>
 <14566f49-7f7b-4583-98b7-8a473054f7c3@sirena.org.uk>
 <kwp3q4r5rzahzro5f6l6ml24vbiutyxokrhjsbtzcb5kvanx5e@elagxv6w5dq7>
 <d072b19d-bc01-45c8-8cf3-bceb53ca9b2c@quicinc.com>
Message-ID: <2dc54d35-4811-4153-bd36-843a374d9c4f@quicinc.com>



On 8/12/2025 1:18 AM, Nitin Rawat wrote:
> 
> 
> On 8/11/2025 9:20 PM, Bjorn Andersson wrote:
>> On Thu, Aug 07, 2025 at 08:09:56PM +0100, Mark Brown wrote:
>>> On Thu, Aug 07, 2025 at 07:43:15PM +0200, Konrad Dybcio wrote:
>>>> On 8/7/25 7:26 PM, Mark Brown wrote:
>>>
>>>>> Note that that's specifying OPPs which is different...
>>>
>>>> The microamp properties are in the top-level, not under OPP if
>>>> that's what you meant
>>>
>>> I mean the OPPs use case is an existing well known one for dumping stuff
>>> into DT.
>>>
>>>>> That doesn't mean that it's a good idea to put that information in the
>>>>> DT, nor if it is sensible to put in DT does it mean that it's a good
>>>>> idea to define a generic property that applies to all regulator
>>>>> consumers which is what I now think Konrad is proposing.
>>>
>>>> Yeah, that's what I had in mind
>>>
>>>> I was never able to get a reliable source for those numbers myselfe
>>>> either.. At least some of them are prooooobably? chosen based on the
>>>> used regulator type, to ensure it's always in HPM..
>>>
>>> That's what set_mode() is for.? Like I say it's becoming less and less
>>> relevant though.
>>>
>>
>> set_mode() just applies the mode to the regulator_dev, so in cases where
>> you have multiple consumers of a regulator_dev things would break.
>>
>> Further, there are numerous cases where we have multiple consumers each
>> needing a "low" mode, but their combined load requires a "high" mode.
>>
>> set_load() and its aggregation of the inputs deals with both of these
>> issues.
>>
>>
>> Whether mode setting is becoming less relevant in our hardware, that I
>> don't have the definitive answer to.
>>
>>>> That said, our drivers cover a wide variety of hardware, built on a
>>>> wide variety of process nodes, with different configurations, etc.,
>>>> so it's either polluting the DT, or polluting the driver with
>>>> per-compatible hardcoded data (and additional compatibles because
>>>> fallbacks wouldn't work most of the time)
>>
>> If this is our reason for putting it in DeviceTree, then we should write
>> that in the commit message :)
>>
>>>
>>> That's really not a persuasive argument for adding a genric property
>>> that applies to all regulator consumers...
>>>
>>
>> I agree, even if we determine that this belongs in DT, because it needs
>> to be tweaked on a per-board basis, it's still only applicable to a
>> fraction of our device nodes.
> 
> Hi Bjorn & Mark,
> 
> I had a follow-up discussion with the PHY designer to confirm whether 
> this value could vary at the board level. Based on their response, it's 
> a fixed value for the SoC and remains consistent across different 
> boards. Therefore, I'm comfortable removing it from the device tree and 
> using hardcoded, per-compatible data in the driver.
> 
> The only concern is that this approach may lead to driver bloat over 
> time, as more SoCs are added and each requires its own hardcoded 
> configuration.
> 
> Regards,
> Nitin
> 
> 
Based on the current understanding, I plan to post a revised patch that 
uses hardcoded, per-compatible data within the driver, rather than 
specifying it in the device tree. Please let me know if anyone has any 
concerns with this approach.

Thanks,
Nitin


> 
> 
> 
> 
>>
>> Regards,
>> Bjorn
>>
>>> My instinct with this stuff is generally to avoid putting it in the DT,
>>> we see far too many instances where someone's typed some numbers in
>>> wrongly or discovers the ability to drive the hardware harder and needs
>>> to tune the numbers - once something is ABI you're stuck just trusting
>>> the numbers.? That said I'm not going to stop you putting something
>>> specific to this driver in there, I just don't think this is a good idea
>>> as a generic property.
>>
> 



From elder at riscstar.com  Wed Aug 13 14:21:22 2025
From: elder at riscstar.com (Alex Elder)
Date: Wed, 13 Aug 2025 16:21:22 -0500
Subject: [PATCH 3/6] dt-bindings: phy: spacemit: introduce PCIe root
 complex
In-Reply-To: <175511815210.798605.10564052572461813362.robh@kernel.org>
References: <20250813184701.2444372-1-elder@riscstar.com>
 <20250813184701.2444372-4-elder@riscstar.com>
 <175511815210.798605.10564052572461813362.robh@kernel.org>
Message-ID: <8ebc466c-1b9f-4ba3-a38e-bda6007c5b97@riscstar.com>

On 8/13/25 3:49 PM, Rob Herring (Arm) wrote:
> 
> On Wed, 13 Aug 2025 13:46:57 -0500, Alex Elder wrote:
>> Add the Device Tree binding for the PCIe root complex found on the
>> SpacemiT K1 SoC.  This device is derived from the Synopsys Designware
>> PCIe IP.  It supports up to three PCIe ports operating at PCIe gen 2
>> link speeds (5 GT/sec).  One of the ports uses a combo PHY, which is
>> typically used to support a USB 3 port.
>>
>> Signed-off-by: Alex Elder <elder at riscstar.com>
>> ---
>>   .../bindings/pci/spacemit,k1-pcie-rc.yaml     | 141 ++++++++++++++++++
>>   1 file changed, 141 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/pci/spacemit,k1-pcie-rc.yaml
>>
> 
> My bot found errors running 'make dt_binding_check' on your patch:

Mine didn't for some reason, so I must be doing something wrong.

Simple inspection shows my compatible string contains ".yaml"!

I'll fix in a new version.  Sorry I missed this.

					-Alex

> yamllint warnings/errors:
> 
> dtschema/dtc warnings/errors:
> Documentation/devicetree/bindings/pci/spacemit,k1-pcie-rc.example.dtb: /example-0/pcie at ca000000: failed to match any schema with compatible: ['spacemit,k1-pcie-rc']
> 
> doc reference errors (make refcheckdocs):
> 
> See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20250813184701.2444372-4-elder at riscstar.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 helgaas at kernel.org  Wed Aug 13 14:22:19 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Wed, 13 Aug 2025 16:22:19 -0500
Subject: [PATCH 5/6] PCI: spacemit: introduce SpacemiT PCIe host driver
In-Reply-To: <20250813184701.2444372-6-elder@riscstar.com>
Message-ID: <20250813212219.GA294849@bhelgaas>

On Wed, Aug 13, 2025 at 01:46:59PM -0500, Alex Elder wrote:
> Introduce a driver for the PCIe root complex found in the SpacemiT
> K1 SoC.  The hardware is derived from the Synopsys DesignWare PCIe IP.
> The driver supports three PCIe ports that operate at PCIe v2 transfer
> rates (5 GT/sec).  The first port uses a combo PHY, which may be
> configured for use for USB 3 instead.

I assume "PCIe v2" means what most people call "PCIe gen2", but the
spec encourages avoidance "genX" because it's ambiguous.

> +config PCIE_K1
> +	bool "SpacemiT K1 host mode PCIe controller"

Style of nearby entries is:

  "SpacemiT K1 PCIe controller (host mode)"

Please alphabetize by the company name ("SpacemiT") in the menu entry.

> +#define K1_PCIE_VENDOR_ID	0x201f
> +#define K1_PCIE_DEVICE_ID	0x0001

I assume this (0x201f) has been reserved by the PCI-SIG?  I don't see
it at:

  https://pcisig.com/membership/member-companies?combine=0x201f

Possibly rename this to PCI_VENDOR_ID_K1 (or maybe
PCI_VENDOR_ID_SPACEMIT?) to match the usual format in
include/linux/pci_ids.h, since it seems likely to end up there
eventually.

> +#define PCIE_RC_PERST			BIT(12)	/* 0: PERST# high; 1: low */

Maybe avoid confusion by describing as "1: assert PERST#" or similar?

> +	/* Wait the PCIe-mandated 100 msec before deasserting PERST# */
> +	mdelay(100);

I think this is PCIE_T_PVPERL_MS.  Comment is superfluous then.

> +static int k1_pcie_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct dw_pcie_rp *pp;
> +	struct dw_pcie *pci;
> +	struct k1_pcie *k1;
> +	int ret;
> +
> +	k1 = devm_kzalloc(dev, sizeof(*k1), GFP_KERNEL);
> +	if (!k1)
> +		return -ENOMEM;
> +	dev_set_drvdata(dev, k1);

Most neighboring drivers use platform_set_drvdata().  Personally, I
would set drvdata after initializing k1 because I don't like to
advertise pointers to uninitialized things.

> +static void k1_pcie_remove(struct platform_device *pdev)
> +{
> +	struct k1_pcie *k1 = dev_get_drvdata(&pdev->dev);

Neighbors use platform_get_drvdata().

> +	struct dw_pcie_rp *pp = &k1->pci.pp;
> +
> +	dw_pcie_host_deinit(pp);
> +}


From elder at riscstar.com  Wed Aug 13 14:27:22 2025
From: elder at riscstar.com (Alex Elder)
Date: Wed, 13 Aug 2025 16:27:22 -0500
Subject: [PATCH 5/6] PCI: spacemit: introduce SpacemiT PCIe host driver
In-Reply-To: <20250813212219.GA294849@bhelgaas>
References: <20250813212219.GA294849@bhelgaas>
Message-ID: <5d5eacff-4c32-4df4-8da0-3b55974b74aa@riscstar.com>

On 8/13/25 4:22 PM, Bjorn Helgaas wrote:
> On Wed, Aug 13, 2025 at 01:46:59PM -0500, Alex Elder wrote:
>> Introduce a driver for the PCIe root complex found in the SpacemiT
>> K1 SoC.  The hardware is derived from the Synopsys DesignWare PCIe IP.
>> The driver supports three PCIe ports that operate at PCIe v2 transfer
>> rates (5 GT/sec).  The first port uses a combo PHY, which may be
>> configured for use for USB 3 instead.
> 
> I assume "PCIe v2" means what most people call "PCIe gen2", but the
> spec encourages avoidance "genX" because it's ambiguous.

Yes, that's what I meant, but I did try to clarify with the
transfer rate.

>> +config PCIE_K1
>> +	bool "SpacemiT K1 host mode PCIe controller"
> 
> Style of nearby entries is:
> 
>    "SpacemiT K1 PCIe controller (host mode)"

OK I'll fix that.

> Please alphabetize by the company name ("SpacemiT") in the menu entry.

OK.

>> +#define K1_PCIE_VENDOR_ID	0x201f
>> +#define K1_PCIE_DEVICE_ID	0x0001
> 
> I assume this (0x201f) has been reserved by the PCI-SIG?  I don't see
> it at:
> 
>    https://pcisig.com/membership/member-companies?combine=0x201f

I hadn't even thought to check that.  I will follow up.  Thanks
for pointing this out.

> Possibly rename this to PCI_VENDOR_ID_K1 (or maybe
> PCI_VENDOR_ID_SPACEMIT?) to match the usual format in
> include/linux/pci_ids.h, since it seems likely to end up there
> eventually.

OK.

>> +#define PCIE_RC_PERST			BIT(12)	/* 0: PERST# high; 1: low */
> 
> Maybe avoid confusion by describing as "1: assert PERST#" or similar?

OK.  I struggled with how to express this to avoid confusion.
But I do think "assert PERST#" is better.

>> +	/* Wait the PCIe-mandated 100 msec before deasserting PERST# */
>> +	mdelay(100);
> 
> I think this is PCIE_T_PVPERL_MS.  Comment is superfluous then.

Excellent, thank you, I'll use that.

>> +static int k1_pcie_probe(struct platform_device *pdev)
>> +{
>> +	struct device *dev = &pdev->dev;
>> +	struct dw_pcie_rp *pp;
>> +	struct dw_pcie *pci;
>> +	struct k1_pcie *k1;
>> +	int ret;
>> +
>> +	k1 = devm_kzalloc(dev, sizeof(*k1), GFP_KERNEL);
>> +	if (!k1)
>> +		return -ENOMEM;
>> +	dev_set_drvdata(dev, k1);
> 
> Most neighboring drivers use platform_set_drvdata().  Personally, I
> would set drvdata after initializing k1 because I don't like to
> advertise pointers to uninitialized things.

OK, I understand that and will do it the way you suggest.

>> +static void k1_pcie_remove(struct platform_device *pdev)
>> +{
>> +	struct k1_pcie *k1 = dev_get_drvdata(&pdev->dev);
> 
> Neighbors use platform_get_drvdata().

Yes, that goes with platform_set_drvdata().

>> +	struct dw_pcie_rp *pp = &k1->pci.pp;
>> +
>> +	dw_pcie_host_deinit(pp);
>> +}

Thank you very much for your review.

					-Alex


From helgaas at kernel.org  Wed Aug 13 16:07:33 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Wed, 13 Aug 2025 18:07:33 -0500
Subject: [PATCH v3 05/12] PCI: exynos: Add resource ops, soc variant and
 device mode
In-Reply-To: <20250811154638.95732-6-shradha.t@samsung.com>
Message-ID: <20250813230733.GA299608@bhelgaas>

On Mon, Aug 11, 2025 at 09:16:31PM +0530, Shradha Todi wrote:
> Some resources might differ based on platforms and we need platform
> specific functions to initialize or alter them. For better code
> re-usability, making a separate res_ops which will hold all such
> function pointers or other resource specific data. Include ops like
>  - init_regulator (initialize the regulator data)
>  - pcie_irq_handler (interrupt handler for PCIe)
>  - set_device_mode (set device mode to EP or RC)
> 
> Some operations maybe specific to certain SoCs and not applicable
> to others. For such use cases, adding an SoC variant data field
> which can be used to distinguish between the variants.
> 
> Some SoCs may have dual-role PCIe controller which can work as
> RC or EP. Add device_mode to store the role and take decisions
> accordingly.
> 
> Make enable/disable of regulator and initialization of IRQ as
> common functions to be used by all Samsung SoCs.

As hinted above, this patch ends up being a mixture of several things
that makes this kind of hard to review.  Separating these into their
own patches would make it easier.

> Suggested-by: Pankaj Dubey <pankaj.dubey at samsung.com>
> Signed-off-by: Shradha Todi <shradha.t at samsung.com>
> ---
>  drivers/pci/controller/dwc/pci-exynos.c | 143 +++++++++++++++++++-----
>  1 file changed, 116 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pci-exynos.c b/drivers/pci/controller/dwc/pci-exynos.c
> index c830b20d54f0..ef1f42236575 100644
> --- a/drivers/pci/controller/dwc/pci-exynos.c
> +++ b/drivers/pci/controller/dwc/pci-exynos.c
> @@ -49,10 +49,18 @@
>  #define EXYNOS_PCIE_ELBI_SLV_ARMISC		0x120
>  #define EXYNOS_PCIE_ELBI_SLV_DBI_ENABLE		BIT(21)
>  
> +/* to store different SoC variants of Samsung */
> +enum samsung_pcie_variants {
> +	EXYNOS_5433,
> +};
> +
>  struct samsung_pcie_pdata {
>  	struct pci_ops				*pci_ops;
>  	const struct dw_pcie_ops		*dwc_ops;
>  	const struct dw_pcie_host_ops		*host_ops;
> +	const struct samsung_res_ops		*res_ops;
> +	unsigned int				soc_variant;
> +	enum dw_pcie_device_mode		device_mode;
>  };
>  
>  struct exynos_pcie {
> @@ -61,7 +69,14 @@ struct exynos_pcie {
>  	const struct samsung_pcie_pdata	*pdata;
>  	struct clk_bulk_data		*clks;
>  	struct phy			*phy;
> -	struct regulator_bulk_data	supplies[2];
> +	struct regulator_bulk_data	*supplies;
> +	int				supplies_cnt;
> +};
> +
> +struct samsung_res_ops {
> +	int (*init_regulator)(struct exynos_pcie *ep);
> +	irqreturn_t (*pcie_irq_handler)(int irq, void *arg);
> +	void (*set_device_mode)(struct exynos_pcie *ep);
>  };
>  
>  static void exynos_pcie_writel(void __iomem *base, u32 val, u32 reg)
> @@ -74,6 +89,31 @@ static u32 exynos_pcie_readl(void __iomem *base, u32 reg)
>  	return readl(base + reg);
>  }
>  
> +static int samsung_regulator_enable(struct exynos_pcie *ep)
> +{
> +	int ret;
> +
> +	if (ep->supplies_cnt == 0)
> +		return 0;
> +
> +	ret = regulator_bulk_enable(ep->supplies_cnt, ep->supplies);
> +
> +	return ret;

Unless you want a warning here, there's no need for "ret":

  return regulator_bulk_enable(ep->supplies_cnt, ep->supplies);

> +}
> +
> +static void samsung_regulator_disable(struct exynos_pcie *ep)
> +{
> +	struct device *dev = ep->pci.dev;
> +	int ret;
> +
> +	if (ep->supplies_cnt == 0)
> +		return;
> +
> +	ret = regulator_bulk_disable(ep->supplies_cnt, ep->supplies);
> +	if (ret)
> +		dev_warn(dev, "failed to disable regulators: %d\n", ret);
> +}
> +
>  static void exynos_pcie_sideband_dbi_w_mode(struct exynos_pcie *ep, bool on)
>  {
>  	u32 val;
> @@ -244,7 +284,26 @@ static const struct dw_pcie_host_ops exynos_pcie_host_ops = {
>  	.init = exynos_pcie_host_init,
>  };
>  
> -static int exynos_add_pcie_port(struct exynos_pcie *ep,
> +static int exynos_init_regulator(struct exynos_pcie *ep)
> +{
> +	struct device *dev = ep->pci.dev;
> +	int ret = 0;
> +
> +	ep->supplies_cnt = 2;
> +
> +	ep->supplies = devm_kcalloc(dev, ep->supplies_cnt, sizeof(*ep->supplies), GFP_KERNEL);
> +	if (!ep->supplies)
> +		return -ENOMEM;
> +
> +	ep->supplies[0].supply = "vdd18";
> +	ep->supplies[1].supply = "vdd10";
> +
> +	ret = devm_regulator_bulk_get(dev, ep->supplies_cnt, ep->supplies);
> +
> +	return ret;

No need for ret.

> +}
> +
> +static int samsung_irq_init(struct exynos_pcie *ep,
>  				       struct platform_device *pdev)
>  {
>  	struct dw_pcie *pci = &ep->pci;
> @@ -256,22 +315,15 @@ static int exynos_add_pcie_port(struct exynos_pcie *ep,
>  	if (pp->irq < 0)
>  		return pp->irq;
>  
> -	ret = devm_request_irq(dev, pp->irq, exynos_pcie_irq_handler,
> +	ret = devm_request_irq(dev, pp->irq, ep->pdata->res_ops->pcie_irq_handler,
>  			       IRQF_SHARED, "exynos-pcie", ep);
>  	if (ret) {
>  		dev_err(dev, "failed to request irq\n");
>  		return ret;
>  	}
>  
> -	pp->ops = &exynos_pcie_host_ops;
>  	pp->msi_irq[0] = -ENODEV;
>  
> -	ret = dw_pcie_host_init(pp);
> -	if (ret) {
> -		dev_err(dev, "failed to initialize host\n");
> -		return ret;
> -	}
> -
>  	return 0;
>  }
>  
> @@ -282,6 +334,11 @@ static const struct dw_pcie_ops exynos_dw_pcie_ops = {
>  	.start_link = exynos_pcie_start_link,
>  };
>  
> +static const struct samsung_res_ops exynos_res_ops_data = {
> +	.init_regulator		= exynos_init_regulator,
> +	.pcie_irq_handler	= exynos_pcie_irq_handler,
> +};
> +
>  static int exynos_pcie_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> @@ -313,28 +370,46 @@ static int exynos_pcie_probe(struct platform_device *pdev)
>  	if (ret < 0)
>  		return ret;
>  
> -	ep->supplies[0].supply = "vdd18";
> -	ep->supplies[1].supply = "vdd10";
> -	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ep->supplies),
> -				      ep->supplies);
> -	if (ret)
> -		return ret;
> +	if (pdata->res_ops && pdata->res_ops->init_regulator) {
> +		ret = ep->pdata->res_ops->init_regulator(ep);
> +		if (ret)
> +			return ret;
> +	}
>  
> -	ret = regulator_bulk_enable(ARRAY_SIZE(ep->supplies), ep->supplies);
> +	ret = samsung_regulator_enable(ep);
>  	if (ret)
>  		return ret;
>  
>  	platform_set_drvdata(pdev, ep);
>  
> -	ret = exynos_add_pcie_port(ep, pdev);
> -	if (ret < 0)
> -		goto fail_probe;
> +	if (pdata->res_ops && pdata->res_ops->set_device_mode)
> +		pdata->res_ops->set_device_mode(ep);
> +
> +	switch (ep->pdata->device_mode) {
> +	case DW_PCIE_RC_TYPE:
> +		ret = samsung_irq_init(ep, pdev);
> +		if (ret)
> +			goto fail_regulator;
> +
> +		ep->pci.pp.ops = pdata->host_ops;
> +
> +		ret = dw_pcie_host_init(&ep->pci.pp);
> +		if (ret < 0)
> +			goto fail_phy_init;
> +
> +		break;
> +	default:
> +		dev_err(dev, "invalid device type\n");
> +		ret = -EINVAL;
> +		goto fail_regulator;
> +	}
>  
>  	return 0;
>  
> -fail_probe:
> +fail_phy_init:
>  	phy_exit(ep->phy);
> -	regulator_bulk_disable(ARRAY_SIZE(ep->supplies), ep->supplies);
> +fail_regulator:
> +	samsung_regulator_disable(ep);
>  
>  	return ret;
>  }
> @@ -343,21 +418,29 @@ static void exynos_pcie_remove(struct platform_device *pdev)
>  {
>  	struct exynos_pcie *ep = platform_get_drvdata(pdev);
>  
> +	if (ep->pdata->device_mode == DW_PCIE_EP_TYPE)
> +		return;
>  	dw_pcie_host_deinit(&ep->pci.pp);
> -	exynos_pcie_assert_core_reset(ep);
> +	if (ep->pdata->soc_variant == EXYNOS_5433)
> +		exynos_pcie_assert_core_reset(ep);

I think it's a mistake to test for specific soc_variants.  Better to
test a *property* (or use a function pointer than can be SoC-specific)
because it's likely that several SoCs will share the same property.

>  	phy_power_off(ep->phy);
>  	phy_exit(ep->phy);
> -	regulator_bulk_disable(ARRAY_SIZE(ep->supplies), ep->supplies);
> +	samsung_regulator_disable(ep);
>  }
>  
>  static int exynos_pcie_suspend_noirq(struct device *dev)
>  {
>  	struct exynos_pcie *ep = dev_get_drvdata(dev);
> +	struct dw_pcie *pci = &ep->pci;
>  
> -	exynos_pcie_assert_core_reset(ep);
> +	if (ep->pdata->device_mode == DW_PCIE_EP_TYPE)
> +		return 0;
> +
> +	if (ep->pdata->soc_variant == EXYNOS_5433)
> +		exynos_pcie_assert_core_reset(ep);
>  	phy_power_off(ep->phy);
>  	phy_exit(ep->phy);
> -	regulator_bulk_disable(ARRAY_SIZE(ep->supplies), ep->supplies);
> +	samsung_regulator_disable(ep);
>  
>  	return 0;
>  }
> @@ -369,7 +452,10 @@ static int exynos_pcie_resume_noirq(struct device *dev)
>  	struct dw_pcie_rp *pp = &pci->pp;
>  	int ret;
>  
> -	ret = regulator_bulk_enable(ARRAY_SIZE(ep->supplies), ep->supplies);
> +	if (ep->pdata->device_mode == DW_PCIE_EP_TYPE)
> +		return 0;
> +
> +	ret = samsung_regulator_enable(ep);
>  	if (ret)
>  		return ret;
>  
> @@ -389,6 +475,9 @@ static const struct samsung_pcie_pdata exynos_5433_pcie_rc_pdata = {
>  	.dwc_ops		= &exynos_dw_pcie_ops,
>  	.pci_ops		= &exynos_pci_ops,
>  	.host_ops		= &exynos_pcie_host_ops,
> +	.res_ops		= &exynos_res_ops_data,
> +	.soc_variant		= EXYNOS_5433,
> +	.device_mode		= DW_PCIE_RC_TYPE,
>  };
>  
>  static const struct of_device_id exynos_pcie_of_match[] = {
> -- 
> 2.49.0
> 


From helgaas at kernel.org  Wed Aug 13 16:07:44 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Wed, 13 Aug 2025 18:07:44 -0500
Subject: [PATCH v3 11/12] PCI: exynos: Add support for Tesla FSD SoC
In-Reply-To: <20250811154638.95732-12-shradha.t@samsung.com>
Message-ID: <20250813230744.GA299971@bhelgaas>

On Mon, Aug 11, 2025 at 09:16:37PM +0530, Shradha Todi wrote:
> Add host and endpoint controller driver support for FSD SoC.

I think this might be easier if you added host mode first, then added
endpoint mode with a separate patch.

It's kind of unfortunate that the driver uses "ep" everywhere for
struct exynos_pcie pointers.  It's going to be confusing because "ep"
is also commonly used for endpoint-related things, e.g., struct
dw_pcie_ep pointers.  Maybe it's not worth changing; I dunno.

> Signed-off-by: Shradha Todi <shradha.t at samsung.com>
> ---
>  drivers/pci/controller/dwc/pci-exynos.c | 278 ++++++++++++++++++++++++
>  1 file changed, 278 insertions(+)
> 
> diff --git a/drivers/pci/controller/dwc/pci-exynos.c b/drivers/pci/controller/dwc/pci-exynos.c
> index ef1f42236575..9aabfecdc147 100644
> --- a/drivers/pci/controller/dwc/pci-exynos.c
> +++ b/drivers/pci/controller/dwc/pci-exynos.c
> @@ -18,6 +18,8 @@
>  #include <linux/platform_device.h>
>  #include <linux/phy/phy.h>
>  #include <linux/regulator/consumer.h>
> +#include <linux/regmap.h>
> +#include <linux/mfd/syscon.h>
>  #include <linux/mod_devicetable.h>
>  #include <linux/module.h>
>  
> @@ -49,15 +51,35 @@
>  #define EXYNOS_PCIE_ELBI_SLV_ARMISC		0x120
>  #define EXYNOS_PCIE_ELBI_SLV_DBI_ENABLE		BIT(21)
>  
> +#define FSD_IRQ2_STS				0x008
> +#define FSD_IRQ_MSI_ENABLE			BIT(17)
> +#define FSD_IRQ2_EN				0x018
> +#define FSD_PCIE_APP_LTSSM_ENABLE		0x054
> +#define FSD_PCIE_LTSSM_ENABLE			0x1
> +#define FSD_PCIE_DEVICE_TYPE			0x080
> +#define FSD_DEVICE_TYPE_RC			0x4
> +#define FSD_DEVICE_TYPE_EP			0x0
> +#define FSD_PCIE_CXPL_DEBUG_00_31		0x2c8
> +
>  /* to store different SoC variants of Samsung */
>  enum samsung_pcie_variants {
> +	FSD,
>  	EXYNOS_5433,
>  };
>  
> +/* Values to be written to SYSREG to view DBI space as CDM/DBI2/IATU/DMA */
> +enum fsd_pcie_addr_type {
> +	ADDR_TYPE_DBI = 0x0,
> +	ADDR_TYPE_DBI2 = 0x12,
> +	ADDR_TYPE_ATU = 0x36,
> +	ADDR_TYPE_DMA = 0x3f,
> +};
> +
>  struct samsung_pcie_pdata {
>  	struct pci_ops				*pci_ops;
>  	const struct dw_pcie_ops		*dwc_ops;
>  	const struct dw_pcie_host_ops		*host_ops;
> +	const struct dw_pcie_ep_ops		*ep_ops;
>  	const struct samsung_res_ops		*res_ops;
>  	unsigned int				soc_variant;
>  	enum dw_pcie_device_mode		device_mode;
> @@ -67,6 +89,8 @@ struct exynos_pcie {
>  	struct dw_pcie			pci;
>  	void __iomem			*elbi_base;
>  	const struct samsung_pcie_pdata	*pdata;
> +	struct regmap			*sysreg;
> +	unsigned int			sysreg_offset;
>  	struct clk_bulk_data		*clks;
>  	struct phy			*phy;
>  	struct regulator_bulk_data	*supplies;
> @@ -334,11 +358,201 @@ static const struct dw_pcie_ops exynos_dw_pcie_ops = {
>  	.start_link = exynos_pcie_start_link,
>  };
>  
> +static void fsd_pcie_stop_link(struct dw_pcie *pci)
> +{
> +	u32 val;
> +	struct exynos_pcie *ep = to_exynos_pcie(pci);
> +
> +	val = readl(ep->elbi_base + FSD_PCIE_APP_LTSSM_ENABLE);
> +	val &= ~FSD_PCIE_LTSSM_ENABLE;
> +	writel(val, ep->elbi_base + FSD_PCIE_APP_LTSSM_ENABLE);
> +}
> +
> +static int fsd_pcie_start_link(struct dw_pcie *pci)
> +{
> +	struct exynos_pcie *ep = to_exynos_pcie(pci);
> +	struct dw_pcie_ep *dw_ep = &pci->ep;
> +
> +	if (dw_pcie_link_up(pci))
> +		return 0;
> +
> +	writel(FSD_PCIE_LTSSM_ENABLE, ep->elbi_base + FSD_PCIE_APP_LTSSM_ENABLE);
> +
> +	/* no need to wait for link in case of host as core files take care */
> +	if (ep->pdata->device_mode == DW_PCIE_RC_TYPE)
> +		return 0;
> +
> +	/* check if the link is up or not in case of EP */
> +	if (!dw_pcie_wait_for_link(pci)) {
> +		dw_pcie_ep_linkup(dw_ep);
> +		return 0;
> +	}
> +
> +	return -ETIMEDOUT;
> +}
> +
> +static irqreturn_t fsd_pcie_irq_handler(int irq, void *arg)
> +{
> +	u32 val;
> +	struct exynos_pcie *ep = arg;
> +	struct dw_pcie *pci = &ep->pci;
> +	struct dw_pcie_rp *pp = &pci->pp;
> +
> +	val = readl(ep->elbi_base + FSD_IRQ2_STS);
> +	if ((val & FSD_IRQ_MSI_ENABLE) == FSD_IRQ_MSI_ENABLE) {
> +		val &= FSD_IRQ_MSI_ENABLE;
> +		writel(val, ep->elbi_base + FSD_IRQ2_STS);

This looks weird because FSD_IRQ_MSI_ENABLE sounds like an *enable*
bit, but here you're treating it as a *status* bit.

As far as I can tell, you set FSD_IRQ_MSI_ENABLE once at probe-time in
fsd_pcie_msi_init(), then you clear it here in an IRQ handler, and it
will never be set again.  That seems wrong; am I missing something?

> +		dw_handle_msi_irq(pp);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static void fsd_pcie_msi_init(struct exynos_pcie *ep)
> +{
> +	int val;
> +
> +	val = readl(ep->elbi_base + FSD_IRQ2_EN);
> +	val |= FSD_IRQ_MSI_ENABLE;
> +	writel(val, ep->elbi_base + FSD_IRQ2_EN);
> +}
> +
> +static void __iomem *fsd_atu_setting(struct dw_pcie *pci, void __iomem *base)

The "setting" name suggests that this merely returns an address
without side effects, but in fact it actively *sets* the view.

In this case there's no locking around:

  addr = fsd_atu_setting(pci, base);
  dw_pcie_read(addr + reg, size, &val);

even though concurrent calls would cause issues, but I think that's OK
because we only get there via the driver, and I assume multiple DBI or
DBI2 accesses never happen because they're not used in asynchronous
paths like interrupt handlers.

But I think a name that hints at the fact that this does have side
effects would be helpful as a reminder in the callers that they must
not be used concurrently.

> +{
> +	struct exynos_pcie *ep = to_exynos_pcie(pci);
> +
> +	if (base >= pci->atu_base) {
> +		regmap_write(ep->sysreg, ep->sysreg_offset, ADDR_TYPE_ATU);
> +		return (base - DEFAULT_DBI_ATU_OFFSET);
> +	} else if (base == pci->dbi_base) {
> +		regmap_write(ep->sysreg, ep->sysreg_offset, ADDR_TYPE_DBI);
> +	} else if (base == pci->dbi_base2) {
> +		regmap_write(ep->sysreg, ep->sysreg_offset, ADDR_TYPE_DBI2);
> +	}
> +
> +	return base;
> +}
> +
> +static u32 fsd_pcie_read_dbi(struct dw_pcie *pci, void __iomem *base,
> +				u32 reg, size_t size)
> +{
> +	void __iomem *addr;
> +	u32 val;
> +
> +	addr = fsd_atu_setting(pci, base);
> +	dw_pcie_read(addr + reg, size, &val);
> +
> +	return val;
> +}
> +
> +static void fsd_pcie_write_dbi(struct dw_pcie *pci, void __iomem *base,
> +				u32 reg, size_t size, u32 val)
> +{
> +	void __iomem *addr;
> +
> +	addr = fsd_atu_setting(pci, base);
> +	dw_pcie_write(addr + reg, size, val);
> +}
> +
> +static void fsd_pcie_write_dbi2(struct dw_pcie *pci, void __iomem *base,
> +				u32 reg, size_t size, u32 val)
> +{
> +	struct exynos_pcie *ep = to_exynos_pcie(pci);
> +
> +	fsd_atu_setting(pci, base);
> +	dw_pcie_write(pci->dbi_base + reg, size, val);
> +	regmap_write(ep->sysreg, ep->sysreg_offset, ADDR_TYPE_DBI);
> +}
> +
> +static bool fsd_pcie_link_up(struct dw_pcie *pci)
> +{
> +	u32 val;
> +	struct exynos_pcie *ep = to_exynos_pcie(pci);
> +
> +	val = readl(ep->elbi_base + FSD_PCIE_CXPL_DEBUG_00_31);
> +	val &= PORT_LOGIC_LTSSM_STATE_MASK;
> +
> +	return (val == PORT_LOGIC_LTSSM_STATE_L0);
> +}
> +
> +static int fsd_pcie_host_init(struct dw_pcie_rp *pp)
> +{
> +	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> +	struct exynos_pcie *ep = to_exynos_pcie(pci);
> +
> +	phy_init(ep->phy);
> +	fsd_pcie_msi_init(ep);
> +
> +	return 0;
> +}
> +
> +static const struct dw_pcie_host_ops fsd_pcie_host_ops = {
> +	.init = fsd_pcie_host_init,
> +};
> +
> +static int fsd_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
> +				 unsigned int type, u16 interrupt_num)
> +{
> +	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
> +
> +	switch (type) {
> +	case PCI_IRQ_INTX:
> +		return dw_pcie_ep_raise_intx_irq(ep, func_no);
> +	case PCI_IRQ_MSIX:
> +		dev_err(pci->dev, "EP does not support MSI-X\n");
> +		return -EINVAL;
> +	case PCI_IRQ_MSI:
> +		return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num);
> +	default:
> +		dev_err(pci->dev, "UNKNOWN IRQ type\n");
> +	}
> +
> +	return 0;
> +}
> +
> +static const struct pci_epc_features fsd_pcie_epc_features = {
> +	.linkup_notifier = false,
> +	.msi_capable = true,
> +	.msix_capable = false,

I think we should omit features we do *not* support instead of calling
them out explicitly, e.g., we don't need .linkup_notifier or
.msix_capable.

We've added them in the past, but they're unnecessary and they lead to
either pervasive changes (adding ".new_feature = false" to all
existing drivers when adding the feature) or inconsistency (new
drivers include ".new_feature = false" but existing drivers do not).

> +};
> +
> +static const struct pci_epc_features *fsd_pcie_get_features(struct dw_pcie_ep *ep)
> +{
> +	return &fsd_pcie_epc_features;
> +}
> +
> +static const struct dw_pcie_ep_ops fsd_ep_ops = {
> +	.raise_irq	= fsd_pcie_raise_irq,
> +	.get_features	= fsd_pcie_get_features,
> +};
> +
> +static void fsd_set_device_mode(struct exynos_pcie *ep)
> +{
> +	if (ep->pdata->device_mode == DW_PCIE_RC_TYPE)
> +		writel(FSD_DEVICE_TYPE_RC, ep->elbi_base + FSD_PCIE_DEVICE_TYPE);
> +	else
> +		writel(FSD_DEVICE_TYPE_EP, ep->elbi_base + FSD_PCIE_DEVICE_TYPE);
> +}
> +
> +static const struct dw_pcie_ops fsd_dw_pcie_ops = {
> +	.read_dbi	= fsd_pcie_read_dbi,
> +	.write_dbi	= fsd_pcie_write_dbi,
> +	.write_dbi2	= fsd_pcie_write_dbi2,
> +	.start_link	= fsd_pcie_start_link,
> +	.stop_link	= fsd_pcie_stop_link,
> +	.link_up	= fsd_pcie_link_up,
> +};
> +
>  static const struct samsung_res_ops exynos_res_ops_data = {
>  	.init_regulator		= exynos_init_regulator,
>  	.pcie_irq_handler	= exynos_pcie_irq_handler,
>  };
>  
> +static const struct samsung_res_ops fsd_res_ops_data = {
> +	.pcie_irq_handler	= fsd_pcie_irq_handler,
> +	.set_device_mode	= fsd_set_device_mode,
> +};
> +
>  static int exynos_pcie_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> @@ -361,6 +575,26 @@ static int exynos_pcie_probe(struct platform_device *pdev)
>  	if (IS_ERR(ep->phy))
>  		return PTR_ERR(ep->phy);
>  
> +	if (ep->pdata->soc_variant == FSD) {
> +		ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(36));
> +		if (ret)
> +			return ret;
> +
> +		ep->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
> +				"samsung,syscon-pcie");
> +		if (IS_ERR(ep->sysreg)) {
> +			dev_err(dev, "sysreg regmap lookup failed.\n");
> +			return PTR_ERR(ep->sysreg);
> +		}
> +
> +		ret = of_property_read_u32_index(dev->of_node, "samsung,syscon-pcie", 1,
> +						 &ep->sysreg_offset);
> +		if (ret) {
> +			dev_err(dev, "couldn't get the register offset for syscon!\n");
> +			return ret;
> +		}
> +	}

This is a good example of a complicated set of things where I think
you should either add a SoC-specific function pointer to do this or
test a property, e.g., "DMA width", instead of testing for a specific
SoC.

>  	/* External Local Bus interface (ELBI) registers */
>  	ep->elbi_base = devm_platform_ioremap_resource_byname(pdev, "elbi");
>  	if (IS_ERR(ep->elbi_base))
> @@ -397,6 +631,22 @@ static int exynos_pcie_probe(struct platform_device *pdev)
>  		if (ret < 0)
>  			goto fail_phy_init;
>  
> +		break;
> +	case DW_PCIE_EP_TYPE:
> +		phy_init(ep->phy);
> +
> +		ep->pci.ep.ops = pdata->ep_ops;
> +
> +		ret = dw_pcie_ep_init(&ep->pci.ep);
> +		if (ret < 0)
> +			goto fail_phy_init;
> +
> +		ret = dw_pcie_ep_init_registers(&ep->pci.ep);
> +		if (ret)
> +			goto fail_phy_init;
> +
> +		pci_epc_init_notify(ep->pci.ep.epc);
> +
>  		break;
>  	default:
>  		dev_err(dev, "invalid device type\n");
> @@ -436,6 +686,9 @@ static int exynos_pcie_suspend_noirq(struct device *dev)
>  	if (ep->pdata->device_mode == DW_PCIE_EP_TYPE)
>  		return 0;
>  
> +	if (ep->pdata->dwc_ops->stop_link)
> +		ep->pdata->dwc_ops->stop_link(pci);
> +
>  	if (ep->pdata->soc_variant == EXYNOS_5433)
>  		exynos_pcie_assert_core_reset(ep);
>  	phy_power_off(ep->phy);
> @@ -471,6 +724,23 @@ static const struct dev_pm_ops exynos_pcie_pm_ops = {
>  				  exynos_pcie_resume_noirq)
>  };
>  
> +
> +static const struct samsung_pcie_pdata fsd_hw3_pcie_rc_pdata = {
> +	.dwc_ops		= &fsd_dw_pcie_ops,
> +	.host_ops		= &fsd_pcie_host_ops,
> +	.res_ops		= &fsd_res_ops_data,
> +	.soc_variant		= FSD,
> +	.device_mode		= DW_PCIE_RC_TYPE,
> +};
> +
> +static const struct samsung_pcie_pdata fsd_hw3_pcie_ep_pdata = {
> +	.dwc_ops		= &fsd_dw_pcie_ops,
> +	.ep_ops			= &fsd_ep_ops,
> +	.res_ops		= &fsd_res_ops_data,
> +	.soc_variant		= FSD,
> +	.device_mode		= DW_PCIE_EP_TYPE,
> +};
> +
>  static const struct samsung_pcie_pdata exynos_5433_pcie_rc_pdata = {
>  	.dwc_ops		= &exynos_dw_pcie_ops,
>  	.pci_ops		= &exynos_pci_ops,
> @@ -485,6 +755,14 @@ static const struct of_device_id exynos_pcie_of_match[] = {
>  		.compatible = "samsung,exynos5433-pcie",
>  		.data = (void *) &exynos_5433_pcie_rc_pdata,
>  	},
> +	{
> +		.compatible = "tesla,fsd-pcie",
> +		.data = (void *) &fsd_hw3_pcie_rc_pdata,
> +	},
> +	{
> +		.compatible = "tesla,fsd-pcie-ep",
> +		.data = (void *) &fsd_hw3_pcie_ep_pdata,
> +	},
>  	{ },
>  };
>  
> -- 
> 2.49.0
> 


From robh at kernel.org  Wed Aug 13 16:21:00 2025
From: robh at kernel.org (Rob Herring)
Date: Wed, 13 Aug 2025 18:21:00 -0500
Subject: [PATCH v4 4/8] dt-bindings: reset: renesas,rzg2l-usbphy-ctrl:
 Document RZ/G3S support
In-Reply-To: <20250808061806.2729274-5-claudiu.beznea.uj@bp.renesas.com>
References: <20250808061806.2729274-1-claudiu.beznea.uj@bp.renesas.com>
 <20250808061806.2729274-5-claudiu.beznea.uj@bp.renesas.com>
Message-ID: <20250813232100.GA950521-robh@kernel.org>

On Fri, Aug 08, 2025 at 09:18:02AM +0300, Claudiu wrote:
> From: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
> 
> The Renesas USB PHY hardware block needs to have the PWRRDY bit in the
> system controller set before applying any other settings. The PWRRDY bit
> must be controlled during power-on, power-off, and system suspend/resume
> sequences as follows:
> - during power-on/resume, it must be set to zero before enabling clocks and
>   modules
> - during power-off/suspend, it must be set to one after disabling clocks
>   and modules
> 
> Add the renesas,sysc-pwrrdy device tree property, which allows the
> reset-rzg2l-usbphy-ctrl driver to parse, map, and control the system
> controller PWRRDY bit at the appropriate time. Along with it add a new
> compatible for the RZ/G3S SoC.
> 
> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
> ---
> 
> Changes in v4:
> - dropped blank line from compatible section
> - s/renesas,sysc-signals/renesas,sysc-pwrrdy/g
> - dropped description from renesas,sysc-pwrrdy
> - updated description of renesas,sysc-pwrrdy items
> - updated patch description
> 
> Changes in v3:
> - none; this patch is new
> 
>  .../reset/renesas,rzg2l-usbphy-ctrl.yaml      | 40 ++++++++++++++++---
>  1 file changed, 34 insertions(+), 6 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml b/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml
> index b0b20af15313..c1d5f3228aa9 100644
> --- a/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml
> +++ b/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml
> @@ -15,12 +15,14 @@ description:
>  
>  properties:
>    compatible:
> -    items:
> -      - enum:
> -          - renesas,r9a07g043-usbphy-ctrl # RZ/G2UL and RZ/Five
> -          - renesas,r9a07g044-usbphy-ctrl # RZ/G2{L,LC}
> -          - renesas,r9a07g054-usbphy-ctrl # RZ/V2L
> -      - const: renesas,rzg2l-usbphy-ctrl
> +    oneOf:
> +      - items:
> +          - enum:
> +              - renesas,r9a07g043-usbphy-ctrl # RZ/G2UL and RZ/Five
> +              - renesas,r9a07g044-usbphy-ctrl # RZ/G2{L,LC}
> +              - renesas,r9a07g054-usbphy-ctrl # RZ/V2L
> +          - const: renesas,rzg2l-usbphy-ctrl
> +      - const: renesas,r9a08g045-usbphy-ctrl # RZ/G3S
>  
>    reg:
>      maxItems: 1
> @@ -48,6 +50,19 @@ properties:
>      $ref: /schemas/regulator/regulator.yaml#
>      unevaluatedProperties: false
>  
> +  renesas,sysc-pwrrdy:
> +    description: The system controller PWRRDY indicates to the USB PHY if the
> +                 power supply is ready. PWRRDY needs to be set during power-on
> +                 before applying any other settings. It also needs to
> +                 be set before powering off the USB.

Where did this odd formatting come from? If copied from somewhere else, 
patches reformatting them welcome.

    description:
      The system controller PWRRDY indicates to the USB PHY if the power 
      supply is ready. PWRRDY needs to be set during power-on before applying 
      any other settings. It also needs to be set before powering off the USB.


> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    items:
> +      - items:
> +          - description: System controller phandle required by USB PHY CTRL
> +                         driver to set PWRRDY

Indent by 2 more than 'description'

With that,

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

> +          - description: Register offset associated with PWRRDY
> +          - description: Register bitmask associated with PWRRDY
> +
>  required:
>    - compatible
>    - reg
> @@ -57,6 +72,19 @@ required:
>    - '#reset-cells'
>    - regulator-vbus
>  
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: renesas,r9a08g045-usbphy-ctrl
> +    then:
> +      required:
> +        - renesas,sysc-pwrrdy
> +    else:
> +      properties:
> +        renesas,sysc-pwrrdy: false
> +
>  additionalProperties: false
>  
>  examples:
> -- 
> 2.43.0
> 


From inochiama at gmail.com  Wed Aug 13 16:42:48 2025
From: inochiama at gmail.com (Inochi Amaoto)
Date: Thu, 14 Aug 2025 07:42:48 +0800
Subject: [PATCH 4/6] phy: spacemit: introduce PCIe/combo PHY
In-Reply-To: <20250813184701.2444372-5-elder@riscstar.com>
References: <20250813184701.2444372-1-elder@riscstar.com>
 <20250813184701.2444372-5-elder@riscstar.com>
Message-ID: <valmrbddij2dn4fjxefr46zud2u6eco2isyaa62sd66d27foyl@4hrhafqftgb5>

On Wed, Aug 13, 2025 at 01:46:58PM -0500, Alex Elder wrote:
> Introduce a driver that supports three PHYs found on the SpacemiT
> K1 SoC.  The first PHY is a combo PHY that can be configured for
> use for either USB 3 or PCIe.  The other two PHYs support PCIe
> only.
> 
> All three PHYs must be programmed with an 8 bit receiver termination
> value, which must be determined dynamically; only the combo PHY is
> able to determine this value.  The combo PHY performs a special
> calibration step at probe time to discover this, and that value is
> used to program each PHY that operates in PCIe mode.  The combo
> PHY must therefore be probed--first--if either of the PCIe-only
> PHYs will be used.
> 
> During normal operation, the USB or PCIe driver using the PHY must
> ensure clocks and resets are set up properly.  However clocks are
> enabled and resets are de-asserted temporarily by this driver to
> perform the calibration step on the combo PHY.
> 
> Tested-by: Junzhong Pan <panjunzhong at linux.spacemit.com>
> Signed-off-by: Alex Elder <elder at riscstar.com>
> ---
>  drivers/phy/Kconfig                |  11 +
>  drivers/phy/Makefile               |   1 +
>  drivers/phy/phy-spacemit-k1-pcie.c | 639 +++++++++++++++++++++++++++++
>  3 files changed, 651 insertions(+)
>  create mode 100644 drivers/phy/phy-spacemit-k1-pcie.c
> 
> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
> index 58c911e1b2d20..0fa343203f289 100644
> --- a/drivers/phy/Kconfig
> +++ b/drivers/phy/Kconfig
> @@ -101,6 +101,17 @@ config PHY_NXP_PTN3222
>  	  schemes. It supports all three USB 2.0 data rates: Low Speed, Full
>  	  Speed and High Speed.
>  
> +config PHY_SPACEMIT_K1_PCIE
> +	tristate "PCIe and combo PHY driver for the SpacemiT K1 SoC"
> +	depends on ARCH_SPACEMIT || COMPILE_TEST
> +	depends on HAS_IOMEM
> +	depends on OF
> +	select GENERIC_PHY
> +	default ARCH_SPACEMIT
> +	help
> +	  Enable support for the PCIe and USB 3 combo PHY and two
> +	  PCIe-only PHYs used in the SpacemiT K1 SoC.
> +
>  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 c670a8dac4680..20f0078e543c7 100644
> --- a/drivers/phy/Makefile
> +++ b/drivers/phy/Makefile
> @@ -13,6 +13,7 @@ obj-$(CONFIG_PHY_SNPS_EUSB2)		+= phy-snps-eusb2.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-$(CONFIG_PHY_SPACEMIT_K1_PCIE)	+= phy-spacemit-k1-pcie.o
>  obj-y					+= allwinner/	\
>  					   amlogic/	\
>  					   broadcom/	\
> diff --git a/drivers/phy/phy-spacemit-k1-pcie.c b/drivers/phy/phy-spacemit-k1-pcie.c
> new file mode 100644
> index 0000000000000..32dce53170fbb
> --- /dev/null
> +++ b/drivers/phy/phy-spacemit-k1-pcie.c
> @@ -0,0 +1,639 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * SpacemiT K1 PCIe and PCIe/USB 3 combo PHY driver
> + *
> + * Copyright (C) 2025 by RISCstar Solutions Corporation.  All rights reserved.
> + */
> +
> +#include <linux/bitfield.h>
> +#include <linux/clk.h>
> +#include <linux/iopoll.h>
> +#include <linux/kernel.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/reset.h>
> +
> +#include <dt-bindings/phy/phy.h>
> +
> +/*
> + * Three PCIe ports are supported in the SpacemiT K1 SoC, and this driver
> + * supports their PHYs.
> + *
> + * The PHY for PCIe port A is different from the PHYs for ports B and C:
> + * - It has one lane, while ports B and C have two
> + * - It is a combo PHY can be used for PCIe or USB 3
> + * - It can automatically calibrate PCIe TX and RX termination settings
> + *
> + * The PHY functionality for PCIe ports B and C is identical:
> + * - They have two PCIe lanes (but can be restricted to 1 via Device Tree)
> + * - They are used for PCIe only
> + * - They are configured using TX and RX values computed for port A
> + *
> + * A given board is designed to use the combo PHY for either PCIe or USB 3.
> + * Whether the combo PHY is configured for PCIe or USB 3 is specified in
> + * Device Tree using a phandle plus an argument.  The argument indicates
> + * the type (either PHY_TYPE_PCIE or PHY_TYPE_USB3).
> + *
> + * Each PHY depends on clocks and resets provided by the controller
> + * hardware (PCIe or USB) it is associated with.  The controller drivers
> + * are required to enable any clocks and de-assert any resets that affect
> + * PHY operation.
> + *
> + * PCIe PHYs must be programmed with RX and TX calibration values.  The
> + * combo PHY is the only one that can determine these values.  They are
> + * determined by temporarily enabling the combo PHY in PCIe mode at probe
> + * time (if necessary).  This calibration only needs to be done once, and
> + * when it has completed the TX and RX values are saved.
> + *
> + * To allow the combo PHY to be enabled for calibration, the resets and
> + * clocks it uses in PCIe mode must be supplied.
> + */
> +
> +struct k1_pcie_phy {
> +	struct device *dev;		/* PHY provider device */
> +	struct phy *phy;
> +	void __iomem *regs;
> +	u32 pcie_lanes;			/* Max unless limited by DT */
> +	/* The remaining fields are only used for the combo PHY */
> +	u32 type;			/* PHY_TYPE_PCIE or PHY_TYPE_USB3 */
> +	struct regmap *pmu;
> +};
> +
> +#define CALIBRATION_TIMEOUT		500000	/* microseconds */
> +#define PLL_TIMEOUT			500000	/* microseconds */
> +#define POLL_DELAY			500	/* microseconds */
> +
> +/* Selecting the combo PHY operating mode requires PMU regmap access */
> +#define SYSCON_PMU			"spacemit,syscon-pmu"
> +
> +/* PMU space, for selecting between PCIe and USB3 mode on the combo PHY */
> +
> +#define PMUA_USB_PHY_CTRL0			0x0110
> +#define COMBO_PHY_SEL			BIT(3)	/* 0: PCIe; 1: USB3 */
> +
> +#define PCIE_CLK_RES_CTRL			0x03cc
> +#define PCIE_APP_HOLD_PHY_RST		BIT(30)
> +
> +/* PHY register space */
> +
> +/* Offset between lane 0 and lane 1 registers when there are two */
> +#define PHY_LANE_OFFSET				0x0400
> +
> +#define PCIE_PU_ADDR_CLK_CFG			0x0008
> +#define PLL_READY			BIT(0)		/* read-only */
> +#define CFG_RXCLK_EN			BIT(3)
> +#define CFG_TXCLK_EN			BIT(4)
> +#define CFG_PCLK_EN			BIT(5)
> +#define CFG_PIPE_PCLK_EN		BIT(6)
> +#define CFG_INTERNAL_TIMER_ADJ		GENMASK(10, 7)
> +#define TIMER_ADJ_USB		0x2
> +#define TIMER_ADJ_PCIE		0x6
> +#define CFG_SW_PHY_INIT_DONE		BIT(11)	/* We set after PLL config */
> +
> +#define PCIE_RC_DONE_STATUS			0x0018
> +#define CFG_FORCE_RCV_RETRY		BIT(10)
> +
> +#define PCIE_RC_CAL_REG2			0x0020
> +#define RC_CAL_TOGGLE			BIT(22)
> +#define CLKSEL				GENMASK(31, 29)
> +#define CLKSEL_24M		0x3
> +
> +#define PCIE_PU_PLL_1				0x0048
> +#define REF_100_WSSC			BIT(12)	/* 1: input is 100MHz, SSC */
> +#define FREF_SEL			GENMASK(15, 13)
> +#define FREF_24M		0x1
> +#define SSC_DEP_SEL			GENMASK(19, 16)
> +#define SSC_DEP_NONE		0x0
> +#define SSC_DEP_5000PPM		0xa
> +#define SSC_MODE			GENMASK(21, 20)
> +#define SSC_MODE_DOWN_SPREAD	0x3
> +#define SSC_OFFSET			GENMASK(23, 22)
> +#define SSC_OFFSET_0_PPM	0x0
> +
> +#define PCIE_PU_PLL_2				0x004c
> +#define GEN_REF100			BIT(4)	/* 1: generate 100MHz clk */
> +
> +#define PCIE_RX_REG1				0x0050
> +#define EN_RTERM			BIT(3)
> +#define AFE_RTERM_REG			GENMASK(11, 8)
> +
> +#define PCIE_RX_REG2				0x0054
> +#define RX_RTERM_SEL			BIT(5)	/* 0: use AFE_RTERM_REG value */
> +
> +#define PCIE_LTSSM_DIS_ENTRY			0x005c
> +#define CFG_REFCLK_MODE			GENMASK(9, 8)
> +#define RFCLK_MODE_DRIVER	0x1
> +#define OVRD_REFCLK_MODE		BIT(10)	/* 1: use CFG_RFCLK_MODE */
> +
> +#define PCIE_TX_REG1				0x0064
> +#define TX_RTERM_REG			GENMASK(15, 12)
> +#define TX_RTERM_SEL			BIT(25)	/* 1: use TX_RTERM_REG */
> +
> +#define USB3_TEST_CTRL				0x0068
> +
> +#define PCIE_RCAL_RESULT			0x0084	/* Port A PHY only */
> +#define RTERM_VALUE_RX			GENMASK(3, 0)
> +#define RTERM_VALUE_TX			GENMASK(7, 4)
> +#define R_TUNE_DONE			BIT(10)
> +
> +static u32 k1_phy_rterm = ~0;     /* Invalid initial value */
> +
> +/* Save the RX and TX receiver termination values */
> +static void k1_phy_rterm_set(u32 val)
> +{
> +	k1_phy_rterm = val & (RTERM_VALUE_RX | RTERM_VALUE_TX);
> +}
> +
> +static bool k1_phy_rterm_valid(void)
> +{
> +	/* Valid if no bits outside those we care about are set */
> +	return !(k1_phy_rterm & ~(RTERM_VALUE_RX | RTERM_VALUE_TX));
> +}
> +
> +static u32 k1_phy_rterm_rx(void)
> +{
> +	return FIELD_GET(RTERM_VALUE_RX, k1_phy_rterm);
> +}
> +
> +static u32 k1_phy_rterm_tx(void)
> +{
> +	return FIELD_GET(RTERM_VALUE_TX, k1_phy_rterm);
> +}
> +
> +/* Only the combo PHY has a PMU pointer defined */
> +static bool k1_phy_port_a(struct k1_pcie_phy *k1_phy)
> +{
> +	return !!k1_phy->pmu;
> +}
> +
> +/*
> + * Select PCIe or USB 3 mode for the combo PHY.  Return 1 if the bit
> + * was changed, 0 if it was not, or a negative error value otherwise.
> + */
> +static int k1_combo_phy_sel(struct k1_pcie_phy *k1_phy, bool usb3)
> +{
> +	int ret;
> +
> +	ret = regmap_test_bits(k1_phy->pmu, PMUA_USB_PHY_CTRL0, COMBO_PHY_SEL);
> +	if (ret < 0)
> +		return ret;
> +
> +	/* If it's already in the desired state, we're done */
> +	if (!!ret == usb3)
> +		return 0;
> +
> +	/* Change the bit */
> +	ret = regmap_assign_bits(k1_phy->pmu, PMUA_USB_PHY_CTRL0,
> +				 COMBO_PHY_SEL, usb3);
> +
> +	return ret < 0 ? ret : 1;
> +}
> +

> +static void k1_pcie_phy_init_pll(struct k1_pcie_phy *k1_phy,
> +				 void __iomem *regs, bool pcie)
> +{
> +	void __iomem *virt;
> +	u32 timer_adj;
> +	u32 ssc_dep;
> +	u32 val;
> +
> +	if (pcie) {
> +		timer_adj = TIMER_ADJ_PCIE;
> +		ssc_dep = SSC_DEP_NONE;
> +	} else {
> +		timer_adj = TIMER_ADJ_USB;
> +		ssc_dep = SSC_DEP_5000PPM;
> +	}
> +
> +	/*
> +	 * Disable 100 MHz input reference with spread-spectrum
> +	 * clocking and select the 24 MHz clock input frequency
> +	 */
> +	virt = k1_phy->regs + PCIE_PU_PLL_1;
> +	val = readl(virt);
> +	val &= ~REF_100_WSSC;
> +
> +	val &= ~FREF_SEL;
> +	val |= FIELD_PREP(FREF_SEL, FREF_24M);
> +
> +	val &= ~SSC_DEP_SEL;
> +	val |= FIELD_PREP(SSC_DEP_SEL, ssc_dep);
> +
> +	val &= ~SSC_MODE;
> +	val |= FIELD_PREP(SSC_MODE, SSC_MODE_DOWN_SPREAD);
> +
> +	val &= ~SSC_OFFSET;
> +	val |= FIELD_PREP(SSC_OFFSET, SSC_OFFSET_0_PPM);
> +	writel(val, virt);
> +
> +	if (pcie) {
> +		virt = regs + PCIE_PU_PLL_2;
> +		val = readl(virt);
> +		val |= GEN_REF100;	/* Enable 100 MHz PLL output clock */
> +		writel(val, virt);
> +	}
> +
> +	/* Enable clocks and mark PLL initialization done */
> +	virt = regs + PCIE_PU_ADDR_CLK_CFG;
> +	val = readl(virt);
> +	val |= CFG_RXCLK_EN;
> +	val |= CFG_TXCLK_EN;
> +	val |= CFG_PCLK_EN;
> +	val |= CFG_PIPE_PCLK_EN;
> +
> +	val &= ~CFG_INTERNAL_TIMER_ADJ;
> +	val |= FIELD_PREP(CFG_INTERNAL_TIMER_ADJ, timer_adj);
> +
> +	val |= CFG_SW_PHY_INIT_DONE;
> +	writel(val, virt);
> +}
> +
> +static int k1_pcie_pll_lock(struct k1_pcie_phy *k1_phy, bool pcie)
> +{
> +	u32 val = pcie ? CFG_FORCE_RCV_RETRY : 0;
> +	void __iomem *virt;
> +
> +	writel(val, k1_phy->regs + PCIE_RC_DONE_STATUS);
> +
> +	/*
> +	 * Wait for indication the PHY PLL is locked.  Lanes for ports
> +	 * B and C share a PLL, so it's enough to sample just lane 0.
> +	 */
> +	virt = k1_phy->regs + PCIE_PU_ADDR_CLK_CFG;	/* Lane 0 */
> +
> +	return readl_poll_timeout(virt, val, val & PLL_READY,
> +				  POLL_DELAY, PLL_TIMEOUT);
> +}
> +

Can we use standard clk_ops and clk_mux to normalize this process?

Regards,
Inochi


From harrison.vanderbyl at gmail.com  Wed Aug 13 17:59:01 2025
From: harrison.vanderbyl at gmail.com (Harrison Vanderbyl)
Date: Thu, 14 Aug 2025 10:59:01 +1000
Subject: [PATCH 0/3] Describe x1e80100 ufs
Message-ID: <20250814005904.39173-1-harrison.vanderbyl@gmail.com>

Describes the UFS nodes for the x1e80100/x1p42100 chipset.

This is relevant to the following devices/patches:
Surface Pro 12 Inch 
HONOR MagicBook Art 14 
Link: https://lore.kernel.org/r/871px910m1.wl-kirill at korins.ky/
Samsung Galaxy Book4 Edge 
Link: https://lore.kernel.org/r/p3mhtj2rp6y2ezuwpd2gu7dwx5cbckfu4s4pazcudi4j2wogtr at 4yecb2bkeyms/

Forthcoming work *not* included in this patch:
Surface 12in display description
Surface 12in Surface Aggregator Module description
Surface 12in device tree

harrisonvanderbyl (3):
  dt-bindings: describe x1e80100 ufs
  ufs: ufs-qcom: describe x1e80100 quirks
  dts: describe x1e80100 ufs

 .../phy/qcom,sc8280xp-qmp-ufs-phy.yaml        |  2 +
 .../devicetree/bindings/ufs/qcom,ufs.yaml     |  2 +
 arch/arm64/boot/dts/qcom/x1e80100.dtsi        | 91 +++++++++++++++++++
 drivers/phy/qualcomm/phy-qcom-qmp-ufs.c       |  3 +
 drivers/ufs/host/ufs-qcom.c                   |  1 +
 5 files changed, 99 insertions(+)

-- 
2.48.1



From harrison.vanderbyl at gmail.com  Wed Aug 13 17:59:02 2025
From: harrison.vanderbyl at gmail.com (Harrison Vanderbyl)
Date: Thu, 14 Aug 2025 10:59:02 +1000
Subject: [PATCH 1/3] dt-bindings: describe x1e80100 ufs
In-Reply-To: <20250814005904.39173-1-harrison.vanderbyl@gmail.com>
References: <20250814005904.39173-1-harrison.vanderbyl@gmail.com>
Message-ID: <20250814005904.39173-2-harrison.vanderbyl@gmail.com>

Describe dt-bindings entries for x1e80100 ufs device
Signed-off-by: Harrison Vanderbyl <harrison.vanderbyl at gmail.com>
---
 .../devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml      | 2 ++
 Documentation/devicetree/bindings/ufs/qcom,ufs.yaml             | 2 ++
 2 files changed, 4 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 a58370a6a5d3..a5f115655235 100644
--- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
@@ -45,6 +45,7 @@ properties:
           - qcom,sm8550-qmp-ufs-phy
           - qcom,sm8650-qmp-ufs-phy
           - qcom,sm8750-qmp-ufs-phy
+          - qcom,x1e80100-qmp-ufs-phy
 
   reg:
     maxItems: 1
@@ -113,6 +114,7 @@ allOf:
               - qcom,sm8550-qmp-ufs-phy
               - qcom,sm8650-qmp-ufs-phy
               - qcom,sm8750-qmp-ufs-phy
+              - qcom,x1e80100-qmp-ufs-phy
     then:
       properties:
         clocks:
diff --git a/Documentation/devicetree/bindings/ufs/qcom,ufs.yaml b/Documentation/devicetree/bindings/ufs/qcom,ufs.yaml
index 6c6043d9809e..f820470d4cca 100644
--- a/Documentation/devicetree/bindings/ufs/qcom,ufs.yaml
+++ b/Documentation/devicetree/bindings/ufs/qcom,ufs.yaml
@@ -44,6 +44,7 @@ properties:
           - qcom,sm8550-ufshc
           - qcom,sm8650-ufshc
           - qcom,sm8750-ufshc
+          - qcom,x1e80100-ufshc
       - const: qcom,ufshc
       - const: jedec,ufs-2.0
 
@@ -160,6 +161,7 @@ allOf:
               - qcom,sm8550-ufshc
               - qcom,sm8650-ufshc
               - qcom,sm8750-ufshc
+              - qcom,x1e80100-ufshc
     then:
       properties:
         clocks:
-- 
2.48.1



From harrison.vanderbyl at gmail.com  Wed Aug 13 17:59:03 2025
From: harrison.vanderbyl at gmail.com (Harrison Vanderbyl)
Date: Thu, 14 Aug 2025 10:59:03 +1000
Subject: [PATCH 2/3] ufs: ufs-qcom: describe x1e80100 quirks
In-Reply-To: <20250814005904.39173-1-harrison.vanderbyl@gmail.com>
References: <20250814005904.39173-1-harrison.vanderbyl@gmail.com>
Message-ID: <20250814005904.39173-3-harrison.vanderbyl@gmail.com>

Describe describe driver quirks for x1e80100 ufs device
Signed-off-by: Harrison Vanderbyl <harrison.vanderbyl at gmail.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 3 +++
 drivers/ufs/host/ufs-qcom.c             | 1 +
 2 files changed, 4 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
index 9c69c77d10c8..b88cafac4da7 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
@@ -2168,6 +2168,9 @@ static const struct of_device_id qmp_ufs_of_match_table[] = {
 	}, {
 		.compatible = "qcom,sm8750-qmp-ufs-phy",
 		.data = &sm8750_ufsphy_cfg,
+	}, {
+		.compatible = "qcom,x1e80100-qmp-ufs-phy",
+		.data = &sm8550_ufsphy_cfg,
 	},
 
 	{ },
diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c
index 76fc70503a62..2e143ccd1a03 100644
--- a/drivers/ufs/host/ufs-qcom.c
+++ b/drivers/ufs/host/ufs-qcom.c
@@ -2282,6 +2282,7 @@ static const struct of_device_id ufs_qcom_of_match[] __maybe_unused = {
 	{ .compatible = "qcom,ufshc" },
 	{ .compatible = "qcom,sm8550-ufshc", .data = &ufs_qcom_sm8550_drvdata },
 	{ .compatible = "qcom,sm8650-ufshc", .data = &ufs_qcom_sm8550_drvdata },
+	{ .compatible = "qcom,x1e80100-ufshc", .data = &ufs_qcom_sm8550_drvdata },
 	{},
 };
 MODULE_DEVICE_TABLE(of, ufs_qcom_of_match);
-- 
2.48.1



From harrison.vanderbyl at gmail.com  Wed Aug 13 17:59:04 2025
From: harrison.vanderbyl at gmail.com (Harrison Vanderbyl)
Date: Thu, 14 Aug 2025 10:59:04 +1000
Subject: [PATCH 3/3] dts: describe x1e80100 ufs
In-Reply-To: <20250814005904.39173-1-harrison.vanderbyl@gmail.com>
References: <20250814005904.39173-1-harrison.vanderbyl@gmail.com>
Message-ID: <20250814005904.39173-4-harrison.vanderbyl@gmail.com>

Describe device tree entry for x1e80100 ufs device
Signed-off-by: Harrison Vanderbyl <harrison.vanderbyl at gmail.com>
---
 arch/arm64/boot/dts/qcom/x1e80100.dtsi | 91 ++++++++++++++++++++++++++
 1 file changed, 91 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/x1e80100.dtsi b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
index a9a7bb676c6f..effa776e3dd0 100644
--- a/arch/arm64/boot/dts/qcom/x1e80100.dtsi
+++ b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
@@ -2819,6 +2819,97 @@ tsens3: thermal-sensor at c274000 {
 			#thermal-sensor-cells = <1>;
 		};
 
+
+		ufs_mem_hc: ufs at 1d84000 {
+			compatible = "qcom,x1e80100-ufshc",
+			"qcom,ufshc", "jedec,ufs-2.0";
+			reg = <0 0x01d84000 0 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-gpios = <&tlmm 238 GPIO_ACTIVE_LOW>;
+			reset-names = "rst";
+
+			power-domains = <&gcc GCC_UFS_PHY_GDSC>;
+
+			iommus = <&apps_smmu 0x1a0 0x0>;
+
+			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";
+
+			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>;
+
+			freq-table-hz = <100000000 403000000>,
+					<0 0>,
+					<0 0>,
+					<100000000 403000000>,
+					<100000000 403000000>,
+					<0 0>,
+					<0 0>,
+					<0 0>;
+
+			interconnects = <&aggre1_noc MASTER_UFS_MEM QCOM_ICC_TAG_ALWAYS
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+					<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+					 &config_noc SLAVE_UFS_MEM_CFG QCOM_ICC_TAG_ALWAYS>;
+			interconnect-names = "ufs-ddr", "cpu-ufs";
+
+			qcom,ice = <&ice>;
+
+			status = "disabled";
+		};
+
+		ufs_mem_phy: phy at 1d80000 {
+			compatible = "qcom,x1e80100-qmp-ufs-phy";
+			reg = <0 0x01d80000 0 0x2000>;
+
+			clocks = <&rpmhcc RPMH_CXO_CLK>,
+				 <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
+
+			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";
+		};
+
+		ice: crypto at 1d90000 {
+			compatible = "qcom,x1e80100-inline-crypto-engine",
+				     "qcom,inline-crypto-engine";
+			reg = <0 0x1d88000 0 0x8000>;
+
+			clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>;
+		};
+
 		usb_1_ss0_hsphy: phy at fd3000 {
 			compatible = "qcom,x1e80100-snps-eusb2-phy",
 				     "qcom,sm8550-snps-eusb2-phy";
-- 
2.48.1



From nichen at iscas.ac.cn  Wed Aug 13 18:39:43 2025
From: nichen at iscas.ac.cn (Chen Ni)
Date: Thu, 14 Aug 2025 09:39:43 +0800
Subject: [PATCH] phy: rockchip: naneng-combphy: Convert comma to semicolon
Message-ID: <20250814013943.2905307-1-nichen@iscas.ac.cn>

Replace comma between expressions with semicolons.

Using a ',' in place of a ';' can have unintended side effects.
Although that is not the case here, it is seems best to use ';'
unless ',' is intended.

Found by inspection.
No functional change intended.
Compile tested only.

Signed-off-by: Chen Ni <nichen at iscas.ac.cn>
---
 drivers/phy/rockchip/phy-rockchip-naneng-combphy.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
index 0d25872e6712..a3ef19807b9e 100644
--- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
+++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
@@ -1252,7 +1252,7 @@ static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv)
 		writel(val, priv->mmio + RK3568_PHYREG15);
 
 		/* Set PLL KVCO fine tuning signals. */
-		val = RK3568_PHYREG33_PLL_KVCO_VALUE << RK3568_PHYREG33_PLL_KVCO_SHIFT,
+		val = RK3568_PHYREG33_PLL_KVCO_VALUE << RK3568_PHYREG33_PLL_KVCO_SHIFT;
 		rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, val, RK3568_PHYREG33);
 
 		/* Enable controlling random jitter. */
-- 
2.25.1



From andersson at kernel.org  Wed Aug 13 19:42:26 2025
From: andersson at kernel.org (Bjorn Andersson)
Date: Wed, 13 Aug 2025 21:42:26 -0500
Subject: [PATCH 3/3] dts: describe x1e80100 ufs
In-Reply-To: <20250814005904.39173-4-harrison.vanderbyl@gmail.com>
References: <20250814005904.39173-1-harrison.vanderbyl@gmail.com>
 <20250814005904.39173-4-harrison.vanderbyl@gmail.com>
Message-ID: <tlkv63ccpnti367am47ymhaw3agjnyuonqstgtfaazhhptvgsp@q4wzuzdph323>

On Thu, Aug 14, 2025 at 10:59:04AM +1000, Harrison Vanderbyl wrote:

Welcome to LKML, Harrison. Some small things to improve.

Please extend the subject prefix to match other changes in the files of
each patch, e.g. this one would be "arm64: dts: qcom: x1e80100: ".

"git log --oneline -- file" is your friend here.

> Describe device tree entry for x1e80100 ufs device

A blank line here please.

> Signed-off-by: Harrison Vanderbyl <harrison.vanderbyl at gmail.com>
> ---
>  arch/arm64/boot/dts/qcom/x1e80100.dtsi | 91 ++++++++++++++++++++++++++
>  1 file changed, 91 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/qcom/x1e80100.dtsi b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
> index a9a7bb676c6f..effa776e3dd0 100644
> --- a/arch/arm64/boot/dts/qcom/x1e80100.dtsi
> +++ b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
> @@ -2819,6 +2819,97 @@ tsens3: thermal-sensor at c274000 {
>  			#thermal-sensor-cells = <1>;
>  		};
>  
> +

Watch out for unnecessary white spaces, we want to keep things neat and
tidy.

> +		ufs_mem_hc: ufs at 1d84000 {

Please place nodes sorted based on address, then name, then label (i.e.
in this case, only address).

> +			compatible = "qcom,x1e80100-ufshc",
> +			"qcom,ufshc", "jedec,ufs-2.0";

This line break is a bit weird, please indent it.

Regards,
Bjorn

> +			reg = <0 0x01d84000 0 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-gpios = <&tlmm 238 GPIO_ACTIVE_LOW>;
> +			reset-names = "rst";
> +
> +			power-domains = <&gcc GCC_UFS_PHY_GDSC>;
> +
> +			iommus = <&apps_smmu 0x1a0 0x0>;
> +
> +			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";
> +
> +			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>;
> +
> +			freq-table-hz = <100000000 403000000>,
> +					<0 0>,
> +					<0 0>,
> +					<100000000 403000000>,
> +					<100000000 403000000>,
> +					<0 0>,
> +					<0 0>,
> +					<0 0>;
> +
> +			interconnects = <&aggre1_noc MASTER_UFS_MEM QCOM_ICC_TAG_ALWAYS
> +					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
> +					<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
> +					 &config_noc SLAVE_UFS_MEM_CFG QCOM_ICC_TAG_ALWAYS>;
> +			interconnect-names = "ufs-ddr", "cpu-ufs";
> +
> +			qcom,ice = <&ice>;
> +
> +			status = "disabled";
> +		};
> +
> +		ufs_mem_phy: phy at 1d80000 {
> +			compatible = "qcom,x1e80100-qmp-ufs-phy";
> +			reg = <0 0x01d80000 0 0x2000>;
> +
> +			clocks = <&rpmhcc RPMH_CXO_CLK>,
> +				 <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
> +
> +			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";
> +		};
> +
> +		ice: crypto at 1d90000 {
> +			compatible = "qcom,x1e80100-inline-crypto-engine",
> +				     "qcom,inline-crypto-engine";
> +			reg = <0 0x1d88000 0 0x8000>;
> +
> +			clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>;
> +		};
> +
>  		usb_1_ss0_hsphy: phy at fd3000 {
>  			compatible = "qcom,x1e80100-snps-eusb2-phy",
>  				     "qcom,sm8550-snps-eusb2-phy";
> -- 
> 2.48.1
> 


From ziyao at disroot.org  Wed Aug 13 19:52:03 2025
From: ziyao at disroot.org (Yao Zi)
Date: Thu, 14 Aug 2025 02:52:03 +0000
Subject: [PATCH 1/6] dt-bindings: phy: spacemit: add SpacemiT PCIe/combo
 PHY
In-Reply-To: <20250813184701.2444372-2-elder@riscstar.com>
References: <20250813184701.2444372-1-elder@riscstar.com>
 <20250813184701.2444372-2-elder@riscstar.com>
Message-ID: <aJ1PJBax-Pj983OZ@pie>

On Wed, Aug 13, 2025 at 01:46:55PM -0500, Alex Elder wrote:
> Add the Device Tree binding for the PCIe/USB 3.0 combo PHY found in
> the SpacemiT K1 SoC.  This is one of three PCIe PHYs, and is unusual
> in that only the combo PHY can perform a calibration step needed to
> determine settings used by the other two PCIe PHYs.
> 
> Calibration must be done with the combo PHY in PCIe mode, and to allow
> this to occur independent of the eventual use for the PHY (PCIe or USB)
> some PCIe-related properties must be supplied: clocks; resets; and a
> syscon phandle.
> 
> Signed-off-by: Alex Elder <elder at riscstar.com>
> ---
>  .../bindings/phy/spacemit,k1-combo-phy.yaml   | 110 ++++++++++++++++++
>  1 file changed, 110 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/phy/spacemit,k1-combo-phy.yaml
> 
> diff --git a/Documentation/devicetree/bindings/phy/spacemit,k1-combo-phy.yaml b/Documentation/devicetree/bindings/phy/spacemit,k1-combo-phy.yaml
> new file mode 100644
> index 0000000000000..ed78083a53231
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/spacemit,k1-combo-phy.yaml

...

> +  spacemit,syscon-pmu:
> +    description:
> +      PHandle that refers to the APMU system controller, whose
> +      regmap is used in setting the mode
> +    $ref: /schemas/types.yaml#/definitions/phandle

Clock controllers and ethernet controllers all use spacemit,apmu to
refer the APMU system controller. Do you think it's better to keep them
aligned?

...

> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/spacemit,k1-syscon.h>
> +    combo_phy: phy at c0b10000 {

This label is unnecessary.

> +        compatible = "spacemit,k1-combo-phy";
> +        reg = <0xc0b10000 0x1000>;
> +        clocks = <&syscon_apmu CLK_PCIE0_DBI>,
> +                 <&syscon_apmu CLK_PCIE0_MASTER>,
> +                 <&syscon_apmu CLK_PCIE0_SLAVE>;
> +        clock-names = "dbi",
> +                      "mstr",
> +                      "slv";
> +        resets = <&syscon_apmu RESET_PCIE0_DBI>,
> +                 <&syscon_apmu RESET_PCIE0_MASTER>,
> +                 <&syscon_apmu RESET_PCIE0_SLAVE>,
> +                 <&syscon_apmu RESET_PCIE0_GLOBAL>;
> +        reset-names = "dbi",
> +                      "mstr",
> +                      "slv",
> +                      "global";
> +        spacemit,syscon-pmu = <&syscon_apmu>;
> +        #phy-cells = <1>;
> +        status = "disabled";
> +    };

Best regards,
Yao Zi


From yangxiuwei2025 at 163.com  Wed Aug 13 22:37:42 2025
From: yangxiuwei2025 at 163.com (Yang Xiuwei)
Date: Thu, 14 Aug 2025 13:37:42 +0800
Subject: [PATCH] phy: use IS_ERR_OR_NULL() helper in of_phy_put()
Message-ID: <20250814053742.2186419-1-yangxiuwei2025@163.com>

From: Yang Xiuwei <yangxiuwei at kylinos.cn>

The current check for `!phy || IS_ERR(phy)` can be simplified to
the standard helper macro IS_ERR_OR_NULL(). This improves code
readability and maintains consistency with kernel coding practices.

Signed-off-by: Yang Xiuwei <yangxiuwei at kylinos.cn>

diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index 04a5a34e7a95..9248f2249849 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -677,7 +677,7 @@ EXPORT_SYMBOL_GPL(of_phy_get);
  */
 void of_phy_put(struct phy *phy)
 {
-	if (!phy || IS_ERR(phy))
+	if (IS_ERR_OR_NULL(phy))
 		return;
 
 	mutex_lock(&phy->mutex);
-- 
2.25.1



From krzk at kernel.org  Wed Aug 13 23:11:24 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 14 Aug 2025 08:11:24 +0200
Subject: [PATCH 1/6] dt-bindings: phy: spacemit: add SpacemiT PCIe/combo
 PHY
In-Reply-To: <20250813184701.2444372-2-elder@riscstar.com>
References: <20250813184701.2444372-1-elder@riscstar.com>
 <20250813184701.2444372-2-elder@riscstar.com>
Message-ID: <22bd5b5b-ca06-4499-b21f-22c2ff202167@kernel.org>

On 13/08/2025 20:46, Alex Elder wrote:
> +                      "mstr",
> +                      "slv",
> +                      "global";
> +        spacemit,syscon-pmu = <&syscon_apmu>;
> +        #phy-cells = <1>;
> +        status = "disabled";

You cannot have disabled examples. This also means it could not be
checked/tested.

> +    };


Best regards,
Krzysztof


From krzk at kernel.org  Wed Aug 13 23:17:28 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 14 Aug 2025 08:17:28 +0200
Subject: [PATCH 2/6] dt-bindings: phy: spacemit: introduce PCIe PHY
In-Reply-To: <20250813184701.2444372-3-elder@riscstar.com>
References: <20250813184701.2444372-1-elder@riscstar.com>
 <20250813184701.2444372-3-elder@riscstar.com>
Message-ID: <ab151314-c504-4a26-9ca2-685ab57b8fe9@kernel.org>

On 13/08/2025 20:46, Alex Elder wrote:
> +
> +required:
> +  - compatible
> +  - reg
> +  - "#phy-cells"
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/spacemit,k1-syscon.h>
> +    pcie1_phy: phy at c0c10000 {
> +        compatible = "spacemit,k1-pcie-phy";
> +        reg = <0xc0c10000 0x1000>;
> +        #phy-cells = <0>;
> +        status = "disabled";
Same problem here.

Best regards,
Krzysztof


From dmitry.baryshkov at oss.qualcomm.com  Wed Aug 13 23:56:01 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Thu, 14 Aug 2025 09:56:01 +0300
Subject: [PATCH 1/3] dt-bindings: describe x1e80100 ufs
In-Reply-To: <20250814005904.39173-2-harrison.vanderbyl@gmail.com>
References: <20250814005904.39173-1-harrison.vanderbyl@gmail.com>
 <20250814005904.39173-2-harrison.vanderbyl@gmail.com>
Message-ID: <iezjm5d5o7ec7jqweyip2vcqtjv3icidw34yq36k7blxuff2sf@ou7ub3cpwx2k>

On Thu, Aug 14, 2025 at 10:59:02AM +1000, Harrison Vanderbyl wrote:
> Describe dt-bindings entries for x1e80100 ufs device
> Signed-off-by: Harrison Vanderbyl <harrison.vanderbyl at gmail.com>

EMpty line before the SoB tag, UFS not ufs.

> ---
>  .../devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml      | 2 ++
>  Documentation/devicetree/bindings/ufs/qcom,ufs.yaml             | 2 ++

These two files are going to be merged by different maintainers through
different trees. Please split into two patches.

>  2 files changed, 4 insertions(+)
> 

-- 
With best wishes
Dmitry


From dmitry.baryshkov at oss.qualcomm.com  Wed Aug 13 23:57:38 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Thu, 14 Aug 2025 09:57:38 +0300
Subject: [PATCH 2/3] ufs: ufs-qcom: describe x1e80100 quirks
In-Reply-To: <20250814005904.39173-3-harrison.vanderbyl@gmail.com>
References: <20250814005904.39173-1-harrison.vanderbyl@gmail.com>
 <20250814005904.39173-3-harrison.vanderbyl@gmail.com>
Message-ID: <lj7qsbtk5xlmji6eknfv4ffrqypcsfkq5m7icrz4mvplncflpi@5j2opxwb5lft>

On Thu, Aug 14, 2025 at 10:59:03AM +1000, Harrison Vanderbyl wrote:
> Describe describe driver quirks for x1e80100 ufs device
> Signed-off-by: Harrison Vanderbyl <harrison.vanderbyl at gmail.com>

Again, missing empty line

> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 3 +++
>  drivers/ufs/host/ufs-qcom.c             | 1 +
>  2 files changed, 4 insertions(+)

And this also needs to be split into two patches.


-- 
With best wishes
Dmitry


From krzk at kernel.org  Wed Aug 13 23:59:07 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 14 Aug 2025 08:59:07 +0200
Subject: [PATCH 3/3] dts: describe x1e80100 ufs
In-Reply-To: <tlkv63ccpnti367am47ymhaw3agjnyuonqstgtfaazhhptvgsp@q4wzuzdph323>
References: <20250814005904.39173-1-harrison.vanderbyl@gmail.com>
 <20250814005904.39173-4-harrison.vanderbyl@gmail.com>
 <tlkv63ccpnti367am47ymhaw3agjnyuonqstgtfaazhhptvgsp@q4wzuzdph323>
Message-ID: <57ce520f-a562-471f-b6b4-44f0766a7556@kernel.org>

On 14/08/2025 04:42, Bjorn Andersson wrote:
> On Thu, Aug 14, 2025 at 10:59:04AM +1000, Harrison Vanderbyl wrote:
> 
> Welcome to LKML, Harrison. Some small things to improve.
> 
> Please extend the subject prefix to match other changes in the files of
> each patch, e.g. this one would be "arm64: dts: qcom: x1e80100: ".
> 
> "git log --oneline -- file" is your friend here.
> 
>> Describe device tree entry for x1e80100 ufs device

This is duplicating earlier patches:
https://lore.kernel.org/all/szudb2teaacchrp4kn4swkqkoplgi5lbw7vbqtu5vhds4qat62 at 2tciswvelbmu/

Best regards,
Krzysztof


From krzk at kernel.org  Wed Aug 13 23:59:22 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 14 Aug 2025 08:59:22 +0200
Subject: [PATCH 2/3] ufs: ufs-qcom: describe x1e80100 quirks
In-Reply-To: <20250814005904.39173-3-harrison.vanderbyl@gmail.com>
References: <20250814005904.39173-1-harrison.vanderbyl@gmail.com>
 <20250814005904.39173-3-harrison.vanderbyl@gmail.com>
Message-ID: <6a22ef70-02ed-4436-8c6d-822d04f2c930@kernel.org>

On 14/08/2025 02:59, Harrison Vanderbyl wrote:
> Describe describe driver quirks for x1e80100 ufs device
> Signed-off-by: Harrison Vanderbyl <harrison.vanderbyl at gmail.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 3 +++
>  drivers/ufs/host/ufs-qcom.c             | 1 +
>  2 files changed, 4 insertions(+)
> 
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> index 9c69c77d10c8..b88cafac4da7 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> @@ -2168,6 +2168,9 @@ static const struct of_device_id qmp_ufs_of_match_table[] = {
>  	}, {
>  		.compatible = "qcom,sm8750-qmp-ufs-phy",
>  		.data = &sm8750_ufsphy_cfg,
> +	}, {
> +		.compatible = "qcom,x1e80100-qmp-ufs-phy",
> +		.data = &sm8550_ufsphy_cfg,

So it is fully compatible? If so then don't duplicate entries and
express compatibility with fallback.

>  	},
>  
>  	{ },
> diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c
> index 76fc70503a62..2e143ccd1a03 100644
> --- a/drivers/ufs/host/ufs-qcom.c
> +++ b/drivers/ufs/host/ufs-qcom.c
> @@ -2282,6 +2282,7 @@ static const struct of_device_id ufs_qcom_of_match[] __maybe_unused = {
>  	{ .compatible = "qcom,ufshc" },
>  	{ .compatible = "qcom,sm8550-ufshc", .data = &ufs_qcom_sm8550_drvdata },
>  	{ .compatible = "qcom,sm8650-ufshc", .data = &ufs_qcom_sm8550_drvdata },
> +	{ .compatible = "qcom,x1e80100-ufshc", .data = &ufs_qcom_sm8550_drvdata },

Same problem here.


Best regards,
Krzysztof


From quic_nitirawa at quicinc.com  Thu Aug 14 00:20:17 2025
From: quic_nitirawa at quicinc.com (Nitin Rawat)
Date: Thu, 14 Aug 2025 12:50:17 +0530
Subject: [PATCH 3/3] dts: describe x1e80100 ufs
In-Reply-To: <20250814005904.39173-4-harrison.vanderbyl@gmail.com>
References: <20250814005904.39173-1-harrison.vanderbyl@gmail.com>
 <20250814005904.39173-4-harrison.vanderbyl@gmail.com>
Message-ID: <bc001360-1cfe-4886-a023-367a8edc21c5@quicinc.com>



On 8/14/2025 6:29 AM, Harrison Vanderbyl wrote:
> Describe device tree entry for x1e80100 ufs device
> Signed-off-by: Harrison Vanderbyl <harrison.vanderbyl at gmail.com>
> ---
>   arch/arm64/boot/dts/qcom/x1e80100.dtsi | 91 ++++++++++++++++++++++++++
>   1 file changed, 91 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/qcom/x1e80100.dtsi b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
> index a9a7bb676c6f..effa776e3dd0 100644
> --- a/arch/arm64/boot/dts/qcom/x1e80100.dtsi
> +++ b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
> @@ -2819,6 +2819,97 @@ tsens3: thermal-sensor at c274000 {
>   			#thermal-sensor-cells = <1>;
>   		};
>   
> +
> +		ufs_mem_hc: ufs at 1d84000 {
> +			compatible = "qcom,x1e80100-ufshc",
> +			"qcom,ufshc", "jedec,ufs-2.0";
> +			reg = <0 0x01d84000 0 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-gpios = <&tlmm 238 GPIO_ACTIVE_LOW>;
> +			reset-names = "rst";
> +
> +			power-domains = <&gcc GCC_UFS_PHY_GDSC>;
> +
> +			iommus = <&apps_smmu 0x1a0 0x0>;
> +
> +			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";
> +
> +			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>;
> +
> +			freq-table-hz = <100000000 403000000>,
> +					<0 0>,
> +					<0 0>,
> +					<100000000 403000000>,
> +					<100000000 403000000>,
> +					<0 0>,
> +					<0 0>,
> +					<0 0>;
> +
Please use OPP table instead of freq-table-hz.


> +			interconnects = <&aggre1_noc MASTER_UFS_MEM QCOM_ICC_TAG_ALWAYS
> +					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
> +					<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
> +					 &config_noc SLAVE_UFS_MEM_CFG QCOM_ICC_TAG_ALWAYS>;

For Config Path, use QCOM_ICC_TAG_ACTIVE_ONLY.

YOu can refer to ICC discussion link for SM8750 - 
https://lore.kernel.org/linux-devicetree/354f8710-a5ec-47b5-bcfa-bff75ac3ca71 at oss.qualcomm.com/ 




> +			interconnect-names = "ufs-ddr", "cpu-ufs";
> +
> +			qcom,ice = <&ice>;
> +
> +			status = "disabled";
> +		};
> +
> +		ufs_mem_phy: phy at 1d80000 {
> +			compatible = "qcom,x1e80100-qmp-ufs-phy";
> +			reg = <0 0x01d80000 0 0x2000>;
> +
> +			clocks = <&rpmhcc RPMH_CXO_CLK>,
> +				 <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
> +
> +			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";
> +		};
> +
> +		ice: crypto at 1d90000 {
> +			compatible = "qcom,x1e80100-inline-crypto-engine",
> +				     "qcom,inline-crypto-engine";
> +			reg = <0 0x1d88000 0 0x8000>;
> +
> +			clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>;
> +		};
> +
>   		usb_1_ss0_hsphy: phy at fd3000 {
>   			compatible = "qcom,x1e80100-snps-eusb2-phy",
>   				     "qcom,sm8550-snps-eusb2-phy";



From krzk at kernel.org  Thu Aug 14 01:13:35 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 14 Aug 2025 10:13:35 +0200
Subject: [PATCH v3 08/12] dt-bindings: phy: Add PCIe PHY support for FSD
 SoC
In-Reply-To: <20250811154638.95732-9-shradha.t@samsung.com>
References: <20250811154638.95732-1-shradha.t@samsung.com>
 <CGME20250811154729epcas5p456ddb0d1ba34b992204f54724b57a401@epcas5p4.samsung.com>
 <20250811154638.95732-9-shradha.t@samsung.com>
Message-ID: <20250814-refreshing-watchful-lemming-4feb03@kuoka>

On Mon, Aug 11, 2025 at 09:16:34PM +0530, Shradha Todi wrote:
> Since Tesla FSD SoC uses Samsung PCIe PHY, add support in
> exynos PCIe PHY bindings.
> 
> In Tesla FSD SoC, the two PHY instances, although having identical
> hardware design and register maps, are placed in different locations
> (Placement and routing) inside the SoC and have distinct
> PHY-to-Controller topologies. (One instance is connected to two PCIe
> controllers, while the other is connected to only one). As a result,
> they experience different analog environments, including varying
> channel losses and noise profiles.
> 
> Since these PHYs lack internal adaptation mechanisms and f/w based
> tuning, manual register programming is required for analog tuning.
> To ensure optimal signal integrity, it is essential to use different
> register values for each PHY instance, despite their identical hardware
> design. This is because the same register values may not be suitable
> for both instances due to their differing environments and topologies.

Would be nice if above (or most of it) would be reflected in binding
description. Please do so and:

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From lkp at intel.com  Thu Aug 14 01:15:16 2025
From: lkp at intel.com (kernel test robot)
Date: Thu, 14 Aug 2025 16:15:16 +0800
Subject: [PATCH v3 2/2] phy: samsung: gs101-ufs: Add .notify_phystate() &
 hibern8 enter/exit values
In-Reply-To: <20250813-phy-notify-pmstate-v3-2-3bda59055dd3@linaro.org>
References: <20250813-phy-notify-pmstate-v3-2-3bda59055dd3@linaro.org>
Message-ID: <202508141555.NJvU2oYQ-lkp@intel.com>

Hi Peter,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 43c3c17f0c805882d1b48818b1085747a68c80ec]

url:    https://github.com/intel-lab-lkp/linux/commits/Peter-Griffin/phy-add-new-phy_notify_state-api/20250813-231312
base:   43c3c17f0c805882d1b48818b1085747a68c80ec
patch link:    https://lore.kernel.org/r/20250813-phy-notify-pmstate-v3-2-3bda59055dd3%40linaro.org
patch subject: [PATCH v3 2/2] phy: samsung: gs101-ufs: Add .notify_phystate() & hibern8 enter/exit values
config: arm-randconfig-001-20250814 (https://download.01.org/0day-ci/archive/20250814/202508141555.NJvU2oYQ-lkp at intel.com/config)
compiler: clang version 22.0.0git (https://github.com/llvm/llvm-project 3769ce013be2879bf0b329c14a16f5cb766f26ce)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250814/202508141555.NJvU2oYQ-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/202508141555.NJvU2oYQ-lkp at intel.com/

All warnings (new ones prefixed by >>):

>> drivers/phy/samsung/phy-samsung-ufs.c:232:11: warning: variable 'cfg' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized]
     232 |         else if (state.ufs_state == PHY_UFS_HIBERN8_EXIT)
         |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/phy/samsung/phy-samsung-ufs.c:235:19: note: uninitialized use occurs here
     235 |         for_each_phy_cfg(cfg) {
         |                          ^~~
   drivers/phy/samsung/phy-samsung-ufs.c:232:7: note: remove the 'if' if its condition is always true
     232 |         else if (state.ufs_state == PHY_UFS_HIBERN8_EXIT)
         |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     233 |                 cfg = ufs_phy->cfgs_hibern8[CFG_PRE_HIBERN8_EXIT];
   drivers/phy/samsung/phy-samsung-ufs.c:224:39: note: initialize the variable 'cfg' to silence this warning
     224 |         const struct samsung_ufs_phy_cfg *cfg;
         |                                              ^
         |                                               = NULL
   1 warning generated.


vim +232 drivers/phy/samsung/phy-samsung-ufs.c

   219	
   220	static int samsung_ufs_phy_notify_state(struct phy *phy,
   221						union phy_notify state)
   222	{
   223		struct samsung_ufs_phy *ufs_phy = get_samsung_ufs_phy(phy);
   224		const struct samsung_ufs_phy_cfg *cfg;
   225		int i, err;
   226	
   227		if (!ufs_phy->cfgs_hibern8)
   228			return 0;
   229	
   230		if (state.ufs_state == PHY_UFS_HIBERN8_ENTER)
   231			cfg = ufs_phy->cfgs_hibern8[CFG_POST_HIBERN8_ENTER];
 > 232		else if (state.ufs_state == PHY_UFS_HIBERN8_EXIT)
   233			cfg = ufs_phy->cfgs_hibern8[CFG_PRE_HIBERN8_EXIT];
   234	
   235		for_each_phy_cfg(cfg) {
   236			for_each_phy_lane(ufs_phy, i) {
   237				samsung_ufs_phy_config(ufs_phy, cfg, i);
   238			}
   239		}
   240	
   241		if (state.ufs_state == PHY_UFS_HIBERN8_EXIT) {
   242			for_each_phy_lane(ufs_phy, i) {
   243				if (ufs_phy->drvdata->wait_for_cdr) {
   244					err = ufs_phy->drvdata->wait_for_cdr(phy, i);
   245					if (err)
   246						goto err_out;
   247				}
   248			}
   249		}
   250	
   251		return 0;
   252	err_out:
   253		return err;
   254	}
   255	

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


From konrad.dybcio at oss.qualcomm.com  Thu Aug 14 02:27:12 2025
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Thu, 14 Aug 2025 11:27:12 +0200
Subject: [PATCH 0/3] Describe x1e80100 ufs
In-Reply-To: <20250814005904.39173-1-harrison.vanderbyl@gmail.com>
References: <20250814005904.39173-1-harrison.vanderbyl@gmail.com>
Message-ID: <0e1fbd77-b651-4614-adf9-d2f8e66abac2@oss.qualcomm.com>

On 8/14/25 2:59 AM, Harrison Vanderbyl wrote:
> Describes the UFS nodes for the x1e80100/x1p42100 chipset.
> 
> This is relevant to the following devices/patches:
> Surface Pro 12 Inch 
> HONOR MagicBook Art 14 
> Link: https://lore.kernel.org/r/871px910m1.wl-kirill at korins.ky/
> Samsung Galaxy Book4 Edge 
> Link: https://lore.kernel.org/r/p3mhtj2rp6y2ezuwpd2gu7dwx5cbckfu4s4pazcudi4j2wogtr at 4yecb2bkeyms/

+Wesley I think you had it going on the Samsung laptop at one point, could
you compare the diff and maybe give it a test?

Konrad


From stephan.gerhold at linaro.org  Thu Aug 14 02:27:10 2025
From: stephan.gerhold at linaro.org (Stephan Gerhold)
Date: Thu, 14 Aug 2025 11:27:10 +0200
Subject: [PATCH v2] phy: qcom: qmp-pcie: Fix PHY initialization when
 powered down by firmware
Message-ID: <20250814-phy-qcom-qmp-pcie-nocsr-fix-v2-1-fe562b5d02a1@linaro.org>

Commit 0cc22f5a861c ("phy: qcom: qmp-pcie: Add PHY register retention
support") added support for using the "no_csr" reset to skip configuration
of the PHY if the init sequence was already applied by the boot firmware.
The expectation is that the PHY is only turned on/off by using the "no_csr"
reset, instead of powering it down and re-programming it after a full
reset.

The boot firmware on X1E does not fully conform to this expectation: If the
PCIe3 link fails to come up (e.g. because no PCIe card is inserted), the
firmware powers down the PHY using the QPHY_PCS_POWER_DOWN_CONTROL
register. The QPHY_START_CTRL register is kept as-is, so the driver assumes
the PHY is already initialized and skips the configuration/power up
sequence. The PHY won't come up again without clearing the
QPHY_PCS_POWER_DOWN_CONTROL, so eventually initialization fails:

  qcom-qmp-pcie-phy 1be0000.phy: phy initialization timed-out
  phy phy-1be0000.phy.0: phy poweron failed --> -110
  qcom-pcie 1bd0000.pcie: cannot initialize host
  qcom-pcie 1bd0000.pcie: probe with driver qcom-pcie failed with error -110

This can be reliably reproduced on the X1E CRD, QCP and Devkit when no card
is inserted for PCIe3.

Fix this by checking the QPHY_PCS_POWER_DOWN_CONTROL register in addition
to QPHY_START_CTRL. If the PHY is powered down with the register, it
doesn't conform to the expectations for using the "no_csr" reset, so we
fully re-initialize with the normal reset sequence.

Also check the register more carefully to ensure all of the bits we expect
are actually set. A simple !!(readl()) is not enough, because the PHY might
be only partially set up with some of the expected bits set.

Cc: stable at vger.kernel.org
Fixes: 0cc22f5a861c ("phy: qcom: qmp-pcie: Add PHY register retention support")
Signed-off-by: Stephan Gerhold <stephan.gerhold at linaro.org>
---
Changes in v2:
- Ensure that all expected bits are set (Konrad)
- Link to v1: https://lore.kernel.org/r/20250812-phy-qcom-qmp-pcie-nocsr-fix-v1-1-9a7d0a5d2b46 at linaro.org
---
 drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index 95830dcfdec9b1f68fd55d1cc3c102985cfafcc1..80973527fafcb294273dff1864828532dab738db 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -3067,6 +3067,14 @@ struct qmp_pcie {
 	struct clk_fixed_rate aux_clk_fixed;
 };
 
+static bool qphy_checkbits(const void __iomem *base, u32 offset, u32 val)
+{
+	u32 reg;
+
+	reg = readl(base + offset);
+	return (reg & val) == val;
+}
+
 static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
 {
 	u32 reg;
@@ -4339,10 +4347,12 @@ static int qmp_pcie_init(struct phy *phy)
 	struct qmp_pcie *qmp = phy_get_drvdata(phy);
 	const struct qmp_phy_cfg *cfg = qmp->cfg;
 	void __iomem *pcs = qmp->pcs;
-	bool phy_initialized = !!(readl(pcs + cfg->regs[QPHY_START_CTRL]));
 	int ret;
 
-	qmp->skip_init = qmp->nocsr_reset && phy_initialized;
+	qmp->skip_init = qmp->nocsr_reset &&
+		qphy_checkbits(pcs, cfg->regs[QPHY_START_CTRL], SERDES_START | PCS_START) &&
+		qphy_checkbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], cfg->pwrdn_ctrl);
+
 	/*
 	 * We need to check the existence of init sequences in two cases:
 	 * 1. The PHY doesn't support no_csr reset.

---
base-commit: 8f5ae30d69d7543eee0d70083daf4de8fe15d585
change-id: 20250812-phy-qcom-qmp-pcie-nocsr-fix-1603106294cd

Best regards,
-- 
Stephan Gerhold <stephan.gerhold at linaro.org>



From konrad.dybcio at oss.qualcomm.com  Thu Aug 14 02:46:21 2025
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Thu, 14 Aug 2025 11:46:21 +0200
Subject: [PATCH 3/3] dts: describe x1e80100 ufs
In-Reply-To: <57ce520f-a562-471f-b6b4-44f0766a7556@kernel.org>
References: <20250814005904.39173-1-harrison.vanderbyl@gmail.com>
 <20250814005904.39173-4-harrison.vanderbyl@gmail.com>
 <tlkv63ccpnti367am47ymhaw3agjnyuonqstgtfaazhhptvgsp@q4wzuzdph323>
 <57ce520f-a562-471f-b6b4-44f0766a7556@kernel.org>
Message-ID: <aa0ed59a-4eb6-4f7f-b430-4976ee9724d8@oss.qualcomm.com>

On 8/14/25 8:59 AM, Krzysztof Kozlowski wrote:
> On 14/08/2025 04:42, Bjorn Andersson wrote:
>> On Thu, Aug 14, 2025 at 10:59:04AM +1000, Harrison Vanderbyl wrote:
>>
>> Welcome to LKML, Harrison. Some small things to improve.
>>
>> Please extend the subject prefix to match other changes in the files of
>> each patch, e.g. this one would be "arm64: dts: qcom: x1e80100: ".
>>
>> "git log --oneline -- file" is your friend here.
>>
>>> Describe device tree entry for x1e80100 ufs device
> 
> This is duplicating earlier patches:
> https://lore.kernel.org/all/szudb2teaacchrp4kn4swkqkoplgi5lbw7vbqtu5vhds4qat62 at 2tciswvelbmu/

(that submitter clearly expressed lack of interest in proceeding)

Konrad



From krzk at kernel.org  Thu Aug 14 04:18:46 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 14 Aug 2025 13:18:46 +0200
Subject: [PATCH 3/3] dts: describe x1e80100 ufs
In-Reply-To: <aa0ed59a-4eb6-4f7f-b430-4976ee9724d8@oss.qualcomm.com>
References: <20250814005904.39173-1-harrison.vanderbyl@gmail.com>
 <20250814005904.39173-4-harrison.vanderbyl@gmail.com>
 <tlkv63ccpnti367am47ymhaw3agjnyuonqstgtfaazhhptvgsp@q4wzuzdph323>
 <57ce520f-a562-471f-b6b4-44f0766a7556@kernel.org>
 <aa0ed59a-4eb6-4f7f-b430-4976ee9724d8@oss.qualcomm.com>
Message-ID: <433e1189-e2b6-4299-9fa7-13e7994ec89c@kernel.org>

On 14/08/2025 11:46, Konrad Dybcio wrote:
> On 8/14/25 8:59 AM, Krzysztof Kozlowski wrote:
>> On 14/08/2025 04:42, Bjorn Andersson wrote:
>>> On Thu, Aug 14, 2025 at 10:59:04AM +1000, Harrison Vanderbyl wrote:
>>>
>>> Welcome to LKML, Harrison. Some small things to improve.
>>>
>>> Please extend the subject prefix to match other changes in the files of
>>> each patch, e.g. this one would be "arm64: dts: qcom: x1e80100: ".
>>>
>>> "git log --oneline -- file" is your friend here.
>>>
>>>> Describe device tree entry for x1e80100 ufs device
>>
>> This is duplicating earlier patches:
>> https://lore.kernel.org/all/szudb2teaacchrp4kn4swkqkoplgi5lbw7vbqtu5vhds4qat62 at 2tciswvelbmu/
> 
> (that submitter clearly expressed lack of interest in proceeding)
> 

Sure, would be good though to reflect that - provide summary of previous
discussions, changelogs or at least give links.

Best regards,
Krzysztof


From dmitry.baryshkov at oss.qualcomm.com  Thu Aug 14 04:26:07 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Thu, 14 Aug 2025 14:26:07 +0300
Subject: [PATCH 3/3] dts: describe x1e80100 ufs
In-Reply-To: <433e1189-e2b6-4299-9fa7-13e7994ec89c@kernel.org>
References: <20250814005904.39173-1-harrison.vanderbyl@gmail.com>
 <20250814005904.39173-4-harrison.vanderbyl@gmail.com>
 <tlkv63ccpnti367am47ymhaw3agjnyuonqstgtfaazhhptvgsp@q4wzuzdph323>
 <57ce520f-a562-471f-b6b4-44f0766a7556@kernel.org>
 <aa0ed59a-4eb6-4f7f-b430-4976ee9724d8@oss.qualcomm.com>
 <433e1189-e2b6-4299-9fa7-13e7994ec89c@kernel.org>
Message-ID: <25c5vwdgrfar6rz657nyijan7ozo5nzyyxb2w26wf5rvxftkvm@wy2fbsi77prj>

On Thu, Aug 14, 2025 at 01:18:46PM +0200, Krzysztof Kozlowski wrote:
> On 14/08/2025 11:46, Konrad Dybcio wrote:
> > On 8/14/25 8:59 AM, Krzysztof Kozlowski wrote:
> >> On 14/08/2025 04:42, Bjorn Andersson wrote:
> >>> On Thu, Aug 14, 2025 at 10:59:04AM +1000, Harrison Vanderbyl wrote:
> >>>
> >>> Welcome to LKML, Harrison. Some small things to improve.
> >>>
> >>> Please extend the subject prefix to match other changes in the files of
> >>> each patch, e.g. this one would be "arm64: dts: qcom: x1e80100: ".
> >>>
> >>> "git log --oneline -- file" is your friend here.
> >>>
> >>>> Describe device tree entry for x1e80100 ufs device
> >>
> >> This is duplicating earlier patches:
> >> https://lore.kernel.org/all/szudb2teaacchrp4kn4swkqkoplgi5lbw7vbqtu5vhds4qat62 at 2tciswvelbmu/
> > 
> > (that submitter clearly expressed lack of interest in proceeding)
> > 
> 
> Sure, would be good though to reflect that - provide summary of previous
> discussions, changelogs or at least give links.

... Also keep authorship and SoB chain.

-- 
With best wishes
Dmitry


From elder at riscstar.com  Thu Aug 14 04:59:53 2025
From: elder at riscstar.com (Alex Elder)
Date: Thu, 14 Aug 2025 06:59:53 -0500
Subject: [PATCH 1/6] dt-bindings: phy: spacemit: add SpacemiT PCIe/combo
 PHY
In-Reply-To: <22bd5b5b-ca06-4499-b21f-22c2ff202167@kernel.org>
References: <20250813184701.2444372-1-elder@riscstar.com>
 <20250813184701.2444372-2-elder@riscstar.com>
 <22bd5b5b-ca06-4499-b21f-22c2ff202167@kernel.org>
Message-ID: <86174012-fd87-41d7-9568-f9c0b544c1c4@riscstar.com>

On 8/14/25 1:11 AM, Krzysztof Kozlowski wrote:
> On 13/08/2025 20:46, Alex Elder wrote:
>> +                      "mstr",
>> +                      "slv",
>> +                      "global";
>> +        spacemit,syscon-pmu = <&syscon_apmu>;
>> +        #phy-cells = <1>;
>> +        status = "disabled";
> 
> You cannot have disabled examples. This also means it could not be
> checked/tested.
> 
>> +    };
> 
> 
> Best regards,
> Krzysztof

OK I'll fix that in both places.  I think I just copied in the
actual DTS content, but I now understand the problem.

Thanks.

					-Alex


From elder at riscstar.com  Thu Aug 14 05:15:43 2025
From: elder at riscstar.com (Alex Elder)
Date: Thu, 14 Aug 2025 07:15:43 -0500
Subject: [PATCH 4/6] phy: spacemit: introduce PCIe/combo PHY
In-Reply-To: <valmrbddij2dn4fjxefr46zud2u6eco2isyaa62sd66d27foyl@4hrhafqftgb5>
References: <20250813184701.2444372-1-elder@riscstar.com>
 <20250813184701.2444372-5-elder@riscstar.com>
 <valmrbddij2dn4fjxefr46zud2u6eco2isyaa62sd66d27foyl@4hrhafqftgb5>
Message-ID: <4eaa30bc-9a25-4fe0-b685-1d0d8fa503c2@riscstar.com>

On 8/13/25 6:42 PM, Inochi Amaoto wrote:
> On Wed, Aug 13, 2025 at 01:46:58PM -0500, Alex Elder wrote:
>> Introduce a driver that supports three PHYs found on the SpacemiT
>> K1 SoC.  The first PHY is a combo PHY that can be configured for
>> use for either USB 3 or PCIe.  The other two PHYs support PCIe
>> only.
>>
>> All three PHYs must be programmed with an 8 bit receiver termination
>> value, which must be determined dynamically; only the combo PHY is
>> able to determine this value.  The combo PHY performs a special
>> calibration step at probe time to discover this, and that value is
>> used to program each PHY that operates in PCIe mode.  The combo
>> PHY must therefore be probed--first--if either of the PCIe-only
>> PHYs will be used.
>>
>> During normal operation, the USB or PCIe driver using the PHY must
>> ensure clocks and resets are set up properly.  However clocks are
>> enabled and resets are de-asserted temporarily by this driver to
>> perform the calibration step on the combo PHY.
>>
>> Tested-by: Junzhong Pan <panjunzhong at linux.spacemit.com>
>> Signed-off-by: Alex Elder <elder at riscstar.com>
>> ---
>>   drivers/phy/Kconfig                |  11 +
>>   drivers/phy/Makefile               |   1 +
>>   drivers/phy/phy-spacemit-k1-pcie.c | 639 +++++++++++++++++++++++++++++
>>   3 files changed, 651 insertions(+)
>>   create mode 100644 drivers/phy/phy-spacemit-k1-pcie.c

. . .

>> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
>> index c670a8dac4680..20f0078e543c7 100644
>> --- a/drivers/phy/Makefile
>> +++ b/drivers/phy/Makefile

. . .

>> +static int k1_pcie_pll_lock(struct k1_pcie_phy *k1_phy, bool pcie)
>> +{
>> +	u32 val = pcie ? CFG_FORCE_RCV_RETRY : 0;
>> +	void __iomem *virt;
>> +
>> +	writel(val, k1_phy->regs + PCIE_RC_DONE_STATUS);
>> +
>> +	/*
>> +	 * Wait for indication the PHY PLL is locked.  Lanes for ports
>> +	 * B and C share a PLL, so it's enough to sample just lane 0.
>> +	 */
>> +	virt = k1_phy->regs + PCIE_PU_ADDR_CLK_CFG;	/* Lane 0 */
>> +
>> +	return readl_poll_timeout(virt, val, val & PLL_READY,
>> +				  POLL_DELAY, PLL_TIMEOUT);
>> +}
>> +
> 
> Can we use standard clk_ops and clk_mux to normalize this process?

I understand you're suggesting that we represent this as a clock.

Can you be more specific about how you suggest I do that?

For example, are you suggesting I create a separate clock driver
for this one PLL (in each PCIe register space)?

Or do you mean use clock structures and callbacks within this
driver to represent this?

I'm just not sure what you have in mind, and the two options I
mention seem a lot more complicated than this one function.

Thanks.

					-Alex

> Regards,
> Inochi



From elder at riscstar.com  Thu Aug 14 05:30:52 2025
From: elder at riscstar.com (Alex Elder)
Date: Thu, 14 Aug 2025 07:30:52 -0500
Subject: [PATCH 1/6] dt-bindings: phy: spacemit: add SpacemiT PCIe/combo
 PHY
In-Reply-To: <aJ1PJBax-Pj983OZ@pie>
References: <20250813184701.2444372-1-elder@riscstar.com>
 <20250813184701.2444372-2-elder@riscstar.com> <aJ1PJBax-Pj983OZ@pie>
Message-ID: <8f7bac84-623b-47dc-bc58-dc0013a85877@riscstar.com>

On 8/13/25 9:52 PM, Yao Zi wrote:
> On Wed, Aug 13, 2025 at 01:46:55PM -0500, Alex Elder wrote:
>> Add the Device Tree binding for the PCIe/USB 3.0 combo PHY found in
>> the SpacemiT K1 SoC.  This is one of three PCIe PHYs, and is unusual
>> in that only the combo PHY can perform a calibration step needed to
>> determine settings used by the other two PCIe PHYs.
>>
>> Calibration must be done with the combo PHY in PCIe mode, and to allow
>> this to occur independent of the eventual use for the PHY (PCIe or USB)
>> some PCIe-related properties must be supplied: clocks; resets; and a
>> syscon phandle.
>>
>> Signed-off-by: Alex Elder <elder at riscstar.com>
>> ---
>>   .../bindings/phy/spacemit,k1-combo-phy.yaml   | 110 ++++++++++++++++++
>>   1 file changed, 110 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/phy/spacemit,k1-combo-phy.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/phy/spacemit,k1-combo-phy.yaml b/Documentation/devicetree/bindings/phy/spacemit,k1-combo-phy.yaml
>> new file mode 100644
>> index 0000000000000..ed78083a53231
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/phy/spacemit,k1-combo-phy.yaml
> 
> ...
> 
>> +  spacemit,syscon-pmu:
>> +    description:
>> +      PHandle that refers to the APMU system controller, whose
>> +      regmap is used in setting the mode
>> +    $ref: /schemas/types.yaml#/definitions/phandle
> 
> Clock controllers and ethernet controllers all use spacemit,apmu to
> refer the APMU system controller. Do you think it's better to keep them
> aligned?

I do think it's better to keep them aligned.

And I appreciate your noticing this.  I don't see anything
that's accepted upstream that defines properties like this,
but I now see this:
  
https://lore.kernel.org/lkml/20250812-net-k1-emac-v5-2-dd17c4905f49 at iscas.ac.cn/

I did a quick scan for what others do when a property's
value is a phandle, and other than just "syscon" it seems
that word is omitted.

So unless someone else suggests otherwise, I'll use
"spacemit,apmu" for this property in my next version.

> ...
> 
>> +
>> +additionalProperties: false
>> +
>> +examples:
>> +  - |
>> +    #include <dt-bindings/clock/spacemit,k1-syscon.h>
>> +    combo_phy: phy at c0b10000 {
> 
> This label is unnecessary.

OK.  I used it when testing USB but we can add the label
back when that driver gets reviewed.

>> +        compatible = "spacemit,k1-combo-phy";
>> +        reg = <0xc0b10000 0x1000>;
>> +        clocks = <&syscon_apmu CLK_PCIE0_DBI>,
>> +                 <&syscon_apmu CLK_PCIE0_MASTER>,
>> +                 <&syscon_apmu CLK_PCIE0_SLAVE>;
>> +        clock-names = "dbi",
>> +                      "mstr",
>> +                      "slv";
>> +        resets = <&syscon_apmu RESET_PCIE0_DBI>,
>> +                 <&syscon_apmu RESET_PCIE0_MASTER>,
>> +                 <&syscon_apmu RESET_PCIE0_SLAVE>,
>> +                 <&syscon_apmu RESET_PCIE0_GLOBAL>;
>> +        reset-names = "dbi",
>> +                      "mstr",
>> +                      "slv",
>> +                      "global";
>> +        spacemit,syscon-pmu = <&syscon_apmu>;
>> +        #phy-cells = <1>;
>> +        status = "disabled";
>> +    };
> 
> Best regards,
> Yao Zi

Thanks a lot.

					-Alex



From payne.lin at mediatek.com  Thu Aug 14 05:54:02 2025
From: payne.lin at mediatek.com (payne.lin)
Date: Thu, 14 Aug 2025 20:54:02 +0800
Subject: [PATCH] phy: mediatek: Modify mipi clk upper bound to 2.5Gbps
Message-ID: <20250814125406.4161220-1-payne.lin@mediatek.com>

From: Bincai Liu <bincai.liu at mediatek.com>

Mipi dphy can support up to 4k30 without dsc.

Signed-off-by: Bincai Liu <bincai.liu at mediatek.com>
Signed-off-by: Payne Lin <payne.lin at mediatek.com>
---
 drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
index 553725e1269c..b8233c496070 100644
--- a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
+++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
@@ -100,7 +100,7 @@ static void mtk_mipi_tx_pll_disable(struct clk_hw *hw)
 static long mtk_mipi_tx_pll_round_rate(struct clk_hw *hw, unsigned long rate,
 				       unsigned long *prate)
 {
-	return clamp_val(rate, 125000000, 1600000000);
+	return clamp_val(rate, 125000000, 2500000000);
 }
 
 static const struct clk_ops mtk_mipi_tx_pll_ops = {
-- 
2.45.2



From liaoyuanhong at vivo.com  Thu Aug 14 06:13:53 2025
From: liaoyuanhong at vivo.com (Liao Yuanhong)
Date: Thu, 14 Aug 2025 21:13:53 +0800
Subject: [PATCH] phy: core: Use IS_ERR_OR_NULL() to simplify code
Message-ID: <20250814131353.231276-1-liaoyuanhong@vivo.com>

Use IS_ERR_OR_NULL() instead of the original !xxx || IS_ERR(xxx) logic.
This will simplify the code and enhance readability.

Signed-off-by: Liao Yuanhong <liaoyuanhong at vivo.com>
---
 drivers/phy/phy-core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index 04a5a34e7a95..9248f2249849 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -677,7 +677,7 @@ EXPORT_SYMBOL_GPL(of_phy_get);
  */
 void of_phy_put(struct phy *phy)
 {
-	if (!phy || IS_ERR(phy))
+	if (IS_ERR_OR_NULL(phy))
 		return;
 
 	mutex_lock(&phy->mutex);
-- 
2.34.1



From pritam.sutar at samsung.com  Thu Aug 14 06:26:01 2025
From: pritam.sutar at samsung.com (Pritam Manohar Sutar)
Date: Thu, 14 Aug 2025 18:56:01 +0530
Subject: [PATCH v5 2/6] phy: exynos5-usbdrd: support HS phy for
 ExynosAutov920
In-Reply-To: <aJtMdHcidETZyiIp@vaman>
References: <20250805115216.3798121-1-pritam.sutar@samsung.com>
	<CGME20250805114310epcas5p459aa232884d22501f5fefe42f239fecc@epcas5p4.samsung.com>
	<20250805115216.3798121-3-pritam.sutar@samsung.com> <aJtMdHcidETZyiIp@vaman>
Message-ID: <02f101dc0d1e$fd018ef0$f704acd0$@samsung.com>

Hi Vinod, 

> -----Original Message-----
> From: Vinod Koul <vkoul at kernel.org>
> Sent: 12 August 2025 07:45 PM
> To: Pritam Manohar Sutar <pritam.sutar at samsung.com>
> Cc: kishon at kernel.org; robh at kernel.org; krzk+dt at kernel.org;
> conor+dt at kernel.org; alim.akhtar at samsung.com; andre.draszik at linaro.org;
> peter.griffin at linaro.org; kauschluss at disroot.org;
> ivo.ivanov.ivanov1 at gmail.com; igor.belwon at mentallysanemainliners.org;
> m.szyprowski at samsung.com; s.nawrocki at samsung.com; linux-
> phy at lists.infradead.org; devicetree at vger.kernel.org; linux-
> kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-
> samsung-soc at vger.kernel.org; rosa.pila at samsung.com;
> dev.tailor at samsung.com; faraz.ata at samsung.com;
> muhammed.ali at samsung.com; selvarasu.g at samsung.com
> Subject: Re: [PATCH v5 2/6] phy: exynos5-usbdrd: support HS phy for
> ExynosAutov920
> 
> On 05-08-25, 17:22, Pritam Manohar Sutar wrote:
> > Enable UTMI+ phy support for this SoC which is very similar to what
> > the existing Exynos850 supports.
> >
> > Add required change in phy driver to support HS phy for this SoC.
> >
> > Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
> > ---
> >  drivers/phy/samsung/phy-exynos5-usbdrd.c    | 123
> ++++++++++++++++++++
> >  include/linux/soc/samsung/exynos-regs-pmu.h |   2 +
> >  2 files changed, 125 insertions(+)
> >
> > diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c
> > b/drivers/phy/samsung/phy-exynos5-usbdrd.c
> > index dd660ebe8045..5400dd23e500 100644
> > --- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
> > +++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
> > @@ -2054,6 +2054,126 @@ static const struct
> exynos5_usbdrd_phy_drvdata exynos990_usbdrd_phy = {
> >  	.n_regulators		= ARRAY_SIZE(exynos5_regulator_names),
> >  };
> >
> > +static int exynosautov920_usbdrd_phy_init(struct phy *phy) {
> > +	struct phy_usb_instance *inst = phy_get_drvdata(phy);
> > +	struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
> > +	int ret;
> > +
> > +	ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks,
> phy_drd->clks);
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* Bypass PHY isol */
> > +	inst->phy_cfg->phy_isol(inst, false);
> > +
> > +	/* UTMI or PIPE3 specific init */
> > +	inst->phy_cfg->phy_init(phy_drd);
> > +
> > +	clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks,
> > +phy_drd->clks);
> > +
> > +	return 0;
> > +}
> > +
> > +static int exynosautov920_usbdrd_phy_exit(struct phy *phy) {
> > +	struct phy_usb_instance *inst = phy_get_drvdata(phy);
> > +	struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
> > +	int ret = 0;
> 
> Superfluous init..
> 
> > +
> > +	ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks,
> phy_drd->clks);
> > +	if (ret)
> > +		return ret;
> > +
> > +	exynos850_usbdrd_phy_exit(phy);
> > +
> > +	/* enable PHY isol */
> > +	inst->phy_cfg->phy_isol(inst, true);
> > +
> > +	clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks,
> > +phy_drd->clks);
> > +
> > +	return 0;
> > +}
> > +
> > +static int exynosautov920_usbdrd_phy_power_on(struct phy *phy) {
> > +	int ret;
> > +	struct phy_usb_instance *inst = phy_get_drvdata(phy);
> > +	struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
> 
> Reverse chrsitmas tree pls
> 
> --
> ~Vinod

Will address these comments in next version of the patch-set (v6).

Thank you.

Regards,
Pritam




From andersson at kernel.org  Thu Aug 14 06:57:31 2025
From: andersson at kernel.org (Bjorn Andersson)
Date: Thu, 14 Aug 2025 08:57:31 -0500
Subject: [PATCH 3/3] dts: describe x1e80100 ufs
In-Reply-To: <25c5vwdgrfar6rz657nyijan7ozo5nzyyxb2w26wf5rvxftkvm@wy2fbsi77prj>
References: <20250814005904.39173-1-harrison.vanderbyl@gmail.com>
 <20250814005904.39173-4-harrison.vanderbyl@gmail.com>
 <tlkv63ccpnti367am47ymhaw3agjnyuonqstgtfaazhhptvgsp@q4wzuzdph323>
 <57ce520f-a562-471f-b6b4-44f0766a7556@kernel.org>
 <aa0ed59a-4eb6-4f7f-b430-4976ee9724d8@oss.qualcomm.com>
 <433e1189-e2b6-4299-9fa7-13e7994ec89c@kernel.org>
 <25c5vwdgrfar6rz657nyijan7ozo5nzyyxb2w26wf5rvxftkvm@wy2fbsi77prj>
Message-ID: <r52n5wfjsfrdotrawjes5pscrcyd5jwnsxkue7v5x55gq3ad3o@egwactada25n>

On Thu, Aug 14, 2025 at 02:26:07PM +0300, Dmitry Baryshkov wrote:
> On Thu, Aug 14, 2025 at 01:18:46PM +0200, Krzysztof Kozlowski wrote:
> > On 14/08/2025 11:46, Konrad Dybcio wrote:
> > > On 8/14/25 8:59 AM, Krzysztof Kozlowski wrote:
> > >> On 14/08/2025 04:42, Bjorn Andersson wrote:
> > >>> On Thu, Aug 14, 2025 at 10:59:04AM +1000, Harrison Vanderbyl wrote:
> > >>>
> > >>> Welcome to LKML, Harrison. Some small things to improve.
> > >>>
> > >>> Please extend the subject prefix to match other changes in the files of
> > >>> each patch, e.g. this one would be "arm64: dts: qcom: x1e80100: ".
> > >>>
> > >>> "git log --oneline -- file" is your friend here.
> > >>>
> > >>>> Describe device tree entry for x1e80100 ufs device
> > >>
> > >> This is duplicating earlier patches:
> > >> https://lore.kernel.org/all/szudb2teaacchrp4kn4swkqkoplgi5lbw7vbqtu5vhds4qat62 at 2tciswvelbmu/
> > > 
> > > (that submitter clearly expressed lack of interest in proceeding)
> > > 
> > 
> > Sure, would be good though to reflect that - provide summary of previous
> > discussions, changelogs or at least give links.
> 
> ... Also keep authorship and SoB chain.
> 

If it's based on those patches yes, otherwise no.

Regards,
Bjorn

> -- 
> With best wishes
> Dmitry


From andersson at kernel.org  Thu Aug 14 07:16:43 2025
From: andersson at kernel.org (Bjorn Andersson)
Date: Thu, 14 Aug 2025 09:16:43 -0500
Subject: [PATCH v2 1/2] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy:
 Document SC7280 PCIe0 phy
In-Reply-To: <20250812-sc7280-v2-1-814e36121af0@oss.qualcomm.com>
References: <20250812-sc7280-v2-0-814e36121af0@oss.qualcomm.com>
 <20250812-sc7280-v2-1-814e36121af0@oss.qualcomm.com>
Message-ID: <yncizuu6bhr3xvuzkb5xri4gh6mdjg4r4d4nkufgxxpquetyir@kiagpup6wqgx>

On Tue, Aug 12, 2025 at 07:26:44PM +0530, Krishna Chaitanya Chundru wrote:
> SC7280 PCIe0 PHY is functionally compatible with the SM8250 Gen3 x1 PCIe
> PHY. To reflect this compatibility, update the binding schema to include
      ^--- I think here would be a good place to break for a new
           paragraph, to give separation between problem description and
	   solution description.

> qcom,sc7280-qmp-gen3x1-pcie-phy using enum within a oneOf block, while
> retaining qcom,sm8250-qmp-gen3x1-pcie-phy as a const.
> 

Isn't this the case for &pcie1 as well? If so, can you please fix both?


Also, before we do that, the fact that they are "functionally
compatible", can you confirm that these two platforms really has the
same PHY settings?

Regards,
Bjorn

> Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
> ---
>  .../bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml   | 69 ++++++++++++----------
>  1 file changed, 37 insertions(+), 32 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 a1ae8c7988c891a11f6872e58d25e9d04abb41ce..1e08e26892f7b769b75bb905377d30a301e6631c 100644
> --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
> +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
> @@ -15,38 +15,43 @@ description:
>  
>  properties:
>    compatible:
> -    enum:
> -      - qcom,qcs615-qmp-gen3x1-pcie-phy
> -      - qcom,qcs8300-qmp-gen4x2-pcie-phy
> -      - qcom,sa8775p-qmp-gen4x2-pcie-phy
> -      - qcom,sa8775p-qmp-gen4x4-pcie-phy
> -      - qcom,sar2130p-qmp-gen3x2-pcie-phy
> -      - qcom,sc8180x-qmp-pcie-phy
> -      - qcom,sc8280xp-qmp-gen3x1-pcie-phy
> -      - qcom,sc8280xp-qmp-gen3x2-pcie-phy
> -      - qcom,sc8280xp-qmp-gen3x4-pcie-phy
> -      - qcom,sdm845-qhp-pcie-phy
> -      - qcom,sdm845-qmp-pcie-phy
> -      - qcom,sdx55-qmp-pcie-phy
> -      - qcom,sdx65-qmp-gen4x2-pcie-phy
> -      - qcom,sm8150-qmp-gen3x1-pcie-phy
> -      - qcom,sm8150-qmp-gen3x2-pcie-phy
> -      - qcom,sm8250-qmp-gen3x1-pcie-phy
> -      - qcom,sm8250-qmp-gen3x2-pcie-phy
> -      - qcom,sm8250-qmp-modem-pcie-phy
> -      - qcom,sm8350-qmp-gen3x1-pcie-phy
> -      - qcom,sm8350-qmp-gen3x2-pcie-phy
> -      - qcom,sm8450-qmp-gen3x1-pcie-phy
> -      - qcom,sm8450-qmp-gen4x2-pcie-phy
> -      - qcom,sm8550-qmp-gen3x2-pcie-phy
> -      - 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
> -      - qcom,x1e80100-qmp-gen4x4-pcie-phy
> -      - qcom,x1e80100-qmp-gen4x8-pcie-phy
> -      - qcom,x1p42100-qmp-gen4x4-pcie-phy
> +    oneOf:
> +      - items:
> +          - const: qcom,sc7280-qmp-gen3x1-pcie-phy
> +          - const: qcom,sm8250-qmp-gen3x1-pcie-phy
> +      - items:
> +          - enum:
> +              - qcom,qcs615-qmp-gen3x1-pcie-phy
> +              - qcom,qcs8300-qmp-gen4x2-pcie-phy
> +              - qcom,sa8775p-qmp-gen4x2-pcie-phy
> +              - qcom,sa8775p-qmp-gen4x4-pcie-phy
> +              - qcom,sar2130p-qmp-gen3x2-pcie-phy
> +              - qcom,sc8180x-qmp-pcie-phy
> +              - qcom,sc8280xp-qmp-gen3x1-pcie-phy
> +              - qcom,sc8280xp-qmp-gen3x2-pcie-phy
> +              - qcom,sc8280xp-qmp-gen3x4-pcie-phy
> +              - qcom,sdm845-qhp-pcie-phy
> +              - qcom,sdm845-qmp-pcie-phy
> +              - qcom,sdx55-qmp-pcie-phy
> +              - qcom,sdx65-qmp-gen4x2-pcie-phy
> +              - qcom,sm8150-qmp-gen3x1-pcie-phy
> +              - qcom,sm8150-qmp-gen3x2-pcie-phy
> +              - qcom,sm8250-qmp-gen3x1-pcie-phy
> +              - qcom,sm8250-qmp-gen3x2-pcie-phy
> +              - qcom,sm8250-qmp-modem-pcie-phy
> +              - qcom,sm8350-qmp-gen3x1-pcie-phy
> +              - qcom,sm8350-qmp-gen3x2-pcie-phy
> +              - qcom,sm8450-qmp-gen3x1-pcie-phy
> +              - qcom,sm8450-qmp-gen4x2-pcie-phy
> +              - qcom,sm8550-qmp-gen3x2-pcie-phy
> +              - 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
> +              - qcom,x1e80100-qmp-gen4x4-pcie-phy
> +              - qcom,x1e80100-qmp-gen4x8-pcie-phy
> +              - qcom,x1p42100-qmp-gen4x4-pcie-phy
>  
>    reg:
>      minItems: 1
> 
> -- 
> 2.34.1
> 


From cristian.ciocaltea at collabora.com  Thu Aug 14 09:36:44 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Thu, 14 Aug 2025 19:36:44 +0300
Subject: [PATCH v2 8/9] phy: rockchip: phy-rockchip-samsung-hdptx: convert
 from round_rate() to determine_rate()
In-Reply-To: <20250810-phy-clk-round-rate-v2-8-9162470bb9f2@redhat.com>
References: <20250810-phy-clk-round-rate-v2-0-9162470bb9f2@redhat.com>
 <20250810-phy-clk-round-rate-v2-8-9162470bb9f2@redhat.com>
Message-ID: <708d3814-f414-4174-95b3-d3450e9780ec@collabora.com>

On 8/11/25 1:45 AM, Brian Masney wrote:
> The round_rate() clk ops is deprecated, so migrate this driver from
> round_rate() to determine_rate() using the Coccinelle semantic patch
> on the cover letter of this series.
> 
> Signed-off-by: Brian Masney <bmasney at redhat.com>
> ---
>  drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 14 ++++++++------
>  1 file changed, 8 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> index 79db57ee90d1487b51f4ddadde870a275dd7b17b..0d4e578c8c6a08aad355aa8aa5a1cf75c7d354ed 100644
> --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> @@ -1869,8 +1869,8 @@ static unsigned long rk_hdptx_phy_clk_recalc_rate(struct clk_hw *hw,
>  	return hdptx->hw_rate;
>  }
>  
> -static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
> -					unsigned long *parent_rate)
> +static int rk_hdptx_phy_clk_determine_rate(struct clk_hw *hw,
> +					   struct clk_rate_request *req)
>  {
>  	struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);
>  
> @@ -1879,9 +1879,9 @@ static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
>  	 * To be dropped as soon as the RK DW HDMI QP bridge driver
>  	 * switches to make use of phy_configure().
>  	 */
> -	if (!hdptx->restrict_rate_change && rate != hdptx->hdmi_cfg.tmds_char_rate) {
> +	if (!hdptx->restrict_rate_change && req->rate != hdptx->hdmi_cfg.tmds_char_rate) {
>  		struct phy_configure_opts_hdmi hdmi = {
> -			.tmds_char_rate = rate,
> +			.tmds_char_rate = req->rate,
>  		};
>  		int ret = rk_hdptx_phy_verify_hdmi_config(hdptx, &hdmi);
>  
> @@ -1896,7 +1896,9 @@ static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
>  	 * hence ensure rk_hdptx_phy_clk_set_rate() won't be invoked with
>  	 * a different rate argument.
>  	 */
> -	return hdptx->hdmi_cfg.tmds_char_rate;
> +	req->rate = hdptx->hdmi_cfg.tmds_char_rate;
> +
> +	return 0;
>  }

This LGTM now, hence

Reviewed-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>



From robh at kernel.org  Thu Aug 14 13:51:28 2025
From: robh at kernel.org (Rob Herring)
Date: Thu, 14 Aug 2025 15:51:28 -0500
Subject: [PATCH 1/6] dt-bindings: phy: spacemit: add SpacemiT PCIe/combo
 PHY
In-Reply-To: <20250813184701.2444372-2-elder@riscstar.com>
References: <20250813184701.2444372-1-elder@riscstar.com>
 <20250813184701.2444372-2-elder@riscstar.com>
Message-ID: <20250814205128.GA3873683-robh@kernel.org>

On Wed, Aug 13, 2025 at 01:46:55PM -0500, Alex Elder wrote:
> Add the Device Tree binding for the PCIe/USB 3.0 combo PHY found in
> the SpacemiT K1 SoC.  This is one of three PCIe PHYs, and is unusual
> in that only the combo PHY can perform a calibration step needed to
> determine settings used by the other two PCIe PHYs.
> 
> Calibration must be done with the combo PHY in PCIe mode, and to allow
> this to occur independent of the eventual use for the PHY (PCIe or USB)
> some PCIe-related properties must be supplied: clocks; resets; and a
> syscon phandle.
> 
> Signed-off-by: Alex Elder <elder at riscstar.com>
> ---
>  .../bindings/phy/spacemit,k1-combo-phy.yaml   | 110 ++++++++++++++++++
>  1 file changed, 110 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/phy/spacemit,k1-combo-phy.yaml
> 
> diff --git a/Documentation/devicetree/bindings/phy/spacemit,k1-combo-phy.yaml b/Documentation/devicetree/bindings/phy/spacemit,k1-combo-phy.yaml
> new file mode 100644
> index 0000000000000..ed78083a53231
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/spacemit,k1-combo-phy.yaml
> @@ -0,0 +1,110 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/phy/spacemit,k1-combo-phy.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: SpacemiT K1 PCIe/USB3 Combo PHY
> +
> +maintainers:
> +  - Alex Elder <elder at riscstar.com>
> +
> +description:

You need a '>' or the paragraphs formatting will not be maintained 
(should we ever render docs from this).

> +  Of the three PHYs on the SpacemiT K1 SoC capable of being used for
> +  PCIe, one is a combo PHY that can also be configured for use by a
> +  USB 3 controller.  Using PCIe or USB 3 is a board design decision.
> +
> +  The combo PHY is also the only PCIe PHY that is able to determine
> +  PCIe calibration values to use, and this must be determined before
> +  the other two PCIe PHYs can be used.  This calibration must be
> +  performed with the combo PHY in PCIe mode, and is this is done
> +  when the combo PHY is probed.
> +
> +  During normal operation, the PCIe or USB port driver is responsible
> +  for ensuring all clocks needed by a PHY are enabled, and all resets
> +  affecting the PHY are deasserted.  However, for the combo PHY to
> +  perform calibration independent of whether it's later used for
> +  PCIe or USB, all PCIe mode clocks and resets must be defined.
> +
> +properties:
> +  compatible:
> +    const: spacemit,k1-combo-phy
> +
> +  reg:
> +    items:
> +      - description: PHY control registers
> +
> +  clocks:
> +    items:
> +      - description: DWC PCIe Data Bus Interface (DBI) clock
> +      - description: DWC PCIe application AXI-bus Master interface clock
> +      - description: DWC PCIe application AXI-bus Slave interface clock.

End with a period or don't. Just be consistent.

You need DWC PCIe clocks for your PHY? A ref clock would make sense, but 
these? I've never seen a PHY with a AXI master interface.

> +
> +  clock-names:
> +    items:
> +      - const: dbi
> +      - const: mstr
> +      - const: slv
> +
> +  resets:
> +    items:
> +      - description: DWC PCIe Data Bus Interface (DBI) reset
> +      - description: DWC PCIe application AXI-bus Master interface reset
> +      - description: DWC PCIe application AXI-bus Slave interface reset.

Same here (on both points).

> +      - description: Global reset; must be deasserted for PHY to function
> +
> +  reset-names:
> +    items:
> +      - const: dbi
> +      - const: mstr
> +      - const: slv
> +      - const: global
> +
> +  spacemit,syscon-pmu:
> +    description:
> +      PHandle that refers to the APMU system controller, whose
> +      regmap is used in setting the mode
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +
> +  "#phy-cells":
> +    const: 1
> +    description:
> +      The argument value (PHY_TYPE_PCIE or PHY_TYPE_USB3) determines
> +      whether the PHY operates in PCIe or USB3 mode.
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - clock-names
> +  - resets
> +  - reset-names
> +  - spacemit,syscon-pmu
> +  - "#phy-cells"
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/spacemit,k1-syscon.h>
> +    combo_phy: phy at c0b10000 {

Drop unused labels.

> +        compatible = "spacemit,k1-combo-phy";
> +        reg = <0xc0b10000 0x1000>;
> +        clocks = <&syscon_apmu CLK_PCIE0_DBI>,
> +                 <&syscon_apmu CLK_PCIE0_MASTER>,
> +                 <&syscon_apmu CLK_PCIE0_SLAVE>;
> +        clock-names = "dbi",
> +                      "mstr",
> +                      "slv";
> +        resets = <&syscon_apmu RESET_PCIE0_DBI>,
> +                 <&syscon_apmu RESET_PCIE0_MASTER>,
> +                 <&syscon_apmu RESET_PCIE0_SLAVE>,
> +                 <&syscon_apmu RESET_PCIE0_GLOBAL>;
> +        reset-names = "dbi",
> +                      "mstr",
> +                      "slv",
> +                      "global";
> +        spacemit,syscon-pmu = <&syscon_apmu>;
> +        #phy-cells = <1>;
> +        status = "disabled";
> +    };
> -- 
> 2.48.1
> 


From robh at kernel.org  Thu Aug 14 14:12:24 2025
From: robh at kernel.org (Rob Herring (Arm))
Date: Thu, 14 Aug 2025 16:12:24 -0500
Subject: [PATCH RESEND 1/2] dt-bindings: leds: issi,is31fl319x: Drop 'db'
 suffix duplicating dtschema
In-Reply-To: <20250811-dt-bindings-db-v1-1-457301523bb5@linaro.org>
References: <20250811-dt-bindings-db-v1-0-457301523bb5@linaro.org>
 <20250811-dt-bindings-db-v1-1-457301523bb5@linaro.org>
Message-ID: <175520594376.3919024.11270343433080389857.robh@kernel.org>


On Mon, 11 Aug 2025 15:54:03 +0200, Krzysztof Kozlowski wrote:
> A common property unit suffix '-db' was added to dtschema, thus
> in-kernel bindings should not reference the type.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> 
> ---
> 
> RFC because this depends on dtschema changes and should be accepted
> after new dtschema is released with this merged:
> https://github.com/devicetree-org/dt-schema/pull/166
> ---
>  Documentation/devicetree/bindings/leds/issi,is31fl319x.yaml | 1 -
>  1 file changed, 1 deletion(-)
> 

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



From elder at riscstar.com  Thu Aug 14 14:48:48 2025
From: elder at riscstar.com (Alex Elder)
Date: Thu, 14 Aug 2025 16:48:48 -0500
Subject: [PATCH 1/6] dt-bindings: phy: spacemit: add SpacemiT PCIe/combo
 PHY
In-Reply-To: <20250814205128.GA3873683-robh@kernel.org>
References: <20250813184701.2444372-1-elder@riscstar.com>
 <20250813184701.2444372-2-elder@riscstar.com>
 <20250814205128.GA3873683-robh@kernel.org>
Message-ID: <bc6975bd-cc1a-41ff-887c-0509bc8f03c3@riscstar.com>

On 8/14/25 3:51 PM, Rob Herring wrote:
> On Wed, Aug 13, 2025 at 01:46:55PM -0500, Alex Elder wrote:
>> Add the Device Tree binding for the PCIe/USB 3.0 combo PHY found in
>> the SpacemiT K1 SoC.  This is one of three PCIe PHYs, and is unusual
>> in that only the combo PHY can perform a calibration step needed to
>> determine settings used by the other two PCIe PHYs.
>>
>> Calibration must be done with the combo PHY in PCIe mode, and to allow
>> this to occur independent of the eventual use for the PHY (PCIe or USB)
>> some PCIe-related properties must be supplied: clocks; resets; and a
>> syscon phandle.
>>
>> Signed-off-by: Alex Elder <elder at riscstar.com>
>> ---
>>   .../bindings/phy/spacemit,k1-combo-phy.yaml   | 110 ++++++++++++++++++
>>   1 file changed, 110 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/phy/spacemit,k1-combo-phy.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/phy/spacemit,k1-combo-phy.yaml b/Documentation/devicetree/bindings/phy/spacemit,k1-combo-phy.yaml
>> new file mode 100644
>> index 0000000000000..ed78083a53231
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/phy/spacemit,k1-combo-phy.yaml
>> @@ -0,0 +1,110 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/phy/spacemit,k1-combo-phy.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: SpacemiT K1 PCIe/USB3 Combo PHY
>> +
>> +maintainers:
>> +  - Alex Elder <elder at riscstar.com>
>> +
>> +description:
> 
> You need a '>' or the paragraphs formatting will not be maintained
> (should we ever render docs from this).

OK.

>> +  Of the three PHYs on the SpacemiT K1 SoC capable of being used for
>> +  PCIe, one is a combo PHY that can also be configured for use by a
>> +  USB 3 controller.  Using PCIe or USB 3 is a board design decision.
>> +
>> +  The combo PHY is also the only PCIe PHY that is able to determine
>> +  PCIe calibration values to use, and this must be determined before
>> +  the other two PCIe PHYs can be used.  This calibration must be
>> +  performed with the combo PHY in PCIe mode, and is this is done
>> +  when the combo PHY is probed.
>> +
>> +  During normal operation, the PCIe or USB port driver is responsible
>> +  for ensuring all clocks needed by a PHY are enabled, and all resets
>> +  affecting the PHY are deasserted.  However, for the combo PHY to
>> +  perform calibration independent of whether it's later used for
>> +  PCIe or USB, all PCIe mode clocks and resets must be defined.
>> +
>> +properties:
>> +  compatible:
>> +    const: spacemit,k1-combo-phy
>> +
>> +  reg:
>> +    items:
>> +      - description: PHY control registers
>> +
>> +  clocks:
>> +    items:
>> +      - description: DWC PCIe Data Bus Interface (DBI) clock
>> +      - description: DWC PCIe application AXI-bus Master interface clock
>> +      - description: DWC PCIe application AXI-bus Slave interface clock.
> 
> End with a period or don't. Just be consistent.

OK.

> You need DWC PCIe clocks for your PHY? A ref clock would make sense, but
> these? I've never seen a PHY with a AXI master interface.

*This* is what I was waiting for.  I explained it briefly in
the patch headers and elsewhere but I expected questions.

This is needed to support USB mode, while also supporting the other
PCIe interfaces.

The SpacemiT IP requires its PCIe interfaces to have 4-bit RX and TX
receiver termination values be configured during initialization.  The
values to use must be determined dynamically by doing a calibration
step, then reading a (PCIe) register that contains the values to use.

Only the combo PHY is able to perform this calibration. and the
configuration values it determines must then be used to configure
the other two PCIe (only) PHYs.

This means that to calibrate, the combo PHY must be started (clocks
enabled, resets de-asserted) in PCIe mode.

If the combo PHY were going to be used for PCIe, this could be done
when it is initialized, because the PCIe driver would ensure the
clocks and resets were set up properly.

But if the combo PHY is going to be used for USB, the PCIe
calibration step would (otherwise) never be done, and that
means the other two PCIe interfaces could not be used.

So my solution is to move this calibration step into the PHY.
The combo PHY performs the calibration step when it is probed,
and to do that the driver needs to use its PCIe clocks and resets.
Once the calibration values are known, the clocks and resets
are essentially forgotten, and the PHY is available for use (by
either PCIe or USB 3).

The other two PCIe interfaces cannot probe (-EPROBE_DEFER) until
the calibration values are known, which means they might have to
wait until after the combo PHY has probed successfully.

I asked SpacemiT about this a lot, but their answer is that the
combo PHY is the only one that can determine these values, and
they must be determined each time the hardware is powered up.

I think this approach is less ugly than some alternatives.

Is this clear?  Can you think of a different way of handling it?

>> +
>> +  clock-names:
>> +    items:
>> +      - const: dbi
>> +      - const: mstr
>> +      - const: slv
>> +
>> +  resets:
>> +    items:
>> +      - description: DWC PCIe Data Bus Interface (DBI) reset
>> +      - description: DWC PCIe application AXI-bus Master interface reset
>> +      - description: DWC PCIe application AXI-bus Slave interface reset.
> 
> Same here (on both points).

I will remove the period on the third one.

> 
>> +      - description: Global reset; must be deasserted for PHY to function
>> +
>> +  reset-names:
>> +    items:
>> +      - const: dbi
>> +      - const: mstr
>> +      - const: slv
>> +      - const: global
>> +
>> +  spacemit,syscon-pmu:
>> +    description:
>> +      PHandle that refers to the APMU system controller, whose
>> +      regmap is used in setting the mode
>> +    $ref: /schemas/types.yaml#/definitions/phandle
>> +
>> +  "#phy-cells":
>> +    const: 1
>> +    description:
>> +      The argument value (PHY_TYPE_PCIE or PHY_TYPE_USB3) determines
>> +      whether the PHY operates in PCIe or USB3 mode.
>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +  - clocks
>> +  - clock-names
>> +  - resets
>> +  - reset-names
>> +  - spacemit,syscon-pmu
>> +  - "#phy-cells"
>> +
>> +additionalProperties: false
>> +
>> +examples:
>> +  - |
>> +    #include <dt-bindings/clock/spacemit,k1-syscon.h>
>> +    combo_phy: phy at c0b10000 {
> 
> Drop unused labels.

OK.

>> +        compatible = "spacemit,k1-combo-phy";
>> +        reg = <0xc0b10000 0x1000>;
>> +        clocks = <&syscon_apmu CLK_PCIE0_DBI>,
>> +                 <&syscon_apmu CLK_PCIE0_MASTER>,
>> +                 <&syscon_apmu CLK_PCIE0_SLAVE>;
>> +        clock-names = "dbi",
>> +                      "mstr",
>> +                      "slv";
>> +        resets = <&syscon_apmu RESET_PCIE0_DBI>,
>> +                 <&syscon_apmu RESET_PCIE0_MASTER>,
>> +                 <&syscon_apmu RESET_PCIE0_SLAVE>,
>> +                 <&syscon_apmu RESET_PCIE0_GLOBAL>;
>> +        reset-names = "dbi",
>> +                      "mstr",
>> +                      "slv",
>> +                      "global";
>> +        spacemit,syscon-pmu = <&syscon_apmu>;
>> +        #phy-cells = <1>;
>> +        status = "disabled";

Krzysztof also pointed out that I can't disable it so I'll drop
the above line as well.

Thanks for the review.

					-Alex

>> +    };
>> -- 
>> 2.48.1
>>



From andersson at kernel.org  Thu Aug 14 15:26:05 2025
From: andersson at kernel.org (Bjorn Andersson)
Date: Thu, 14 Aug 2025 17:26:05 -0500
Subject: [PATCH v2] phy: qcom: qmp-pcie: Fix PHY initialization when
 powered down by firmware
In-Reply-To: <20250814-phy-qcom-qmp-pcie-nocsr-fix-v2-1-fe562b5d02a1@linaro.org>
References: <20250814-phy-qcom-qmp-pcie-nocsr-fix-v2-1-fe562b5d02a1@linaro.org>
Message-ID: <e5hn42qxz2eqgjanyoxb2456wvuw6zy55ibbg6fh33jma7utvq@mlq2a57owz4g>

On Thu, Aug 14, 2025 at 11:27:10AM +0200, Stephan Gerhold wrote:
> Commit 0cc22f5a861c ("phy: qcom: qmp-pcie: Add PHY register retention
> support") added support for using the "no_csr" reset to skip configuration
> of the PHY if the init sequence was already applied by the boot firmware.
> The expectation is that the PHY is only turned on/off by using the "no_csr"
> reset, instead of powering it down and re-programming it after a full
> reset.
> 
> The boot firmware on X1E does not fully conform to this expectation: If the
> PCIe3 link fails to come up (e.g. because no PCIe card is inserted), the
> firmware powers down the PHY using the QPHY_PCS_POWER_DOWN_CONTROL
> register. The QPHY_START_CTRL register is kept as-is, so the driver assumes
> the PHY is already initialized and skips the configuration/power up
> sequence. The PHY won't come up again without clearing the
> QPHY_PCS_POWER_DOWN_CONTROL, so eventually initialization fails:
> 
>   qcom-qmp-pcie-phy 1be0000.phy: phy initialization timed-out
>   phy phy-1be0000.phy.0: phy poweron failed --> -110
>   qcom-pcie 1bd0000.pcie: cannot initialize host
>   qcom-pcie 1bd0000.pcie: probe with driver qcom-pcie failed with error -110
> 
> This can be reliably reproduced on the X1E CRD, QCP and Devkit when no card
> is inserted for PCIe3.
> 
> Fix this by checking the QPHY_PCS_POWER_DOWN_CONTROL register in addition
> to QPHY_START_CTRL. If the PHY is powered down with the register, it
> doesn't conform to the expectations for using the "no_csr" reset, so we
> fully re-initialize with the normal reset sequence.
> 
> Also check the register more carefully to ensure all of the bits we expect
> are actually set. A simple !!(readl()) is not enough, because the PHY might
> be only partially set up with some of the expected bits set.
> 
> Cc: stable at vger.kernel.org
> Fixes: 0cc22f5a861c ("phy: qcom: qmp-pcie: Add PHY register retention support")
> Signed-off-by: Stephan Gerhold <stephan.gerhold at linaro.org>
> ---
> Changes in v2:
> - Ensure that all expected bits are set (Konrad)
> - Link to v1: https://lore.kernel.org/r/20250812-phy-qcom-qmp-pcie-nocsr-fix-v1-1-9a7d0a5d2b46 at linaro.org
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 14 ++++++++++++--
>  1 file changed, 12 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
> index 95830dcfdec9b1f68fd55d1cc3c102985cfafcc1..80973527fafcb294273dff1864828532dab738db 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
> @@ -3067,6 +3067,14 @@ struct qmp_pcie {
>  	struct clk_fixed_rate aux_clk_fixed;
>  };
>  
> +static bool qphy_checkbits(const void __iomem *base, u32 offset, u32 val)
> +{
> +	u32 reg;
> +
> +	reg = readl(base + offset);
> +	return (reg & val) == val;
> +}
> +
>  static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
>  {
>  	u32 reg;
> @@ -4339,10 +4347,12 @@ static int qmp_pcie_init(struct phy *phy)
>  	struct qmp_pcie *qmp = phy_get_drvdata(phy);
>  	const struct qmp_phy_cfg *cfg = qmp->cfg;
>  	void __iomem *pcs = qmp->pcs;
> -	bool phy_initialized = !!(readl(pcs + cfg->regs[QPHY_START_CTRL]));
>  	int ret;
>  
> -	qmp->skip_init = qmp->nocsr_reset && phy_initialized;
> +	qmp->skip_init = qmp->nocsr_reset &&
> +		qphy_checkbits(pcs, cfg->regs[QPHY_START_CTRL], SERDES_START | PCS_START) &&
> +		qphy_checkbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], cfg->pwrdn_ctrl);

IMHO the "phy_initialized" variable does provide valuable context to
what those (now) two lines represents. That is particularly relevant as
the second one is active low...so at least I need to think a bit extra
to understand what's going on.

Other than that, I think this looks good.

Regards,
Bjorn

> +
>  	/*
>  	 * We need to check the existence of init sequences in two cases:
>  	 * 1. The PHY doesn't support no_csr reset.
> 
> ---
> base-commit: 8f5ae30d69d7543eee0d70083daf4de8fe15d585
> change-id: 20250812-phy-qcom-qmp-pcie-nocsr-fix-1603106294cd
> 
> Best regards,
> -- 
> Stephan Gerhold <stephan.gerhold at linaro.org>
> 


From inochiama at gmail.com  Thu Aug 14 15:49:58 2025
From: inochiama at gmail.com (Inochi Amaoto)
Date: Fri, 15 Aug 2025 06:49:58 +0800
Subject: [PATCH 4/6] phy: spacemit: introduce PCIe/combo PHY
In-Reply-To: <4eaa30bc-9a25-4fe0-b685-1d0d8fa503c2@riscstar.com>
References: <20250813184701.2444372-1-elder@riscstar.com>
 <20250813184701.2444372-5-elder@riscstar.com>
 <valmrbddij2dn4fjxefr46zud2u6eco2isyaa62sd66d27foyl@4hrhafqftgb5>
 <4eaa30bc-9a25-4fe0-b685-1d0d8fa503c2@riscstar.com>
Message-ID: <mj5e6afmbqo2tpt3zjuebcfif3flvgqq663erv3xuvbg72nd6g@bapy44nobzyw>

On Thu, Aug 14, 2025 at 07:15:43AM -0500, Alex Elder wrote:
> On 8/13/25 6:42 PM, Inochi Amaoto wrote:
> > On Wed, Aug 13, 2025 at 01:46:58PM -0500, Alex Elder wrote:
> > > Introduce a driver that supports three PHYs found on the SpacemiT
> > > K1 SoC.  The first PHY is a combo PHY that can be configured for
> > > use for either USB 3 or PCIe.  The other two PHYs support PCIe
> > > only.
> > > 
> > > All three PHYs must be programmed with an 8 bit receiver termination
> > > value, which must be determined dynamically; only the combo PHY is
> > > able to determine this value.  The combo PHY performs a special
> > > calibration step at probe time to discover this, and that value is
> > > used to program each PHY that operates in PCIe mode.  The combo
> > > PHY must therefore be probed--first--if either of the PCIe-only
> > > PHYs will be used.
> > > 
> > > During normal operation, the USB or PCIe driver using the PHY must
> > > ensure clocks and resets are set up properly.  However clocks are
> > > enabled and resets are de-asserted temporarily by this driver to
> > > perform the calibration step on the combo PHY.
> > > 
> > > Tested-by: Junzhong Pan <panjunzhong at linux.spacemit.com>
> > > Signed-off-by: Alex Elder <elder at riscstar.com>
> > > ---
> > >   drivers/phy/Kconfig                |  11 +
> > >   drivers/phy/Makefile               |   1 +
> > >   drivers/phy/phy-spacemit-k1-pcie.c | 639 +++++++++++++++++++++++++++++
> > >   3 files changed, 651 insertions(+)
> > >   create mode 100644 drivers/phy/phy-spacemit-k1-pcie.c
> 
> . . .
> 
> > > diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
> > > index c670a8dac4680..20f0078e543c7 100644
> > > --- a/drivers/phy/Makefile
> > > +++ b/drivers/phy/Makefile
> 
> . . .
> 
> > > +static int k1_pcie_pll_lock(struct k1_pcie_phy *k1_phy, bool pcie)
> > > +{
> > > +	u32 val = pcie ? CFG_FORCE_RCV_RETRY : 0;
> > > +	void __iomem *virt;
> > > +
> > > +	writel(val, k1_phy->regs + PCIE_RC_DONE_STATUS);
> > > +
> > > +	/*
> > > +	 * Wait for indication the PHY PLL is locked.  Lanes for ports
> > > +	 * B and C share a PLL, so it's enough to sample just lane 0.
> > > +	 */
> > > +	virt = k1_phy->regs + PCIE_PU_ADDR_CLK_CFG;	/* Lane 0 */
> > > +
> > > +	return readl_poll_timeout(virt, val, val & PLL_READY,
> > > +				  POLL_DELAY, PLL_TIMEOUT);
> > > +}
> > > +
> > 
> > Can we use standard clk_ops and clk_mux to normalize this process?
> 
> I understand you're suggesting that we represent this as a clock.
> 
> Can you be more specific about how you suggest I do that?
> 
> For example, are you suggesting I create a separate clock driver
> for this one PLL (in each PCIe register space)?
> 
> Or do you mean use clock structures and callbacks within this
> driver to represent this?
> 

I think using clock structures and registering them is just fine, 
there are many phy drivers already do this.

> I'm just not sure what you have in mind, and the two options I
> mention seem a lot more complicated than this one function.
> 

Yes, it is more complex than just adding one function, but it 
make the code clean and easy to understand as the clock looks
complex. Also, register this clock allow us to know the state
of internal clock by looking clk_summary.

Regards,
Inochi


From me at adomerle.pw  Thu Aug 14 16:48:24 2025
From: me at adomerle.pw (Arseniy Velikanov)
Date: Fri, 15 Aug 2025 03:48:24 +0400
Subject: [PATCH v1 1/2] dt-bindings: phy: mtk-tphy: add property for software role switch
Message-ID: <20250814234825.810-1-me@adomerle.pw>

Add a boolean property to enable software control of the PHY mode
switching.

Signed-off-by: Arseniy Velikanov <me at adomerle.pw>
---
 Documentation/devicetree/bindings/phy/mediatek,tphy.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
index b2218c151939..a90890d4a86f 100644
--- a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
+++ b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
@@ -255,6 +255,12 @@ patternProperties:
           use the property "mediatek,syscon-type" for newer SoCs that support it.
         type: boolean
 
+      mediatek,software-role-switch:
+        description:
+          Forcibly sets the phy mode. In dual-role mode, it polls
+          role switcher and manually changes mode accordingly.
+          PHY port must be linked with the role switcher via device tree graphs.
+
       mediatek,syscon-type:
         $ref: /schemas/types.yaml#/definitions/phandle-array
         maxItems: 1
-- 
2.50.1


From me at adomerle.pw  Thu Aug 14 16:48:25 2025
From: me at adomerle.pw (Arseniy Velikanov)
Date: Fri, 15 Aug 2025 03:48:25 +0400
Subject: [PATCH v1 2/2] phy: mediatek: tphy: Add software role switching
In-Reply-To: <20250814234825.810-1-me@adomerle.pw>
References: <20250814234825.810-1-me@adomerle.pw>
Message-ID: <20250814234825.810-2-me@adomerle.pw>

MediaTek USB T-PHY has broken role switching on (likely) all mobile SoCs.
Known affected socs are: MT6735, MT6757, MT6761, MT6765, MT6768, MT6771,
MT6785, MT6789.

The downstream kernel manually controls the PHY mode by writing
"test mode" FORCE regs. Setting all these regs fixes device/host modes, but
breaks dual-role functionality. As a workaround we use workqueue that
periodically checks the USB role and changes the PHY mode accordingly.

To address this issue only on affected SoCs, we introduce a new
device-tree property `mediatek,software-role-switch`. This ensures
the workaround is applied only to broken hardware while leaving unaffected
devices (like Chromebooks) untouched.

Signed-off-by: Arseniy Velikanov <me at adomerle.pw>
---
 drivers/phy/mediatek/phy-mtk-tphy.c | 148 ++++++++++++++++++++++++++++
 1 file changed, 148 insertions(+)

diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
index f6504e0ecd1a..472859ec929c 100644
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
@@ -18,6 +18,9 @@
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
+#include <linux/usb/role.h>
+#include <linux/usb/otg.h>
+#include <linux/workqueue.h>
 
 #include "phy-mtk-io.h"
 
@@ -111,11 +114,18 @@
 
 #define U3P_U2PHYDTM1		0x06C
 #define P2C_RG_UART_EN			BIT(16)
+#define P2C_FORCE_IDPULLUP	BIT(8)
 #define P2C_FORCE_IDDIG		BIT(9)
+#define P2C_FORCE_AVALID	BIT(10)
+#define P2C_FORCE_SESSEND	BIT(12)
+#define P2C_FORCE_VBUSVALID	BIT(13)
+
 #define P2C_RG_VBUSVALID		BIT(5)
 #define P2C_RG_SESSEND			BIT(4)
+#define P2C_RG_BVALID			BIT(3)
 #define P2C_RG_AVALID			BIT(2)
 #define P2C_RG_IDDIG			BIT(1)
+#define P2C_RG_IDPULLUP			BIT(0)
 
 #define U3P_U2PHYBC12C		0x080
 #define P2C_RG_CHGDT_EN		BIT(0)
@@ -317,6 +327,8 @@ struct mtk_phy_instance {
 		struct u3phy_banks u3_banks;
 	};
 	struct clk_bulk_data clks[TPHY_CLKS_CNT];
+	struct delayed_work dr_work;
+	struct usb_role_switch *role_switch;
 	u32 index;
 	u32 type;
 	struct regmap *type_sw;
@@ -326,14 +338,17 @@ struct mtk_phy_instance {
 	u32 efuse_intr;
 	u32 efuse_tx_imp;
 	u32 efuse_rx_imp;
+	int current_role;
 	int eye_src;
 	int eye_vrt;
 	int eye_term;
 	int intr;
 	int discth;
 	int pre_emphasis;
+	int sw_get_retries;
 	bool bc12_en;
 	bool type_force_mode;
+	bool software_role_switch;
 };
 
 struct mtk_tphy {
@@ -818,12 +833,118 @@ static void u2_phy_pll_26m_set(struct mtk_tphy *tphy,
 			 P2R_RG_U2PLL_FRA_EN | P2R_RG_U2PLL_REFCLK_SEL);
 }
 
+static void u2_phy_instance_role_set(struct mtk_phy_instance *instance,
+				     int role)
+{
+	struct u2phy_banks *u2_banks = &instance->u2_banks;
+	void __iomem *com = u2_banks->com;
+
+	instance->current_role = role;
+
+	/* end session before role switch */
+	mtk_phy_set_bits(com + U3P_U2PHYDTM1, P2C_RG_SESSEND);
+	mdelay(5);
+	mtk_phy_clear_bits(com + U3P_U2PHYDTM1, P2C_RG_SESSEND);
+
+	switch (role) {
+	case USB_ROLE_DEVICE:
+		dev_dbg(&instance->phy->dev, "set device role\n");
+		mtk_phy_set_bits(com + U3P_U2PHYDTM1, P2C_RG_IDDIG);
+		break;
+	case USB_ROLE_HOST:
+		dev_dbg(&instance->phy->dev, "set host role\n");
+		mtk_phy_clear_bits(com + U3P_U2PHYDTM1, P2C_RG_IDDIG);
+		break;
+	default:
+		break;
+	}
+}
+
+static void u2_phy_role_switch_work(struct work_struct *work)
+{
+	struct mtk_phy_instance *instance =
+		container_of(work, struct mtk_phy_instance, dr_work.work);
+	int role;
+
+	if (IS_ERR_OR_NULL(instance->role_switch))
+		instance->role_switch = usb_role_switch_get(&instance->phy->dev);
+
+	if (IS_ERR_OR_NULL(instance->role_switch)) {
+		if (instance->sw_get_retries >= 10) {
+			dev_warn(&instance->phy->dev, "failed to get role switch\n");
+			return;
+		}
+
+		instance->sw_get_retries += 1;
+		schedule_delayed_work(&instance->dr_work, msecs_to_jiffies(500));
+	}
+
+	role = usb_role_switch_get_role(instance->role_switch);
+
+	if (instance->current_role == role)
+		goto reschedule_work;
+
+	u2_phy_instance_role_set(instance, role);
+
+reschedule_work:
+	schedule_delayed_work(&instance->dr_work, msecs_to_jiffies(100));
+}
+
+static int u2_phy_software_role_switch_init(struct mtk_phy_instance *instance)
+{
+	struct fwnode_handle *ep, *remote_ep, *usb_fwnode;
+	struct device *usb_dev;
+	int mode;
+
+	instance->sw_get_retries = 0;
+
+	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(&instance->phy->dev),
+					     0,
+					     0,
+					     FWNODE_GRAPH_ENDPOINT_NEXT);
+	if (!ep)
+		return -ENODEV;
+
+	remote_ep = fwnode_graph_get_remote_endpoint(ep);
+	fwnode_handle_put(ep);
+	if (!remote_ep)
+		return -ENODEV;
+
+	usb_fwnode = fwnode_graph_get_port_parent(remote_ep);
+	fwnode_handle_put(remote_ep);
+
+	if (!usb_fwnode)
+		return -ENODEV;
+
+	usb_dev = bus_find_device_by_fwnode(&platform_bus_type, usb_fwnode);
+	fwnode_handle_put(usb_fwnode);
+	if (!usb_dev)
+		return -ENODEV;
+
+	mode = usb_get_role_switch_default_mode(usb_dev);
+	if (mode == USB_DR_MODE_HOST)
+		u2_phy_instance_role_set(instance, USB_ROLE_HOST);
+	else
+		u2_phy_instance_role_set(instance, USB_ROLE_DEVICE);
+
+	INIT_DELAYED_WORK(&instance->dr_work, u2_phy_role_switch_work);
+
+	return 0;
+}
+
 static void u2_phy_instance_init(struct mtk_tphy *tphy,
 	struct mtk_phy_instance *instance)
 {
 	struct u2phy_banks *u2_banks = &instance->u2_banks;
 	void __iomem *com = u2_banks->com;
 	u32 index = instance->index;
+	int ret;
+
+	if (instance->software_role_switch) {
+		ret = u2_phy_software_role_switch_init(instance);
+		if (ret)
+			dev_warn(&instance->phy->dev, "failed to initialize role switching\n");
+	}
 
 	/* switch to USB function, and enable usb pll */
 	mtk_phy_clear_bits(com + U3P_U2PHYDTM0, P2C_FORCE_UART_EN | P2C_FORCE_SUSPENDM);
@@ -883,6 +1004,18 @@ static void u2_phy_instance_power_on(struct mtk_tphy *tphy,
 
 		mtk_phy_set_bits(com + U3P_U2PHYDTM0, P2C_RG_SUSPENDM | P2C_FORCE_SUSPENDM);
 	}
+
+	if (instance->software_role_switch) {
+		/* Set FORCE modes for manual role switching */
+		mtk_phy_set_bits(com + U3P_U2PHYDTM1, P2C_FORCE_IDPULLUP
+			| P2C_FORCE_IDDIG | P2C_FORCE_AVALID | P2C_FORCE_VBUSVALID
+			| P2C_FORCE_SESSEND);
+		mtk_phy_set_bits(com + U3P_U2PHYDTM1, P2C_RG_IDPULLUP | P2C_RG_BVALID);
+
+		if (!instance->role_switch)
+			schedule_delayed_work(&instance->dr_work, msecs_to_jiffies(100));
+	}
+
 	dev_dbg(tphy->dev, "%s(%d)\n", __func__, index);
 }
 
@@ -906,6 +1039,9 @@ static void u2_phy_instance_power_off(struct mtk_tphy *tphy,
 		mtk_phy_clear_bits(com + U3D_U2PHYDCR0, P2C_RG_SIF_U2PLL_FORCE_ON);
 	}
 
+	if (instance->role_switch)
+		cancel_delayed_work_sync(&instance->dr_work);
+
 	dev_dbg(tphy->dev, "%s(%d)\n", __func__, index);
 }
 
@@ -940,6 +1076,9 @@ static void u2_phy_instance_set_mode(struct mtk_tphy *tphy,
 		tmp &= ~P2C_RG_IDDIG;
 		break;
 	case PHY_MODE_USB_OTG:
+		/* We are managing role in workqueue */
+		if (instance->software_role_switch)
+			return;
 		tmp &= ~(P2C_FORCE_IDDIG | P2C_RG_IDDIG);
 		break;
 	default:
@@ -1129,6 +1268,11 @@ static void phy_parse_property(struct mtk_tphy *tphy,
 	if (instance->type == PHY_TYPE_USB3)
 		instance->type_force_mode = device_property_read_bool(dev, "mediatek,force-mode");
 
+	instance->software_role_switch =
+		device_property_read_bool(dev, "mediatek,software-role-switch");
+	if (instance->software_role_switch)
+		dev_info(dev, "software role switch enabled\n");
+
 	if (instance->type != PHY_TYPE_USB2)
 		return;
 
@@ -1618,6 +1762,10 @@ static int mtk_tphy_probe(struct platform_device *pdev)
 		struct phy *phy;
 		int retval;
 
+		/* filter non-phy nodes (e.g. graphs) */
+		if (!of_find_property(child_np, "reg", NULL))
+			continue;
+
 		instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
 		if (!instance)
 			return -ENOMEM;
-- 
2.50.1


From dlan at gentoo.org  Thu Aug 14 16:57:57 2025
From: dlan at gentoo.org (Yixun Lan)
Date: Fri, 15 Aug 2025 07:57:57 +0800
Subject: [PATCH 4/6] phy: spacemit: introduce PCIe/combo PHY
In-Reply-To: <4eaa30bc-9a25-4fe0-b685-1d0d8fa503c2@riscstar.com>
References: <20250813184701.2444372-1-elder@riscstar.com>
 <20250813184701.2444372-5-elder@riscstar.com>
 <valmrbddij2dn4fjxefr46zud2u6eco2isyaa62sd66d27foyl@4hrhafqftgb5>
 <4eaa30bc-9a25-4fe0-b685-1d0d8fa503c2@riscstar.com>
Message-ID: <20250814235757-GYA1008367@gentoo>

Hi Alex,

On 07:15 Thu 14 Aug     , Alex Elder wrote:
> On 8/13/25 6:42 PM, Inochi Amaoto wrote:
> > On Wed, Aug 13, 2025 at 01:46:58PM -0500, Alex Elder wrote:
> >> Introduce a driver that supports three PHYs found on the SpacemiT
> >> K1 SoC.  The first PHY is a combo PHY that can be configured for
> >> use for either USB 3 or PCIe.  The other two PHYs support PCIe
> >> only.
> >>
> >> All three PHYs must be programmed with an 8 bit receiver termination
> >> value, which must be determined dynamically; only the combo PHY is
> >> able to determine this value.  The combo PHY performs a special
> >> calibration step at probe time to discover this, and that value is
> >> used to program each PHY that operates in PCIe mode.  The combo
> >> PHY must therefore be probed--first--if either of the PCIe-only
> >> PHYs will be used.
> >>
> >> During normal operation, the USB or PCIe driver using the PHY must
> >> ensure clocks and resets are set up properly.  However clocks are
> >> enabled and resets are de-asserted temporarily by this driver to
> >> perform the calibration step on the combo PHY.
> >>
> >> Tested-by: Junzhong Pan <panjunzhong at linux.spacemit.com>
> >> Signed-off-by: Alex Elder <elder at riscstar.com>
> >> ---
> >>   drivers/phy/Kconfig                |  11 +
> >>   drivers/phy/Makefile               |   1 +
> >>   drivers/phy/phy-spacemit-k1-pcie.c | 639 +++++++++++++++++++++++++++++
> >>   3 files changed, 651 insertions(+)
> >>   create mode 100644 drivers/phy/phy-spacemit-k1-pcie.c
> 
> . . .
> 
> >> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
> >> index c670a8dac4680..20f0078e543c7 100644
> >> --- a/drivers/phy/Makefile
> >> +++ b/drivers/phy/Makefile
> 
> . . .
> 
> >> +static int k1_pcie_pll_lock(struct k1_pcie_phy *k1_phy, bool pcie)
> >> +{
> >> +	u32 val = pcie ? CFG_FORCE_RCV_RETRY : 0;
> >> +	void __iomem *virt;
> >> +
> >> +	writel(val, k1_phy->regs + PCIE_RC_DONE_STATUS);
> >> +
> >> +	/*
> >> +	 * Wait for indication the PHY PLL is locked.  Lanes for ports
> >> +	 * B and C share a PLL, so it's enough to sample just lane 0.
> >> +	 */
> >> +	virt = k1_phy->regs + PCIE_PU_ADDR_CLK_CFG;	/* Lane 0 */
> >> +
> >> +	return readl_poll_timeout(virt, val, val & PLL_READY,
> >> +				  POLL_DELAY, PLL_TIMEOUT);
> >> +}
> >> +
> > 
> > Can we use standard clk_ops and clk_mux to normalize this process?
> 
> I understand you're suggesting that we represent this as a clock.
> 
> Can you be more specific about how you suggest I do that?
> 
> For example, are you suggesting I create a separate clock driver
> for this one PLL (in each PCIe register space)?
> 
> Or do you mean use clock structures and callbacks within this
> driver to represent this?
> 
> I'm just not sure what you have in mind, and the two options I
> mention seem a lot more complicated than this one function.
> 
> Thanks.
you can take a look at k1's i2c patch that Troy just sent which has similar case

https://lore.kernel.org/all/20250814-k1-i2c-ilcr-v3-1-317723e74bcd at linux.spacemit.com/

> 
> 					-Alex
> 
> > Regards,
> > Inochi
> 

-- 
Yixun Lan (dlan)


From robh at kernel.org  Thu Aug 14 19:29:01 2025
From: robh at kernel.org (Rob Herring (Arm))
Date: Thu, 14 Aug 2025 21:29:01 -0500
Subject: [PATCH v1 1/2] dt-bindings: phy: mtk-tphy: add property for
 software role switch
In-Reply-To: <20250814234825.810-1-me@adomerle.pw>
References: <20250814234825.810-1-me@adomerle.pw>
Message-ID: <175522494130.180632.985870901068506270.robh@kernel.org>


On Fri, 15 Aug 2025 03:48:24 +0400, Arseniy Velikanov wrote:
> Add a boolean property to enable software control of the PHY mode
> switching.
> 
> Signed-off-by: Arseniy Velikanov <me at adomerle.pw>
> ---
>  Documentation/devicetree/bindings/phy/mediatek,tphy.yaml | 6 ++++++
>  1 file changed, 6 insertions(+)
> 

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/phy/mediatek,tphy.yaml: mediatek,software-role-switch: missing type definition

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20250814234825.810-1-me at adomerle.pw

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  Thu Aug 14 23:28:47 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 15 Aug 2025 08:28:47 +0200
Subject: [PATCH v1 1/2] dt-bindings: phy: mtk-tphy: add property for
 software role switch
In-Reply-To: <20250814234825.810-1-me@adomerle.pw>
References: <20250814234825.810-1-me@adomerle.pw>
Message-ID: <20250815-important-warm-dove-03dde5@kuoka>

On Fri, Aug 15, 2025 at 03:48:24AM +0400, Arseniy Velikanov wrote:
> Add a boolean property to enable software control of the PHY mode
> switching.
> 
> Signed-off-by: Arseniy Velikanov <me at adomerle.pw>
> ---
>  Documentation/devicetree/bindings/phy/mediatek,tphy.yaml | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
> index b2218c151939..a90890d4a86f 100644
> --- a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
> +++ b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
> @@ -255,6 +255,12 @@ patternProperties:
>            use the property "mediatek,syscon-type" for newer SoCs that support it.
>          type: boolean
>  
> +      mediatek,software-role-switch:

No, bindings do not describe software.

Also, never tested.

Best regards,
Krzysztof



From xiangxu.yin at oss.qualcomm.com  Fri Aug 15 01:25:43 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Fri, 15 Aug 2025 16:25:43 +0800
Subject: [PATCH v2 02/13] dt-bindings: phy: Add binding for QCS615
 standalone QMP DP PHY
In-Reply-To: <0c94206c-f70f-4bed-81ec-bb2870748121@kernel.org>
References: <20250722-add-displayport-support-for-qcs615-platform-v2-0-42b4037171f8@oss.qualcomm.com>
 <20250722-add-displayport-support-for-qcs615-platform-v2-2-42b4037171f8@oss.qualcomm.com>
 <0c94206c-f70f-4bed-81ec-bb2870748121@kernel.org>
Message-ID: <661789d6-5fbe-4915-b70a-5ff2466c7a26@oss.qualcomm.com>


On 7/22/2025 5:18 PM, Krzysztof Kozlowski wrote:
> On 22/07/2025 09:22, Xiangxu Yin wrote:
>> Introduce device tree binding documentation for the Qualcomm QMP DP PHY
>> on QCS615 SoCs. This PHY supports DisplayPort functionality and is
>> designed to operate independently from the USB3 PHY.
> A nit, subject: drop second/last, redundant "binding for". 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

Ok, will update subject in next patch.

>> Unlike combo PHYs found on other platforms, the QCS615 DP PHY is
>> standalone and does not support USB/DP multiplexing. The binding
>> describes the required clocks, resets, TCSR configuration, and clock/PHY
>> cells for proper integration.
>>
>> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
>> ---
>>  .../bindings/phy/qcom,qcs615-qmp-dp-phy.yaml       | 111 +++++++++++++++++++++
>>  1 file changed, 111 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-dp-phy.yaml
>> new file mode 100644
>> index 0000000000000000000000000000000000000000..17e37c1df7b61dc2f7aa35ee106fd94ee2829c5f
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-dp-phy.yaml
>> @@ -0,0 +1,111 @@
>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/phy/qcom,qcs615-qmp-dp-phy.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Qualcomm QMP PHY controller (DP, QCS615)
> That's too vague title. You are not adding here Qualcomm QMP PHY
> controllers.

Will update to 'Qualcomm QMP USB3-DP PHY controller (DP, QCS615)' in next patch.

>
>> +
>> +maintainers:
>> +  - Vinod Koul <vkoul at kernel.org>
> Hm? Why?


I referred to the definitions in qcom,msm8998-qmp-usb3-phy.yaml and qcom,sc8280xp-qmp-usb43dp-phy.yaml.

I also found that Vinod Koul is listed as the maintainer of the GENERIC PHY FRAMEWORK in linux-next/MAINTAINERS.

Did I misunderstand anything here?


>> +
>> +description:
>> +  The QMP DP PHY controller supports DisplayPort physical layer functionality
>> +  on Qualcomm QCS615 SoCs. This PHY is independent from USB3 PHY and does not
>> +  support combo mode.
>> +
>> +properties:
>> +  compatible:
>> +    enum:
>> +      - qcom,qcs615-qmp-dp-phy
>> +
>> +  reg:
>> +    maxItems: 4
> I don't understand what you are doing here. Why previous patch evolved
> into this? Where is any reasoning for that in the changelog? You said:
>
> "- Add new binding qcom,qcs615-qmp-dp-phy.yaml for QCS615 standalone DP
> [Krzysztof]"
>
> but you must say WHY you are doing things...
>
> Anyway, missing constraints. Look at other Qualcomm bindings.


I misunderstood your earlier comment in?'20241129-add-displayport-support-for-qcs615-platform-v1-2-09a4338d93ef at quicinc.com'?and mistakenly included "[Krzysztof]" in the commit message as if it were a quote.?

Apologies for the confusion and will drop this part in cover letter in next patch.

In next patch, the address regions will be consolidated into a single range, similar to other QMP PHYs, and?|maxItems|?will be updated to?|1|.


>
>> +
>> +  clocks:
>> +    maxItems: 2
>> +
>> +  clock-names:
>> +    items:
>> +      - const: cfg_ahb
>> +      - const: ref
>> +
>> +  clock-output-names:
>> +    maxItems: 2
>> +    description:
>> +      Names of the clocks provided by the PHY.
> Drop description, redundant. It cannot be anything else.


Ok, will drop it.


>
>> +
>> +  qcom,tcsr-reg:
>> +    $ref: /schemas/types.yaml#/definitions/phandle-array
>> +    items:
>> +      - items:
>> +          - description: phandle to TCSR hardware block
>> +          - description: offset of the DP PHY moode register
>> +    description:
>> +      DP PHY moode register present in the TCSR
>> +
>> +  resets:
>> +    maxItems: 1
>> +
>> +  reset-names:
>> +    items:
>> +      - const: phy
> Drop reset-names, useless.


In next patch, this config will be updated to USB or DP PHY binding with two resets: 'phy_phy' for USB and 'dp_phy' for DP.
Shall I keep 'reset-names' prop here?

>
>> +
>> +  vdda-phy-supply: true
>> +
>> +  vdda-pll-supply: true
>> +
>> +  "#clock-cells":
>> +    const: 1
>> +    description:
>> +      See include/dt-bindings/phy/phy-qcom-qmp.h
>> +
>> +  "#phy-cells":
>> +    const: 1
>> +    description:
>> +      See include/dt-bindings/phy/phy-qcom-qmp.h
>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +  - clocks
>> +  - clock-names
>> +  - clock-output-names
>> +  - qcom,tcsr-reg
>> +  - resets
>> +  - reset-names
>> +  - vdda-phy-supply
>> +  - vdda-pll-supply
>> +  - "#clock-cells"
>> +  - "#phy-cells"
>> +
> Why introducing completely different order? See existing binding and DTS
> coding style.
>
> Best regards,
> Krzysztof


Ok, will update to follow the existing order.

compatible
reg
clocks
clock-names
resets
reset-names
vdda-phy-supply
vdda-pll-supply
#clock-cells
#phy-cells
qcom,tcsr-reg



From xiangxu.yin at oss.qualcomm.com  Fri Aug 15 01:30:08 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Fri, 15 Aug 2025 16:30:08 +0800
Subject: [PATCH v2 03/13] dt-bindings: phy: qcom,msm8998-qmp-usb3-phy:
 support dual TCSR registers
In-Reply-To: <2fd202a6-2c92-469c-81c0-8852562d4e35@kernel.org>
References: <20250722-add-displayport-support-for-qcs615-platform-v2-0-42b4037171f8@oss.qualcomm.com>
 <20250722-add-displayport-support-for-qcs615-platform-v2-3-42b4037171f8@oss.qualcomm.com>
 <2fd202a6-2c92-469c-81c0-8852562d4e35@kernel.org>
Message-ID: <f330e6a4-ec51-4682-aa35-bef9c6e8ad3a@oss.qualcomm.com>


On 7/22/2025 5:19 PM, Krzysztof Kozlowski wrote:
> On 22/07/2025 09:22, Xiangxu Yin wrote:
>> Add support for specifying two TCSR register addresses in the
>> qcom,tcsr-reg property to enable DP-only mode switching. This change
>> maintains backward compatibility with the original single-register
>> format.
>>
>> Also update #clock-cells and #phy-cells to <1> to support clock and PHY
>> provider interfaces, respectively. This is required for platforms that
>> consume the PHY clock and select PHY mode dynamically.
>>
>> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
>> ---
>>  .../bindings/phy/qcom,msm8998-qmp-usb3-phy.yaml    | 28 +++++++++++++++++-----
>>  1 file changed, 22 insertions(+), 6 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/phy/qcom,msm8998-qmp-usb3-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,msm8998-qmp-usb3-phy.yaml
>> index 1636285fbe535c430fdf792b33a5e9c523de323b..badfc46cda6c3a128688ac63b00d97dc2ba742d6 100644
>> --- a/Documentation/devicetree/bindings/phy/qcom,msm8998-qmp-usb3-phy.yaml
>> +++ b/Documentation/devicetree/bindings/phy/qcom,msm8998-qmp-usb3-phy.yaml
>> @@ -44,13 +44,21 @@ properties:
>>    vdda-pll-supply: true
>>  
>>    "#clock-cells":
>> -    const: 0
>> +    oneOf:
>> +      - description: Set to 0 for legacy platforms without clock provider
>> +        const: 0
>> +      - description: Set to 1 to expose PHY pipe clock.
>> +        const: 1
>>  
>>    clock-output-names:
>>      maxItems: 1
>>  
>>    "#phy-cells":
>> -    const: 0
>> +    oneOf:
>> +      - description: Set to 0 for legacy platforms
>> +        const: 0
>> +      - description: Set to 1 to supports mode selection (e.g. USB/DP)
>> +        const: 1
> I don't understand why EXISTING platforms now get more clocks. What did
> you change in the hardware? This you must explain in the commit msg.
>
>
> Best regards,
> Krzysztof


As discussed in [PATCH v2 02/13], I misunderstood Dmitry's intent regarding backward compatibility in v1.?

This part will be dropped in the next patch to avoid affecting existing platform configurations. Thanks for pointing it out.




From ziyue.zhang at oss.qualcomm.com  Fri Aug 15 01:51:20 2025
From: ziyue.zhang at oss.qualcomm.com (Ziyue Zhang)
Date: Fri, 15 Aug 2025 16:51:20 +0800
Subject: [PATCH v10 0/5] pci: qcom: Add QCS8300 PCIe support
In-Reply-To: <20250811071131.982983-1-ziyue.zhang@oss.qualcomm.com>
References: <20250811071131.982983-1-ziyue.zhang@oss.qualcomm.com>
Message-ID: <c931bbc5-f246-4d34-9280-0c1a551a1e7e@oss.qualcomm.com>


On 8/11/2025 3:11 PM, Ziyue Zhang wrote:
> This series depend on the sa8775p gcc_aux_clock and link_down reset change
> https://lore.kernel.org/all/20250725102231.3608298-2-ziyue.zhang at oss.qualcomm.com/
>
> This series adds document, phy, configs support for PCIe in QCS8300.
> It also adds 'link_down' reset for sa8775p.
>
> Have follwing changes:
> 	- Add dedicated schema for the PCIe controllers found on QCS8300.
> 	- Add compatible for qcs8300 platform.
> 	- Add configurations in devicetree for PCIe0, including registers, clocks, interrupts and phy setting sequence.
> 	- Add configurations in devicetree for PCIe1, including registers, clocks, interrupts and phy setting sequence.
>
> Signed-off-by: Krishna chaitanya chundru <quic_krichai at quicinc.com>
> Signed-off-by: Ziyue Zhang <quic_ziyuzhan at quicinc.com>
> ---
> Changes in v10:
> - Update PHY max_items (Johan)
> - Link to v9: https://lore.kernel.org/all/20250725104037.4054070-1-ziyue.zhang at oss.qualcomm.com/
>
> Changes in v9:
> - Fix DTB error (Vinod)
> - Link to v8: https://lore.kernel.org/all/20250714081529.3847385-1-ziyue.zhang at oss.qualcomm.com/
>
> Changes in v8:
> - rebase sc8280xp-qmp-pcie-phy change to solve conflicts.
> - Add Fixes tag to phy change (Johan)
> - Link to v7: https://lore.kernel.org/all/20250625092539.762075-1-quic_ziyuzhan at quicinc.com/
>
> Changes in v7:
> - rebase qcs8300-ride.dtsi change to solve conflicts.
> - Link to v6: https://lore.kernel.org/all/20250529035635.4162149-1-quic_ziyuzhan at quicinc.com/
>
> Changes in v6:
> - move the qcs8300 and sa8775p phy compatibility entry into the list of PHYs that require six clocks
> - Update QCS8300 and sa8775p phy dt, remove aux clock.
> - Fixed compile error found by kernel test robot
> - Link to v5: https://lore.kernel.org/all/20250507031019.4080541-1-quic_ziyuzhan at quicinc.com/
>
> Changes in v5:
> - Add QCOM PCIe controller version in commit msg (Mani)
> - Modify platform dts change subject (Dmitry)
> - Fixed compile error found by kernel test robot
> - Link to v4: https://lore.kernel.org/linux-phy/20241220055239.2744024-1-quic_ziyuzhan at quicinc.com/
>
> Changes in v4:
> - Add received tag
> - Fixed compile error found by kernel test robot
> - Link to v3: https://lore.kernel.org/lkml/202412211301.bQO6vXpo-lkp at intel.com/T/#mdd63e5be39acbf879218aef91c87b12d4540e0f7
>
> Changes in v3:
> - Add received tag(Rob & Dmitry)
> - Update pcie_phy in gcc node to soc dtsi(Dmitry & Konrad)
> - remove pcieprot0 node(Konrad & Mani)
> - Fix format comments(Konrad)
> - Update base-commit to tag: next-20241213(Bjorn)
> - Corrected of_device_id.data from 1.9.0 to 1.34.0.
> - Link to v2: https://lore.kernel.org/all/20241128081056.1361739-1-quic_ziyuzhan at quicinc.com/
>
> Changes in v2:
> - Fix some format comments and match the style in x1e80100(Konrad)
> - Add global interrupt for PCIe0 and PCIe1(Konrad)
> - split the soc dtsi and the platform dts into two changes(Konrad)
> - Link to v1: https://lore.kernel.org/all/20241114095409.2682558-1-quic_ziyuzhan at quicinc.com/
>
> Ziyue Zhang (5):
>    dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Update pcie phy bindings
>      for qcs8300
>    arm64: dts: qcom: qcs8300: enable pcie0
>    arm64: dts: qcom: qcs8300-ride: enable pcie0 interface
>    arm64: dts: qcom: qcs8300: enable pcie1
>    arm64: dts: qcom: qcs8300-ride: enable pcie1 interface
>
>   .../phy/qcom,sc8280xp-qmp-pcie-phy.yaml       |  17 +-
>   arch/arm64/boot/dts/qcom/qcs8300-ride.dts     |  80 +++++
>   arch/arm64/boot/dts/qcom/qcs8300.dtsi         | 296 +++++++++++++++++-
>   3 files changed, 376 insertions(+), 17 deletions(-)
>
>
> base-commit: e2622a23e8405644c7188af39d4c1bd2b405bb27
Hi Maintainers,

It seems the patches get reviewed tag for a long time, can you give this

series further comment or help me to merge them ?

Thanks very much.

The phy binding's dependency is merged, the patch do not need to rebase.

dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Update pcie phy bindings
commit: aac1256a41cfbbaca12d6c0a5753d1e3b8d2d8bf


BRs
Ziyue


From krzk at kernel.org  Fri Aug 15 02:15:58 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 15 Aug 2025 11:15:58 +0200
Subject: [PATCH v10 0/5] pci: qcom: Add QCS8300 PCIe support
In-Reply-To: <c931bbc5-f246-4d34-9280-0c1a551a1e7e@oss.qualcomm.com>
References: <20250811071131.982983-1-ziyue.zhang@oss.qualcomm.com>
 <c931bbc5-f246-4d34-9280-0c1a551a1e7e@oss.qualcomm.com>
Message-ID: <8783e13d-65d0-4bfd-97e7-b3a0d1c7efe1@kernel.org>

On 15/08/2025 10:51, Ziyue Zhang wrote:
>>
>>   .../phy/qcom,sc8280xp-qmp-pcie-phy.yaml       |  17 +-
>>   arch/arm64/boot/dts/qcom/qcs8300-ride.dts     |  80 +++++
>>   arch/arm64/boot/dts/qcom/qcs8300.dtsi         | 296 +++++++++++++++++-
>>   3 files changed, 376 insertions(+), 17 deletions(-)
>>
>>
>> base-commit: e2622a23e8405644c7188af39d4c1bd2b405bb27
> Hi Maintainers,
> 
> It seems the patches get reviewed tag for a long time, can you give this
> 
> series further comment or help me to merge them ?


You pinged after one day.

I asked you to stop.

No respond. Now you pinged after 2 days.

Pinging time is 2 weeks. Read your internal guideline or kernel process
documents. Such frequent pings are only contributing to unnecessary
mailbox traffic.

Best regards,
Krzysztof


From stephan.gerhold at linaro.org  Fri Aug 15 02:43:18 2025
From: stephan.gerhold at linaro.org (Stephan Gerhold)
Date: Fri, 15 Aug 2025 11:43:18 +0200
Subject: [PATCH v2] phy: qcom: qmp-pcie: Fix PHY initialization when
 powered down by firmware
In-Reply-To: <e5hn42qxz2eqgjanyoxb2456wvuw6zy55ibbg6fh33jma7utvq@mlq2a57owz4g>
References: <20250814-phy-qcom-qmp-pcie-nocsr-fix-v2-1-fe562b5d02a1@linaro.org>
 <e5hn42qxz2eqgjanyoxb2456wvuw6zy55ibbg6fh33jma7utvq@mlq2a57owz4g>
Message-ID: <aJ8BNq7NLgYzzOMA@linaro.org>

On Thu, Aug 14, 2025 at 05:26:05PM -0500, Bjorn Andersson wrote:
> On Thu, Aug 14, 2025 at 11:27:10AM +0200, Stephan Gerhold wrote:
> > Commit 0cc22f5a861c ("phy: qcom: qmp-pcie: Add PHY register retention
> > support") added support for using the "no_csr" reset to skip configuration
> > of the PHY if the init sequence was already applied by the boot firmware.
> > The expectation is that the PHY is only turned on/off by using the "no_csr"
> > reset, instead of powering it down and re-programming it after a full
> > reset.
> > 
> > The boot firmware on X1E does not fully conform to this expectation: If the
> > PCIe3 link fails to come up (e.g. because no PCIe card is inserted), the
> > firmware powers down the PHY using the QPHY_PCS_POWER_DOWN_CONTROL
> > register. The QPHY_START_CTRL register is kept as-is, so the driver assumes
> > the PHY is already initialized and skips the configuration/power up
> > sequence. The PHY won't come up again without clearing the
> > QPHY_PCS_POWER_DOWN_CONTROL, so eventually initialization fails:
> > 
> >   qcom-qmp-pcie-phy 1be0000.phy: phy initialization timed-out
> >   phy phy-1be0000.phy.0: phy poweron failed --> -110
> >   qcom-pcie 1bd0000.pcie: cannot initialize host
> >   qcom-pcie 1bd0000.pcie: probe with driver qcom-pcie failed with error -110
> > 
> > This can be reliably reproduced on the X1E CRD, QCP and Devkit when no card
> > is inserted for PCIe3.
> > 
> > Fix this by checking the QPHY_PCS_POWER_DOWN_CONTROL register in addition
> > to QPHY_START_CTRL. If the PHY is powered down with the register, it
> > doesn't conform to the expectations for using the "no_csr" reset, so we
> > fully re-initialize with the normal reset sequence.
> > 
> > Also check the register more carefully to ensure all of the bits we expect
> > are actually set. A simple !!(readl()) is not enough, because the PHY might
> > be only partially set up with some of the expected bits set.
> > 
> > Cc: stable at vger.kernel.org
> > Fixes: 0cc22f5a861c ("phy: qcom: qmp-pcie: Add PHY register retention support")
> > Signed-off-by: Stephan Gerhold <stephan.gerhold at linaro.org>
> > ---
> > Changes in v2:
> > - Ensure that all expected bits are set (Konrad)
> > - Link to v1: https://lore.kernel.org/r/20250812-phy-qcom-qmp-pcie-nocsr-fix-v1-1-9a7d0a5d2b46 at linaro.org
> > ---
> >  drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 14 ++++++++++++--
> >  1 file changed, 12 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
> > index 95830dcfdec9b1f68fd55d1cc3c102985cfafcc1..80973527fafcb294273dff1864828532dab738db 100644
> > --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
> > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
> > @@ -3067,6 +3067,14 @@ struct qmp_pcie {
> >  	struct clk_fixed_rate aux_clk_fixed;
> >  };
> >  
> > +static bool qphy_checkbits(const void __iomem *base, u32 offset, u32 val)
> > +{
> > +	u32 reg;
> > +
> > +	reg = readl(base + offset);
> > +	return (reg & val) == val;
> > +}
> > +
> >  static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
> >  {
> >  	u32 reg;
> > @@ -4339,10 +4347,12 @@ static int qmp_pcie_init(struct phy *phy)
> >  	struct qmp_pcie *qmp = phy_get_drvdata(phy);
> >  	const struct qmp_phy_cfg *cfg = qmp->cfg;
> >  	void __iomem *pcs = qmp->pcs;
> > -	bool phy_initialized = !!(readl(pcs + cfg->regs[QPHY_START_CTRL]));
> >  	int ret;
> >  
> > -	qmp->skip_init = qmp->nocsr_reset && phy_initialized;
> > +	qmp->skip_init = qmp->nocsr_reset &&
> > +		qphy_checkbits(pcs, cfg->regs[QPHY_START_CTRL], SERDES_START | PCS_START) &&
> > +		qphy_checkbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], cfg->pwrdn_ctrl);
> 
> IMHO the "phy_initialized" variable does provide valuable context to
> what those (now) two lines represents. That is particularly relevant as
> the second one is active low...so at least I need to think a bit extra
> to understand what's going on.
> 

I dropped the "phy_initialized" variable mainly because it didn't "look
good" together with the line wrapping of the two new longer lines. :-)

Perhaps it would already help to reuse and clarify the comment block
below, like this?

Thanks,
Stephan

@@ -4339,16 +4347,21 @@ static int qmp_pcie_init(struct phy *phy)
 	struct qmp_pcie *qmp = phy_get_drvdata(phy);
 	const struct qmp_phy_cfg *cfg = qmp->cfg;
 	void __iomem *pcs = qmp->pcs;
-	bool phy_initialized = !!(readl(pcs + cfg->regs[QPHY_START_CTRL]));
 	int ret;
 
-	qmp->skip_init = qmp->nocsr_reset && phy_initialized;
 	/*
-	 * We need to check the existence of init sequences in two cases:
-	 * 1. The PHY doesn't support no_csr reset.
-	 * 2. The PHY supports no_csr reset but isn't initialized by bootloader.
-	 * As we can't skip init in these two cases.
+	 * We can skip PHY initialization if all of the following conditions
+	 * are met:
+	 *  1. The PHY supports the nocsr_reset that preserves the PHY config.
+	 *  2. The PHY was started (and not powered down again) by the
+	 *     bootloader, with all of the expected bits set correctly.
+	 * In this case, we can continue without having the init sequence
+	 * defined in the driver.
 	 */
+	qmp->skip_init = qmp->nocsr_reset &&
+		qphy_checkbits(pcs, cfg->regs[QPHY_START_CTRL], SERDES_START | PCS_START) &&
+		qphy_checkbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], cfg->pwrdn_ctrl);
+
 	if (!qmp->skip_init && !cfg->tbls.serdes_num) {
 		dev_err(qmp->dev, "Init sequence not available\n");
 		return -ENODATA;


From ck.hu at mediatek.com  Fri Aug 15 02:43:55 2025
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Fri, 15 Aug 2025 09:43:55 +0000
Subject: [PATCH] phy: mediatek: Modify mipi clk upper bound to 2.5Gbps
In-Reply-To: <20250814125406.4161220-1-payne.lin@mediatek.com>
References: <20250814125406.4161220-1-payne.lin@mediatek.com>
Message-ID: <94672a94c59bd6b65317044f070129446b5ec8cb.camel@mediatek.com>

On Thu, 2025-08-14 at 20:54 +0800, payne.lin wrote:
> From: Bincai Liu <bincai.liu at mediatek.com>
> 
> Mipi dphy can support up to 4k30 without dsc.

Reviewed-by: CK Hu <ck.hu at mediatek.com>

> 
> Signed-off-by: Bincai Liu <bincai.liu at mediatek.com>
> Signed-off-by: Payne Lin <payne.lin at mediatek.com>
> ---
>  drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
> index 553725e1269c..b8233c496070 100644
> --- a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
> +++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
> @@ -100,7 +100,7 @@ static void mtk_mipi_tx_pll_disable(struct clk_hw *hw)
>  static long mtk_mipi_tx_pll_round_rate(struct clk_hw *hw, unsigned long rate,
>  				       unsigned long *prate)
>  {
> -	return clamp_val(rate, 125000000, 1600000000);
> +	return clamp_val(rate, 125000000, 2500000000);
>  }
>  
>  static const struct clk_ops mtk_mipi_tx_pll_ops = {


From robh at kernel.org  Fri Aug 15 14:19:08 2025
From: robh at kernel.org (Rob Herring (Arm))
Date: Fri, 15 Aug 2025 16:19:08 -0500
Subject: [PATCH 0/3] Describe x1e80100 ufs
In-Reply-To: <20250814005904.39173-1-harrison.vanderbyl@gmail.com>
References: <20250814005904.39173-1-harrison.vanderbyl@gmail.com>
Message-ID: <175529259928.3212336.2833391770643806145.robh@kernel.org>


On Thu, 14 Aug 2025 10:59:01 +1000, Harrison Vanderbyl wrote:
> Describes the UFS nodes for the x1e80100/x1p42100 chipset.
> 
> This is relevant to the following devices/patches:
> Surface Pro 12 Inch
> HONOR MagicBook Art 14
> Link: https://lore.kernel.org/r/871px910m1.wl-kirill at korins.ky/
> Samsung Galaxy Book4 Edge
> Link: https://lore.kernel.org/r/p3mhtj2rp6y2ezuwpd2gu7dwx5cbckfu4s4pazcudi4j2wogtr at 4yecb2bkeyms/
> 
> Forthcoming work *not* included in this patch:
> Surface 12in display description
> Surface 12in Surface Aggregator Module description
> Surface 12in device tree
> 
> harrisonvanderbyl (3):
>   dt-bindings: describe x1e80100 ufs
>   ufs: ufs-qcom: describe x1e80100 quirks
>   dts: describe x1e80100 ufs
> 
>  .../phy/qcom,sc8280xp-qmp-ufs-phy.yaml        |  2 +
>  .../devicetree/bindings/ufs/qcom,ufs.yaml     |  2 +
>  arch/arm64/boot/dts/qcom/x1e80100.dtsi        | 91 +++++++++++++++++++
>  drivers/phy/qualcomm/phy-qcom-qmp-ufs.c       |  3 +
>  drivers/ufs/host/ufs-qcom.c                   |  1 +
>  5 files changed, 99 insertions(+)
> 
> --
> 2.48.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


This patch series was applied (using b4) to base:
 Base: attempting to guess base-commit...
 Base: tags/v6.17-rc1-2-gc123519bffd2 (exact match)

If this is not the correct base, please add 'base-commit' tag
(or use b4 which does this automatically)

New warnings running 'make CHECK_DTBS=y for arch/arm64/boot/dts/qcom/' for 20250814005904.39173-1-harrison.vanderbyl at gmail.com:

Error: arch/arm64/boot/dts/qcom/x1e80100.dtsi:2839.29-30 syntax error
FATAL ERROR: Unable to parse input tree
make[3]: *** [scripts/Makefile.dtbs:131: arch/arm64/boot/dts/qcom/x1e80100-asus-zenbook-a14.dtb] Error 1
make[2]: *** [scripts/Makefile.build:556: arch/arm64/boot/dts/qcom] Error 2
make[2]: Target 'arch/arm64/boot/dts/qcom/x1e80100-asus-zenbook-a14.dtb' not remade because of errors.
make[1]: *** [/home/rob/proj/linux-dt-testing/Makefile:1480: qcom/x1e80100-asus-zenbook-a14.dtb] Error 2
arch/arm64/boot/dts/qcom/x1e80100-dell-xps13-9345.dtb: phy at 1d80000 (qcom,x1e80100-qmp-ufs-phy): clocks: [[2, 0], [61, 242]] is too short
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-ufs-phy.yaml#
arch/arm64/boot/dts/qcom/x1e80100-dell-xps13-9345.dtb: crypto at 1d90000 (qcom,x1e80100-inline-crypto-engine): compatible:0: 'qcom,x1e80100-inline-crypto-engine' is not one of ['qcom,qcs8300-inline-crypto-engine', 'qcom,sa8775p-inline-crypto-engine', 'qcom,sc7180-inline-crypto-engine', 'qcom,sc7280-inline-crypto-engine', 'qcom,sm8450-inline-crypto-engine', 'qcom,sm8550-inline-crypto-engine', 'qcom,sm8650-inline-crypto-engine', 'qcom,sm8750-inline-crypto-engine']
	from schema $id: http://devicetree.org/schemas/crypto/qcom,inline-crypto-engine.yaml#
arch/arm64/boot/dts/qcom/x1e80100-dell-xps13-9345.dtb: /soc at 0/crypto at 1d90000: failed to match any schema with compatible: ['qcom,x1e80100-inline-crypto-engine', 'qcom,inline-crypto-engine']
arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s-oled.dtb: phy at 1d80000 (qcom,x1e80100-qmp-ufs-phy): clocks: [[2, 0], [61, 242]] is too short
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-ufs-phy.yaml#
arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s-oled.dtb: crypto at 1d90000 (qcom,x1e80100-inline-crypto-engine): compatible:0: 'qcom,x1e80100-inline-crypto-engine' is not one of ['qcom,qcs8300-inline-crypto-engine', 'qcom,sa8775p-inline-crypto-engine', 'qcom,sc7180-inline-crypto-engine', 'qcom,sc7280-inline-crypto-engine', 'qcom,sm8450-inline-crypto-engine', 'qcom,sm8550-inline-crypto-engine', 'qcom,sm8650-inline-crypto-engine', 'qcom,sm8750-inline-crypto-engine']
	from schema $id: http://devicetree.org/schemas/crypto/qcom,inline-crypto-engine.yaml#
arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s-oled.dtb: /soc at 0/crypto at 1d90000: failed to match any schema with compatible: ['qcom,x1e80100-inline-crypto-engine', 'qcom,inline-crypto-engine']
arch/arm64/boot/dts/qcom/x1e80100-lenovo-yoga-slim7x.dtb: phy at 1d80000 (qcom,x1e80100-qmp-ufs-phy): clocks: [[2, 0], [61, 242]] is too short
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-ufs-phy.yaml#
arch/arm64/boot/dts/qcom/x1e80100-lenovo-yoga-slim7x.dtb: crypto at 1d90000 (qcom,x1e80100-inline-crypto-engine): compatible:0: 'qcom,x1e80100-inline-crypto-engine' is not one of ['qcom,qcs8300-inline-crypto-engine', 'qcom,sa8775p-inline-crypto-engine', 'qcom,sc7180-inline-crypto-engine', 'qcom,sc7280-inline-crypto-engine', 'qcom,sm8450-inline-crypto-engine', 'qcom,sm8550-inline-crypto-engine', 'qcom,sm8650-inline-crypto-engine', 'qcom,sm8750-inline-crypto-engine']
	from schema $id: http://devicetree.org/schemas/crypto/qcom,inline-crypto-engine.yaml#
arch/arm64/boot/dts/qcom/x1e80100-lenovo-yoga-slim7x.dtb: /soc at 0/crypto at 1d90000: failed to match any schema with compatible: ['qcom,x1e80100-inline-crypto-engine', 'qcom,inline-crypto-engine']
Error: arch/arm64/boot/dts/qcom/x1e80100.dtsi:2839.29-30 syntax error
FATAL ERROR: Unable to parse input tree
make[3]: *** [scripts/Makefile.dtbs:131: arch/arm64/boot/dts/qcom/x1p42100-crd.dtb] Error 1
make[2]: *** [scripts/Makefile.build:556: arch/arm64/boot/dts/qcom] Error 2
make[2]: Target 'arch/arm64/boot/dts/qcom/x1p42100-crd.dtb' not remade because of errors.
make[1]: *** [/home/rob/proj/linux-dt-testing/Makefile:1480: qcom/x1p42100-crd.dtb] Error 2
arch/arm64/boot/dts/qcom/x1e001de-devkit.dtb: phy at 1d80000 (qcom,x1e80100-qmp-ufs-phy): clocks: [[2, 0], [61, 242]] is too short
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-ufs-phy.yaml#
arch/arm64/boot/dts/qcom/x1e001de-devkit.dtb: crypto at 1d90000 (qcom,x1e80100-inline-crypto-engine): compatible:0: 'qcom,x1e80100-inline-crypto-engine' is not one of ['qcom,qcs8300-inline-crypto-engine', 'qcom,sa8775p-inline-crypto-engine', 'qcom,sc7180-inline-crypto-engine', 'qcom,sc7280-inline-crypto-engine', 'qcom,sm8450-inline-crypto-engine', 'qcom,sm8550-inline-crypto-engine', 'qcom,sm8650-inline-crypto-engine', 'qcom,sm8750-inline-crypto-engine']
	from schema $id: http://devicetree.org/schemas/crypto/qcom,inline-crypto-engine.yaml#
arch/arm64/boot/dts/qcom/x1e001de-devkit.dtb: /soc at 0/crypto at 1d90000: failed to match any schema with compatible: ['qcom,x1e80100-inline-crypto-engine', 'qcom,inline-crypto-engine']
arch/arm64/boot/dts/qcom/x1e80100-hp-omnibook-x14.dtb: phy at 1d80000 (qcom,x1e80100-qmp-ufs-phy): clocks: [[2, 0], [61, 242]] is too short
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-ufs-phy.yaml#
arch/arm64/boot/dts/qcom/x1e80100-hp-omnibook-x14.dtb: crypto at 1d90000 (qcom,x1e80100-inline-crypto-engine): compatible:0: 'qcom,x1e80100-inline-crypto-engine' is not one of ['qcom,qcs8300-inline-crypto-engine', 'qcom,sa8775p-inline-crypto-engine', 'qcom,sc7180-inline-crypto-engine', 'qcom,sc7280-inline-crypto-engine', 'qcom,sm8450-inline-crypto-engine', 'qcom,sm8550-inline-crypto-engine', 'qcom,sm8650-inline-crypto-engine', 'qcom,sm8750-inline-crypto-engine']
	from schema $id: http://devicetree.org/schemas/crypto/qcom,inline-crypto-engine.yaml#
arch/arm64/boot/dts/qcom/x1e80100-hp-omnibook-x14.dtb: /soc at 0/crypto at 1d90000: failed to match any schema with compatible: ['qcom,x1e80100-inline-crypto-engine', 'qcom,inline-crypto-engine']
arch/arm64/boot/dts/qcom/x1e80100-qcp.dtb: phy at 1d80000 (qcom,x1e80100-qmp-ufs-phy): clocks: [[2, 0], [61, 242]] is too short
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-ufs-phy.yaml#
arch/arm64/boot/dts/qcom/x1e80100-qcp.dtb: crypto at 1d90000 (qcom,x1e80100-inline-crypto-engine): compatible:0: 'qcom,x1e80100-inline-crypto-engine' is not one of ['qcom,qcs8300-inline-crypto-engine', 'qcom,sa8775p-inline-crypto-engine', 'qcom,sc7180-inline-crypto-engine', 'qcom,sc7280-inline-crypto-engine', 'qcom,sm8450-inline-crypto-engine', 'qcom,sm8550-inline-crypto-engine', 'qcom,sm8650-inline-crypto-engine', 'qcom,sm8750-inline-crypto-engine']
	from schema $id: http://devicetree.org/schemas/crypto/qcom,inline-crypto-engine.yaml#
arch/arm64/boot/dts/qcom/x1e80100-qcp.dtb: /soc at 0/crypto at 1d90000: failed to match any schema with compatible: ['qcom,x1e80100-inline-crypto-engine', 'qcom,inline-crypto-engine']
arch/arm64/boot/dts/qcom/x1e80100-asus-vivobook-s15.dtb: phy at 1d80000 (qcom,x1e80100-qmp-ufs-phy): clocks: [[2, 0], [61, 242]] is too short
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-ufs-phy.yaml#
arch/arm64/boot/dts/qcom/x1e80100-asus-vivobook-s15.dtb: crypto at 1d90000 (qcom,x1e80100-inline-crypto-engine): compatible:0: 'qcom,x1e80100-inline-crypto-engine' is not one of ['qcom,qcs8300-inline-crypto-engine', 'qcom,sa8775p-inline-crypto-engine', 'qcom,sc7180-inline-crypto-engine', 'qcom,sc7280-inline-crypto-engine', 'qcom,sm8450-inline-crypto-engine', 'qcom,sm8550-inline-crypto-engine', 'qcom,sm8650-inline-crypto-engine', 'qcom,sm8750-inline-crypto-engine']
	from schema $id: http://devicetree.org/schemas/crypto/qcom,inline-crypto-engine.yaml#
arch/arm64/boot/dts/qcom/x1e80100-asus-vivobook-s15.dtb: /soc at 0/crypto at 1d90000: failed to match any schema with compatible: ['qcom,x1e80100-inline-crypto-engine', 'qcom,inline-crypto-engine']
arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtb: phy at 1d80000 (qcom,x1e80100-qmp-ufs-phy): clocks: [[2, 0], [61, 242]] is too short
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-ufs-phy.yaml#
arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtb: crypto at 1d90000 (qcom,x1e80100-inline-crypto-engine): compatible:0: 'qcom,x1e80100-inline-crypto-engine' is not one of ['qcom,qcs8300-inline-crypto-engine', 'qcom,sa8775p-inline-crypto-engine', 'qcom,sc7180-inline-crypto-engine', 'qcom,sc7280-inline-crypto-engine', 'qcom,sm8450-inline-crypto-engine', 'qcom,sm8550-inline-crypto-engine', 'qcom,sm8650-inline-crypto-engine', 'qcom,sm8750-inline-crypto-engine']
	from schema $id: http://devicetree.org/schemas/crypto/qcom,inline-crypto-engine.yaml#
arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtb: /soc at 0/crypto at 1d90000: failed to match any schema with compatible: ['qcom,x1e80100-inline-crypto-engine', 'qcom,inline-crypto-engine']
Error: arch/arm64/boot/dts/qcom/x1e80100.dtsi:2839.29-30 syntax error
FATAL ERROR: Unable to parse input tree
make[3]: *** [scripts/Makefile.dtbs:131: arch/arm64/boot/dts/qcom/x1p42100-asus-zenbook-a14.dtb] Error 1
make[2]: *** [scripts/Makefile.build:556: arch/arm64/boot/dts/qcom] Error 2
make[2]: Target 'arch/arm64/boot/dts/qcom/x1p42100-asus-zenbook-a14.dtb' not remade because of errors.
make[1]: *** [/home/rob/proj/linux-dt-testing/Makefile:1480: qcom/x1p42100-asus-zenbook-a14.dtb] Error 2
arch/arm64/boot/dts/qcom/x1e80100-hp-elitebook-ultra-g1q.dtb: phy at 1d80000 (qcom,x1e80100-qmp-ufs-phy): clocks: [[2, 0], [61, 242]] is too short
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-ufs-phy.yaml#
arch/arm64/boot/dts/qcom/x1e80100-hp-elitebook-ultra-g1q.dtb: crypto at 1d90000 (qcom,x1e80100-inline-crypto-engine): compatible:0: 'qcom,x1e80100-inline-crypto-engine' is not one of ['qcom,qcs8300-inline-crypto-engine', 'qcom,sa8775p-inline-crypto-engine', 'qcom,sc7180-inline-crypto-engine', 'qcom,sc7280-inline-crypto-engine', 'qcom,sm8450-inline-crypto-engine', 'qcom,sm8550-inline-crypto-engine', 'qcom,sm8650-inline-crypto-engine', 'qcom,sm8750-inline-crypto-engine']
	from schema $id: http://devicetree.org/schemas/crypto/qcom,inline-crypto-engine.yaml#
arch/arm64/boot/dts/qcom/x1e80100-hp-elitebook-ultra-g1q.dtb: /soc at 0/crypto at 1d90000: failed to match any schema with compatible: ['qcom,x1e80100-inline-crypto-engine', 'qcom,inline-crypto-engine']
arch/arm64/boot/dts/qcom/x1e80100-microsoft-romulus15.dtb: phy at 1d80000 (qcom,x1e80100-qmp-ufs-phy): clocks: [[2, 0], [61, 242]] is too short
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-ufs-phy.yaml#
arch/arm64/boot/dts/qcom/x1e80100-microsoft-romulus15.dtb: crypto at 1d90000 (qcom,x1e80100-inline-crypto-engine): compatible:0: 'qcom,x1e80100-inline-crypto-engine' is not one of ['qcom,qcs8300-inline-crypto-engine', 'qcom,sa8775p-inline-crypto-engine', 'qcom,sc7180-inline-crypto-engine', 'qcom,sc7280-inline-crypto-engine', 'qcom,sm8450-inline-crypto-engine', 'qcom,sm8550-inline-crypto-engine', 'qcom,sm8650-inline-crypto-engine', 'qcom,sm8750-inline-crypto-engine']
	from schema $id: http://devicetree.org/schemas/crypto/qcom,inline-crypto-engine.yaml#
arch/arm64/boot/dts/qcom/x1e80100-microsoft-romulus15.dtb: /soc at 0/crypto at 1d90000: failed to match any schema with compatible: ['qcom,x1e80100-inline-crypto-engine', 'qcom,inline-crypto-engine']
Error: arch/arm64/boot/dts/qcom/x1e80100.dtsi:2839.29-30 syntax error
FATAL ERROR: Unable to parse input tree
make[3]: *** [scripts/Makefile.dtbs:131: arch/arm64/boot/dts/qcom/x1e80100-crd.dtb] Error 1
make[2]: *** [scripts/Makefile.build:556: arch/arm64/boot/dts/qcom] Error 2
make[2]: Target 'arch/arm64/boot/dts/qcom/x1e80100-crd.dtb' not remade because of errors.
make[1]: *** [/home/rob/proj/linux-dt-testing/Makefile:1480: qcom/x1e80100-crd.dtb] Error 2
arch/arm64/boot/dts/qcom/x1e80100-microsoft-romulus13.dtb: phy at 1d80000 (qcom,x1e80100-qmp-ufs-phy): clocks: [[2, 0], [61, 242]] is too short
	from schema $id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-ufs-phy.yaml#
arch/arm64/boot/dts/qcom/x1e80100-microsoft-romulus13.dtb: crypto at 1d90000 (qcom,x1e80100-inline-crypto-engine): compatible:0: 'qcom,x1e80100-inline-crypto-engine' is not one of ['qcom,qcs8300-inline-crypto-engine', 'qcom,sa8775p-inline-crypto-engine', 'qcom,sc7180-inline-crypto-engine', 'qcom,sc7280-inline-crypto-engine', 'qcom,sm8450-inline-crypto-engine', 'qcom,sm8550-inline-crypto-engine', 'qcom,sm8650-inline-crypto-engine', 'qcom,sm8750-inline-crypto-engine']
	from schema $id: http://devicetree.org/schemas/crypto/qcom,inline-crypto-engine.yaml#
arch/arm64/boot/dts/qcom/x1e80100-microsoft-romulus13.dtb: /soc at 0/crypto at 1d90000: failed to match any schema with compatible: ['qcom,x1e80100-inline-crypto-engine', 'qcom,inline-crypto-engine']
make: *** [Makefile:248: __sub-make] Error 2
make: Target 'qcom/apq8096-ifc6640.dtb' not remade because of errors.
make: Target 'qcom/msm8916-samsung-j3ltetw.dtb' not remade because of errors.
make: Target 'qcom/msm8998-fxtec-pro1.dtb' not remade because of errors.
make: Target 'qcom/sm7325-nothing-spacewar.dtb' not remade because of errors.
make: Target 'qcom/x1e80100-asus-zenbook-a14.dtb' not remade because of errors.
make: Target 'qcom/sm7125-xiaomi-curtana.dtb' not remade because of errors.
make: Target 'qcom/x1e80100-dell-xps13-9345.dtb' not remade because of errors.
make: Target 'qcom/msm8998-mtp.dtb' not remade because of errors.
make: Target 'qcom/msm8916-samsung-a5u-eur.dtb' not remade because of errors.
make: Target 'qcom/sc8280xp-lenovo-thinkpad-x13s.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-lazor-r3-lte.dtb' not remade because of errors.
make: Target 'qcom/sc7280-herobrine-crd-pro.dtb' not remade because of errors.
make: Target 'qcom/sm6115p-lenovo-j606f.dtb' not remade because of errors.
make: Target 'qcom/msm8998-sony-xperia-yoshino-maple.dtb' not remade because of errors.
make: Target 'qcom/ipq9574-rdp454.dtb' not remade because of errors.
make: Target 'qcom/qcs6490-rb3gen2.dtb' not remade because of errors.
make: Target 'qcom/msm8992-xiaomi-libra.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-lazor-limozeen-r4.dtb' not remade because of errors.
make: Target 'qcom/sdm450-motorola-ali.dtb' not remade because of errors.
make: Target 'qcom/x1e78100-lenovo-thinkpad-t14s-oled.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-quackingstick-r0.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-pazquel360-wifi.dtb' not remade because of errors.
make: Target 'qcom/sdm630-sony-xperia-ganges-kirin.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-coachz-r1-lte.dtb' not remade because of errors.
make: Target 'qcom/sdm845-lg-judyp.dtb' not remade because of errors.
make: Target 'qcom/sdm845-cheza-r3.dtb' not remade because of errors.
make: Target 'qcom/msm8939-wingtech-wt82918.dtb' not remade because of errors.
make: Target 'qcom/qrb2210-rb1.dtb' not remade because of errors.
make: Target 'qcom/msm8996-mtp.dtb' not remade because of errors.
make: Target 'qcom/sm8750-mtp.dtb' not remade because of errors.
make: Target 'qcom/sc7280-herobrine-zombie.dtb' not remade because of errors.
make: Target 'qcom/msm8992-lg-bullhead-rev-10.dtb' not remade because of errors.
make: Target 'qcom/qrb5165-rb5.dtb' not remade because of errors.
make: Target 'qcom/x1e80100-lenovo-yoga-slim7x.dtb' not remade because of errors.
make: Target 'qcom/sm8550-qrd.dtb' not remade because of errors.
make: Target 'qcom/sdm630-sony-xperia-nile-discovery.dtb' not remade because of errors.
make: Target 'qcom/sm8550-sony-xperia-yodo-pdx234.dtb' not remade because of errors.
make: Target 'qcom/msm8939-huawei-kiwi.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-wormdingler-rev1-inx.dtb' not remade because of errors.
make: Target 'qcom/sc8280xp-microsoft-arcata.dtb' not remade because of errors.
make: Target 'qcom/sdm845-oneplus-fajita.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-lazor-limozeen-nots-r4.dtb' not remade because of errors.
make: Target 'qcom/sdm660-xiaomi-lavender.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-coachz-r1.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-lazor-r10.dtb' not remade because of errors.
make: Target 'qcom/msm8939-wingtech-wt82918hd.dtb' not remade because of errors.
make: Target 'qcom/ipq6018-cp01-c1.dtb' not remade because of errors.
make: Target 'qcom/msm8916-motorola-surnia.dtb' not remade because of errors.
make: Target 'qcom/sm8350-microsoft-surface-duo2.dtb' not remade because of errors.
make: Target 'qcom/qcm6490-idp.dtb' not remade because of errors.
make: Target 'qcom/sm8550-mtp.dtb' not remade because of errors.
make: Target 'qcom/msm8916-samsung-a3u-eur.dtb' not remade because of errors.
make: Target 'qcom/sdm845-sony-xperia-tama-akari.dtb' not remade because of errors.
make: Target 'qcom/x1p42100-crd.dtb' not remade because of errors.
make: Target 'qcom/sm8250-mtp.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-lazor-limozeen-nots-r9.dtb' not remade because of errors.
make: Target 'qcom/sm8250-xiaomi-elish-csot.dtb' not remade because of errors.
make: Target 'qcom/msm8916-wingtech-wt88047.dtb' not remade because of errors.
make: Target 'qcom/msm8916-thwc-ufi001c.dtb' not remade because of errors.
make: Target 'qcom/msm8998-xiaomi-sagit.dtb' not remade because of errors.
make: Target 'qcom/qcs8550-aim300-aiot.dtb' not remade because of errors.
make: Target 'qcom/sdm450-lenovo-tbx605f.dtb' not remade because of errors.
make: Target 'qcom/sm8250-xiaomi-elish-boe.dtb' not remade because of errors.
make: Target 'qcom/qcs404-evb-4000.dtb' not remade because of errors.
make: Target 'qcom/qcs9100-ride.dtb' not remade because of errors.
make: Target 'qcom/msm8996-sony-xperia-tone-kagura.dtb' not remade because of errors.
make: Target 'qcom/sm8150-sony-xperia-kumano-griffin.dtb' not remade because of errors.
make: Target 'qcom/sdm670-google-sargo.dtb' not remade because of errors.
make: Target 'qcom/x1e001de-devkit.dtb' not remade because of errors.
make: Target 'qcom/sa8775p-ride.dtb' not remade because of errors.
make: Target 'qcom/sc7280-herobrine-crd.dtb' not remade because of errors.
make: Target 'qcom/ipq5424-rdp466.dtb' not remade because of errors.
make: Target 'qcom/sc8180x-lenovo-flex-5g.dtb' not remade because of errors.
make: Target 'qcom/sdm845-lg-judyln.dtb' not remade because of errors.
make: Target 'qcom/sm6125-xiaomi-ginkgo.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-lazor-r3-kb.dtb' not remade because of errors.
make: Target 'qcom/msm8916-motorola-osprey.dtb' not remade because of errors.
make: Target 'qcom/sm8250-xiaomi-pipa.dtb' not remade because of errors.
make: Target 'qcom/sdm845-oneplus-enchilada.dtb' not remade because of errors.
make: Target 'qcom/msm8956-sony-xperia-loire-suzu.dtb' not remade because of errors.
make: Target 'qcom/sc7280-idp.dtb' not remade because of errors.
make: Target 'qcom/sc7280-herobrine-evoker-lte.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-homestar-r4.dtb' not remade because of errors.
make: Target 'qcom/msm8916-samsung-rossa.dtb' not remade because of errors.
make: Target 'qcom/apq8039-t2.dtb' not remade because of errors.
make: Target 'qcom/msm8916-motorola-harpia.dtb' not remade because of errors.
make: Target 'qcom/msm8916-samsung-e5.dtb' not remade because of errors.
make: Target 'qcom/sc7280-idp2.dtb' not remade because of errors.
make: Target 'qcom/msm8939-sony-xperia-kanuti-tulip.dtb' not remade because of errors.
make: Target 'qcom/ipq8074-hk01.dtb' not remade because of errors.
make: Target 'qcom/sm8150-mtp.dtb' not remade because of errors.
make: Target 'qcom/ipq9574-rdp433.dtb' not remade because of errors.
make: Target 'qcom/sdm845-sony-xperia-tama-apollo.dtb' not remade because of errors.
make: Target 'qcom/msm8998-lenovo-miix-630.dtb' not remade because of errors.
make: Target 'qcom/msm8994-sony-xperia-kitakami-karin.dtb' not remade because of errors.
make: Target 'qcom/sdm630-sony-xperia-nile-pioneer.dtb' not remade because of errors.
make: Target 'qcom/msm8916-samsung-grandmax.dtb' not remade because of errors.
make: Target 'qcom/msm8916-alcatel-idol347.dtb' not remade because of errors.
make: Target 'qcom/ipq9574-rdp453.dtb' not remade because of errors.
make: Target 'qcom/sc7180-acer-aspire1.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-r1.dtb' not remade because of errors.
make: Target 'qcom/msm8916-samsung-e7.dtb' not remade because of errors.
make: Target 'qcom/ipq5018-rdp432-c2.dtb' not remade because of errors.
make: Target 'qcom/apq8016-schneider-hmibsc.dtb' not remade because of errors.
make: Target 'qcom/qrb4210-rb2.dtb' not remade because of errors.
make: Target 'qcom/ipq5018-tplink-archer-ax55-v1.dtb' not remade because of errors.
make: Target 'qcom/sc7280-herobrine-evoker.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-kingoftown.dtb' not remade because of errors.
make: Target 'qcom/sm4450-qrd.dtb' not remade because of errors.
make: Target 'qcom/msm8916-samsung-j5.dtb' not remade because of errors.
make: Target 'qcom/msm8998-asus-novago-tp370ql.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-pompom-r2-lte.dtb' not remade because of errors.
make: Target 'qcom/msm8992-lg-h815.dtb' not remade because of errors.
make: Target 'qcom/sdx75-idp.dtb' not remade because of errors.
make: Target 'qcom/sm8350-sony-xperia-sagami-pdx215.dtb' not remade because of errors.
make: Target 'qcom/apq8096-db820c.dtb' not remade because of errors.
make: Target 'qcom/msm8996-sony-xperia-tone-keyaki.dtb' not remade because of errors.
make: Target 'qcom/msm8916-longcheer-l8150.dtb' not remade because of errors.
make: Target 'qcom/msm8994-sony-xperia-kitakami-suzuran.dtb' not remade because of errors.
make: Target 'qcom/sdm845-mtp.dtb' not remade because of errors.
make: Target 'qcom/sm6375-sony-xperia-murray-pdx225.dtb' not remade because of errors.
make: Target 'qcom/msm8916-yiming-uz801v3.dtb' not remade because of errors.
make: Target 'qcom/qcs9100-ride-r3.dtb' not remade because of errors.
make: Target 'qcom/x1e80100-hp-omnibook-x14.dtb' not remade because of errors.
make: Target 'qcom/msm8953-xiaomi-vince.dtb' not remade because of errors.
make: Target 'qcom/sdm845-cheza-r2.dtb' not remade because of errors.
make: Target 'qcom/ipq5332-rdp441.dtb' not remade because of errors.
make: Target 'qcom/msm8992-lg-bullhead-rev-101.dtb' not remade because of errors.
make: Target 'qcom/msm8917-xiaomi-riva.dtb' not remade because of errors.
make: Target 'qcom/msm8996-xiaomi-gemini.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-lazor-limozeen-r9.dtb' not remade because of errors.
make: Target 'qcom/msm8998-sony-xperia-yoshino-lilac.dtb' not remade because of errors.
make: Target 'qcom/msm8916-samsung-gprimeltecan.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-pazquel360-lte.dtb' not remade because of errors.
make: Target 'qcom/sdm845-shift-axolotl.dtb' not remade because of errors.
make: Target 'qcom/msm8996-oneplus3t.dtb' not remade because of errors.
make: Target 'qcom/sc7280-herobrine-zombie-lte.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-lazor-r3.dtb' not remade because of errors.
make: Target 'qcom/sar2130p-qar2130p.dtb' not remade because of errors.
make: Target 'qcom/sm8650-hdk.dtb' not remade because of errors.
make: Target 'qcom/sc7280-herobrine-herobrine-r1.dtb' not remade because of errors.
make: Target 'qcom/msm8916-longcheer-l8910.dtb' not remade because of errors.
make: Target 'qcom/sdm630-sony-xperia-nile-voyager.dtb' not remade because of errors.
make: Target 'qcom/sm8450-hdk.dtb' not remade because of errors.
make: Target 'qcom/msm8929-wingtech-wt82918hd.dtb' not remade because of errors.
make: Target 'qcom/sm8250-sony-xperia-edo-pdx203.dtb' not remade because of errors.
make: Target 'qcom/sm8350-hdk.dtb' not remade because of errors.
make: Target 'qcom/ipq8074-hk10-c1.dtb' not remade because of errors.
make: Target 'qcom/sm8450-qrd.dtb' not remade because of errors.
make: Target 'qcom/msm8916-lg-c50.dtb' not remade because of errors.
make: Target 'qcom/sm8250-sony-xperia-edo-pdx206.dtb' not remade because of errors.
make: Target 'qcom/sm7225-fairphone-fp4.dtb' not remade because of errors.
make: Target 'qcom/sa8155p-adp.dtb' not remade because of errors.
make: Target 'qcom/x1e80100-qcp.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-lazor-r1-kb.dtb' not remade because of errors.
make: Target 'qcom/msm8916-samsung-grandprimelte.dtb' not remade because of errors.
make: Target 'qcom/sc7280-herobrine-zombie-nvme-lte.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-homestar-r3.dtb' not remade because of errors.
make: Target 'qcom/ipq5332-rdp474.dtb' not remade because of errors.
make: Target 'qcom/x1e80100-asus-vivobook-s15.dtb' not remade because of errors.
make: Target 'qcom/sm8150-microsoft-surface-duo.dtb' not remade because of errors.
make: Target 'qcom/msm8996pro-xiaomi-scorpio.dtb' not remade because of errors.
make: Target 'qcom/x1e78100-lenovo-thinkpad-t14s.dtb' not remade because of errors.
make: Target 'qcom/sm8150-hdk.dtb' not remade because of errors.
make: Target 'qcom/sc8180x-primus.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-lazor-r10-lte.dtb' not remade because of errors.
make: Target 'qcom/msm8916-samsung-j5x.dtb' not remade because of errors.
make: Target 'qcom/x1p42100-asus-zenbook-a14.dtb' not remade because of errors.
make: Target 'qcom/sc7180-idp.dtb' not remade because of errors.
make: Target 'qcom/msm8916-mtp.dtb' not remade because of errors.
make: Target 'qcom/x1e80100-hp-elitebook-ultra-g1q.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-lazor-limozeen-r10.dtb' not remade because of errors.
make: Target 'qcom/sc7280-herobrine-zombie-nvme.dtb' not remade because of errors.
make: Target 'qcom/x1e80100-microsoft-romulus15.dtb' not remade because of errors.
make: Target 'qcom/qru1000-idp.dtb' not remade because of errors.
make: Target 'qcom/msm8998-hp-envy-x2.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-wormdingler-rev1-boe-rt5682s.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-pazquel-parade.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-lazor-r9-kb.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-wormdingler-rev1-boe.dtb' not remade because of errors.
make: Target 'qcom/qcs615-ride.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-coachz-r3-lte.dtb' not remade because of errors.
make: Target 'qcom/sc7280-crd-r3.dtb' not remade because of errors.
make: Target 'qcom/msm8916-samsung-gt58.dtb' not remade because of errors.
make: Target 'qcom/sa8775p-ride-r3.dtb' not remade because of errors.
make: Target 'qcom/sc7280-herobrine-villager-r1.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-pazquel-ti.dtb' not remade because of errors.
make: Target 'qcom/qcm6490-shift-otter.dtb' not remade because of errors.
make: Target 'qcom/qcs8300-ride.dtb' not remade because of errors.
make: Target 'qcom/apq8016-sbc.dtb' not remade because of errors.
make: Target 'qcom/msm8996pro-xiaomi-natrium.dtb' not remade because of errors.
make: Target 'qcom/sdm845-samsung-starqltechn.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-pompom-r1-lte.dtb' not remade because of errors.
make: Target 'qcom/msm8953-xiaomi-tissot.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-lazor-r9.dtb' not remade because of errors.
make: Target 'qcom/sm6125-xiaomi-laurel-sprout.dtb' not remade because of errors.
make: Target 'qcom/msm8994-sony-xperia-kitakami-sumire.dtb' not remade because of errors.
make: Target 'qcom/msm8916-samsung-serranove.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-coachz-r3.dtb' not remade because of errors.
make: Target 'qcom/sdm845-sony-xperia-tama-akatsuki.dtb' not remade because of errors.
make: Target 'qcom/ipq9574-rdp449.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-r1-lte.dtb' not remade because of errors.
make: Target 'qcom/msm8916-lg-m216.dtb' not remade because of errors.
make: Target 'qcom/x1e80100-crd.dtb' not remade because of errors.
make: Target 'qcom/apq8094-sony-xperia-kitakami-karin_windy.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-lazor-r9-lte.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-pazquel-lte-ti.dtb' not remade because of errors.
make: Target 'qcom/msm8996-sony-xperia-tone-dora.dtb' not remade because of errors.
make: Target 'qcom/sa8295p-adp.dtb' not remade because of errors.
make: Target 'qcom/msm8994-sony-xperia-kitakami-ivy.dtb' not remade because of errors.
make: Target 'qcom/sdm845-xiaomi-beryllium-ebbg.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-pompom-r3.dtb' not remade because of errors.
make: Target 'qcom/msm8998-oneplus-dumpling.dtb' not remade because of errors.
make: Target 'qcom/sm8650-mtp.dtb' not remade because of errors.
make: Target 'qcom/msm8996-oneplus3.dtb' not remade because of errors.
make: Target 'qcom/sm8550-hdk.dtb' not remade because of errors.
make: Target 'qcom/x1e80100-microsoft-romulus13.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-lazor-r1-lte.dtb' not remade because of errors.
make: Target 'qcom/msm8939-samsung-a7.dtb' not remade because of errors.
make: Target 'qcom/qcm6490-fairphone-fp5.dtb' not remade because of errors.
make: Target 'qcom/sc8280xp-huawei-gaokun3.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-wormdingler-rev1-inx-rt5682s.dtb' not remade because of errors.
make: Target 'qcom/msm8953-xiaomi-mido.dtb' not remade because of errors.
make: Target 'qcom/msm8916-asus-z00l.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-pompom-r2.dtb' not remade because of errors.
make: Target 'qcom/sm6350-sony-xperia-lena-pdx213.dtb' not remade because of errors.
make: Target 'qcom/sdm632-fairphone-fp3.dtb' not remade because of errors.
make: Target 'qcom/msm8953-motorola-potter.dtb' not remade because of errors.
make: Target 'qcom/sda660-inforce-ifc6560.dtb' not remade because of errors.
make: Target 'qcom/sm8150-sony-xperia-kumano-bahamut.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-pazquel-lte-parade.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-homestar-r2.dtb' not remade because of errors.
make: Target 'qcom/sm8250-hdk.dtb' not remade because of errors.
make: Target 'qcom/sm8650-qrd.dtb' not remade because of errors.
make: Target 'qcom/sc8280xp-microsoft-blackrock.dtb' not remade because of errors.
make: Target 'qcom/ipq8074-hk10-c2.dtb' not remade because of errors.
make: Target 'qcom/msm8953-xiaomi-daisy.dtb' not remade because of errors.
make: Target 'qcom/sc8280xp-crd.dtb' not remade because of errors.
make: Target 'qcom/sdm850-samsung-w737.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-lazor-limozeen-nots-r5.dtb' not remade because of errors.
make: Target 'qcom/msm8916-samsung-gt510.dtb' not remade because of errors.
make: Target 'qcom/sdm850-lenovo-yoga-c630.dtb' not remade because of errors.
make: Target 'qcom/msm8916-thwc-uf896.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-lazor-r10-kb.dtb' not remade because of errors.
make: Target 'qcom/msm8994-sony-xperia-kitakami-satsuki.dtb' not remade because of errors.
make: Target 'qcom/sdm632-motorola-ocean.dtb' not remade because of errors.
make: Target 'qcom/sc7280-herobrine-villager-r1-lte.dtb' not remade because of errors.
make: Target 'qcom/sm6115-fxtec-pro1x.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-pompom-r3-lte.dtb' not remade because of errors.
make: Target 'qcom/msm8998-sony-xperia-yoshino-poplar.dtb' not remade because of errors.
make: Target 'qcom/msm8916-huawei-g7.dtb' not remade because of errors.
make: Target 'qcom/msm8916-wingtech-wt86518.dtb' not remade because of errors.
make: Target 'qcom/sm8350-sony-xperia-sagami-pdx214.dtb' not remade because of errors.
make: Target 'qcom/msm8916-wingtech-wt86528.dtb' not remade because of errors.
make: Target 'qcom/sdm845-db845c.dtb' not remade because of errors.
make: Target 'qcom/sa8540p-ride.dtb' not remade because of errors.
make: Target 'qcom/msm8939-longcheer-l9100.dtb' not remade because of errors.
make: Target 'qcom/qdu1000-idp.dtb' not remade because of errors.
make: Target 'qcom/sm8550-samsung-q5q.dtb' not remade because of errors.
make: Target 'qcom/msm8992-msft-lumia-octagon-talkman.dtb' not remade because of errors.
make: Target 'qcom/msm8916-gplus-fl8005a.dtb' not remade because of errors.
make: Target 'qcom/sm8350-mtp.dtb' not remade because of errors.
make: Target 'qcom/msm8956-sony-xperia-loire-kugo.dtb' not remade because of errors.
make: Target 'qcom/msm8976-longcheer-l9360.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-lazor-r1.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-pompom-r1.dtb' not remade because of errors.
make: Target 'qcom/msm8998-oneplus-cheeseburger.dtb' not remade because of errors.
make: Target 'qcom/sc7280-herobrine-villager-r0.dtb' not remade because of errors.
make: Target 'qcom/sm8750-qrd.dtb' not remade because of errors.
make: Target 'qcom/sm4250-oneplus-billie2.dtb' not remade because of errors.
make: Target 'qcom/sdm636-sony-xperia-ganges-mermaid.dtb' not remade because of errors.
make: Target 'qcom/qcs404-evb-1000.dtb' not remade because of errors.
make: Target 'qcom/ipq5332-rdp442.dtb' not remade because of errors.
make: Target 'qcom/sdm845-cheza-r1.dtb' not remade because of errors.
make: Target 'qcom/msm8994-msft-lumia-octagon-cityman.dtb' not remade because of errors.
make: Target 'qcom/msm8916-acer-a1-724.dtb' not remade because of errors.
make: Target 'qcom/sdm845-xiaomi-beryllium-tianma.dtb' not remade because of errors.
make: Target 'qcom/sm6125-sony-xperia-seine-pdx201.dtb' not remade because of errors.
make: Target 'qcom/sdm845-xiaomi-polaris.dtb' not remade because of errors.
make: Target 'qcom/ipq9574-rdp418.dtb' not remade because of errors.
make: Target 'qcom/msm8216-samsung-fortuna3g.dtb' not remade because of errors.
make: Target 'qcom/sm8450-sony-xperia-nagara-pdx223.dtb' not remade because of errors.
make: Target 'qcom/sm8450-sony-xperia-nagara-pdx224.dtb' not remade because of errors.
make: Target 'qcom/sm7125-xiaomi-joyeuse.dtb' not remade because of errors.
make: Target 'qcom/msm8994-huawei-angler-rev-101.dtb' not remade because of errors.
make: Target 'qcom/ipq5332-rdp468.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-lazor-limozeen-nots-r10.dtb' not remade because of errors.
make: Target 'qcom/sc7180-trogdor-quackingstick-r0-lte.dtb' not remade because of errors.







From dmitry.baryshkov at oss.qualcomm.com  Fri Aug 15 15:23:00 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Sat, 16 Aug 2025 01:23:00 +0300
Subject: [PATCH v2 01/14] phy: hdmi: Add HDMI 2.1 FRL configuration
 options
In-Reply-To: <20250805-phy-hdptx-frl-v2-1-d118bd4b6e0b@collabora.com>
References: <20250805-phy-hdptx-frl-v2-0-d118bd4b6e0b@collabora.com>
 <20250805-phy-hdptx-frl-v2-1-d118bd4b6e0b@collabora.com>
Message-ID: <3d796f6c-d1d0-4499-8e63-bd37bfcc7c3a@oss.qualcomm.com>

On 05/08/2025 14:56, Cristian Ciocaltea wrote:
> Add support for configuring the Fixed Rate Link (FRL) mode for HDMI
> PHYs.
> 
> For improved clarity, also rename existing HDMI mode to HDMI_TMDS.
> Since this mode is currently not being used explicitly, no further
> changes are needed.


I'd say, this need some explanation, especially for those who don't have 
access to the HDMI standard. Please mention that FRL is an alternative 
to the traditional TMDS mode, etc.

> 
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
> ---
>   include/linux/phy/phy-hdmi.h | 14 ++++++++++++--
>   include/linux/phy/phy.h      |  3 ++-
>   2 files changed, 14 insertions(+), 3 deletions(-)
> 
> diff --git a/include/linux/phy/phy-hdmi.h b/include/linux/phy/phy-hdmi.h
> index f0ec963c6e84f1b7728acafc824dff191c6b873d..0b26472d8defcc9ded142d4283e29861dc2b3746 100644
> --- a/include/linux/phy/phy-hdmi.h
> +++ b/include/linux/phy/phy-hdmi.h
> @@ -6,16 +6,26 @@
>   #ifndef __PHY_HDMI_H_
>   #define __PHY_HDMI_H_
>   
> +#include <linux/types.h>
> +
>   /**
>    * struct phy_configure_opts_hdmi - HDMI configuration set
> - * @tmds_char_rate: HDMI TMDS Character Rate in Hertz.
>    * @bpc: Bits per color channel.
> + * @tmds_char_rate: HDMI TMDS Character Rate in Hertz.
> + * @frl.rate_per_lane: HDMI FRL Rate per Lane in Gbps.
> + * @frl.lanes: HDMI FRL lanes count.
>    *
>    * This structure is used to represent the configuration state of a HDMI phy.
>    */
>   struct phy_configure_opts_hdmi {
> -	unsigned long long tmds_char_rate;
>   	unsigned int bpc;
> +	union {
> +		unsigned long long tmds_char_rate;
> +		struct {
> +			u8 rate_per_lane;
> +			u8 lanes;
> +		} frl;
> +	};
>   };
>   
>   #endif /* __PHY_HDMI_H_ */
> diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
> index 13add0c2c40721fe9ca3f0350d13c035cd25af45..04c84c1dbd6dac55fd04c54203cff4f9d939d970 100644
> --- a/include/linux/phy/phy.h
> +++ b/include/linux/phy/phy.h
> @@ -44,7 +44,8 @@ enum phy_mode {
>   	PHY_MODE_SATA,
>   	PHY_MODE_LVDS,
>   	PHY_MODE_DP,
> -	PHY_MODE_HDMI,
> +	PHY_MODE_HDMI_TMDS,
> +	PHY_MODE_HDMI_FRL,

I'd maybe suggest keeping PHY_MODE_HDMI and having two submodes: one for 
TMDS (default), one for FRL.

>   };
>   
>   enum phy_media {
> 


-- 
With best wishes
Dmitry


From iuncuim at gmail.com  Sat Aug 16 01:46:53 2025
From: iuncuim at gmail.com (iuncuim)
Date: Sat, 16 Aug 2025 16:46:53 +0800
Subject: [PATCH 0/7] arm64: allwinner: a523: add USB3.0 support
Message-ID: <20250816084700.569524-1-iuncuim@gmail.com>

From: Mikhail Kalashnikov <iuncuim at gmail.com>

This series is a draft and does not include patches for dt-bindings.
The first series is necessary for testing on other devices and
initiating discussion.

This series of patches adds USB 3.0 functionality for the
A523/A527/H728/T527 processor.Most of the code is derived from the BSP,
 as the datasheet does not fully describe this feature.

I have verified functionality on two of my boards, walnutpi 2b (t527)
and x96qproplus (h728). When testing usb3.0 on x96qproplus, I get
reconnections of my nvme, it looks like the port does not provide enough
 current to work. I have encountered similar complaints from users of the
  device on Android. In the case of walnutpi, there is no such problem.

Based on 6.17-rc1

Mikhail Kalashnikov (7):
  clk: sunxi-ng: a523: add missing usb related clocks
  arm64: dts: allwinner: a523: add third usb2 phy
  phy: sun4i-usb: a523: add support for the USB2 PHY
  phy: allwinner: a523: add USB3/PCIe PHY driver
  arm64: dts: allwinner: a523: add USB3.0 phy node
  arm64: dts: allwinner: a523: add DWC3 USB3.0 node
  arm64: dts: allwinner: a523: activate USB3 for all boards

 .../arm64/boot/dts/allwinner/sun55i-a523.dtsi |  52 +++-
 .../dts/allwinner/sun55i-a527-cubie-a5e.dts   |   8 +
 .../dts/allwinner/sun55i-h728-x96qpro+.dts    |   8 +
 .../dts/allwinner/sun55i-t527-avaota-a1.dts   |   8 +
 drivers/clk/sunxi-ng/ccu-sun55i-a523.c        |  32 +++
 drivers/clk/sunxi-ng/ccu-sun55i-a523.h        |   2 +-
 drivers/phy/allwinner/Kconfig                 |   9 +
 drivers/phy/allwinner/Makefile                |   1 +
 drivers/phy/allwinner/phy-sun4i-usb.c         |  10 +
 drivers/phy/allwinner/phy-sun55i-usb3-pcie.c  | 267 ++++++++++++++++++
 include/dt-bindings/clock/sun55i-a523-ccu.h   |   4 +
 11 files changed, 392 insertions(+), 9 deletions(-)
 create mode 100644 drivers/phy/allwinner/phy-sun55i-usb3-pcie.c

-- 
2.50.1



From iuncuim at gmail.com  Sat Aug 16 01:46:54 2025
From: iuncuim at gmail.com (iuncuim)
Date: Sat, 16 Aug 2025 16:46:54 +0800
Subject: [PATCH 1/7] clk: sunxi-ng: a523: add missing usb related clocks
In-Reply-To: <20250816084700.569524-1-iuncuim@gmail.com>
References: <20250816084700.569524-1-iuncuim@gmail.com>
Message-ID: <20250816084700.569524-2-iuncuim@gmail.com>

From: Mikhail Kalashnikov <iuncuim at gmail.com>

Several clocks were omitted when adding the original driver. These clocks
are necessary for USB 3.0 to work correctly. I added these declarations
according to the driver's BSP code.

Signed-off-by: Mikhail Kalashnikov <iuncuim at gmail.com>
---
 drivers/clk/sunxi-ng/ccu-sun55i-a523.c      | 32 +++++++++++++++++++++
 drivers/clk/sunxi-ng/ccu-sun55i-a523.h      |  2 +-
 include/dt-bindings/clock/sun55i-a523-ccu.h |  4 +++
 3 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/sunxi-ng/ccu-sun55i-a523.c b/drivers/clk/sunxi-ng/ccu-sun55i-a523.c
index 1a9a1cb86..7bf41e628 100644
--- a/drivers/clk/sunxi-ng/ccu-sun55i-a523.c
+++ b/drivers/clk/sunxi-ng/ccu-sun55i-a523.c
@@ -853,6 +853,31 @@ static struct ccu_mux usb_ohci1_clk = {
 	},
 };
 
+static SUNXI_CCU_GATE_DATA(usb2_clk, "usb2", osc24M, 0xa80, BIT(31), 0);
+
+static const struct clk_parent_data usb3_parents[] = {
+	{ .fw_name = "hosc" },
+	{ .hw = &pll_periph0_200M_clk.hw },
+	{ .hw = &pll_periph1_200M_clk.hw },
+};
+
+static SUNXI_CCU_M_DATA_WITH_MUX_GATE(usb3_clk, "usb3", usb3_parents, 0xa84,
+				      0, 5,	/* M */
+				      24, 3,	/* mux */
+				      BIT(31),	/* gate */
+				      0);
+
+static const struct clk_parent_data usb3_suspend_parents[] = {
+	{ .fw_name = "losc" },
+};
+
+static SUNXI_CCU_M_DATA_WITH_MUX_GATE(usb3_suspend_clk, "usb3-suspend",
+				      usb3_suspend_parents, 0xa88,
+				      0, 5,	/* M */
+				      24, 1,	/* mux */
+				      BIT(31),	/* gate */
+				      0);
+
 static SUNXI_CCU_GATE_HWS(bus_ohci0_clk, "bus-ohci0", ahb_hws, 0xa8c,
 			  BIT(0), 0);
 static SUNXI_CCU_GATE_HWS(bus_ohci1_clk, "bus-ohci1", ahb_hws, 0xa8c,
@@ -1290,6 +1315,9 @@ static struct ccu_common *sun55i_a523_ccu_clks[] = {
 	&bus_ths_clk.common,
 	&usb_ohci0_clk.common,
 	&usb_ohci1_clk.common,
+	&usb2_clk.common,
+	&usb3_clk.common,
+	&usb3_suspend_clk.common,
 	&bus_ohci0_clk.common,
 	&bus_ohci1_clk.common,
 	&bus_ehci0_clk.common,
@@ -1422,6 +1450,7 @@ static struct clk_hw_onecell_data sun55i_a523_hw_clks = {
 		[CLK_MBUS_DMA]		= &mbus_dma_clk.common.hw,
 		[CLK_MBUS_VE]		= &mbus_ve_clk.common.hw,
 		[CLK_MBUS_CE]		= &mbus_ce_clk.common.hw,
+		[CLK_MBUS_USB3]		= &mbus_usb3_clk.common.hw,
 		[CLK_MBUS_CSI]		= &mbus_csi_clk.common.hw,
 		[CLK_MBUS_ISP]		= &mbus_isp_clk.common.hw,
 		[CLK_MBUS_EMAC1]	= &mbus_gmac1_clk.common.hw,
@@ -1474,6 +1503,9 @@ static struct clk_hw_onecell_data sun55i_a523_hw_clks = {
 		[CLK_BUS_THS]		= &bus_ths_clk.common.hw,
 		[CLK_USB_OHCI0]		= &usb_ohci0_clk.common.hw,
 		[CLK_USB_OHCI1]		= &usb_ohci1_clk.common.hw,
+		[CLK_USB2]		= &usb2_clk.common.hw,
+		[CLK_USB3]		= &usb3_clk.common.hw,
+		[CLK_USB3_SUSPEND]	= &usb3_suspend_clk.common.hw,
 		[CLK_BUS_OHCI0]		= &bus_ohci0_clk.common.hw,
 		[CLK_BUS_OHCI1]		= &bus_ohci1_clk.common.hw,
 		[CLK_BUS_EHCI0]		= &bus_ehci0_clk.common.hw,
diff --git a/drivers/clk/sunxi-ng/ccu-sun55i-a523.h b/drivers/clk/sunxi-ng/ccu-sun55i-a523.h
index fc8dd42f1..d6916c728 100644
--- a/drivers/clk/sunxi-ng/ccu-sun55i-a523.h
+++ b/drivers/clk/sunxi-ng/ccu-sun55i-a523.h
@@ -9,6 +9,6 @@
 #include <dt-bindings/clock/sun55i-a523-ccu.h>
 #include <dt-bindings/reset/sun55i-a523-ccu.h>
 
-#define CLK_NUMBER	(CLK_FANOUT2 + 1)
+#define CLK_NUMBER	(CLK_MBUS_USB3 + 1)
 
 #endif /* _CCU_SUN55I_A523_H */
diff --git a/include/dt-bindings/clock/sun55i-a523-ccu.h b/include/dt-bindings/clock/sun55i-a523-ccu.h
index c8259ac5a..26b2e9dc8 100644
--- a/include/dt-bindings/clock/sun55i-a523-ccu.h
+++ b/include/dt-bindings/clock/sun55i-a523-ccu.h
@@ -185,5 +185,9 @@
 #define CLK_FANOUT0		176
 #define CLK_FANOUT1		177
 #define CLK_FANOUT2		178
+#define CLK_USB2		179
+#define CLK_USB3		180
+#define CLK_USB3_SUSPEND	181
+#define CLK_MBUS_USB3		182
 
 #endif /* _DT_BINDINGS_CLK_SUN55I_A523_CCU_H_ */
-- 
2.50.1



From iuncuim at gmail.com  Sat Aug 16 01:46:55 2025
From: iuncuim at gmail.com (iuncuim)
Date: Sat, 16 Aug 2025 16:46:55 +0800
Subject: [PATCH 2/7] arm64: dts: allwinner: a523: add third usb2 phy
In-Reply-To: <20250816084700.569524-1-iuncuim@gmail.com>
References: <20250816084700.569524-1-iuncuim@gmail.com>
Message-ID: <20250816084700.569524-3-iuncuim@gmail.com>

From: Mikhail Kalashnikov <iuncuim at gmail.com>

It seems that there are actually three usb2 phys in the processor, which
makes it incompatible with D1.
The third phy is used together with USB3/PCIe combophy with DWC3
controller. In the BSP code, the third PHY requires a separate glue
driver, but it seems that it is not needed.
According to the BSP code, the third phy does not have a reset line; the
only reset is declared in the DWC3 node, but none of this is documented.
Since sun4i-usb-phy driver requires a reset, I added RST_BUS_3 here.

Signed-off-by: Mikhail Kalashnikov <iuncuim at gmail.com>
---
 .../arm64/boot/dts/allwinner/sun55i-a523.dtsi | 21 ++++++++++++-------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
index 6b6f2296b..e4ed4fa82 100644
--- a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
@@ -503,22 +503,27 @@ usb_otg: usb at 4100000 {
 		};
 
 		usbphy: phy at 4100400 {
-			compatible = "allwinner,sun55i-a523-usb-phy",
-				     "allwinner,sun20i-d1-usb-phy";
+			compatible = "allwinner,sun55i-a523-usb-phy";
 			reg = <0x4100400 0x100>,
 			      <0x4101800 0x100>,
-			      <0x4200800 0x100>;
+			      <0x4200800 0x100>,
+				  <0x4e00000 0x100>;
 			reg-names = "phy_ctrl",
 				    "pmu0",
-				    "pmu1";
+				    "pmu1",
+					"pmu2";
 			clocks = <&osc24M>,
-				 <&osc24M>;
+				 <&osc24M>,
+				 <&ccu CLK_USB2>;
 			clock-names = "usb0_phy",
-				      "usb1_phy";
+				      "usb1_phy",
+					  "usb2_phy";
 			resets = <&ccu RST_USB_PHY0>,
-				 <&ccu RST_USB_PHY1>;
+				 <&ccu RST_USB_PHY1>,
+				 <&ccu RST_BUS_3>;
 			reset-names = "usb0_reset",
-				      "usb1_reset";
+				      "usb1_reset",
+					  "usb2_reset";
 			status = "disabled";
 			#phy-cells = <1>;
 		};
-- 
2.50.1



From iuncuim at gmail.com  Sat Aug 16 01:46:56 2025
From: iuncuim at gmail.com (iuncuim)
Date: Sat, 16 Aug 2025 16:46:56 +0800
Subject: [PATCH 3/7] phy: sun4i-usb: a523: add support for the USB2 PHY
In-Reply-To: <20250816084700.569524-1-iuncuim@gmail.com>
References: <20250816084700.569524-1-iuncuim@gmail.com>
Message-ID: <20250816084700.569524-4-iuncuim@gmail.com>

From: Mikhail Kalashnikov <iuncuim at gmail.com>

Previously, USB PHY was compatible with D1 and did not require
separatedata options. But now we need to add a third PHY, which makes it
incompatible. The third PHY is used together with USB3/PCIe combophy with
DWC3 controller. In the BSP code, the third PHY requires a separate glue
driver, but it seems that it is not needed.

Signed-off-by: Mikhail Kalashnikov <iuncuim at gmail.com>
---
 drivers/phy/allwinner/phy-sun4i-usb.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c
index 8873aed3a..bb79339f2 100644
--- a/drivers/phy/allwinner/phy-sun4i-usb.c
+++ b/drivers/phy/allwinner/phy-sun4i-usb.c
@@ -1025,6 +1025,15 @@ static const struct sun4i_usb_phy_cfg sun50i_h616_cfg = {
 	.siddq_in_base = true,
 };
 
+static const struct sun4i_usb_phy_cfg sun55i_a523_cfg = {
+	.num_phys = 3,
+	.phyctl_offset = REG_PHYCTL_A33,
+	.dedicated_clocks = true,
+	.hci_phy_ctl_clear = PHY_CTL_SIDDQ,
+	.phy0_dual_route = true,
+	.siddq_in_base = true,
+};
+
 static const struct of_device_id sun4i_usb_phy_of_match[] = {
 	{ .compatible = "allwinner,sun4i-a10-usb-phy", .data = &sun4i_a10_cfg },
 	{ .compatible = "allwinner,sun5i-a13-usb-phy", .data = &sun5i_a13_cfg },
@@ -1041,6 +1050,7 @@ static const struct of_device_id sun4i_usb_phy_of_match[] = {
 	  .data = &sun50i_a64_cfg},
 	{ .compatible = "allwinner,sun50i-h6-usb-phy", .data = &sun50i_h6_cfg },
 	{ .compatible = "allwinner,sun50i-h616-usb-phy", .data = &sun50i_h616_cfg },
+	{ .compatible = "allwinner,sun55i-a523-usb-phy", .data = &sun55i_a523_cfg },
 	{ .compatible = "allwinner,suniv-f1c100s-usb-phy",
 	  .data = &suniv_f1c100s_cfg },
 	{ },
-- 
2.50.1



From iuncuim at gmail.com  Sat Aug 16 01:46:57 2025
From: iuncuim at gmail.com (iuncuim)
Date: Sat, 16 Aug 2025 16:46:57 +0800
Subject: [PATCH 4/7] phy: allwinner: a523: add USB3/PCIe PHY driver
In-Reply-To: <20250816084700.569524-1-iuncuim@gmail.com>
References: <20250816084700.569524-1-iuncuim@gmail.com>
Message-ID: <20250816084700.569524-5-iuncuim@gmail.com>

From: Mikhail Kalashnikov <iuncuim at gmail.com>

The A523 family of processors features a combophy for USB 3.0 and PCIe,
developed by Innosilicon. Simultaneous operation of both interfaces is
not supported by design.
Currently, the driver only adds support for USB 3.0. PCIe support is
currently unavailable and will be added later.
All data on phy configuration is taken from the manufacturer's BSP driver.

Signed-off-by: Mikhail Kalashnikov <iuncuim at gmail.com>
---
 drivers/phy/allwinner/Kconfig                |   9 +
 drivers/phy/allwinner/Makefile               |   1 +
 drivers/phy/allwinner/phy-sun55i-usb3-pcie.c | 267 +++++++++++++++++++
 3 files changed, 277 insertions(+)
 create mode 100644 drivers/phy/allwinner/phy-sun55i-usb3-pcie.c

diff --git a/drivers/phy/allwinner/Kconfig b/drivers/phy/allwinner/Kconfig
index fb584518b..af2a82e51 100644
--- a/drivers/phy/allwinner/Kconfig
+++ b/drivers/phy/allwinner/Kconfig
@@ -57,3 +57,12 @@ config PHY_SUN50I_USB3
 	  part of Allwinner H6 SoC.
 
 	  This driver controls each individual USB 2+3 host PHY combo.
+
+config PHY_SUN55I_USB3_PCIE
+	tristate "Allwinner A523 Innosilicon USB3/PCIe Combophy Driver"
+	depends on ARCH_SUNXI || COMPILE_TEST
+	depends on RESET_CONTROLLER
+	select GENERIC_PHY
+	help
+	  Enable this to support the Allwinner PCIe/USB3.0 combo PHY
+	  with Innosilicon IP block founded in A523/A527/H728/T527 SOC
diff --git a/drivers/phy/allwinner/Makefile b/drivers/phy/allwinner/Makefile
index bd74901a1..5948a27ef 100644
--- a/drivers/phy/allwinner/Makefile
+++ b/drivers/phy/allwinner/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_PHY_SUN4I_USB)		+= phy-sun4i-usb.o
 obj-$(CONFIG_PHY_SUN6I_MIPI_DPHY)	+= phy-sun6i-mipi-dphy.o
 obj-$(CONFIG_PHY_SUN9I_USB)		+= phy-sun9i-usb.o
 obj-$(CONFIG_PHY_SUN50I_USB3)		+= phy-sun50i-usb3.o
+obj-$(CONFIG_PHY_SUN55I_USB3_PCIE)		+= phy-sun55i-usb3-pcie.o
diff --git a/drivers/phy/allwinner/phy-sun55i-usb3-pcie.c b/drivers/phy/allwinner/phy-sun55i-usb3-pcie.c
new file mode 100644
index 000000000..905c54a67
--- /dev/null
+++ b/drivers/phy/allwinner/phy-sun55i-usb3-pcie.c
@@ -0,0 +1,267 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Driver for Innosilicon USB3.0/PCIe phy found in Allwinner A523 processors.
+ * Currently, the driver only supports the USB3.0 part.
+ *
+ * Copyright (C) 2025 Mikhail Kalashnikov <iuncuim at gmail.com>
+ * Based on phy-sun50i-usb3.c, which is:
+ * Copyright (C) 2017 Icenowy Zheng <icenowy at aosc.io>
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+
+#define PHY_SYS_VER			0x00
+
+#define PHY_USB3_BGR		0x08
+/* Control bits for the USB3 part */
+#define USB3_RESETN			BIT(0)
+#define USB3_ACLK_EN		BIT(17)
+#define USB3_HCLK_EN		BIT(16)
+
+#define PHY_CTL				0x10
+/* Control bits for the common part */
+#define PHY_RSTN			BIT(0)
+/* Bit for selecting internal(0) or external(1) clock */
+#define PHY_CLK_SEL			BIT(30)
+/* Bit for selecting PCIe(0) or USB3(1) role */
+#define PHY_USE_SEL			BIT(31)
+
+#define PHY_CLK_OFFSET		0x80000
+
+struct sun55i_usb3_pcie_phy {
+	struct device *dev;
+	struct phy *phy;
+	void __iomem *regs;
+	void __iomem *regs_clk;
+	struct reset_control *reset;
+	struct clk *clk;
+};
+
+/*
+ * These values are derived from the manufacturer's driver code.
+ * Comments are preserved.
+ */
+static void sun55i_usb3_phy_open(struct sun55i_usb3_pcie_phy *phy)
+{
+	u32 val;
+
+	val = readl(phy->regs_clk + 0x1418);
+	val &= ~(GENMASK(17, 16));
+	val |= BIT(25);
+	writel(val, phy->regs_clk + 0x1418);
+
+	/* reg_rx_eq_bypass[3]=1, rx_ctle_res_cal_bypass */
+	val = readl(phy->regs_clk + 0x674);
+	val |= BIT(3);
+	writel(val, phy->regs_clk + 0x674);
+
+	/* rx_ctle_res_cal=0xf, 0x4->0xf */
+	val = readl(phy->regs_clk + 0x704);
+	val |= BIT(8) | BIT(9) | BIT(11);
+	writel(val, phy->regs_clk + 0x704);
+
+	/* CDR_div_fin_gain1 */
+	val = readl(phy->regs_clk + 0x400);
+	val |= BIT(4);
+	writel(val, phy->regs_clk + 0x400);
+
+	/* CDR_div1_fin_gain1 */
+	val = readl(phy->regs_clk + 0x404);
+	val |= GENMASK(3, 0);
+	val |= BIT(5);
+	writel(val, phy->regs_clk + 0x404);
+
+	/* CDR_div3_fin_gain1 */
+	val = readl(phy->regs_clk + 0x408);
+	val |= BIT(5);
+	writel(val, phy->regs_clk + 0x408);
+
+	val = readl(phy->regs_clk + 0x109c);
+	val |= BIT(1);
+	writel(val, phy->regs_clk + 0x109c);
+
+	/* SSC configure */
+	/* div_N */
+	val = readl(phy->regs_clk + 0x107c);
+	val &= ~(GENMASK(17, 12));
+	val |= BIT(12);
+	writel(val, phy->regs_clk + 0x107c);
+
+	/* modulation freq div */
+	val = readl(phy->regs_clk + 0x1020);
+	val &= ~(GENMASK(4, 0));
+	val |= BIT(1) | BIT(2);
+	writel(val, phy->regs_clk + 0x1020);
+
+	/* spread[6:0], 400*9=4410ppm ssc */
+	val = readl(phy->regs_clk + 0x1034);
+	val &= ~(GENMASK(22, 16));
+	val |= BIT(16) | BIT(19);
+	writel(val, phy->regs_clk + 0x1034);
+
+	val = readl(phy->regs_clk + 0x101c);
+	/* don't disable ssc = 0 */
+	val &= ~BIT(28);
+	/* choose downspread */
+	val |= BIT(27);
+	writel(val, phy->regs_clk + 0x101c);
+}
+
+static int sun55i_usb3_pcie_clk_init(struct sun55i_usb3_pcie_phy *phy)
+{
+	u32 val;
+	int ret;
+
+	ret = clk_prepare_enable(phy->clk);
+	if (ret)
+		return ret;
+
+	ret = reset_control_deassert(phy->reset);
+	if (ret) {
+		clk_disable_unprepare(phy->clk);
+		return ret;
+	}
+
+	val = readl(phy->regs + PHY_CTL);
+	val |= PHY_USE_SEL | PHY_RSTN;
+	val &= ~PHY_CLK_SEL;
+	writel(val, phy->regs + PHY_CTL);
+
+	val = readl(phy->regs + PHY_USB3_BGR);
+	val |= USB3_ACLK_EN | USB3_HCLK_EN | USB3_RESETN;
+	writel(val, phy->regs + PHY_USB3_BGR);
+
+	return 0;
+}
+
+static int sun55i_usb3_pcie_phy_init(struct phy *_phy)
+{
+	struct sun55i_usb3_pcie_phy *phy = phy_get_drvdata(_phy);
+
+	sun55i_usb3_phy_open(phy);
+
+	return 0;
+}
+
+static int sun55i_usb3_pcie_phy_exit(struct phy *_phy)
+{
+	struct sun55i_usb3_pcie_phy *phy = phy_get_drvdata(_phy);
+
+	reset_control_assert(phy->reset);
+	clk_disable_unprepare(phy->clk);
+
+	return 0;
+}
+
+static void sun55i_usb3_pcie_phy_power_set(struct phy *_phy, bool on)
+{
+	struct sun55i_usb3_pcie_phy *phy = phy_get_drvdata(_phy);
+	u32 val;
+
+	val = readl(phy->regs_clk + 0x14);
+	val = on ? (val & ~BIT(26)) : (val | BIT(26));
+	writel(val, phy->regs_clk + 0x14);
+
+	val = readl(phy->regs_clk);
+	val = on ? (val & ~BIT(10)) : (val | BIT(10));
+	writel(val, phy->regs_clk);
+}
+
+static int sun55i_usb3_pcie_phy_power_on(struct phy *_phy)
+{
+	sun55i_usb3_pcie_phy_power_set(_phy, true);
+
+	return 0;
+}
+
+static int sun55i_usb3_pcie_phy_power_off(struct phy *_phy)
+{
+	sun55i_usb3_pcie_phy_power_set(_phy, false);
+
+	return 0;
+}
+
+static const struct phy_ops sun55i_usb3_pcie_phy_ops = {
+	.init		= sun55i_usb3_pcie_phy_init,
+	.exit		= sun55i_usb3_pcie_phy_exit,
+	.power_on	= sun55i_usb3_pcie_phy_power_on,
+	.power_off	= sun55i_usb3_pcie_phy_power_off,
+	.owner		= THIS_MODULE,
+};
+
+static int sun55i_usb3_pcie_phy_probe(struct platform_device *pdev)
+{
+	struct sun55i_usb3_pcie_phy *phy;
+	struct device *dev = &pdev->dev;
+	struct phy_provider *phy_provider;
+	int ret;
+
+	phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
+	if (!phy)
+		return -ENOMEM;
+
+	phy->dev = dev;
+	phy->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(phy->clk)) {
+		if (PTR_ERR(phy->clk) != -EPROBE_DEFER)
+			dev_err(dev, "failed to get phy clock\n");
+		return PTR_ERR(phy->clk);
+	}
+
+	phy->reset = devm_reset_control_get(dev, NULL);
+	if (IS_ERR(phy->reset)) {
+		dev_err(dev, "failed to get reset control\n");
+		return PTR_ERR(phy->reset);
+	}
+
+	phy->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(phy->regs))
+		return PTR_ERR(phy->regs);
+
+	phy->regs_clk = phy->regs + PHY_CLK_OFFSET;
+	if (IS_ERR(phy->regs_clk))
+		return PTR_ERR(phy->regs_clk);
+
+	phy->phy = devm_phy_create(dev, NULL, &sun55i_usb3_pcie_phy_ops);
+	if (IS_ERR(phy->phy)) {
+		dev_err(dev, "failed to create PHY\n");
+		return PTR_ERR(phy->phy);
+	}
+
+	phy_set_drvdata(phy->phy, phy);
+	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+
+	ret = sun55i_usb3_pcie_clk_init(phy);
+	if (ret)
+		return ret;
+	dev_info(phy->dev, "phy version is: 0x%x\n", readl(phy->regs));
+
+	return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct of_device_id sun55i_usb3_pcie_phy_of_match[] = {
+	{ .compatible = "allwinner,sun55i-a523-usb3-pcie-phy" },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, sun55i_usb3_pcie_phy_of_match);
+
+static struct platform_driver sun55i_usb3_pcie_phy_driver = {
+	.probe	= sun55i_usb3_pcie_phy_probe,
+	.driver = {
+		.of_match_table	= sun55i_usb3_pcie_phy_of_match,
+		.name  = "sun55i-usb3-pcie-phy",
+	}
+};
+module_platform_driver(sun55i_usb3_pcie_phy_driver);
+
+MODULE_DESCRIPTION("Allwinner A523 USB3/PCIe phy driver");
+MODULE_AUTHOR("Mikhail Kalashnikov <iuncuim at gmail.com>");
+MODULE_LICENSE("GPL");
-- 
2.50.1



From iuncuim at gmail.com  Sat Aug 16 01:46:58 2025
From: iuncuim at gmail.com (iuncuim)
Date: Sat, 16 Aug 2025 16:46:58 +0800
Subject: [PATCH 5/7] arm64: dts: allwinner: a523: add USB3.0 phy node
In-Reply-To: <20250816084700.569524-1-iuncuim@gmail.com>
References: <20250816084700.569524-1-iuncuim@gmail.com>
Message-ID: <20250816084700.569524-6-iuncuim@gmail.com>

From: Mikhail Kalashnikov <iuncuim at gmail.com>

After adding the phy driver, we can also add phy node. In addition to the
clk and reset lines, the power domain PD_PCIE is declared in this node
according to the bsp dtb. So let's mention it. 
Currently, phy driver does not support role selection and only works in
USB3.0 mode.

Signed-off-by: Mikhail Kalashnikov <iuncuim at gmail.com>
---
 arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
index e4ed4fa82..233365496 100644
--- a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
@@ -606,6 +606,16 @@ mdio0: mdio {
 			};
 		};
 
+		combophy: phy at 4f00000 {
+			compatible = "allwinner,sun55i-a523-usb3-pcie-phy";
+			reg = <0x04f00000 0x100000>;
+			clocks = <&ccu CLK_USB3>;
+			resets = <&ccu RST_BUS_PCIE_USB3>;
+			#phy-cells = <0>;
+			power-domains = <&pck600 PD_PCIE>;
+			status = "disabled";
+		};
+
 		ppu: power-controller at 7001400 {
 			compatible = "allwinner,sun55i-a523-ppu";
 			reg = <0x07001400 0x400>;
-- 
2.50.1



From iuncuim at gmail.com  Sat Aug 16 01:46:59 2025
From: iuncuim at gmail.com (iuncuim)
Date: Sat, 16 Aug 2025 16:46:59 +0800
Subject: [PATCH 6/7] arm64: dts: allwinner: a523: add DWC3 USB3.0 node
In-Reply-To: <20250816084700.569524-1-iuncuim@gmail.com>
References: <20250816084700.569524-1-iuncuim@gmail.com>
Message-ID: <20250816084700.569524-7-iuncuim@gmail.com>

From: Mikhail Kalashnikov <iuncuim at gmail.com>

After adding the phy bindings, we can also add dwc3 node, which uses the
previously added usbphy2 and part of usb3 from combophy.
All settings declared in dwc3 node are obtained from the x96qproplus' dtb.
BSP contains an additional glue driver for dwc3, but it seems that it is
not needed.

Signed-off-by: Mikhail Kalashnikov <iuncuim at gmail.com>
---
 .../arm64/boot/dts/allwinner/sun55i-a523.dtsi | 21 +++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
index 233365496..ec170888a 100644
--- a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
@@ -606,6 +606,27 @@ mdio0: mdio {
 			};
 		};
 
+		dwc3: usb at 4d00000 {
+			compatible = "snps,dwc3";
+			reg = <0x04d00000 0x100000>;
+			interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+			dr_mode = "host";
+			clocks = <&ccu CLK_MBUS_USB3>, <&ccu CLK_USB3>,
+				 <&ccu CLK_USB2>, <&ccu CLK_USB3_SUSPEND>;
+			clock-names = "bus_clk", "ref_clk3", "ref_clk2", "suspend";
+			maximum-speed = "super-speed";
+			phy_type = "utmi";
+			snps,dis_enblslpm_quirk;
+			snps,dis-u1-entry-quirk;
+			snps,dis-u2-entry-quirk;
+			snps,dis_u3_susphy_quirk;
+			snps,dis_u2_susphy_quirk;
+			snps,dis_rxdet_inp3_quirk;
+			phys = <&usbphy 2>, <&combophy>;
+			phy-names = "usb2-phy", "usb3-phy";
+			status = "disabled";
+		};
+
 		combophy: phy at 4f00000 {
 			compatible = "allwinner,sun55i-a523-usb3-pcie-phy";
 			reg = <0x04f00000 0x100000>;
-- 
2.50.1



From iuncuim at gmail.com  Sat Aug 16 01:47:00 2025
From: iuncuim at gmail.com (iuncuim)
Date: Sat, 16 Aug 2025 16:47:00 +0800
Subject: [PATCH 7/7] arm64: dts: allwinner: a523: activate USB3 for all boards
In-Reply-To: <20250816084700.569524-1-iuncuim@gmail.com>
References: <20250816084700.569524-1-iuncuim@gmail.com>
Message-ID: <20250816084700.569524-8-iuncuim@gmail.com>

From: Mikhail Kalashnikov <iuncuim at gmail.com>

Currently, these devices have a USB 3.0 port. Therefore, we can activate
it.

Signed-off-by: Mikhail Kalashnikov <iuncuim at gmail.com>
---
 arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts | 8 ++++++++
 arch/arm64/boot/dts/allwinner/sun55i-h728-x96qpro+.dts  | 8 ++++++++
 arch/arm64/boot/dts/allwinner/sun55i-t527-avaota-a1.dts | 8 ++++++++
 3 files changed, 24 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts b/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts
index 553ad774e..6842f8e8d 100644
--- a/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts
+++ b/arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dts
@@ -47,6 +47,14 @@ reg_usb_vbus: vbus {
 	};
 };
 
+&combophy {
+	status = "okay";
+};
+
+&dwc3 {
+	status = "okay";
+};
+
 &ehci0 {
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/allwinner/sun55i-h728-x96qpro+.dts b/arch/arm64/boot/dts/allwinner/sun55i-h728-x96qpro+.dts
index a96927fbd..19388bc11 100644
--- a/arch/arm64/boot/dts/allwinner/sun55i-h728-x96qpro+.dts
+++ b/arch/arm64/boot/dts/allwinner/sun55i-h728-x96qpro+.dts
@@ -46,6 +46,14 @@ reg_vcc3v3: vcc3v3 {
 	};
 };
 
+&combophy {
+	status = "okay";
+};
+
+&dwc3 {
+	status = "okay";
+};
+
 &ehci0 {
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/allwinner/sun55i-t527-avaota-a1.dts b/arch/arm64/boot/dts/allwinner/sun55i-t527-avaota-a1.dts
index b9eeb6753..6f05cd297 100644
--- a/arch/arm64/boot/dts/allwinner/sun55i-t527-avaota-a1.dts
+++ b/arch/arm64/boot/dts/allwinner/sun55i-t527-avaota-a1.dts
@@ -57,6 +57,14 @@ reg_usb_vbus: vbus {
 	};
 };
 
+&combophy {
+	status = "okay";
+};
+
+&dwc3 {
+	status = "okay";
+};
+
 &ehci0 {
 	status = "okay";
 };
-- 
2.50.1



From krzk at kernel.org  Sat Aug 16 02:30:01 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sat, 16 Aug 2025 11:30:01 +0200
Subject: [PATCH 1/7] clk: sunxi-ng: a523: add missing usb related clocks
In-Reply-To: <20250816084700.569524-2-iuncuim@gmail.com>
References: <20250816084700.569524-1-iuncuim@gmail.com>
 <20250816084700.569524-2-iuncuim@gmail.com>
Message-ID: <0e149bdb-8830-42a2-927b-a489b4195015@kernel.org>

On 16/08/2025 10:46, iuncuim wrote:
> From: Mikhail Kalashnikov <iuncuim at gmail.com>
> 
> Several clocks were omitted when adding the original driver. These clocks
> are necessary for USB 3.0 to work correctly. I added these declarations
> according to the driver's BSP code.
> 
> Signed-off-by: Mikhail Kalashnikov <iuncuim at gmail.com>
> ---
>  drivers/clk/sunxi-ng/ccu-sun55i-a523.c      | 32 +++++++++++++++++++++
>  drivers/clk/sunxi-ng/ccu-sun55i-a523.h      |  2 +-
>  include/dt-bindings/clock/sun55i-a523-ccu.h |  4 +++


Bindings should be a separate patch. Checkpatch should also suggest that.

Best regards,
Krzysztof


From krzk at kernel.org  Sat Aug 16 02:31:12 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sat, 16 Aug 2025 11:31:12 +0200
Subject: [PATCH 2/7] arm64: dts: allwinner: a523: add third usb2 phy
In-Reply-To: <20250816084700.569524-3-iuncuim@gmail.com>
References: <20250816084700.569524-1-iuncuim@gmail.com>
 <20250816084700.569524-3-iuncuim@gmail.com>
Message-ID: <c7468189-deee-449f-b7d0-fa1830ca88fc@kernel.org>

On 16/08/2025 10:46, iuncuim wrote:
> From: Mikhail Kalashnikov <iuncuim at gmail.com>
> 
> It seems that there are actually three usb2 phys in the processor, which
> makes it incompatible with D1.
> The third phy is used together with USB3/PCIe combophy with DWC3
> controller. In the BSP code, the third PHY requires a separate glue
> driver, but it seems that it is not needed.
> According to the BSP code, the third phy does not have a reset line; the
> only reset is declared in the DWC3 node, but none of this is documented.
> Since sun4i-usb-phy driver requires a reset, I added RST_BUS_3 here.
> 
> Signed-off-by: Mikhail Kalashnikov <iuncuim at gmail.com>
> ---
>  .../arm64/boot/dts/allwinner/sun55i-a523.dtsi | 21 ++++++++++++-------
>  1 file changed, 13 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
> index 6b6f2296b..e4ed4fa82 100644
> --- a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
> @@ -503,22 +503,27 @@ usb_otg: usb at 4100000 {
>  		};
>  
>  		usbphy: phy at 4100400 {
> -			compatible = "allwinner,sun55i-a523-usb-phy",
> -				     "allwinner,sun20i-d1-usb-phy";
> +			compatible = "allwinner,sun55i-a523-usb-phy";


That's potential break of all users. Also, having third phy (so
additional piece) is not making things incompatible.



Best regards,
Krzysztof


From krzk at kernel.org  Sat Aug 16 02:32:00 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sat, 16 Aug 2025 11:32:00 +0200
Subject: [PATCH 5/7] arm64: dts: allwinner: a523: add USB3.0 phy node
In-Reply-To: <20250816084700.569524-6-iuncuim@gmail.com>
References: <20250816084700.569524-1-iuncuim@gmail.com>
 <20250816084700.569524-6-iuncuim@gmail.com>
Message-ID: <5e89d0c7-5ac5-4376-bc6e-c7ff8ee05024@kernel.org>

On 16/08/2025 10:46, iuncuim wrote:
> From: Mikhail Kalashnikov <iuncuim at gmail.com>
> 
> After adding the phy driver, we can also add phy node. In addition to the
> clk and reset lines, the power domain PD_PCIE is declared in this node
> according to the bsp dtb. So let's mention it. 
> Currently, phy driver does not support role selection and only works in
> USB3.0 mode.
> 
> Signed-off-by: Mikhail Kalashnikov <iuncuim at gmail.com>
> ---
>  arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi | 10 ++++++++++
>  1 file changed, 10 insertions(+)

Please organize your patches correctly. One DTS was in the middle of
patchset, other is at the end. They all must be at the end, because you
cannot have dependency of driver on DTS.

Best regards,
Krzysztof


From krzk at kernel.org  Sat Aug 16 02:33:07 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sat, 16 Aug 2025 11:33:07 +0200
Subject: [PATCH 4/7] phy: allwinner: a523: add USB3/PCIe PHY driver
In-Reply-To: <20250816084700.569524-5-iuncuim@gmail.com>
References: <20250816084700.569524-1-iuncuim@gmail.com>
 <20250816084700.569524-5-iuncuim@gmail.com>
Message-ID: <484e4ff2-c7b2-4087-8850-5a972e7c82b4@kernel.org>

On 16/08/2025 10:46, iuncuim wrote:
> +
> +	phy->reset = devm_reset_control_get(dev, NULL);
> +	if (IS_ERR(phy->reset)) {
> +		dev_err(dev, "failed to get reset control\n");
> +		return PTR_ERR(phy->reset);

Syntax is return dev_err_probe.

> +	}
> +
> +	phy->regs = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(phy->regs))
> +		return PTR_ERR(phy->regs);
> +
> +	phy->regs_clk = phy->regs + PHY_CLK_OFFSET;
> +	if (IS_ERR(phy->regs_clk))
> +		return PTR_ERR(phy->regs_clk);
> +
> +	phy->phy = devm_phy_create(dev, NULL, &sun55i_usb3_pcie_phy_ops);
> +	if (IS_ERR(phy->phy)) {
> +		dev_err(dev, "failed to create PHY\n");
> +		return PTR_ERR(phy->phy);
> +	}
> +
> +	phy_set_drvdata(phy->phy, phy);
> +	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> +
> +	ret = sun55i_usb3_pcie_clk_init(phy);
> +	if (ret)
> +		return ret;
> +	dev_info(phy->dev, "phy version is: 0x%x\n", readl(phy->regs));


This should be rather dev_dbg. See coding style.

> +
> +	return PTR_ERR_OR_ZERO(phy_provider);
> +}
> +
> +static const struct of_device_id sun55i_usb3_pcie_phy_of_match[] = {
> +	{ .compatible = "allwinner,sun55i-a523-usb3-pcie-phy" },

Please run scripts/checkpatch.pl on the patches and fix reported
warnings. After that, run also 'scripts/checkpatch.pl --strict' on the
patches and (probably) fix more warnings. Some warnings can be ignored,
especially from --strict run, but the code here looks like it needs a
fix. Feel free to get in touch if the warning is not clear.

> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, sun55i_usb3_pcie_phy_of_match);
> +
> +static struct platform_driver sun55i_usb3_pcie_phy_driver = {
> +	.probe	= sun55i_usb3_pcie_phy_probe,
> +	.driver = {
> +		.of_match_table	= sun55i_usb3_pcie_phy_of_match,
> +		.name  = "sun55i-usb3-pcie-phy",
> +	}
> +};
> +module_platform_driver(sun55i_usb3_pcie_phy_driver);
> +
> +MODULE_DESCRIPTION("Allwinner A523 USB3/PCIe phy driver");
> +MODULE_AUTHOR("Mikhail Kalashnikov <iuncuim at gmail.com>");
> +MODULE_LICENSE("GPL");


Best regards,
Krzysztof


From andre.przywara at arm.com  Sat Aug 16 06:31:17 2025
From: andre.przywara at arm.com (Andre Przywara)
Date: Sat, 16 Aug 2025 14:31:17 +0100
Subject: [PATCH 3/7] phy: sun4i-usb: a523: add support for the USB2 PHY
In-Reply-To: <20250816084700.569524-4-iuncuim@gmail.com>
References: <20250816084700.569524-1-iuncuim@gmail.com>
	<20250816084700.569524-4-iuncuim@gmail.com>
Message-ID: <20250816143117.4b86ecc6@minigeek.lan>

On Sat, 16 Aug 2025 16:46:56 +0800
iuncuim <iuncuim at gmail.com> wrote:

Hi Mikhail,

many thanks for posting these patches, that's a nice surprise to see
this moving forward!

I think there are some issues with this series, but we can surely iron
those out.

> From: Mikhail Kalashnikov <iuncuim at gmail.com>
> 
> Previously, USB PHY was compatible with D1 and did not require
> separatedata options. But now we need to add a third PHY, which makes it
> incompatible. The third PHY is used together with USB3/PCIe combophy with
> DWC3 controller.

It is really used together? I think on IRC we lately established that
the USB2.0 and USB3.0 parts are somewhat independent, and I think the
Radxa board wires PHY1 to the D-/D+ pins of the USB3.0 socket, instead
of PHY2.

Regardless: this change would be a compatibility break: When a new
kernel with this change sees an old DT, it would bail out, because it
doesn't find the resources for the third PHY in the DT.

What I'd suggest instead is to drop the hardcoded assumption about the
number of PHYs, and instead just enumerate all "pmu<x>" cells in
reg-names. That would work with both old and new DTs, and then we can
also keep the fallback compatible name in the DT, to allow new DTs on
older kernels (for instance a U-Boot provided DT on a stable kernel).

As an added benefit, it would make future enablement easier, as we are
more likely to find a matching compatible string, even when the number
of PHYs differ.

Cheers,
Andre

> In the BSP code, the third PHY requires a separate glue
> driver, but it seems that it is not needed.





> 
> Signed-off-by: Mikhail Kalashnikov <iuncuim at gmail.com>
> ---
>  drivers/phy/allwinner/phy-sun4i-usb.c | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c
> index 8873aed3a..bb79339f2 100644
> --- a/drivers/phy/allwinner/phy-sun4i-usb.c
> +++ b/drivers/phy/allwinner/phy-sun4i-usb.c
> @@ -1025,6 +1025,15 @@ static const struct sun4i_usb_phy_cfg sun50i_h616_cfg = {
>  	.siddq_in_base = true,
>  };
>  
> +static const struct sun4i_usb_phy_cfg sun55i_a523_cfg = {
> +	.num_phys = 3,
> +	.phyctl_offset = REG_PHYCTL_A33,
> +	.dedicated_clocks = true,
> +	.hci_phy_ctl_clear = PHY_CTL_SIDDQ,
> +	.phy0_dual_route = true,
> +	.siddq_in_base = true,
> +};
> +
>  static const struct of_device_id sun4i_usb_phy_of_match[] = {
>  	{ .compatible = "allwinner,sun4i-a10-usb-phy", .data = &sun4i_a10_cfg },
>  	{ .compatible = "allwinner,sun5i-a13-usb-phy", .data = &sun5i_a13_cfg },
> @@ -1041,6 +1050,7 @@ static const struct of_device_id sun4i_usb_phy_of_match[] = {
>  	  .data = &sun50i_a64_cfg},
>  	{ .compatible = "allwinner,sun50i-h6-usb-phy", .data = &sun50i_h6_cfg },
>  	{ .compatible = "allwinner,sun50i-h616-usb-phy", .data = &sun50i_h616_cfg },
> +	{ .compatible = "allwinner,sun55i-a523-usb-phy", .data = &sun55i_a523_cfg },
>  	{ .compatible = "allwinner,suniv-f1c100s-usb-phy",
>  	  .data = &suniv_f1c100s_cfg },
>  	{ },



From andre.przywara at arm.com  Sat Aug 16 06:38:13 2025
From: andre.przywara at arm.com (Andre Przywara)
Date: Sat, 16 Aug 2025 14:38:13 +0100
Subject: [PATCH 2/7] arm64: dts: allwinner: a523: add third usb2 phy
In-Reply-To: <c7468189-deee-449f-b7d0-fa1830ca88fc@kernel.org>
References: <20250816084700.569524-1-iuncuim@gmail.com>
	<20250816084700.569524-3-iuncuim@gmail.com>
	<c7468189-deee-449f-b7d0-fa1830ca88fc@kernel.org>
Message-ID: <20250816143813.77551ff2@minigeek.lan>

On Sat, 16 Aug 2025 11:31:12 +0200
Krzysztof Kozlowski <krzk at kernel.org> wrote:

> On 16/08/2025 10:46, iuncuim wrote:
> > From: Mikhail Kalashnikov <iuncuim at gmail.com>
> > 
> > It seems that there are actually three usb2 phys in the processor, which
> > makes it incompatible with D1.
> > The third phy is used together with USB3/PCIe combophy with DWC3
> > controller. In the BSP code, the third PHY requires a separate glue
> > driver, but it seems that it is not needed.
> > According to the BSP code, the third phy does not have a reset line; the
> > only reset is declared in the DWC3 node, but none of this is documented.
> > Since sun4i-usb-phy driver requires a reset, I added RST_BUS_3 here.
> > 
> > Signed-off-by: Mikhail Kalashnikov <iuncuim at gmail.com>
> > ---
> >  .../arm64/boot/dts/allwinner/sun55i-a523.dtsi | 21 ++++++++++++-------
> >  1 file changed, 13 insertions(+), 8 deletions(-)
> > 
> > diff --git a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
> > index 6b6f2296b..e4ed4fa82 100644
> > --- a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
> > +++ b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
> > @@ -503,22 +503,27 @@ usb_otg: usb at 4100000 {
> >  		};
> >  
> >  		usbphy: phy at 4100400 {
> > -			compatible = "allwinner,sun55i-a523-usb-phy",
> > -				     "allwinner,sun20i-d1-usb-phy";
> > +			compatible = "allwinner,sun55i-a523-usb-phy";  
> 
> 
> That's potential break of all users. Also, having third phy (so
> additional piece) is not making things incompatible.

Yes, we would want to keep the fallback, to allow newer DTs working on
older kernel. As the Linux driver is implemented right now, it's not
fully compatible, since it ties the number of PHYs to the compatible
string - but that's a Linux implementation choice, not something really
related to the binding. And as I replied on the driver patch, that
breaks anyway, and I think we can change it there to preserve
compatibility, and make everyone happy: newer DTs on older kernels,
older DTs on newer kernels, and all working within the kernel's
capability.

Oh, and it looks like there are whitespace issues in the patch ...

Cheers,
Andre


From andre.przywara at arm.com  Sat Aug 16 06:49:36 2025
From: andre.przywara at arm.com (Andre Przywara)
Date: Sat, 16 Aug 2025 14:49:36 +0100
Subject: [PATCH 5/7] arm64: dts: allwinner: a523: add USB3.0 phy node
In-Reply-To: <20250816084700.569524-6-iuncuim@gmail.com>
References: <20250816084700.569524-1-iuncuim@gmail.com>
	<20250816084700.569524-6-iuncuim@gmail.com>
Message-ID: <20250816144936.3f2738cc@minigeek.lan>

On Sat, 16 Aug 2025 16:46:58 +0800
iuncuim <iuncuim at gmail.com> wrote:

Hi,

> From: Mikhail Kalashnikov <iuncuim at gmail.com>
> 
> After adding the phy driver, we can also add phy node. In addition to the
> clk and reset lines, the power domain PD_PCIE is declared in this node
> according to the bsp dtb. So let's mention it. 
> Currently, phy driver does not support role selection and only works in
> USB3.0 mode.

That's the current limitation of the proposed Linux driver, but should
not affect the binding or DT:

> 
> Signed-off-by: Mikhail Kalashnikov <iuncuim at gmail.com>
> ---
>  arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
> index e4ed4fa82..233365496 100644
> --- a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
> @@ -606,6 +606,16 @@ mdio0: mdio {
>  			};
>  		};
>  
> +		combophy: phy at 4f00000 {
> +			compatible = "allwinner,sun55i-a523-usb3-pcie-phy";
> +			reg = <0x04f00000 0x100000>;
> +			clocks = <&ccu CLK_USB3>;

Will we need more clocks (or resets) when supporting PCIe later? If
yes, we should add them already now, even if they are not used by the
current driver.

> +			resets = <&ccu RST_BUS_PCIE_USB3>;
> +			#phy-cells = <0>;

I think we should use one PHY cell here, to allow users to select the
PHY path they need. A USB3.0-only driver implementation could choose to
ignore it, or require the number to be 0 only, rejecting anything else.
But this way we keep compatibility with newer DTs.

Cheers,
Andre

> +			power-domains = <&pck600 PD_PCIE>;
> +			status = "disabled";
> +		};
> +
>  		ppu: power-controller at 7001400 {
>  			compatible = "allwinner,sun55i-a523-ppu";
>  			reg = <0x07001400 0x400>;



From andre.przywara at arm.com  Sat Aug 16 07:10:15 2025
From: andre.przywara at arm.com (Andre Przywara)
Date: Sat, 16 Aug 2025 15:10:15 +0100
Subject: [PATCH 6/7] arm64: dts: allwinner: a523: add DWC3 USB3.0 node
In-Reply-To: <20250816084700.569524-7-iuncuim@gmail.com>
References: <20250816084700.569524-1-iuncuim@gmail.com>
	<20250816084700.569524-7-iuncuim@gmail.com>
Message-ID: <20250816151015.621f8da4@minigeek.lan>

On Sat, 16 Aug 2025 16:46:59 +0800
iuncuim <iuncuim at gmail.com> wrote:

Hi,

> From: Mikhail Kalashnikov <iuncuim at gmail.com>
> 
> After adding the phy bindings, we can also add dwc3 node, which uses the
> previously added usbphy2 and part of usb3 from combophy.
> All settings declared in dwc3 node are obtained from the x96qproplus' dtb.
> BSP contains an additional glue driver for dwc3, but it seems that it is
> not needed.
> 
> Signed-off-by: Mikhail Kalashnikov <iuncuim at gmail.com>
> ---
>  .../arm64/boot/dts/allwinner/sun55i-a523.dtsi | 21 +++++++++++++++++++
>  1 file changed, 21 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
> index 233365496..ec170888a 100644
> --- a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
> @@ -606,6 +606,27 @@ mdio0: mdio {
>  			};
>  		};
>  
> +		dwc3: usb at 4d00000 {
> +			compatible = "snps,dwc3";

Wouldn't we need an A523 specific compatible string first?

> +			reg = <0x04d00000 0x100000>;
> +			interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
> +			dr_mode = "host";
> +			clocks = <&ccu CLK_MBUS_USB3>, <&ccu CLK_USB3>,
> +				 <&ccu CLK_USB2>, <&ccu CLK_USB3_SUSPEND>;
> +			clock-names = "bus_clk", "ref_clk3", "ref_clk2", "suspend";

How does this work, exactly? I see "bus_clk" (deprecated, should be
"bus_early") and "suspend" in the bindings and the Linux driver, but
where do ref_clk3 and ref_clk2 come from, and more importantly who is
going to use them? IIUC, the binding hints that certain implementations
could need more clocks, but then it's their responsibility to parse and
enable them, in platform specific glue code, I think.



> +			maximum-speed = "super-speed";
> +			phy_type = "utmi";
> +			snps,dis_enblslpm_quirk;
> +			snps,dis-u1-entry-quirk;
> +			snps,dis-u2-entry-quirk;
> +			snps,dis_u3_susphy_quirk;
> +			snps,dis_u2_susphy_quirk;
> +			snps,dis_rxdet_inp3_quirk;
> +			phys = <&usbphy 2>, <&combophy>;

Related to my comment on the other DT patch, this should be
"<&combophy 0>" (with "#phy-cells = <1>;" in the PHY node, to be forward
compatible.

Cheers,
Andre


> +			phy-names = "usb2-phy", "usb3-phy";
> +			status = "disabled";
> +		};
> +
>  		combophy: phy at 4f00000 {
>  			compatible = "allwinner,sun55i-a523-usb3-pcie-phy";
>  			reg = <0x04f00000 0x100000>;



From quic_nitirawa at quicinc.com  Mon Aug 18 05:41:09 2025
From: quic_nitirawa at quicinc.com (Nitin Rawat)
Date: Mon, 18 Aug 2025 18:11:09 +0530
Subject: [PATCH V2 1/2] phy: qcom-qmp-ufs: Add regulator load voting for UFS QMP Phy
In-Reply-To: <20250818124110.8136-1-quic_nitirawa@quicinc.com>
References: <20250818124110.8136-1-quic_nitirawa@quicinc.com>
Message-ID: <20250818124110.8136-2-quic_nitirawa@quicinc.com>

On some SoCs, regulators are shared between the QMP UFS PHY and other
IP blocks. Hence convey maximum load requirement for UFS PHY to the
regulator framework as supply's capabilities or mode(Low Power Mode
or High Power Mode) change depending on the maximum potential load
at any given time, which the regulator driver must be aware of.
This helps to ensure stable operation and proper power management,
set the regulator load before enabling the regulators.

This patch adds:

- vreg_load_uA field to qmp_phy_cfg structure for load value arrays.
- Enhanced qmp_ufs_vreg_init() to set init_load_uA when loads are
  specified.

Configurations without specific load requirements will continue
to work unchanged, as init_load_uA remains zero-initialized when
vreg_load_uA is not provided.

Signed-off-by: Nitin Rawat <quic_nitirawa at quicinc.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
index 9c69c77d10c8..f7a4a8334026 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
@@ -1110,6 +1110,9 @@ struct qmp_phy_cfg {
 	const char * const *vreg_list;
 	int num_vregs;

+	/* regulator load values in same order as vreg_list */
+	const int *vreg_load_ua;
+
 	/* array of registers with different offsets */
 	const unsigned int *regs;

@@ -1901,8 +1904,11 @@ static int qmp_ufs_vreg_init(struct qmp_ufs *qmp)
 	if (!qmp->vregs)
 		return -ENOMEM;

-	for (i = 0; i < num; i++)
+	for (i = 0; i < num; i++) {
 		qmp->vregs[i].supply = cfg->vreg_list[i];
+		if (cfg->vreg_load_ua)
+			qmp->vregs[i].init_load_uA = cfg->vreg_load_ua[i];
+	}

 	return devm_regulator_bulk_get(dev, num, qmp->vregs);
 }
--
2.48.1



From quic_nitirawa at quicinc.com  Mon Aug 18 05:41:08 2025
From: quic_nitirawa at quicinc.com (Nitin Rawat)
Date: Mon, 18 Aug 2025 18:11:08 +0530
Subject: [PATCH V2 0/2] Add regulator load support for QMP UFS PHY
Message-ID: <20250818124110.8136-1-quic_nitirawa@quicinc.com>

This patch series adds regulator load support to the QMP UFS PHY driver.
Currently, the driver only sets regulator supply names without specifying
load requirements, which can lead to suboptimal power management.

On some SoCs, regulators are shared between the QMP UFS PHY and other IP
blocks. The regulator framework needs to know the maximum load
requirements from all consumers to determine the appropriate
regulator mode (Low Power Mode vs High Power Mode) and ensure stable
operation.

The series implements a simple and efficient approach for regulator load
handling, with varying load requirements across different SoC
configurations.

Changes from v1:
1. Addressed comments to move load configuration from device tree to
   hardcoded, per-compatible data within the driver.
2. Accordingly updated commit text to reflect the same.
3. Addressed Manivannan's comment to avoid initialization of load.

Nitin Rawat (2):
  phy: qcom-qmp-ufs: Add regulator load voting for UFS QMP Phy
  phy: qcom-qmp-ufs: Add regulator loads for SM8550 and SM8750

 drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

--
2.48.1



From quic_nitirawa at quicinc.com  Mon Aug 18 05:41:10 2025
From: quic_nitirawa at quicinc.com (Nitin Rawat)
Date: Mon, 18 Aug 2025 18:11:10 +0530
Subject: [PATCH V2 2/2] phy: qcom-qmp-ufs: Add regulator loads for SM8550 and SM8750
In-Reply-To: <20250818124110.8136-1-quic_nitirawa@quicinc.com>
References: <20250818124110.8136-1-quic_nitirawa@quicinc.com>
Message-ID: <20250818124110.8136-3-quic_nitirawa@quicinc.com>

Add regulator load configuration for SM8550 and SM8750 UFS PHY.
This ensure proper regulator load management and mode selection for
optimal power efficiency on these SoC platforms where regulators may
be shared with other IP blocks.

The load requirements are:

- SM8550: vdda-phy=205000uA, vdda-pll=17500uA
- SM8750: vdda-phy=213000uA, vdda-pll=18300uA

Signed-off-by: Nitin Rawat <quic_nitirawa at quicinc.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
index f7a4a8334026..50875d9609f6 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
@@ -1172,6 +1172,17 @@ static const char * const qmp_phy_vreg_l[] = {
 	"vdda-phy", "vdda-pll",
 };

+/* Regulator load arrays for specific configurations */
+static const int sm8650_vreg_load_ua[] = {
+	205000, /* vdda-phy */
+	17500,  /* vdda-pll */
+};
+
+static const int sm8750_vreg_load_ua[] = {
+	213000, /* vdda-phy */
+	18300,  /* vdda-pll */
+};
+
 static const struct qmp_ufs_offsets qmp_ufs_offsets = {
 	.serdes		= 0,
 	.pcs		= 0xc00,
@@ -1642,6 +1653,7 @@ static const struct qmp_phy_cfg sm8650_ufsphy_cfg = {

 	.vreg_list		= qmp_phy_vreg_l,
 	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
+	.vreg_load_ua		= sm8650_vreg_load_ua,
 	.regs			= ufsphy_v6_regs_layout,
 };

@@ -1680,6 +1692,7 @@ static const struct qmp_phy_cfg sm8750_ufsphy_cfg = {

 	.vreg_list		= qmp_phy_vreg_l,
 	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
+	.vreg_load_ua		= sm8750_vreg_load_ua,
 	.regs			= ufsphy_v6_regs_layout,

 };
--
2.48.1



From devarsht at ti.com  Mon Aug 18 06:05:40 2025
From: devarsht at ti.com (Devarsh Thakkar)
Date: Mon, 18 Aug 2025 18:35:40 +0530
Subject: [PATCH 0/2] phy: cdns-dphy: hs-clk improvement and a cleanup
In-Reply-To: <cac3d853-11aa-481b-90bb-aeb2cd4608f8@ti.com>
References: <20250723-cdns-dphy-hs-clk-rate-fix-v1-0-d4539d44cbe7@ideasonboard.com>
 <cc0e4cf5-1bd9-4ae3-a130-0483dbfc6335@ideasonboard.com>
 <aJM0WPVDUkte9E_D@vaman> <cac3d853-11aa-481b-90bb-aeb2cd4608f8@ti.com>
Message-ID: <b0f176de-3476-4e66-ade3-0df39578c3ac@ti.com>

Gentle reminder.

Hi Vinod,

On 12/08/25 11:32, devarsh wrote:
> Hi Vinod, Kishon,
> 
> On 06/08/25 16:24, Vinod Koul wrote:
>> On 05-08-25, 15:03, Tomi Valkeinen wrote:
>>> Hi Vinod, Kishon,
>>>
>>> On 23/07/2025 13:01, Tomi Valkeinen wrote:
>>>> A cdns-dphy improvement to return the actual hs clock rate, and a
>>>> cleanup to remove leftover code.
>>>>
>>>> These were part of a Cadence DSI series:
>>>>
>>>> https://lore.kernel.org/all/20250618-cdns-dsi-impro-v4-0-862c841dbe02%40ideasonboard.com/
>>>>
>>>> but are now separately here for easier merging.
>>>>
>>>> Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
>>>> ---
>>>> Tomi Valkeinen (2):
>>>>        phy: cdns-dphy: Store hs_clk_rate and return it
>>>>        phy: cdns-dphy: Remove leftover code
>>>>
>>>>   drivers/phy/cadence/cdns-dphy.c | 24 +++++++++---------------
>>>>   1 file changed, 9 insertions(+), 15 deletions(-)
>>>> ---
>>>> base-commit: 89be9a83ccf1f88522317ce02f854f30d6115c41
>>>> change-id: 20250723-cdns-dphy-hs-clk-rate-fix-a8857a5789dd
>>>
>>> Is this good to merge, and if so, do you have any estimate when? While
>>> this is independent from the DSI series, I'd rather push the DSI series
>>> into drm-misc about the same time, so both would appear in linux-next
>>> relatively together.
>>
>> I will start taking patches after merge window closes next monday, so
>> next week should be a good estimate
> 
> On top of this series [1], we have the cadence DPHY fixes for fixing PLL
> lockup timeout [2] and one more patch which enables lower resolutions
> [3], both have been reviewed and tested too.
> 
> Would it be possible for you too merge all 3 together in below order ?
> 
> [1]:
> https://lore.kernel.org/all/cc0e4cf5-1bd9-4ae3-a130-0483dbfc6335 at ideasonboard.com/
> [2]: https://lore.kernel.org/all/20250704125915.1224738-1-devarsht at ti.com/
> [3]: https://lore.kernel.org/all/20250807052002.717807-1-h-shenoy at ti.com/
>

As I understand we see [1] got merged to linux-next but [2] and [3] are 
still pending. Could you please let us know if anything further required 
on our side for these two i.e. [2] and [3] ?

Regards
Devarsh

> Kindly let us know if anything required from our side.
> 
> Regards
> Devarsh
> 



From robh at kernel.org  Mon Aug 18 07:39:26 2025
From: robh at kernel.org (Rob Herring)
Date: Mon, 18 Aug 2025 09:39:26 -0500
Subject: [PATCH v2 01/32] dt-bindings: media: add DW MIPI CSI-2 Host
 support
In-Reply-To: <20250808-95_cam-v2-1-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
 <20250808-95_cam-v2-1-4b29fa6919a7@nxp.com>
Message-ID: <20250818143926.GA1025181-robh@kernel.org>

On Fri, Aug 08, 2025 at 06:39:04PM -0400, Frank Li wrote:
> From: Eugen Hristev <eugen.hristev at linaro.org>
> 
> Add bindings for Synopsys DesignWare MIPI CSI-2 host, which used at i.MX93
> and i.MX95 platform.
> 
> Signed-off-by: Luis Oliveira <lolivei at synopsys.com>
> Signed-off-by: Eugen Hristev <eugen.hristev at linaro.org>
> Signed-off-by: Frank Li <Frank.Li at nxp.com>
> ---
> Change in v2
> - remove Eugen Hristev <eugen.hristev at microchip.com> from mantainer.
> - update ugen Hristev's s-o-b tag to align original author's email address
> - remove single snps,dw-mipi-csi2-v150 compatible string
> - move additionalProperties after required
> ---
>  .../bindings/media/snps,dw-mipi-csi2-v150.yaml     | 158 +++++++++++++++++++++
>  MAINTAINERS                                        |   1 +
>  2 files changed, 159 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/media/snps,dw-mipi-csi2-v150.yaml b/Documentation/devicetree/bindings/media/snps,dw-mipi-csi2-v150.yaml
> new file mode 100644
> index 0000000000000000000000000000000000000000..fc1b167d6d3b142a01e2ea7f04230934260a05e6
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/snps,dw-mipi-csi2-v150.yaml
> @@ -0,0 +1,158 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/media/snps,dw-mipi-csi2-v150.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Synopsys DesignWare CSI-2 Host controller (csi2host)
> +
> +maintainers:
> +  - Frank Li <Frank.Li at nxp.com>
> +
> +description:
> +  CSI2HOST is used to receive image coming from an MIPI CSI-2 compatible
> +  camera. It will convert the incoming CSI-2 stream into a dedicated
> +  interface called the Synopsys IDI (Image Data Interface).
> +  This interface is a 32-bit SoC internal only, and can be assimilated
> +  with a CSI-2 interface.
> +
> +properties:
> +  compatible:
> +    items:
> +      - enum:
> +          - fsl,imx93-mipi-csi2
> +      - const: snps,dw-mipi-csi2-v150
> +
> +  reg:
> +    items:
> +      - description: MIPI CSI-2 core register
> +
> +  reg-names:
> +    items:
> +      - const: core
> +
> +  clocks:
> +    maxItems: 2
> +
> +  clock-names:
> +    items:
> +      - const: per
> +      - const: pixel
> +
> +  phys:
> +    maxItems: 1
> +    description: MIPI D-PHY
> +
> +  phy-names:
> +    items:
> +      - const: rx
> +
> +  resets:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  power-domains:
> +    maxItems: 1
> +
> +  ports:
> +    $ref: /schemas/graph.yaml#/properties/ports
> +
> +    properties:
> +      port at 0:
> +        $ref: /schemas/graph.yaml#/$defs/port-base
> +        unevaluatedProperties: false
> +        description:
> +          Input port node, single endpoint describing the input port.
> +
> +        properties:
> +          endpoint:
> +            $ref: video-interfaces.yaml#
> +            unevaluatedProperties: false
> +            description: Endpoint connected to input device
> +
> +            properties:
> +              bus-type:
> +                const: 4
> +
> +              data-lanes:
> +                minItems: 1
> +                maxItems: 4
> +                items:
> +                  maximum: 4
> +
> +              clock-lanes:
> +                maxItems: 1

Drop. clock-lanes is always 1 entry.

> +
> +              remote-endpoint: true

Drop.

> +
> +      port at 1:
> +        $ref: /schemas/graph.yaml#/$defs/port-base
> +        unevaluatedProperties: false
> +        description:
> +          Output port node, single endpoint describing the output port.
> +
> +        properties:
> +          endpoint:
> +            unevaluatedProperties: false
> +            $ref: video-interfaces.yaml#
> +            description: Endpoint connected to output device
> +
> +            properties:
> +              bus-type:
> +                const: 4
> +
> +              remote-endpoint: true

Drop.

Rob


From robh at kernel.org  Mon Aug 18 07:54:31 2025
From: robh at kernel.org (Rob Herring (Arm))
Date: Mon, 18 Aug 2025 09:54:31 -0500
Subject: [PATCH 1/4] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy:
 Document the SM8750 QMP PCIe PHY Gen3 x2
In-Reply-To: <20250809-pakala-v1-1-abf1c416dbaa@oss.qualcomm.com>
References: <20250809-pakala-v1-0-abf1c416dbaa@oss.qualcomm.com>
 <20250809-pakala-v1-1-abf1c416dbaa@oss.qualcomm.com>
Message-ID: <175552887070.1211494.12034577229167513641.robh@kernel.org>


On Sat, 09 Aug 2025 15:29:16 +0530, Krishna Chaitanya Chundru wrote:
> Document the QMP PCIe PHY on the SM8750 platform.
> 
> Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
> ---
>  Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 

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



From robh at kernel.org  Mon Aug 18 07:54:50 2025
From: robh at kernel.org (Rob Herring (Arm))
Date: Mon, 18 Aug 2025 09:54:50 -0500
Subject: [PATCH 3/4] dt-bindings: PCI: qcom,pcie-sm8550: Add SM8750
 compatible
In-Reply-To: <20250809-pakala-v1-3-abf1c416dbaa@oss.qualcomm.com>
References: <20250809-pakala-v1-0-abf1c416dbaa@oss.qualcomm.com>
 <20250809-pakala-v1-3-abf1c416dbaa@oss.qualcomm.com>
Message-ID: <175552888940.1212051.15924500632335799397.robh@kernel.org>


On Sat, 09 Aug 2025 15:29:18 +0530, Krishna Chaitanya Chundru wrote:
> On the Qualcomm SM8750 platform the PCIe host is compatible with the
> DWC controller present on the SM8550 platorm.
> 
> Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
> ---
>  Documentation/devicetree/bindings/pci/qcom,pcie-sm8550.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 

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



From shradha.t at samsung.com  Mon Aug 18 01:41:04 2025
From: shradha.t at samsung.com (Shradha Todi)
Date: Mon, 18 Aug 2025 14:11:04 +0530
Subject: [PATCH v3 06/12] dt-bindings: PCI: Split exynos host into two
 files
In-Reply-To: <4a47b758-5c20-4e30-bc61-206acd48bdd0@kernel.org>
References: <20250811154638.95732-1-shradha.t@samsung.com>
	<CGME20250811154721epcas5p26c9e2880ca55a470f595d914b4030745@epcas5p2.samsung.com>
	<20250811154638.95732-7-shradha.t@samsung.com>
	<4a47b758-5c20-4e30-bc61-206acd48bdd0@kernel.org>
Message-ID: <000801dc101b$d7b22510$87166f30$@samsung.com>

> >
> > @@ -19,9 +19,6 @@ allOf:
> >    - $ref: /schemas/pci/snps,dw-pcie.yaml#
> >
> >  properties:
> > -  compatible:
> > -    const: samsung,exynos5433-pcie
> > -
> >    reg:
> >      items:
> >        - description: Data Bus Interface (DBI) registers.
> 
> 
> So the only common part left here is reg and phy? I don't think such
> common file brings any value.
> 
> 

Okay, will keep two separate files. 

> Best regards,
> Krzysztof



From shradha.t at samsung.com  Mon Aug 18 01:46:16 2025
From: shradha.t at samsung.com (Shradha Todi)
Date: Mon, 18 Aug 2025 14:16:16 +0530
Subject: [PATCH v3 07/12] dt-bindings: PCI: Add support for Tesla FSD
 SoC
In-Reply-To: <9e065582-9349-4f39-88b5-048d333ab8d7@kernel.org>
References: <20250811154638.95732-1-shradha.t@samsung.com>
	<CGME20250811154725epcas5p428fa3370a32bc2b664a4fd8260078097@epcas5p4.samsung.com>
	<20250811154638.95732-8-shradha.t@samsung.com>
	<9e065582-9349-4f39-88b5-048d333ab8d7@kernel.org>
Message-ID: <000901dc101c$917bf160$b473d420$@samsung.com>

> > +
> > +  phys:
> > +    maxItems: 1
> > +
> > +  samsung,syscon-pcie:
> > +    $ref: /schemas/types.yaml#/definitions/phandle-array
> > +    description: phandle for system control registers, used to
> > +                 control signals at system level
> 
> What is "system level"? and what are these "signals" being controlled?
> 

I will add a more detailed description for why the syscon is being used

> 
> > +title: Tesla FSD SoC series PCIe Host Controller
> > +
> > +maintainers:
> > +  - Shradha Todi <shradha.t at samsung.com>
> > +
> > +description:
> > +  Tesla FSD SoCs PCIe host controller inherits all the common
> > +  properties defined in samsung,exynos-pcie.yaml
> > +
> > +allOf:
> > +  - $ref: /schemas/pci/samsung,exynos-pcie.yaml#
> > +
> > +properties:
> > +  compatible:
> > +    const: tesla,fsd-pcie
> > +
> > +  clocks:
> > +    maxItems: 4
> > +
> > +  clock-names:
> > +    items:
> > +      - const: aux
> > +      - const: dbi
> > +      - const: mstr
> > +      - const: slv
> > +
> > +  num-lanes:
> > +    maximum: 4
> > +
> > +  samsung,syscon-pcie:
> > +    $ref: /schemas/types.yaml#/definitions/phandle-array
> > +    description: phandle for system control registers, used to
> > +                 control signals at system level
> > +
> > +required:
> > +  - samsung,syscon-pcie
> 
> clocks are required, compatible as well.
> 

Since this was inheriting the common exynos yaml file and that had these properties
under required, I did not mention again. Will take care in next version.

> Missing supplies, both as properties and required. PCI devices do not
> work without power.
> 

According to the HW design of FSD SoC, the control to manage PCIe power is given to
a separate CPU where custom firmware runs. Therefore, the Linux side does not control
the PCIe power supplies directly and are hence not included in the device tree.

> > +
> > +unevaluatedProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/clock/fsd-clk.h>
> > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > +
> > +    soc {
> > +        #address-cells = <2>;
> > +        #size-cells = <2>;
> > +
> > +        pcierc1: pcie at 16b00000 {
> > +            compatible = "tesla,fsd-pcie";
> > +            reg = <0x0 0x16b00000 0x0 0x2000>,
> > +                  <0x0 0x168c0000 0x0 0x1000>,
> > +                  <0x0 0x18000000 0x0 0x1000>;
> > +            reg-names = "dbi", "elbi", "config";
> > +            ranges =  <0x82000000 0x0 0x18001000 0x0 0x18001000 0x0 0xffefff>;
> 
> Misaligned. Follow closely DTS coding style.
> 

Will take care.




From shradha.t at samsung.com  Mon Aug 18 01:54:30 2025
From: shradha.t at samsung.com (Shradha Todi)
Date: Mon, 18 Aug 2025 14:24:30 +0530
Subject: [PATCH v3 12/12] arm64: dts: fsd: Add PCIe support for Tesla
 FSD SoC
In-Reply-To: <b22f9381-1835-463a-8daa-97835b159f78@kernel.org>
References: <20250811154638.95732-1-shradha.t@samsung.com>
	<CGME20250811154746epcas5p261ba0c811f9dd8748f8f241b76be6525@epcas5p2.samsung.com>
	<20250811154638.95732-13-shradha.t@samsung.com>
	<b22f9381-1835-463a-8daa-97835b159f78@kernel.org>
Message-ID: <000b01dc101d$b834db40$289e91c0$@samsung.com>

> > +&pcieep2 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&pcie1_clkreq>, <&pcie1_wake>, <&pcie1_preset>,
> > +			<&pcie0_slot1>;
> > +};
> > +
> > +&pcierc0 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&pcie0_clkreq>, <&pcie0_wake0>, <&pcie0_preset0>,
> > +			 <&pcie0_slot0>;
> > +};
> > +
> > +&pcieep0 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&pcie0_clkreq>, <&pcie0_wake0>, <&pcie0_preset0>,
> > +			 <&pcie0_slot0>;
> > +};
> > +
> > +&pcierc1 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&pcie0_clkreq>, <&pcie0_wake1>, <&pcie0_preset0>;
> > +};
> > +
> > +&pcieep1 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&pcie0_clkreq>, <&pcie0_wake1>, <&pcie0_preset0>;
> 
> 
> All these are pointless, because the node is disabled. The board level
> should be complete, so also supplies and enabling the device.
> 

I will enable required nodes. Had enabled while testing but missed to
add in patch. Though all nodes will not be enabled as it is a dual-mode
controller and cannot run as both RC and EP at the same time.

> Best regards,
> Krzysztof



From shradha.t at samsung.com  Mon Aug 18 02:21:34 2025
From: shradha.t at samsung.com (Shradha Todi)
Date: Mon, 18 Aug 2025 14:51:34 +0530
Subject: [PATCH v3 05/12] PCI: exynos: Add resource ops, soc variant and
 device mode
In-Reply-To: <20250813230733.GA299608@bhelgaas>
References: <CGME20250813230739epcas5p3d0b8e4bfa880874092c185c7e9819e99@epcas5p3.samsung.com>
	<20250813230733.GA299608@bhelgaas>
Message-ID: <000c01dc1021$803abad0$80b03070$@samsung.com>

> > Some resources might differ based on platforms and we need platform
> > specific functions to initialize or alter them. For better code
> > re-usability, making a separate res_ops which will hold all such
> > function pointers or other resource specific data. Include ops like
> >  - init_regulator (initialize the regulator data)
> >  - pcie_irq_handler (interrupt handler for PCIe)
> >  - set_device_mode (set device mode to EP or RC)
> >
> > Some operations maybe specific to certain SoCs and not applicable
> > to others. For such use cases, adding an SoC variant data field
> > which can be used to distinguish between the variants.
> >
> > Some SoCs may have dual-role PCIe controller which can work as
> > RC or EP. Add device_mode to store the role and take decisions
> > accordingly.
> >
> > Make enable/disable of regulator and initialization of IRQ as
> > common functions to be used by all Samsung SoCs.
> 
> As hinted above, this patch ends up being a mixture of several things
> that makes this kind of hard to review.  Separating these into their
> own patches would make it easier.
> 

Will split into multiple patches




From shradha.t at samsung.com  Mon Aug 18 02:30:00 2025
From: shradha.t at samsung.com (Shradha Todi)
Date: Mon, 18 Aug 2025 15:00:00 +0530
Subject: [PATCH v3 11/12] PCI: exynos: Add support for Tesla FSD SoC
In-Reply-To: <20250813230744.GA299971@bhelgaas>
References: <CGME20250813230750epcas5p2101d8bb07332cde1beabe70ca6227aca@epcas5p2.samsung.com>
	<20250813230744.GA299971@bhelgaas>
Message-ID: <000d01dc1022$ad8c0740$08a415c0$@samsung.com>

> On Mon, Aug 11, 2025 at 09:16:37PM +0530, Shradha Todi wrote:
> > Add host and endpoint controller driver support for FSD SoC.
> 
> I think this might be easier if you added host mode first, then added
> endpoint mode with a separate patch.
> 

Will do.

> It's kind of unfortunate that the driver uses "ep" everywhere for
> struct exynos_pcie pointers.  It's going to be confusing because "ep"
> is also commonly used for endpoint-related things, e.g., struct
> dw_pcie_ep pointers.  Maybe it's not worth changing; I dunno.
> 

I did try to rename the structure and the pointers 
(https://lore.kernel.org/all/20230214121333.1837-9-shradha.t at samsung.com/)
But the intention was different back then and so the idea was rejected.
I could add a patch to only rename the pointers to something less
confusing like "exy_pci"

> > +static irqreturn_t fsd_pcie_irq_handler(int irq, void *arg)
> > +{
> > +	u32 val;
> > +	struct exynos_pcie *ep = arg;
> > +	struct dw_pcie *pci = &ep->pci;
> > +	struct dw_pcie_rp *pp = &pci->pp;
> > +
> > +	val = readl(ep->elbi_base + FSD_IRQ2_STS);
> > +	if ((val & FSD_IRQ_MSI_ENABLE) == FSD_IRQ_MSI_ENABLE) {
> > +		val &= FSD_IRQ_MSI_ENABLE;
> > +		writel(val, ep->elbi_base + FSD_IRQ2_STS);
> 
> This looks weird because FSD_IRQ_MSI_ENABLE sounds like an *enable*
> bit, but here you're treating it as a *status* bit.
> 
> As far as I can tell, you set FSD_IRQ_MSI_ENABLE once at probe-time in
> fsd_pcie_msi_init(), then you clear it here in an IRQ handler, and it
> will never be set again.  That seems wrong; am I missing something?
> 

Actually the status IRQ and enable IRQ registers are different offsets
but the bit position for MSI remains same in both cases so I just reused
the macro. But I understand that it's confusing so I will add another
macro for FSD_IRQ_MSI_STATUS or just rename the macro to
FSD_IRQ_MSI to re-use.

> > +		dw_handle_msi_irq(pp);
> > +	}
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> > +static void fsd_pcie_msi_init(struct exynos_pcie *ep)
> > +{
> > +	int val;
> > +
> > +	val = readl(ep->elbi_base + FSD_IRQ2_EN);
> > +	val |= FSD_IRQ_MSI_ENABLE;
> > +	writel(val, ep->elbi_base + FSD_IRQ2_EN);
> > +}
> > +
> > +static void __iomem *fsd_atu_setting(struct dw_pcie *pci, void __iomem *base)
> 
> The "setting" name suggests that this merely returns an address
> without side effects, but in fact it actively *sets* the view.
> 
> In this case there's no locking around:
> 
>   addr = fsd_atu_setting(pci, base);
>   dw_pcie_read(addr + reg, size, &val);
> 
> even though concurrent calls would cause issues, but I think that's OK
> because we only get there via the driver, and I assume multiple DBI or
> DBI2 accesses never happen because they're not used in asynchronous
> paths like interrupt handlers.
> 

Yes, there is no concurrent access to this function and hence I have
not added locking mechanism.

> But I think a name that hints at the fact that this does have side
> effects would be helpful as a reminder in the callers that they must
> not be used concurrently.
> 

Sure, I will change the name and also add comment as a reminder.

> > +static const struct pci_epc_features fsd_pcie_epc_features = {
> > +	.linkup_notifier = false,
> > +	.msi_capable = true,
> > +	.msix_capable = false,
> 
> I think we should omit features we do *not* support instead of calling
> them out explicitly, e.g., we don't need .linkup_notifier or
> .msix_capable.
> 
> We've added them in the past, but they're unnecessary and they lead to
> either pervasive changes (adding ".new_feature = false" to all
> existing drivers when adding the feature) or inconsistency (new
> drivers include ".new_feature = false" but existing drivers do not).
> 

Will remove

> > +	if (ep->pdata->soc_variant == FSD) {
> > +		ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(36));
> > +		if (ret)
> > +			return ret;
> > +
> > +		ep->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
> > +				"samsung,syscon-pcie");
> > +		if (IS_ERR(ep->sysreg)) {
> > +			dev_err(dev, "sysreg regmap lookup failed.\n");
> > +			return PTR_ERR(ep->sysreg);
> > +		}
> > +
> > +		ret = of_property_read_u32_index(dev->of_node, "samsung,syscon-pcie", 1,
> > +						 &ep->sysreg_offset);
> > +		if (ret) {
> > +			dev_err(dev, "couldn't get the register offset for syscon!\n");
> > +			return ret;
> > +		}
> > +	}
> 
> This is a good example of a complicated set of things where I think
> you should either add a SoC-specific function pointer to do this or
> test a property, e.g., "DMA width", instead of testing for a specific
> SoC.
> 

Got your point and it makes sense. In future, other drivers could also
want to set DMA width, etc. Will make properties to replace soc_variant:
 - DMA_width
 - has_syscon
 - function pointer to assert_core_reset and deassert_core_reset

Any suggestions or is this approach okay?

-Shradha



From robh at kernel.org  Mon Aug 18 11:24:41 2025
From: robh at kernel.org (Rob Herring (Arm))
Date: Mon, 18 Aug 2025 13:24:41 -0500
Subject: [PATCH 0/7] arm64: allwinner: a523: add USB3.0 support
In-Reply-To: <20250816084700.569524-1-iuncuim@gmail.com>
References: <20250816084700.569524-1-iuncuim@gmail.com>
Message-ID: <175554055617.1719671.12698982859500685788.robh@kernel.org>


On Sat, 16 Aug 2025 16:46:53 +0800, iuncuim wrote:
> From: Mikhail Kalashnikov <iuncuim at gmail.com>
> 
> This series is a draft and does not include patches for dt-bindings.
> The first series is necessary for testing on other devices and
> initiating discussion.
> 
> This series of patches adds USB 3.0 functionality for the
> A523/A527/H728/T527 processor.Most of the code is derived from the BSP,
>  as the datasheet does not fully describe this feature.
> 
> I have verified functionality on two of my boards, walnutpi 2b (t527)
> and x96qproplus (h728). When testing usb3.0 on x96qproplus, I get
> reconnections of my nvme, it looks like the port does not provide enough
>  current to work. I have encountered similar complaints from users of the
>   device on Android. In the case of walnutpi, there is no such problem.
> 
> Based on 6.17-rc1
> 
> Mikhail Kalashnikov (7):
>   clk: sunxi-ng: a523: add missing usb related clocks
>   arm64: dts: allwinner: a523: add third usb2 phy
>   phy: sun4i-usb: a523: add support for the USB2 PHY
>   phy: allwinner: a523: add USB3/PCIe PHY driver
>   arm64: dts: allwinner: a523: add USB3.0 phy node
>   arm64: dts: allwinner: a523: add DWC3 USB3.0 node
>   arm64: dts: allwinner: a523: activate USB3 for all boards
> 
>  .../arm64/boot/dts/allwinner/sun55i-a523.dtsi |  52 +++-
>  .../dts/allwinner/sun55i-a527-cubie-a5e.dts   |   8 +
>  .../dts/allwinner/sun55i-h728-x96qpro+.dts    |   8 +
>  .../dts/allwinner/sun55i-t527-avaota-a1.dts   |   8 +
>  drivers/clk/sunxi-ng/ccu-sun55i-a523.c        |  32 +++
>  drivers/clk/sunxi-ng/ccu-sun55i-a523.h        |   2 +-
>  drivers/phy/allwinner/Kconfig                 |   9 +
>  drivers/phy/allwinner/Makefile                |   1 +
>  drivers/phy/allwinner/phy-sun4i-usb.c         |  10 +
>  drivers/phy/allwinner/phy-sun55i-usb3-pcie.c  | 267 ++++++++++++++++++
>  include/dt-bindings/clock/sun55i-a523-ccu.h   |   4 +
>  11 files changed, 392 insertions(+), 9 deletions(-)
>  create mode 100644 drivers/phy/allwinner/phy-sun55i-usb3-pcie.c
> 
> --
> 2.50.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


This patch series was applied (using b4) to base:
 Base: attempting to guess base-commit...
 Base: remotes/korg/master-95-g90d970cade8e (exact match)

If this is not the correct base, please add 'base-commit' tag
(or use b4 which does this automatically)

New warnings running 'make CHECK_DTBS=y for arch/arm64/boot/dts/allwinner/' for 20250816084700.569524-1-iuncuim at gmail.com:

arch/arm64/boot/dts/allwinner/sun55i-h728-x96qpro+.dtb: phy at 4100400 (allwinner,sun55i-a523-usb-phy): clock-names: ['usb0_phy', 'usb1_phy', 'usb2_phy'] is too long
	from schema $id: http://devicetree.org/schemas/phy/allwinner,sun50i-a64-usb-phy.yaml#
arch/arm64/boot/dts/allwinner/sun55i-h728-x96qpro+.dtb: phy at 4100400 (allwinner,sun55i-a523-usb-phy): clocks: [[5], [5], [2, 179]] is too long
	from schema $id: http://devicetree.org/schemas/phy/allwinner,sun50i-a64-usb-phy.yaml#
arch/arm64/boot/dts/allwinner/sun55i-h728-x96qpro+.dtb: phy at 4100400 (allwinner,sun55i-a523-usb-phy): compatible: 'oneOf' conditional failed, one must be fixed:
	['allwinner,sun55i-a523-usb-phy'] is too short
	'allwinner,sun55i-a523-usb-phy' is not one of ['allwinner,sun20i-d1-usb-phy', 'allwinner,sun50i-a64-usb-phy']
	from schema $id: http://devicetree.org/schemas/phy/allwinner,sun50i-a64-usb-phy.yaml#
arch/arm64/boot/dts/allwinner/sun55i-h728-x96qpro+.dtb: phy at 4100400 (allwinner,sun55i-a523-usb-phy): reg: [[68158464, 256], [68163584, 256], [69208064, 256], [81788928, 256]] is too long
	from schema $id: http://devicetree.org/schemas/phy/allwinner,sun50i-a64-usb-phy.yaml#
arch/arm64/boot/dts/allwinner/sun55i-h728-x96qpro+.dtb: phy at 4100400 (allwinner,sun55i-a523-usb-phy): reg-names: ['phy_ctrl', 'pmu0', 'pmu1', 'pmu2'] is too long
	from schema $id: http://devicetree.org/schemas/phy/allwinner,sun50i-a64-usb-phy.yaml#
arch/arm64/boot/dts/allwinner/sun55i-h728-x96qpro+.dtb: phy at 4100400 (allwinner,sun55i-a523-usb-phy): reset-names: ['usb0_reset', 'usb1_reset', 'usb2_reset'] is too long
	from schema $id: http://devicetree.org/schemas/phy/allwinner,sun50i-a64-usb-phy.yaml#
arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dtb: phy at 4100400 (allwinner,sun55i-a523-usb-phy): clock-names: ['usb0_phy', 'usb1_phy', 'usb2_phy'] is too long
arch/arm64/boot/dts/allwinner/sun55i-h728-x96qpro+.dtb: phy at 4100400 (allwinner,sun55i-a523-usb-phy): resets: [[2, 49], [2, 50], [2, 56]] is too long
	from schema $id: http://devicetree.org/schemas/phy/allwinner,sun50i-a64-usb-phy.yaml#
arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dtb: phy at 4100400 (allwinner,sun55i-a523-usb-phy): clocks: [[5], [5], [2, 179]] is too long
	from schema $id: http://devicetree.org/schemas/phy/allwinner,sun50i-a64-usb-phy.yaml#
arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dtb: phy at 4100400 (allwinner,sun55i-a523-usb-phy): compatible: 'oneOf' conditional failed, one must be fixed:
	['allwinner,sun55i-a523-usb-phy'] is too short
	'allwinner,sun55i-a523-usb-phy' is not one of ['allwinner,sun20i-d1-usb-phy', 'allwinner,sun50i-a64-usb-phy']
	from schema $id: http://devicetree.org/schemas/phy/allwinner,sun50i-a64-usb-phy.yaml#
arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dtb: phy at 4100400 (allwinner,sun55i-a523-usb-phy): reg: [[68158464, 256], [68163584, 256], [69208064, 256], [81788928, 256]] is too long
	from schema $id: http://devicetree.org/schemas/phy/allwinner,sun50i-a64-usb-phy.yaml#
arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dtb: phy at 4100400 (allwinner,sun55i-a523-usb-phy): reg-names: ['phy_ctrl', 'pmu0', 'pmu1', 'pmu2'] is too long
	from schema $id: http://devicetree.org/schemas/phy/allwinner,sun50i-a64-usb-phy.yaml#
arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dtb: phy at 4100400 (allwinner,sun55i-a523-usb-phy): reset-names: ['usb0_reset', 'usb1_reset', 'usb2_reset'] is too long
	from schema $id: http://devicetree.org/schemas/phy/allwinner,sun50i-a64-usb-phy.yaml#
arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dtb: phy at 4100400 (allwinner,sun55i-a523-usb-phy): resets: [[2, 49], [2, 50], [2, 56]] is too long
	from schema $id: http://devicetree.org/schemas/phy/allwinner,sun50i-a64-usb-phy.yaml#
arch/arm64/boot/dts/allwinner/sun55i-t527-orangepi-4a.dtb: phy at 4100400 (allwinner,sun55i-a523-usb-phy): clock-names: ['usb0_phy', 'usb1_phy', 'usb2_phy'] is too long
	from schema $id: http://devicetree.org/schemas/phy/allwinner,sun50i-a64-usb-phy.yaml#
arch/arm64/boot/dts/allwinner/sun55i-t527-orangepi-4a.dtb: phy at 4100400 (allwinner,sun55i-a523-usb-phy): clocks: [[5], [5], [2, 179]] is too long
	from schema $id: http://devicetree.org/schemas/phy/allwinner,sun50i-a64-usb-phy.yaml#
arch/arm64/boot/dts/allwinner/sun55i-t527-orangepi-4a.dtb: phy at 4100400 (allwinner,sun55i-a523-usb-phy): compatible: 'oneOf' conditional failed, one must be fixed:
	['allwinner,sun55i-a523-usb-phy'] is too short
	'allwinner,sun55i-a523-usb-phy' is not one of ['allwinner,sun20i-d1-usb-phy', 'allwinner,sun50i-a64-usb-phy']
	from schema $id: http://devicetree.org/schemas/phy/allwinner,sun50i-a64-usb-phy.yaml#
arch/arm64/boot/dts/allwinner/sun55i-t527-orangepi-4a.dtb: phy at 4100400 (allwinner,sun55i-a523-usb-phy): reg: [[68158464, 256], [68163584, 256], [69208064, 256], [81788928, 256]] is too long
	from schema $id: http://devicetree.org/schemas/phy/allwinner,sun50i-a64-usb-phy.yaml#
arch/arm64/boot/dts/allwinner/sun55i-t527-orangepi-4a.dtb: phy at 4100400 (allwinner,sun55i-a523-usb-phy): reg-names: ['phy_ctrl', 'pmu0', 'pmu1', 'pmu2'] is too long
	from schema $id: http://devicetree.org/schemas/phy/allwinner,sun50i-a64-usb-phy.yaml#
arch/arm64/boot/dts/allwinner/sun55i-t527-orangepi-4a.dtb: phy at 4100400 (allwinner,sun55i-a523-usb-phy): reset-names: ['usb0_reset', 'usb1_reset', 'usb2_reset'] is too long
	from schema $id: http://devicetree.org/schemas/phy/allwinner,sun50i-a64-usb-phy.yaml#
arch/arm64/boot/dts/allwinner/sun55i-t527-orangepi-4a.dtb: phy at 4100400 (allwinner,sun55i-a523-usb-phy): resets: [[2, 49], [2, 50], [2, 56]] is too long
	from schema $id: http://devicetree.org/schemas/phy/allwinner,sun50i-a64-usb-phy.yaml#
arch/arm64/boot/dts/allwinner/sun55i-t527-avaota-a1.dtb: phy at 4100400 (allwinner,sun55i-a523-usb-phy): clock-names: ['usb0_phy', 'usb1_phy', 'usb2_phy'] is too long
	from schema $id: http://devicetree.org/schemas/phy/allwinner,sun50i-a64-usb-phy.yaml#
arch/arm64/boot/dts/allwinner/sun55i-t527-avaota-a1.dtb: phy at 4100400 (allwinner,sun55i-a523-usb-phy): clocks: [[5], [5], [2, 179]] is too long
	from schema $id: http://devicetree.org/schemas/phy/allwinner,sun50i-a64-usb-phy.yaml#
arch/arm64/boot/dts/allwinner/sun55i-t527-avaota-a1.dtb: phy at 4100400 (allwinner,sun55i-a523-usb-phy): compatible: 'oneOf' conditional failed, one must be fixed:
	['allwinner,sun55i-a523-usb-phy'] is too short
	'allwinner,sun55i-a523-usb-phy' is not one of ['allwinner,sun20i-d1-usb-phy', 'allwinner,sun50i-a64-usb-phy']
	from schema $id: http://devicetree.org/schemas/phy/allwinner,sun50i-a64-usb-phy.yaml#
arch/arm64/boot/dts/allwinner/sun55i-t527-avaota-a1.dtb: phy at 4100400 (allwinner,sun55i-a523-usb-phy): reg: [[68158464, 256], [68163584, 256], [69208064, 256], [81788928, 256]] is too long
	from schema $id: http://devicetree.org/schemas/phy/allwinner,sun50i-a64-usb-phy.yaml#
arch/arm64/boot/dts/allwinner/sun55i-t527-avaota-a1.dtb: phy at 4100400 (allwinner,sun55i-a523-usb-phy): reg-names: ['phy_ctrl', 'pmu0', 'pmu1', 'pmu2'] is too long
	from schema $id: http://devicetree.org/schemas/phy/allwinner,sun50i-a64-usb-phy.yaml#
arch/arm64/boot/dts/allwinner/sun55i-t527-avaota-a1.dtb: phy at 4100400 (allwinner,sun55i-a523-usb-phy): reset-names: ['usb0_reset', 'usb1_reset', 'usb2_reset'] is too long
	from schema $id: http://devicetree.org/schemas/phy/allwinner,sun50i-a64-usb-phy.yaml#
arch/arm64/boot/dts/allwinner/sun55i-t527-avaota-a1.dtb: phy at 4100400 (allwinner,sun55i-a523-usb-phy): resets: [[2, 49], [2, 50], [2, 56]] is too long
	from schema $id: http://devicetree.org/schemas/phy/allwinner,sun50i-a64-usb-phy.yaml#
arch/arm64/boot/dts/allwinner/sun55i-h728-x96qpro+.dtb: /soc/phy at 4f00000: failed to match any schema with compatible: ['allwinner,sun55i-a523-usb3-pcie-phy']
arch/arm64/boot/dts/allwinner/sun55i-a527-cubie-a5e.dtb: /soc/phy at 4f00000: failed to match any schema with compatible: ['allwinner,sun55i-a523-usb3-pcie-phy']
arch/arm64/boot/dts/allwinner/sun55i-t527-orangepi-4a.dtb: /soc/phy at 4f00000: failed to match any schema with compatible: ['allwinner,sun55i-a523-usb3-pcie-phy']
arch/arm64/boot/dts/allwinner/sun55i-t527-avaota-a1.dtb: /soc/phy at 4f00000: failed to match any schema with compatible: ['allwinner,sun55i-a523-usb3-pcie-phy']







From helgaas at kernel.org  Mon Aug 18 11:25:44 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Mon, 18 Aug 2025 13:25:44 -0500
Subject: [PATCH v3 11/12] PCI: exynos: Add support for Tesla FSD SoC
In-Reply-To: <000d01dc1022$ad8c0740$08a415c0$@samsung.com>
Message-ID: <20250818182544.GA534647@bhelgaas>

[+to Krzysztof]

On Mon, Aug 18, 2025 at 03:00:00PM +0530, Shradha Todi wrote:
> > On Mon, Aug 11, 2025 at 09:16:37PM +0530, Shradha Todi wrote:
> > > Add host and endpoint controller driver support for FSD SoC.

> > It's kind of unfortunate that the driver uses "ep" everywhere for
> > struct exynos_pcie pointers.  It's going to be confusing because "ep"
> > is also commonly used for endpoint-related things, e.g., struct
> > dw_pcie_ep pointers.  Maybe it's not worth changing; I dunno.
> 
> I did try to rename the structure and the pointers 
> (https://lore.kernel.org/all/20230214121333.1837-9-shradha.t at samsung.com/)
> But the intention was different back then and so the idea was rejected.
> I could add a patch to only rename the pointers to something less
> confusing like "exy_pci"

The patch you mention did several renames:

  s/to_exynos_pcie/to_samsung_pcie/
  s/struct exynos_pcie/struct samsung_pcie/
  s/struct exynos_pcie *ep/struct samsung_pcie *sp/

I'm only concerned about the confusion of "ep" being used both for
"struct exynos_pcie *" and for "struct dw_pcie_ep *".

It would still be sort of an annoying patch to do something like this:

  s/struct exynos_pcie *ep/struct exynos_pcie *pcie/

But 'git grep "struct .*_pcie \*.*=" drivers/pci/controller/' says
using "pcie" in this way is quite common, so maybe it would be worth
doing.

What do you think, Krzysztof?

> > > +static irqreturn_t fsd_pcie_irq_handler(int irq, void *arg)
> > > +{
> > > +	u32 val;
> > > +	struct exynos_pcie *ep = arg;
> > > +	struct dw_pcie *pci = &ep->pci;
> > > +	struct dw_pcie_rp *pp = &pci->pp;
> > > +
> > > +	val = readl(ep->elbi_base + FSD_IRQ2_STS);
> > > +	if ((val & FSD_IRQ_MSI_ENABLE) == FSD_IRQ_MSI_ENABLE) {
> > > +		val &= FSD_IRQ_MSI_ENABLE;
> > > +		writel(val, ep->elbi_base + FSD_IRQ2_STS);
> > 
> > This looks weird because FSD_IRQ_MSI_ENABLE sounds like an *enable*
> > bit, but here you're treating it as a *status* bit.
> > 
> > As far as I can tell, you set FSD_IRQ_MSI_ENABLE once at probe-time in
> > fsd_pcie_msi_init(), then you clear it here in an IRQ handler, and it
> > will never be set again.  That seems wrong; am I missing something?
> 
> Actually the status IRQ and enable IRQ registers are different offsets
> but the bit position for MSI remains same in both cases so I just reused
> the macro.

Ah, that's what I missed, thanks!  At probe-time, fsd_pcie_msi_init()
enables it in FSD_IRQ2_EN.  Here you clear it in FSD_IRQ2_STS.

> But I understand that it's confusing so I will add another
> macro for FSD_IRQ_MSI_STATUS or just rename the macro to
> FSD_IRQ_MSI to re-use.

Using the same name just because a similar bit happens to be at the
same position in two different registers is definitely confusing.  I
think it will be better to have two macros, one for FSD_IRQ2_STS and
another for FSD_IRQ2_EN, e.g.,

  #define FSD_IRQ2_STS                         0x008
  #define   FSD_IRQ2_STS_MSI                   BIT(17)
  #define FSD_IRQ2_EN                          0x018
  #define   FSD_IRQ2_EN_MSI                    BIT(17)

Another question about the test:

  if ((val & FSD_IRQ_MSI_ENABLE) == FSD_IRQ_MSI_ENABLE) {

This assumes there are no other bits in FSD_IRQ2_STS that could be
set.  I would have expected a test like this:

  if (val & FSD_IRQ_MSI_ENABLE) {

Is there a reason to restrict it to the case when *only*
FSD_IRQ_MSI_ENABLE is set?

Bjorn


From cristian.ciocaltea at collabora.com  Mon Aug 18 11:59:01 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Mon, 18 Aug 2025 21:59:01 +0300
Subject: [PATCH v3 01/14] phy: hdmi: Add HDMI 2.1 FRL configuration options
In-Reply-To: <20250818-phy-hdptx-frl-v3-0-c79997d8bb2b@collabora.com>
References: <20250818-phy-hdptx-frl-v3-0-c79997d8bb2b@collabora.com>
Message-ID: <20250818-phy-hdptx-frl-v3-1-c79997d8bb2b@collabora.com>

The HDMI 2.1 specification introduced the Fixed Rate Link (FRL) mode,
aiming to replace the older Transition-Minimized Differential Signaling
(TMDS) mode used in previous HDMI versions to support much higher
bandwidths (up to 48 Gbps) for modern video and audio formats.

FRL has been designed to support ultra high resolution formats at high
refresh rates like 8K at 60Hz or 4K at 120Hz, and eliminates the need for
dynamic bandwidth adjustments, which reduces latency.  It operates with
3 or 4 lanes at different link rates: 3Gbps, 6Gbps, 8Gbps, 10Gbps or
12Gbps.

Add support for configuring the FRL mode for HDMI PHYs.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 include/linux/phy/phy-hdmi.h | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/include/linux/phy/phy-hdmi.h b/include/linux/phy/phy-hdmi.h
index f0ec963c6e84f1b7728acafc824dff191c6b873d..83330d359e3ae345554f20429519da14506b8ab5 100644
--- a/include/linux/phy/phy-hdmi.h
+++ b/include/linux/phy/phy-hdmi.h
@@ -6,16 +6,31 @@
 #ifndef __PHY_HDMI_H_
 #define __PHY_HDMI_H_
 
+#include <linux/types.h>
+
+enum phy_mode_hdmi {
+	PHY_MODE_HDMI_TMDS,
+	PHY_MODE_HDMI_FRL,
+};
+
 /**
  * struct phy_configure_opts_hdmi - HDMI configuration set
- * @tmds_char_rate: HDMI TMDS Character Rate in Hertz.
  * @bpc: Bits per color channel.
+ * @tmds_char_rate: HDMI TMDS Character Rate in Hertz.
+ * @frl.rate_per_lane: HDMI FRL Rate per Lane in Gbps.
+ * @frl.lanes: HDMI FRL lanes count.
  *
  * This structure is used to represent the configuration state of a HDMI phy.
  */
 struct phy_configure_opts_hdmi {
-	unsigned long long tmds_char_rate;
 	unsigned int bpc;
+	union {
+		unsigned long long tmds_char_rate;
+		struct {
+			u8 rate_per_lane;
+			u8 lanes;
+		} frl;
+	};
 };
 
 #endif /* __PHY_HDMI_H_ */

-- 
2.50.1



From cristian.ciocaltea at collabora.com  Mon Aug 18 11:59:00 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Mon, 18 Aug 2025 21:59:00 +0300
Subject: [PATCH v3 00/14] Add HDMI 2.1 FRL support to
 phy-rockchip-samsung-hdptx
Message-ID: <20250818-phy-hdptx-frl-v3-0-c79997d8bb2b@collabora.com>

The Samsung HDMI/eDP Transmitter Combo PHY is capable of handling four
HDMI 2.1 Fixed Rate Link (FRL) lanes, while each lane can operate at
3Gbps, 6Gbps, 8Gbps, 10Gbps or 12Gbps.

This patchset extends the HDMI PHY configuration API to manage the FRL
mode and provides all the required HDMI driver changes to enable FRL in
addition to the already supported TMDS mode.

The series also contains a few driver fixes/improvements that are not
directly related, but are not deemed critical enough to warrant separate
submission.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
Changes in v3:
- Reworked patch "phy: hdmi: Add HDMI 2.1 FRL configuration options"
  according to Dmitry's feedback
  * Updated commit message providing a brief description of FRL mode
  * Kept PHY_MODE_HDMI in enum phy_mode and introduced enum
    phy_mode_hdmi defining the TMDS and FRL submodes
- Updated "phy: rockchip: samsung-hdptx: Add HDMI 2.1 FRL support"
  * Implemented .set_mode() callback in rk_hdptx_phy_ops
  * Introduced .mode member in struct rk_hdptx_hdmi_cfg and used it
    instead of phy_get_mode() to verify PHY_MODE_HDMI_FRL
- Rebased series onto next-20250818
- Link to v2: https://lore.kernel.org/r/20250805-phy-hdptx-frl-v2-0-d118bd4b6e0b at collabora.com

Changes in v2:
- Added a couple of new patches:
  * Fix reported clock rate in high bpc mode
  * Drop hw_rate driver data
- Applied several tweaks to the following patches:
  * Compute clk rate from PLL config
  * Switch to driver specific HDMI config
  * Add HDMI 2.1 FRL support
- Rebased series onto next-20250804
- Link to v1: https://lore.kernel.org/r/20250708-phy-hdptx-frl-v1-0-cfe096e224f4 at collabora.com

---
Cristian Ciocaltea (14):
      phy: hdmi: Add HDMI 2.1 FRL configuration options
      phy: rockchip: samsung-hdptx: Fix reported clock rate in high bpc mode
      phy: rockchip: samsung-hdptx: Reduce ROPLL loop bandwidth
      phy: rockchip: samsung-hdptx: Prevent Inter-Pair Skew from exceeding the limits
      phy: rockchip: samsung-hdptx: Use usleep_range() instead of udelay()
      phy: rockchip: samsung-hdptx: Fix coding style alignment
      phy: rockchip: samsung-hdptx: Consistently use [rk_]hdptx_[tmds_] prefixes
      phy: rockchip: samsung-hdptx: Enable lane output in common helper
      phy: rockchip: samsung-hdptx: Cleanup *_cmn_init_seq lists
      phy: rockchip: samsung-hdptx: Compute clk rate from PLL config
      phy: rockchip: samsung-hdptx: Drop hw_rate driver data
      phy: rockchip: samsung-hdptx: Switch to driver specific HDMI config
      phy: rockchip: samsung-hdptx: Extend rk_hdptx_phy_verify_hdmi_config() helper
      phy: rockchip: samsung-hdptx: Add HDMI 2.1 FRL support

 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 697 ++++++++++++++++++----
 include/linux/phy/phy-hdmi.h                      |  19 +-
 2 files changed, 611 insertions(+), 105 deletions(-)
---
base-commit: 3ac864c2d9bb8608ee236e89bf561811613abfce
change-id: 20250708-phy-hdptx-frl-fc3377db9f2e



From cristian.ciocaltea at collabora.com  Mon Aug 18 11:59:02 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Mon, 18 Aug 2025 21:59:02 +0300
Subject: [PATCH v3 02/14] phy: rockchip: samsung-hdptx: Fix reported clock
 rate in high bpc mode
In-Reply-To: <20250818-phy-hdptx-frl-v3-0-c79997d8bb2b@collabora.com>
References: <20250818-phy-hdptx-frl-v3-0-c79997d8bb2b@collabora.com>
Message-ID: <20250818-phy-hdptx-frl-v3-2-c79997d8bb2b@collabora.com>

When making use of the clock provider functionality, the output clock
does normally match the TMDS character rate, which is what the PHY PLL
gets configured to.

However, this is only applicable for default color depth of 8 bpc.  For
higher depths, the output clock is further divided by the hardware
according to the formula:

  output_clock_rate = tmds_char_rate * 8 / bpc

Since the existence of the clock divider wasn't taken into account when
support for high bpc has been introduced, make the necessary adjustments
to report the correct clock rate.

Fixes: 9d0ec51d7c22 ("phy: rockchip: samsung-hdptx: Add high color depth management")
Reported-by: Andy Yan <andy.yan at rock-chips.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index 79db57ee90d1487b51f4ddadde870a275dd7b17b..8adf6e84fc0b762a7a6042459601c3271572de8e 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -1038,7 +1038,8 @@ static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx)
 
 	ret = rk_hdptx_post_enable_pll(hdptx);
 	if (!ret)
-		hdptx->hw_rate = hdptx->hdmi_cfg.tmds_char_rate;
+		hdptx->hw_rate = DIV_ROUND_CLOSEST_ULL(hdptx->hdmi_cfg.tmds_char_rate * 8,
+						       hdptx->hdmi_cfg.bpc);
 
 	return ret;
 }
@@ -1896,19 +1897,20 @@ static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
 	 * hence ensure rk_hdptx_phy_clk_set_rate() won't be invoked with
 	 * a different rate argument.
 	 */
-	return hdptx->hdmi_cfg.tmds_char_rate;
+	return DIV_ROUND_CLOSEST_ULL(hdptx->hdmi_cfg.tmds_char_rate * 8, hdptx->hdmi_cfg.bpc);
 }
 
 static int rk_hdptx_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate,
 				     unsigned long parent_rate)
 {
 	struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);
+	unsigned long long tmds_rate = DIV_ROUND_CLOSEST_ULL(rate * hdptx->hdmi_cfg.bpc, 8);
 
 	/* Revert any unlikely TMDS char rate change since round_rate() */
-	if (hdptx->hdmi_cfg.tmds_char_rate != rate) {
-		dev_warn(hdptx->dev, "Reverting unexpected rate change from %lu to %llu\n",
-			 rate, hdptx->hdmi_cfg.tmds_char_rate);
-		hdptx->hdmi_cfg.tmds_char_rate = rate;
+	if (hdptx->hdmi_cfg.tmds_char_rate != tmds_rate) {
+		dev_warn(hdptx->dev, "Reverting unexpected rate change from %llu to %llu\n",
+			 tmds_rate, hdptx->hdmi_cfg.tmds_char_rate);
+		hdptx->hdmi_cfg.tmds_char_rate = tmds_rate;
 	}
 
 	/*

-- 
2.50.1



From cristian.ciocaltea at collabora.com  Mon Aug 18 11:59:03 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Mon, 18 Aug 2025 21:59:03 +0300
Subject: [PATCH v3 03/14] phy: rockchip: samsung-hdptx: Reduce ROPLL loop
 bandwidth
In-Reply-To: <20250818-phy-hdptx-frl-v3-0-c79997d8bb2b@collabora.com>
References: <20250818-phy-hdptx-frl-v3-0-c79997d8bb2b@collabora.com>
Message-ID: <20250818-phy-hdptx-frl-v3-3-c79997d8bb2b@collabora.com>

Due to its relatively low frequency, a noise stemming from the 24MHz PLL
reference clock may traverse the low-pass loop filter of ROPLL, which
could potentially generate some HDMI flash artifacts.

Reduce ROPLL loop bandwidth in an attempt to mitigate the problem.

Fixes: 553be2830c5f ("phy: rockchip: Add Samsung HDMI/eDP Combo PHY driver")
Co-developed-by: Algea Cao <algea.cao at rock-chips.com>
Signed-off-by: Algea Cao <algea.cao at rock-chips.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index 8adf6e84fc0b762a7a6042459601c3271572de8e..9751f7ad00f4faf7041dbf4339f633e09f97b107 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -500,9 +500,7 @@ static const struct reg_sequence rk_hdtpx_common_cmn_init_seq[] = {
 	REG_SEQ0(CMN_REG(0043), 0x00),
 	REG_SEQ0(CMN_REG(0044), 0x46),
 	REG_SEQ0(CMN_REG(0045), 0x24),
-	REG_SEQ0(CMN_REG(0046), 0xff),
 	REG_SEQ0(CMN_REG(0047), 0x00),
-	REG_SEQ0(CMN_REG(0048), 0x44),
 	REG_SEQ0(CMN_REG(0049), 0xfa),
 	REG_SEQ0(CMN_REG(004a), 0x08),
 	REG_SEQ0(CMN_REG(004b), 0x00),
@@ -575,6 +573,8 @@ static const struct reg_sequence rk_hdtpx_tmds_cmn_init_seq[] = {
 	REG_SEQ0(CMN_REG(0034), 0x00),
 	REG_SEQ0(CMN_REG(003d), 0x40),
 	REG_SEQ0(CMN_REG(0042), 0x78),
+	REG_SEQ0(CMN_REG(0046), 0xdd),
+	REG_SEQ0(CMN_REG(0048), 0x11),
 	REG_SEQ0(CMN_REG(004e), 0x34),
 	REG_SEQ0(CMN_REG(005c), 0x25),
 	REG_SEQ0(CMN_REG(005e), 0x4f),

-- 
2.50.1



From cristian.ciocaltea at collabora.com  Mon Aug 18 11:59:04 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Mon, 18 Aug 2025 21:59:04 +0300
Subject: [PATCH v3 04/14] phy: rockchip: samsung-hdptx: Prevent Inter-Pair
 Skew from exceeding the limits
In-Reply-To: <20250818-phy-hdptx-frl-v3-0-c79997d8bb2b@collabora.com>
References: <20250818-phy-hdptx-frl-v3-0-c79997d8bb2b@collabora.com>
Message-ID: <20250818-phy-hdptx-frl-v3-4-c79997d8bb2b@collabora.com>

Fixup PHY deskew FIFO to prevent the phase of D2 lane going ahead of
other lanes.  It's worth noting this might only happen when dealing with
HDMI 2.0 rates.

Fixes: 553be2830c5f ("phy: rockchip: Add Samsung HDMI/eDP Combo PHY driver")
Co-developed-by: Algea Cao <algea.cao at rock-chips.com>
Signed-off-by: Algea Cao <algea.cao at rock-chips.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index 9751f7ad00f4faf7041dbf4339f633e09f97b107..5605610465bc812737f773e0f6232cb6dbdc78a4 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -668,13 +668,9 @@ static const struct reg_sequence rk_hdtpx_common_lane_init_seq[] = {
 
 static const struct reg_sequence rk_hdtpx_tmds_lane_init_seq[] = {
 	REG_SEQ0(LANE_REG(0312), 0x00),
-	REG_SEQ0(LANE_REG(031e), 0x00),
 	REG_SEQ0(LANE_REG(0412), 0x00),
-	REG_SEQ0(LANE_REG(041e), 0x00),
 	REG_SEQ0(LANE_REG(0512), 0x00),
-	REG_SEQ0(LANE_REG(051e), 0x00),
 	REG_SEQ0(LANE_REG(0612), 0x00),
-	REG_SEQ0(LANE_REG(061e), 0x08),
 	REG_SEQ0(LANE_REG(0303), 0x2f),
 	REG_SEQ0(LANE_REG(0403), 0x2f),
 	REG_SEQ0(LANE_REG(0503), 0x2f),
@@ -687,6 +683,11 @@ static const struct reg_sequence rk_hdtpx_tmds_lane_init_seq[] = {
 	REG_SEQ0(LANE_REG(0406), 0x1c),
 	REG_SEQ0(LANE_REG(0506), 0x1c),
 	REG_SEQ0(LANE_REG(0606), 0x1c),
+	/* Keep Inter-Pair Skew in the limits */
+	REG_SEQ0(LANE_REG(031e), 0x02),
+	REG_SEQ0(LANE_REG(041e), 0x02),
+	REG_SEQ0(LANE_REG(051e), 0x02),
+	REG_SEQ0(LANE_REG(061e), 0x0a),
 };
 
 static struct tx_drv_ctrl tx_drv_ctrl_rbr[4][4] = {

-- 
2.50.1



From cristian.ciocaltea at collabora.com  Mon Aug 18 11:59:05 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Mon, 18 Aug 2025 21:59:05 +0300
Subject: [PATCH v3 05/14] phy: rockchip: samsung-hdptx: Use usleep_range()
 instead of udelay()
In-Reply-To: <20250818-phy-hdptx-frl-v3-0-c79997d8bb2b@collabora.com>
References: <20250818-phy-hdptx-frl-v3-0-c79997d8bb2b@collabora.com>
Message-ID: <20250818-phy-hdptx-frl-v3-5-c79997d8bb2b@collabora.com>

rk_hdptx_dp_reset() is allowed to sleep, hence replace the busy waiting
with usleep_range(), to allow other threads to run.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index 5605610465bc812737f773e0f6232cb6dbdc78a4..83ec892bd6760865fc9e361f4003c5bfbef55608 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -1075,7 +1075,7 @@ static void rk_hdptx_dp_reset(struct rk_hdptx_phy *hdptx)
 	reset_control_assert(hdptx->rsts[RST_INIT].rstc);
 
 	reset_control_assert(hdptx->rsts[RST_APB].rstc);
-	udelay(10);
+	usleep_range(10, 15);
 	reset_control_deassert(hdptx->rsts[RST_APB].rstc);
 
 	regmap_update_bits(hdptx->regmap, LANE_REG(0301),

-- 
2.50.1



From cristian.ciocaltea at collabora.com  Mon Aug 18 11:59:06 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Mon, 18 Aug 2025 21:59:06 +0300
Subject: [PATCH v3 06/14] phy: rockchip: samsung-hdptx: Fix coding style
 alignment
In-Reply-To: <20250818-phy-hdptx-frl-v3-0-c79997d8bb2b@collabora.com>
References: <20250818-phy-hdptx-frl-v3-0-c79997d8bb2b@collabora.com>
Message-ID: <20250818-phy-hdptx-frl-v3-6-c79997d8bb2b@collabora.com>

Handle a bunch of reported checkpatch.pl complaints:

  CHECK: Alignment should match open parenthesis

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index 83ec892bd6760865fc9e361f4003c5bfbef55608..495427fc44b385e23da02cd21eefdb137d8b5fdb 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -1657,11 +1657,11 @@ static void rk_hdptx_phy_set_voltage(struct rk_hdptx_phy *hdptx,
 		regmap_update_bits(hdptx->regmap, LANE_REG(030a) + offset,
 				   LN_TX_JEQ_EVEN_CTRL_RBR_MASK,
 				   FIELD_PREP(LN_TX_JEQ_EVEN_CTRL_RBR_MASK,
-				   ctrl->tx_jeq_even_ctrl));
+					      ctrl->tx_jeq_even_ctrl));
 		regmap_update_bits(hdptx->regmap, LANE_REG(030c) + offset,
 				   LN_TX_JEQ_ODD_CTRL_RBR_MASK,
 				   FIELD_PREP(LN_TX_JEQ_ODD_CTRL_RBR_MASK,
-				   ctrl->tx_jeq_odd_ctrl));
+					      ctrl->tx_jeq_odd_ctrl));
 		regmap_update_bits(hdptx->regmap, LANE_REG(0311) + offset,
 				   LN_TX_SER_40BIT_EN_RBR_MASK,
 				   FIELD_PREP(LN_TX_SER_40BIT_EN_RBR_MASK, 0x1));
@@ -1671,11 +1671,11 @@ static void rk_hdptx_phy_set_voltage(struct rk_hdptx_phy *hdptx,
 		regmap_update_bits(hdptx->regmap, LANE_REG(030b) + offset,
 				   LN_TX_JEQ_EVEN_CTRL_HBR_MASK,
 				   FIELD_PREP(LN_TX_JEQ_EVEN_CTRL_HBR_MASK,
-				   ctrl->tx_jeq_even_ctrl));
+					      ctrl->tx_jeq_even_ctrl));
 		regmap_update_bits(hdptx->regmap, LANE_REG(030d) + offset,
 				   LN_TX_JEQ_ODD_CTRL_HBR_MASK,
 				   FIELD_PREP(LN_TX_JEQ_ODD_CTRL_HBR_MASK,
-				   ctrl->tx_jeq_odd_ctrl));
+					      ctrl->tx_jeq_odd_ctrl));
 		regmap_update_bits(hdptx->regmap, LANE_REG(0311) + offset,
 				   LN_TX_SER_40BIT_EN_HBR_MASK,
 				   FIELD_PREP(LN_TX_SER_40BIT_EN_HBR_MASK, 0x1));
@@ -1686,11 +1686,11 @@ static void rk_hdptx_phy_set_voltage(struct rk_hdptx_phy *hdptx,
 		regmap_update_bits(hdptx->regmap, LANE_REG(030b) + offset,
 				   LN_TX_JEQ_EVEN_CTRL_HBR2_MASK,
 				   FIELD_PREP(LN_TX_JEQ_EVEN_CTRL_HBR2_MASK,
-				   ctrl->tx_jeq_even_ctrl));
+					      ctrl->tx_jeq_even_ctrl));
 		regmap_update_bits(hdptx->regmap, LANE_REG(030d) + offset,
 				   LN_TX_JEQ_ODD_CTRL_HBR2_MASK,
 				   FIELD_PREP(LN_TX_JEQ_ODD_CTRL_HBR2_MASK,
-				   ctrl->tx_jeq_odd_ctrl));
+					      ctrl->tx_jeq_odd_ctrl));
 		regmap_update_bits(hdptx->regmap, LANE_REG(0311) + offset,
 				   LN_TX_SER_40BIT_EN_HBR2_MASK,
 				   FIELD_PREP(LN_TX_SER_40BIT_EN_HBR2_MASK, 0x1));

-- 
2.50.1



From cristian.ciocaltea at collabora.com  Mon Aug 18 11:59:07 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Mon, 18 Aug 2025 21:59:07 +0300
Subject: [PATCH v3 07/14] phy: rockchip: samsung-hdptx: Consistently use
 [rk_]hdptx_[tmds_] prefixes
In-Reply-To: <20250818-phy-hdptx-frl-v3-0-c79997d8bb2b@collabora.com>
References: <20250818-phy-hdptx-frl-v3-0-c79997d8bb2b@collabora.com>
Message-ID: <20250818-phy-hdptx-frl-v3-7-c79997d8bb2b@collabora.com>

Fix the naming inconsistencies for some of the functions and global
variables:

* Add the missing 'rk_hdptx_' prefix to ropll_tmds_cfg variable
* Replace '_ropll_tmds_' with '_tmds_ropll_' globally
* Replace 'hdtpx' with 'hdptx' globally

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 62 +++++++++++------------
 1 file changed, 31 insertions(+), 31 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index 495427fc44b385e23da02cd21eefdb137d8b5fdb..f2202b1195e7f24c455acdfa9bf2482ddddd6866 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -32,17 +32,17 @@
 #define HDPTX_O_PHY_RDY			BIT(1)
 #define HDPTX_O_SB_RDY			BIT(0)
 
-#define HDTPX_REG(_n, _min, _max)				\
+#define HDPTX_REG(_n, _min, _max)				\
 	(							\
 		BUILD_BUG_ON_ZERO((0x##_n) < (0x##_min)) +	\
 		BUILD_BUG_ON_ZERO((0x##_n) > (0x##_max)) +	\
 		((0x##_n) * 4)					\
 	)
 
-#define CMN_REG(n)			HDTPX_REG(n, 0000, 00a7)
-#define SB_REG(n)			HDTPX_REG(n, 0100, 0129)
-#define LNTOP_REG(n)			HDTPX_REG(n, 0200, 0229)
-#define LANE_REG(n)			HDTPX_REG(n, 0300, 062d)
+#define CMN_REG(n)			HDPTX_REG(n, 0000, 00a7)
+#define SB_REG(n)			HDPTX_REG(n, 0100, 0129)
+#define LNTOP_REG(n)			HDPTX_REG(n, 0200, 0229)
+#define LANE_REG(n)			HDPTX_REG(n, 0300, 062d)
 
 /* CMN_REG(0008) */
 #define OVRD_LCPLL_EN_MASK		BIT(7)
@@ -411,7 +411,7 @@ struct rk_hdptx_phy {
 	unsigned int lanes;
 };
 
-static const struct ropll_config ropll_tmds_cfg[] = {
+static const struct ropll_config rk_hdptx_tmds_ropll_cfg[] = {
 	{ 594000000ULL, 124, 124, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
 	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
 	{ 371250000ULL, 155, 155, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
@@ -456,7 +456,7 @@ static const struct ropll_config ropll_tmds_cfg[] = {
 	  1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
 };
 
-static const struct reg_sequence rk_hdtpx_common_cmn_init_seq[] = {
+static const struct reg_sequence rk_hdptx_common_cmn_init_seq[] = {
 	REG_SEQ0(CMN_REG(0009), 0x0c),
 	REG_SEQ0(CMN_REG(000a), 0x83),
 	REG_SEQ0(CMN_REG(000b), 0x06),
@@ -546,7 +546,7 @@ static const struct reg_sequence rk_hdtpx_common_cmn_init_seq[] = {
 	REG_SEQ0(CMN_REG(009b), 0x10),
 };
 
-static const struct reg_sequence rk_hdtpx_tmds_cmn_init_seq[] = {
+static const struct reg_sequence rk_hdptx_tmds_cmn_init_seq[] = {
 	REG_SEQ0(CMN_REG(0008), 0x00),
 	REG_SEQ0(CMN_REG(0011), 0x01),
 	REG_SEQ0(CMN_REG(0017), 0x20),
@@ -588,14 +588,14 @@ static const struct reg_sequence rk_hdtpx_tmds_cmn_init_seq[] = {
 	REG_SEQ0(CMN_REG(009b), 0x00),
 };
 
-static const struct reg_sequence rk_hdtpx_common_sb_init_seq[] = {
+static const struct reg_sequence rk_hdptx_common_sb_init_seq[] = {
 	REG_SEQ0(SB_REG(0114), 0x00),
 	REG_SEQ0(SB_REG(0115), 0x00),
 	REG_SEQ0(SB_REG(0116), 0x00),
 	REG_SEQ0(SB_REG(0117), 0x00),
 };
 
-static const struct reg_sequence rk_hdtpx_tmds_lntop_highbr_seq[] = {
+static const struct reg_sequence rk_hdptx_tmds_lntop_highbr_seq[] = {
 	REG_SEQ0(LNTOP_REG(0201), 0x00),
 	REG_SEQ0(LNTOP_REG(0202), 0x00),
 	REG_SEQ0(LNTOP_REG(0203), 0x0f),
@@ -603,7 +603,7 @@ static const struct reg_sequence rk_hdtpx_tmds_lntop_highbr_seq[] = {
 	REG_SEQ0(LNTOP_REG(0205), 0xff),
 };
 
-static const struct reg_sequence rk_hdtpx_tmds_lntop_lowbr_seq[] = {
+static const struct reg_sequence rk_hdptx_tmds_lntop_lowbr_seq[] = {
 	REG_SEQ0(LNTOP_REG(0201), 0x07),
 	REG_SEQ0(LNTOP_REG(0202), 0xc1),
 	REG_SEQ0(LNTOP_REG(0203), 0xf0),
@@ -611,7 +611,7 @@ static const struct reg_sequence rk_hdtpx_tmds_lntop_lowbr_seq[] = {
 	REG_SEQ0(LNTOP_REG(0205), 0x1f),
 };
 
-static const struct reg_sequence rk_hdtpx_common_lane_init_seq[] = {
+static const struct reg_sequence rk_hdptx_common_lane_init_seq[] = {
 	REG_SEQ0(LANE_REG(0303), 0x0c),
 	REG_SEQ0(LANE_REG(0307), 0x20),
 	REG_SEQ0(LANE_REG(030a), 0x17),
@@ -666,7 +666,7 @@ static const struct reg_sequence rk_hdtpx_common_lane_init_seq[] = {
 	REG_SEQ0(LANE_REG(0620), 0xa0),
 };
 
-static const struct reg_sequence rk_hdtpx_tmds_lane_init_seq[] = {
+static const struct reg_sequence rk_hdptx_tmds_lane_init_seq[] = {
 	REG_SEQ0(LANE_REG(0312), 0x00),
 	REG_SEQ0(LANE_REG(0412), 0x00),
 	REG_SEQ0(LANE_REG(0512), 0x00),
@@ -971,7 +971,7 @@ static bool rk_hdptx_phy_clk_pll_calc(unsigned long long rate,
 	return true;
 }
 
-static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx)
+static int rk_hdptx_tmds_ropll_cmn_config(struct rk_hdptx_phy *hdptx)
 {
 	const struct ropll_config *cfg = NULL;
 	struct ropll_config rc = {0};
@@ -980,9 +980,9 @@ static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx)
 	if (!hdptx->hdmi_cfg.tmds_char_rate)
 		return 0;
 
-	for (i = 0; i < ARRAY_SIZE(ropll_tmds_cfg); i++)
-		if (hdptx->hdmi_cfg.tmds_char_rate == ropll_tmds_cfg[i].rate) {
-			cfg = &ropll_tmds_cfg[i];
+	for (i = 0; i < ARRAY_SIZE(rk_hdptx_tmds_ropll_cfg); i++)
+		if (hdptx->hdmi_cfg.tmds_char_rate == rk_hdptx_tmds_ropll_cfg[i].rate) {
+			cfg = &rk_hdptx_tmds_ropll_cfg[i];
 			break;
 		}
 
@@ -1002,8 +1002,8 @@ static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx)
 
 	rk_hdptx_pre_power_up(hdptx);
 
-	rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_cmn_init_seq);
-	rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_cmn_init_seq);
+	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_cmn_init_seq);
+	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_tmds_cmn_init_seq);
 
 	regmap_write(hdptx->regmap, CMN_REG(0051), cfg->pms_mdiv);
 	regmap_write(hdptx->regmap, CMN_REG(0055), cfg->pms_mdiv_afc);
@@ -1045,25 +1045,25 @@ static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx)
 	return ret;
 }
 
-static int rk_hdptx_ropll_tmds_mode_config(struct rk_hdptx_phy *hdptx)
+static int rk_hdptx_tmds_ropll_mode_config(struct rk_hdptx_phy *hdptx)
 {
-	rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_sb_init_seq);
+	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_sb_init_seq);
 
 	regmap_write(hdptx->regmap, LNTOP_REG(0200), 0x06);
 
 	if (hdptx->hdmi_cfg.tmds_char_rate > HDMI14_MAX_RATE) {
 		/* For 1/40 bitrate clk */
-		rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lntop_highbr_seq);
+		rk_hdptx_multi_reg_write(hdptx, rk_hdptx_tmds_lntop_highbr_seq);
 	} else {
 		/* For 1/10 bitrate clk */
-		rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lntop_lowbr_seq);
+		rk_hdptx_multi_reg_write(hdptx, rk_hdptx_tmds_lntop_lowbr_seq);
 	}
 
 	regmap_write(hdptx->regmap, LNTOP_REG(0206), 0x07);
 	regmap_write(hdptx->regmap, LNTOP_REG(0207), 0x0f);
 
-	rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_lane_init_seq);
-	rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lane_init_seq);
+	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_lane_init_seq);
+	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_tmds_lane_init_seq);
 
 	return rk_hdptx_post_enable_lane(hdptx);
 }
@@ -1122,7 +1122,7 @@ static int rk_hdptx_phy_consumer_get(struct rk_hdptx_phy *hdptx)
 	if (mode == PHY_MODE_DP) {
 		rk_hdptx_dp_reset(hdptx);
 	} else {
-		ret = rk_hdptx_ropll_tmds_cmn_config(hdptx);
+		ret = rk_hdptx_tmds_ropll_cmn_config(hdptx);
 		if (ret)
 			goto dec_usage;
 	}
@@ -1469,7 +1469,7 @@ static int rk_hdptx_phy_power_on(struct phy *phy)
 		regmap_write(hdptx->grf, GRF_HDPTX_CON0,
 			     HDPTX_MODE_SEL << 16 | FIELD_PREP(HDPTX_MODE_SEL, 0x0));
 
-		ret = rk_hdptx_ropll_tmds_mode_config(hdptx);
+		ret = rk_hdptx_tmds_ropll_mode_config(hdptx);
 		if (ret)
 			rk_hdptx_phy_consumer_put(hdptx, true);
 	}
@@ -1492,11 +1492,11 @@ static int rk_hdptx_phy_verify_hdmi_config(struct rk_hdptx_phy *hdptx,
 	if (!hdmi->tmds_char_rate || hdmi->tmds_char_rate > HDMI20_MAX_RATE)
 		return -EINVAL;
 
-	for (i = 0; i < ARRAY_SIZE(ropll_tmds_cfg); i++)
-		if (hdmi->tmds_char_rate == ropll_tmds_cfg[i].rate)
+	for (i = 0; i < ARRAY_SIZE(rk_hdptx_tmds_ropll_cfg); i++)
+		if (hdmi->tmds_char_rate == rk_hdptx_tmds_ropll_cfg[i].rate)
 			break;
 
-	if (i == ARRAY_SIZE(ropll_tmds_cfg) &&
+	if (i == ARRAY_SIZE(rk_hdptx_tmds_ropll_cfg) &&
 	    !rk_hdptx_phy_clk_pll_calc(hdmi->tmds_char_rate, NULL))
 		return -EINVAL;
 
@@ -1921,7 +1921,7 @@ static int rk_hdptx_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate,
 	 * while the latter being executed only once, i.e. when clock remains
 	 * in the prepared state during rate changes.
 	 */
-	return rk_hdptx_ropll_tmds_cmn_config(hdptx);
+	return rk_hdptx_tmds_ropll_cmn_config(hdptx);
 }
 
 static const struct clk_ops hdptx_phy_clk_ops = {

-- 
2.50.1



From cristian.ciocaltea at collabora.com  Mon Aug 18 11:59:08 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Mon, 18 Aug 2025 21:59:08 +0300
Subject: [PATCH v3 08/14] phy: rockchip: samsung-hdptx: Enable lane output
 in common helper
In-Reply-To: <20250818-phy-hdptx-frl-v3-0-c79997d8bb2b@collabora.com>
References: <20250818-phy-hdptx-frl-v3-0-c79997d8bb2b@collabora.com>
Message-ID: <20250818-phy-hdptx-frl-v3-8-c79997d8bb2b@collabora.com>

In preparation to support FRL mode, move the PHY lane output enablement
from the TMDS specific configuration to the common *_post_enable_lane()
helper and make sure it gets turned off in *_phy_disable().

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index f2202b1195e7f24c455acdfa9bf2482ddddd6866..3bb4ce993088b4a6c17a40ecb235ce98dc0eb9da 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -830,6 +830,8 @@ static int rk_hdptx_post_enable_lane(struct rk_hdptx_phy *hdptx)
 	       HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN;
 	regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);
 
+	regmap_write(hdptx->regmap, LNTOP_REG(0207), 0x0f);
+
 	ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS, val,
 				       (val & HDPTX_O_PHY_RDY) &&
 				       (val & HDPTX_O_PLL_LOCK_DONE),
@@ -883,6 +885,7 @@ static void rk_hdptx_phy_disable(struct rk_hdptx_phy *hdptx)
 	usleep_range(20, 30);
 	reset_control_deassert(hdptx->rsts[RST_APB].rstc);
 
+	regmap_write(hdptx->regmap, LNTOP_REG(0207), 0x0);
 	regmap_write(hdptx->regmap, LANE_REG(0300), 0x82);
 	regmap_write(hdptx->regmap, SB_REG(010f), 0xc1);
 	regmap_write(hdptx->regmap, SB_REG(0110), 0x1);
@@ -1060,7 +1063,6 @@ static int rk_hdptx_tmds_ropll_mode_config(struct rk_hdptx_phy *hdptx)
 	}
 
 	regmap_write(hdptx->regmap, LNTOP_REG(0206), 0x07);
-	regmap_write(hdptx->regmap, LNTOP_REG(0207), 0x0f);
 
 	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_lane_init_seq);
 	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_tmds_lane_init_seq);

-- 
2.50.1



From cristian.ciocaltea at collabora.com  Mon Aug 18 11:59:09 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Mon, 18 Aug 2025 21:59:09 +0300
Subject: [PATCH v3 09/14] phy: rockchip: samsung-hdptx: Cleanup
 *_cmn_init_seq lists
In-Reply-To: <20250818-phy-hdptx-frl-v3-0-c79997d8bb2b@collabora.com>
References: <20250818-phy-hdptx-frl-v3-0-c79997d8bb2b@collabora.com>
Message-ID: <20250818-phy-hdptx-frl-v3-9-c79997d8bb2b@collabora.com>

Drop redundant reg_sequence entries from rk_hdptx_common_cmn_init_seq[],
i.e. those that are either duplicated or overridden in
rk_hdptx_tmds_cmn_init_seq[].

Additionally, a few items do not really belong to the former, hence move
them to the latter.  That's mostly a preparatory step for adding FRL
support.

No functional changes intended at this point.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 22 ++++------------------
 1 file changed, 4 insertions(+), 18 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index 3bb4ce993088b4a6c17a40ecb235ce98dc0eb9da..699b86732b8d7d77b3f9ec3a7a8c801392b796f6 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -465,13 +465,11 @@ static const struct reg_sequence rk_hdptx_common_cmn_init_seq[] = {
 	REG_SEQ0(CMN_REG(000e), 0x0f),
 	REG_SEQ0(CMN_REG(000f), 0x0f),
 	REG_SEQ0(CMN_REG(0010), 0x04),
-	REG_SEQ0(CMN_REG(0011), 0x00),
 	REG_SEQ0(CMN_REG(0012), 0x26),
 	REG_SEQ0(CMN_REG(0013), 0x22),
 	REG_SEQ0(CMN_REG(0014), 0x24),
 	REG_SEQ0(CMN_REG(0015), 0x77),
 	REG_SEQ0(CMN_REG(0016), 0x08),
-	REG_SEQ0(CMN_REG(0017), 0x00),
 	REG_SEQ0(CMN_REG(0018), 0x04),
 	REG_SEQ0(CMN_REG(0019), 0x48),
 	REG_SEQ0(CMN_REG(001a), 0x01),
@@ -479,13 +477,7 @@ static const struct reg_sequence rk_hdptx_common_cmn_init_seq[] = {
 	REG_SEQ0(CMN_REG(001c), 0x01),
 	REG_SEQ0(CMN_REG(001d), 0x64),
 	REG_SEQ0(CMN_REG(001f), 0x00),
-	REG_SEQ0(CMN_REG(0026), 0x53),
 	REG_SEQ0(CMN_REG(0029), 0x01),
-	REG_SEQ0(CMN_REG(0030), 0x00),
-	REG_SEQ0(CMN_REG(0031), 0x20),
-	REG_SEQ0(CMN_REG(0032), 0x30),
-	REG_SEQ0(CMN_REG(0033), 0x0b),
-	REG_SEQ0(CMN_REG(0034), 0x23),
 	REG_SEQ0(CMN_REG(0035), 0x00),
 	REG_SEQ0(CMN_REG(0038), 0x00),
 	REG_SEQ0(CMN_REG(0039), 0x00),
@@ -496,7 +488,6 @@ static const struct reg_sequence rk_hdptx_common_cmn_init_seq[] = {
 	REG_SEQ0(CMN_REG(003f), 0x83),
 	REG_SEQ0(CMN_REG(0040), 0x06),
 	REG_SEQ0(CMN_REG(0041), 0x20),
-	REG_SEQ0(CMN_REG(0042), 0xb8),
 	REG_SEQ0(CMN_REG(0043), 0x00),
 	REG_SEQ0(CMN_REG(0044), 0x46),
 	REG_SEQ0(CMN_REG(0045), 0x24),
@@ -506,14 +497,9 @@ static const struct reg_sequence rk_hdptx_common_cmn_init_seq[] = {
 	REG_SEQ0(CMN_REG(004b), 0x00),
 	REG_SEQ0(CMN_REG(004c), 0x01),
 	REG_SEQ0(CMN_REG(004d), 0x64),
-	REG_SEQ0(CMN_REG(004e), 0x14),
 	REG_SEQ0(CMN_REG(004f), 0x00),
 	REG_SEQ0(CMN_REG(0050), 0x00),
-	REG_SEQ0(CMN_REG(005d), 0x0c),
 	REG_SEQ0(CMN_REG(005f), 0x01),
-	REG_SEQ0(CMN_REG(006b), 0x04),
-	REG_SEQ0(CMN_REG(0073), 0x30),
-	REG_SEQ0(CMN_REG(0074), 0x00),
 	REG_SEQ0(CMN_REG(0075), 0x20),
 	REG_SEQ0(CMN_REG(0076), 0x30),
 	REG_SEQ0(CMN_REG(0077), 0x08),
@@ -525,13 +511,10 @@ static const struct reg_sequence rk_hdptx_common_cmn_init_seq[] = {
 	REG_SEQ0(CMN_REG(007e), 0x00),
 	REG_SEQ0(CMN_REG(007f), 0x00),
 	REG_SEQ0(CMN_REG(0080), 0x00),
-	REG_SEQ0(CMN_REG(0081), 0x09),
 	REG_SEQ0(CMN_REG(0082), 0x04),
 	REG_SEQ0(CMN_REG(0083), 0x24),
 	REG_SEQ0(CMN_REG(0084), 0x20),
 	REG_SEQ0(CMN_REG(0085), 0x03),
-	REG_SEQ0(CMN_REG(0086), 0x01),
-	REG_SEQ0(CMN_REG(0087), 0x0c),
 	REG_SEQ0(CMN_REG(008a), 0x55),
 	REG_SEQ0(CMN_REG(008b), 0x25),
 	REG_SEQ0(CMN_REG(008c), 0x2c),
@@ -543,7 +526,6 @@ static const struct reg_sequence rk_hdptx_common_cmn_init_seq[] = {
 	REG_SEQ0(CMN_REG(0092), 0x00),
 	REG_SEQ0(CMN_REG(0093), 0x00),
 	REG_SEQ0(CMN_REG(009a), 0x11),
-	REG_SEQ0(CMN_REG(009b), 0x10),
 };
 
 static const struct reg_sequence rk_hdptx_tmds_cmn_init_seq[] = {
@@ -577,9 +559,13 @@ static const struct reg_sequence rk_hdptx_tmds_cmn_init_seq[] = {
 	REG_SEQ0(CMN_REG(0048), 0x11),
 	REG_SEQ0(CMN_REG(004e), 0x34),
 	REG_SEQ0(CMN_REG(005c), 0x25),
+	REG_SEQ0(CMN_REG(005d), 0x0c),
 	REG_SEQ0(CMN_REG(005e), 0x4f),
+	REG_SEQ0(CMN_REG(006b), 0x04),
+	REG_SEQ0(CMN_REG(0073), 0x30),
 	REG_SEQ0(CMN_REG(0074), 0x04),
 	REG_SEQ0(CMN_REG(0081), 0x01),
+	REG_SEQ0(CMN_REG(0086), 0x01),
 	REG_SEQ0(CMN_REG(0087), 0x04),
 	REG_SEQ0(CMN_REG(0089), 0x00),
 	REG_SEQ0(CMN_REG(0095), 0x00),

-- 
2.50.1



From cristian.ciocaltea at collabora.com  Mon Aug 18 11:59:10 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Mon, 18 Aug 2025 21:59:10 +0300
Subject: [PATCH v3 10/14] phy: rockchip: samsung-hdptx: Compute clk rate
 from PLL config
In-Reply-To: <20250818-phy-hdptx-frl-v3-0-c79997d8bb2b@collabora.com>
References: <20250818-phy-hdptx-frl-v3-0-c79997d8bb2b@collabora.com>
Message-ID: <20250818-phy-hdptx-frl-v3-10-c79997d8bb2b@collabora.com>

Improve ->recalc_rate() callback of hdptx_phy_clk_ops to calculate the
initial clock rate based on the actual PHY PLL configuration as
retrieved from the related hardware registers.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 91 ++++++++++++++++++++++-
 1 file changed, 90 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index 699b86732b8d7d77b3f9ec3a7a8c801392b796f6..6e2443f78968948b84e4261e33761fe0d189553b 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -1851,12 +1851,101 @@ static void rk_hdptx_phy_clk_unprepare(struct clk_hw *hw)
 	rk_hdptx_phy_consumer_put(hdptx, true);
 }
 
+#define PLL_REF_CLK 24000000ULL
+
+static u64 rk_hdptx_phy_clk_calc_rate_from_pll_cfg(struct rk_hdptx_phy *hdptx)
+{
+	struct ropll_config ropll_hw;
+	u64 fout, sdm;
+	u32 mode, val;
+	int ret;
+
+	ret = regmap_read(hdptx->regmap, CMN_REG(0008), &mode);
+	if (ret)
+		return 0;
+
+	if (mode & LCPLL_LCVCO_MODE_EN_MASK)
+		return 0;
+
+	ret = regmap_read(hdptx->regmap, CMN_REG(0051), &val);
+	if (ret)
+		return 0;
+	ropll_hw.pms_mdiv = val;
+
+	ret = regmap_read(hdptx->regmap, CMN_REG(005E), &val);
+	if (ret)
+		return 0;
+	ropll_hw.sdm_en = val & ROPLL_SDM_EN_MASK;
+
+	ret = regmap_read(hdptx->regmap, CMN_REG(0064), &val);
+	if (ret)
+		return 0;
+	ropll_hw.sdm_num_sign = val & ROPLL_SDM_NUM_SIGN_RBR_MASK;
+
+	ret = regmap_read(hdptx->regmap, CMN_REG(0065), &val);
+	if (ret)
+		return 0;
+	ropll_hw.sdm_num = val;
+
+	ret = regmap_read(hdptx->regmap, CMN_REG(0060), &val);
+	if (ret)
+		return 0;
+	ropll_hw.sdm_deno = val;
+
+	ret = regmap_read(hdptx->regmap, CMN_REG(0069), &val);
+	if (ret)
+		return 0;
+	ropll_hw.sdc_n = (val & ROPLL_SDC_N_RBR_MASK) + 3;
+
+	ret = regmap_read(hdptx->regmap, CMN_REG(006c), &val);
+	if (ret)
+		return 0;
+	ropll_hw.sdc_num = val;
+
+	ret = regmap_read(hdptx->regmap, CMN_REG(0070), &val);
+	if (ret)
+		return 0;
+	ropll_hw.sdc_deno = val;
+
+	ret = regmap_read(hdptx->regmap, CMN_REG(0086), &val);
+	if (ret)
+		return 0;
+	ropll_hw.pms_sdiv = ((val & PLL_PCG_POSTDIV_SEL_MASK) >> 4) + 1;
+
+	fout = PLL_REF_CLK * ropll_hw.pms_mdiv;
+	if (ropll_hw.sdm_en) {
+		sdm = div_u64(PLL_REF_CLK * ropll_hw.sdc_deno *
+			      ropll_hw.pms_mdiv * ropll_hw.sdm_num,
+			      16 * ropll_hw.sdm_deno *
+			      (ropll_hw.sdc_deno * ropll_hw.sdc_n - ropll_hw.sdc_num));
+
+		if (ropll_hw.sdm_num_sign)
+			fout = fout - sdm;
+		else
+			fout = fout + sdm;
+	}
+
+	return div_u64(fout * 2, ropll_hw.pms_sdiv * 10);
+}
+
 static unsigned long rk_hdptx_phy_clk_recalc_rate(struct clk_hw *hw,
 						  unsigned long parent_rate)
 {
 	struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);
+	u32 status;
+	u64 rate;
+	int ret;
+
+	if (hdptx->hw_rate)
+		return hdptx->hw_rate;
+
+	ret = regmap_read(hdptx->grf, GRF_HDPTX_CON0, &status);
+	if (ret || !(status & HDPTX_I_PLL_EN))
+		return 0;
+
+	rate = rk_hdptx_phy_clk_calc_rate_from_pll_cfg(hdptx);
 
-	return hdptx->hw_rate;
+	return DIV_ROUND_CLOSEST_ULL(rate * 8, hdptx->hdmi_cfg.bpc);
 }
 
 static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,

-- 
2.50.1



From cristian.ciocaltea at collabora.com  Mon Aug 18 11:59:11 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Mon, 18 Aug 2025 21:59:11 +0300
Subject: [PATCH v3 11/14] phy: rockchip: samsung-hdptx: Drop hw_rate driver
 data
In-Reply-To: <20250818-phy-hdptx-frl-v3-0-c79997d8bb2b@collabora.com>
References: <20250818-phy-hdptx-frl-v3-0-c79997d8bb2b@collabora.com>
Message-ID: <20250818-phy-hdptx-frl-v3-11-c79997d8bb2b@collabora.com>

The ->hw_rate member of struct rk_hdptx_phy was mainly used to keep
track of the clock rate programmed in hardware and support implementing
the ->recalc_rate() callback in hdptx_phy_clk_ops.

Computing the clock rate from the actual PHY PLL configuration seems to
work reliably, hence remove the now redundant struct member.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 13 ++-----------
 1 file changed, 2 insertions(+), 11 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index 6e2443f78968948b84e4261e33761fe0d189553b..4195387108d8786c2b7cabb6d2f3c07315fefd88 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -401,7 +401,6 @@ struct rk_hdptx_phy {
 
 	/* clk provider */
 	struct clk_hw hw;
-	unsigned long hw_rate;
 	bool restrict_rate_change;
 
 	atomic_t usage_count;
@@ -964,7 +963,7 @@ static int rk_hdptx_tmds_ropll_cmn_config(struct rk_hdptx_phy *hdptx)
 {
 	const struct ropll_config *cfg = NULL;
 	struct ropll_config rc = {0};
-	int ret, i;
+	int i;
 
 	if (!hdptx->hdmi_cfg.tmds_char_rate)
 		return 0;
@@ -1026,12 +1025,7 @@ static int rk_hdptx_tmds_ropll_cmn_config(struct rk_hdptx_phy *hdptx)
 	regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_CLK_EN_MASK,
 			   FIELD_PREP(PLL_PCG_CLK_EN_MASK, 0x1));
 
-	ret = rk_hdptx_post_enable_pll(hdptx);
-	if (!ret)
-		hdptx->hw_rate = DIV_ROUND_CLOSEST_ULL(hdptx->hdmi_cfg.tmds_char_rate * 8,
-						       hdptx->hdmi_cfg.bpc);
-
-	return ret;
+	return rk_hdptx_post_enable_pll(hdptx);
 }
 
 static int rk_hdptx_tmds_ropll_mode_config(struct rk_hdptx_phy *hdptx)
@@ -1936,9 +1930,6 @@ static unsigned long rk_hdptx_phy_clk_recalc_rate(struct clk_hw *hw,
 	u64 rate;
 	int ret;
 
-	if (hdptx->hw_rate)
-		return hdptx->hw_rate;
-
 	ret = regmap_read(hdptx->grf, GRF_HDPTX_CON0, &status);
 	if (ret || !(status & HDPTX_I_PLL_EN))
 		return 0;

-- 
2.50.1



From cristian.ciocaltea at collabora.com  Mon Aug 18 11:59:12 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Mon, 18 Aug 2025 21:59:12 +0300
Subject: [PATCH v3 12/14] phy: rockchip: samsung-hdptx: Switch to driver
 specific HDMI config
In-Reply-To: <20250818-phy-hdptx-frl-v3-0-c79997d8bb2b@collabora.com>
References: <20250818-phy-hdptx-frl-v3-0-c79997d8bb2b@collabora.com>
Message-ID: <20250818-phy-hdptx-frl-v3-12-c79997d8bb2b@collabora.com>

In preparation to support the FRL operation mode which gets configured
via the lanes and rate per lane tuple, switch to a driver specific
struct for configuring the link rate and bpc.

This simplifies and optimizes the implementation by allowing implicit
switches between TMDS and FRL rates, without requiring additional checks
of the active PHY mode followed by recalculations of the link rate when
operating in FRL mode.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 44 +++++++++++++----------
 1 file changed, 25 insertions(+), 19 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index 4195387108d8786c2b7cabb6d2f3c07315fefd88..a44614bc73e9461d4d38663776f547f595169c3b 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -387,6 +387,11 @@ struct rk_hdptx_phy_cfg {
 	unsigned int phy_ids[MAX_HDPTX_PHY_NUM];
 };
 
+struct rk_hdptx_hdmi_cfg {
+	unsigned long long rate;
+	unsigned int bpc;
+};
+
 struct rk_hdptx_phy {
 	struct device *dev;
 	struct regmap *regmap;
@@ -394,7 +399,7 @@ struct rk_hdptx_phy {
 
 	int phy_id;
 	struct phy *phy;
-	struct phy_configure_opts_hdmi hdmi_cfg;
+	struct rk_hdptx_hdmi_cfg hdmi_cfg;
 	struct clk_bulk_data *clks;
 	int nr_clks;
 	struct reset_control_bulk_data rsts[RST_MAX];
@@ -965,19 +970,19 @@ static int rk_hdptx_tmds_ropll_cmn_config(struct rk_hdptx_phy *hdptx)
 	struct ropll_config rc = {0};
 	int i;
 
-	if (!hdptx->hdmi_cfg.tmds_char_rate)
+	if (!hdptx->hdmi_cfg.rate)
 		return 0;
 
 	for (i = 0; i < ARRAY_SIZE(rk_hdptx_tmds_ropll_cfg); i++)
-		if (hdptx->hdmi_cfg.tmds_char_rate == rk_hdptx_tmds_ropll_cfg[i].rate) {
+		if (hdptx->hdmi_cfg.rate == rk_hdptx_tmds_ropll_cfg[i].rate) {
 			cfg = &rk_hdptx_tmds_ropll_cfg[i];
 			break;
 		}
 
 	if (!cfg) {
-		if (!rk_hdptx_phy_clk_pll_calc(hdptx->hdmi_cfg.tmds_char_rate, &rc)) {
+		if (!rk_hdptx_phy_clk_pll_calc(hdptx->hdmi_cfg.rate, &rc)) {
 			dev_err(hdptx->dev, "%s cannot find pll cfg for rate=%llu\n",
-				__func__, hdptx->hdmi_cfg.tmds_char_rate);
+				__func__, hdptx->hdmi_cfg.rate);
 			return -EINVAL;
 		}
 
@@ -985,7 +990,7 @@ static int rk_hdptx_tmds_ropll_cmn_config(struct rk_hdptx_phy *hdptx)
 	}
 
 	dev_dbg(hdptx->dev, "%s rate=%llu mdiv=%u sdiv=%u sdm_en=%u k_sign=%u k=%u lc=%u\n",
-		__func__, hdptx->hdmi_cfg.tmds_char_rate, cfg->pms_mdiv, cfg->pms_sdiv + 1,
+		__func__, hdptx->hdmi_cfg.rate, cfg->pms_mdiv, cfg->pms_sdiv + 1,
 		cfg->sdm_en, cfg->sdm_num_sign, cfg->sdm_num, cfg->sdm_deno);
 
 	rk_hdptx_pre_power_up(hdptx);
@@ -1034,7 +1039,7 @@ static int rk_hdptx_tmds_ropll_mode_config(struct rk_hdptx_phy *hdptx)
 
 	regmap_write(hdptx->regmap, LNTOP_REG(0200), 0x06);
 
-	if (hdptx->hdmi_cfg.tmds_char_rate > HDMI14_MAX_RATE) {
+	if (hdptx->hdmi_cfg.rate > HDMI14_MAX_RATE) {
 		/* For 1/40 bitrate clk */
 		rk_hdptx_multi_reg_write(hdptx, rk_hdptx_tmds_lntop_highbr_seq);
 	} else {
@@ -1405,19 +1410,19 @@ static int rk_hdptx_phy_power_on(struct phy *phy)
 	int ret, lane;
 
 	if (mode != PHY_MODE_DP) {
-		if (!hdptx->hdmi_cfg.tmds_char_rate) {
+		if (!hdptx->hdmi_cfg.rate) {
 			/*
 			 * FIXME: Temporary workaround to setup TMDS char rate
 			 * from the RK DW HDMI QP bridge driver.
 			 * Will be removed as soon the switch to the HDMI PHY
 			 * configuration API has been completed on both ends.
 			 */
-			hdptx->hdmi_cfg.tmds_char_rate = phy_get_bus_width(hdptx->phy) & 0xfffffff;
-			hdptx->hdmi_cfg.tmds_char_rate *= 100;
+			hdptx->hdmi_cfg.rate = phy_get_bus_width(hdptx->phy) & 0xfffffff;
+			hdptx->hdmi_cfg.rate *= 100;
 		}
 
 		dev_dbg(hdptx->dev, "%s rate=%llu bpc=%u\n", __func__,
-			hdptx->hdmi_cfg.tmds_char_rate, hdptx->hdmi_cfg.bpc);
+			hdptx->hdmi_cfg.rate, hdptx->hdmi_cfg.bpc);
 	}
 
 	ret = rk_hdptx_phy_consumer_get(hdptx);
@@ -1764,12 +1769,13 @@ static int rk_hdptx_phy_configure(struct phy *phy, union phy_configure_opts *opt
 		if (ret) {
 			dev_err(hdptx->dev, "invalid hdmi params for phy configure\n");
 		} else {
-			hdptx->hdmi_cfg = opts->hdmi;
+			hdptx->hdmi_cfg.rate = opts->hdmi.tmds_char_rate;
+			hdptx->hdmi_cfg.bpc = opts->hdmi.bpc;
 			hdptx->restrict_rate_change = true;
 		}
 
 		dev_dbg(hdptx->dev, "%s rate=%llu bpc=%u\n", __func__,
-			hdptx->hdmi_cfg.tmds_char_rate, hdptx->hdmi_cfg.bpc);
+			hdptx->hdmi_cfg.rate, hdptx->hdmi_cfg.bpc);
 		return ret;
 	}
 
@@ -1949,7 +1955,7 @@ static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
 	 * To be dropped as soon as the RK DW HDMI QP bridge driver
 	 * switches to make use of phy_configure().
 	 */
-	if (!hdptx->restrict_rate_change && rate != hdptx->hdmi_cfg.tmds_char_rate) {
+	if (!hdptx->restrict_rate_change && rate != hdptx->hdmi_cfg.rate) {
 		struct phy_configure_opts_hdmi hdmi = {
 			.tmds_char_rate = rate,
 		};
@@ -1958,7 +1964,7 @@ static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
 		if (ret)
 			return ret;
 
-		hdptx->hdmi_cfg = hdmi;
+		hdptx->hdmi_cfg.rate = rate;
 	}
 
 	/*
@@ -1966,7 +1972,7 @@ static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
 	 * hence ensure rk_hdptx_phy_clk_set_rate() won't be invoked with
 	 * a different rate argument.
 	 */
-	return DIV_ROUND_CLOSEST_ULL(hdptx->hdmi_cfg.tmds_char_rate * 8, hdptx->hdmi_cfg.bpc);
+	return DIV_ROUND_CLOSEST_ULL(hdptx->hdmi_cfg.rate * 8, hdptx->hdmi_cfg.bpc);
 }
 
 static int rk_hdptx_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -1976,10 +1982,10 @@ static int rk_hdptx_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate,
 	unsigned long long tmds_rate = DIV_ROUND_CLOSEST_ULL(rate * hdptx->hdmi_cfg.bpc, 8);
 
 	/* Revert any unlikely TMDS char rate change since round_rate() */
-	if (hdptx->hdmi_cfg.tmds_char_rate != tmds_rate) {
+	if (hdptx->hdmi_cfg.rate != tmds_rate) {
 		dev_warn(hdptx->dev, "Reverting unexpected rate change from %llu to %llu\n",
-			 tmds_rate, hdptx->hdmi_cfg.tmds_char_rate);
-		hdptx->hdmi_cfg.tmds_char_rate = tmds_rate;
+			 tmds_rate, hdptx->hdmi_cfg.rate);
+		hdptx->hdmi_cfg.rate = tmds_rate;
 	}
 
 	/*

-- 
2.50.1



From cristian.ciocaltea at collabora.com  Mon Aug 18 11:59:13 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Mon, 18 Aug 2025 21:59:13 +0300
Subject: [PATCH v3 13/14] phy: rockchip: samsung-hdptx: Extend
 rk_hdptx_phy_verify_hdmi_config() helper
In-Reply-To: <20250818-phy-hdptx-frl-v3-0-c79997d8bb2b@collabora.com>
References: <20250818-phy-hdptx-frl-v3-0-c79997d8bb2b@collabora.com>
Message-ID: <20250818-phy-hdptx-frl-v3-13-c79997d8bb2b@collabora.com>

In order to facilitate introduction of HDMI 2.1 FRL support and to avoid
recomputing the link rate after verifying the HDMI configuration given
as input, extend rk_hdptx_phy_verify_hdmi_config() by providing an
optional output parameter to store the validated configuration.

For improved code readability, also rename the existing hdmi input
parameter.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 35 ++++++++++++-----------
 1 file changed, 18 insertions(+), 17 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index a44614bc73e9461d4d38663776f547f595169c3b..58eac67cc3b21c17939c303bbea3fcdc5e6b0518 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -1472,25 +1472,24 @@ static int rk_hdptx_phy_power_off(struct phy *phy)
 }
 
 static int rk_hdptx_phy_verify_hdmi_config(struct rk_hdptx_phy *hdptx,
-					   struct phy_configure_opts_hdmi *hdmi)
+					   struct phy_configure_opts_hdmi *hdmi_in,
+					   struct rk_hdptx_hdmi_cfg *hdmi_out)
 {
 	int i;
 
-	if (!hdmi->tmds_char_rate || hdmi->tmds_char_rate > HDMI20_MAX_RATE)
+	if (!hdmi_in->tmds_char_rate || hdmi_in->tmds_char_rate > HDMI20_MAX_RATE)
 		return -EINVAL;
 
 	for (i = 0; i < ARRAY_SIZE(rk_hdptx_tmds_ropll_cfg); i++)
-		if (hdmi->tmds_char_rate == rk_hdptx_tmds_ropll_cfg[i].rate)
+		if (hdmi_in->tmds_char_rate == rk_hdptx_tmds_ropll_cfg[i].rate)
 			break;
 
 	if (i == ARRAY_SIZE(rk_hdptx_tmds_ropll_cfg) &&
-	    !rk_hdptx_phy_clk_pll_calc(hdmi->tmds_char_rate, NULL))
+	    !rk_hdptx_phy_clk_pll_calc(hdmi_in->tmds_char_rate, NULL))
 		return -EINVAL;
 
-	if (!hdmi->bpc)
-		hdmi->bpc = 8;
-
-	switch (hdmi->bpc) {
+	switch (hdmi_in->bpc) {
+	case 0:
 	case 8:
 	case 10:
 	case 12:
@@ -1500,6 +1499,11 @@ static int rk_hdptx_phy_verify_hdmi_config(struct rk_hdptx_phy *hdptx,
 		return -EINVAL;
 	}
 
+	if (hdmi_out) {
+		hdmi_out->rate = hdmi_in->tmds_char_rate;
+		hdmi_out->bpc = hdmi_in->bpc ?: 8;
+	}
+
 	return 0;
 }
 
@@ -1765,17 +1769,15 @@ static int rk_hdptx_phy_configure(struct phy *phy, union phy_configure_opts *opt
 	int ret;
 
 	if (mode != PHY_MODE_DP) {
-		ret = rk_hdptx_phy_verify_hdmi_config(hdptx, &opts->hdmi);
+		ret = rk_hdptx_phy_verify_hdmi_config(hdptx, &opts->hdmi, &hdptx->hdmi_cfg);
 		if (ret) {
 			dev_err(hdptx->dev, "invalid hdmi params for phy configure\n");
 		} else {
-			hdptx->hdmi_cfg.rate = opts->hdmi.tmds_char_rate;
-			hdptx->hdmi_cfg.bpc = opts->hdmi.bpc;
 			hdptx->restrict_rate_change = true;
+			dev_dbg(hdptx->dev, "%s rate=%llu bpc=%u\n", __func__,
+				hdptx->hdmi_cfg.rate, hdptx->hdmi_cfg.bpc);
 		}
 
-		dev_dbg(hdptx->dev, "%s rate=%llu bpc=%u\n", __func__,
-			hdptx->hdmi_cfg.rate, hdptx->hdmi_cfg.bpc);
 		return ret;
 	}
 
@@ -1819,7 +1821,7 @@ static int rk_hdptx_phy_validate(struct phy *phy, enum phy_mode mode,
 	struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy);
 
 	if (mode != PHY_MODE_DP)
-		return rk_hdptx_phy_verify_hdmi_config(hdptx, &opts->hdmi);
+		return rk_hdptx_phy_verify_hdmi_config(hdptx, &opts->hdmi, NULL);
 
 	return rk_hdptx_phy_verify_dp_config(hdptx, &opts->dp);
 }
@@ -1959,12 +1961,11 @@ static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
 		struct phy_configure_opts_hdmi hdmi = {
 			.tmds_char_rate = rate,
 		};
-		int ret = rk_hdptx_phy_verify_hdmi_config(hdptx, &hdmi);
+
+		int ret = rk_hdptx_phy_verify_hdmi_config(hdptx, &hdmi, &hdptx->hdmi_cfg);
 
 		if (ret)
 			return ret;
-
-		hdptx->hdmi_cfg.rate = rate;
 	}
 
 	/*

-- 
2.50.1



From cristian.ciocaltea at collabora.com  Mon Aug 18 11:59:14 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Mon, 18 Aug 2025 21:59:14 +0300
Subject: [PATCH v3 14/14] phy: rockchip: samsung-hdptx: Add HDMI 2.1 FRL
 support
In-Reply-To: <20250818-phy-hdptx-frl-v3-0-c79997d8bb2b@collabora.com>
References: <20250818-phy-hdptx-frl-v3-0-c79997d8bb2b@collabora.com>
Message-ID: <20250818-phy-hdptx-frl-v3-14-c79997d8bb2b@collabora.com>

The PHY is capable of handling four HDMI 2.1 Fixed Rate Link (FRL)
lanes, and each one can operate at any of the rates of 3Gbps, 6Gbps,
8Gbps, 10Gbps or 12Gbps.

Add the necessary driver changes to support the feature.

Co-developed-by: Algea Cao <algea.cao at rock-chips.com>
Signed-off-by: Algea Cao <algea.cao at rock-chips.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 459 ++++++++++++++++++++--
 1 file changed, 436 insertions(+), 23 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index 58eac67cc3b21c17939c303bbea3fcdc5e6b0518..31128a2880b59ad5512da1dcf61234460192d8c6 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -22,6 +22,7 @@
 #include <linux/reset.h>
 
 #define GRF_HDPTX_CON0			0x00
+#define LC_REF_CLK_SEL			BIT(11)
 #define HDPTX_I_PLL_EN			BIT(7)
 #define HDPTX_I_BIAS_EN			BIT(6)
 #define HDPTX_I_BGR_EN			BIT(5)
@@ -322,6 +323,9 @@
 
 #define HDMI14_MAX_RATE			340000000
 #define HDMI20_MAX_RATE			600000000
+#define FRL_3G3L_RATE			900000000
+#define FRL_6G3L_RATE			1800000000
+#define FRL_8G4L_RATE			3200000000
 
 enum dp_link_rate {
 	DP_BW_RBR,
@@ -329,6 +333,37 @@ enum dp_link_rate {
 	DP_BW_HBR2,
 };
 
+struct lcpll_config {
+	unsigned long long rate;
+	u8 lcvco_mode_en;
+	u8 pi_en;
+	u8 clk_en_100m;
+	u8 pms_mdiv;
+	u8 pms_mdiv_afc;
+	u8 pms_pdiv;
+	u8 pms_refdiv;
+	u8 pms_sdiv;
+	u8 pi_cdiv_rstn;
+	u8 pi_cdiv_sel;
+	u8 sdm_en;
+	u8 sdm_rstn;
+	u8 sdc_frac_en;
+	u8 sdc_rstn;
+	u8 sdm_deno;
+	u8 sdm_num_sign;
+	u8 sdm_num;
+	u8 sdc_n;
+	u8 sdc_n2;
+	u8 sdc_num;
+	u8 sdc_deno;
+	u8 sdc_ndiv_rstn;
+	u8 ssc_en;
+	u8 ssc_fm_dev;
+	u8 ssc_fm_freq;
+	u8 ssc_clk_div_sel;
+	u8 cd_tx_ser_rate_sel;
+};
+
 struct ropll_config {
 	unsigned long long rate;
 	u8 pms_mdiv;
@@ -388,6 +423,7 @@ struct rk_hdptx_phy_cfg {
 };
 
 struct rk_hdptx_hdmi_cfg {
+	enum phy_mode_hdmi mode;
 	unsigned long long rate;
 	unsigned int bpc;
 };
@@ -415,6 +451,19 @@ struct rk_hdptx_phy {
 	unsigned int lanes;
 };
 
+static const struct lcpll_config rk_hdptx_frl_lcpll_cfg[] = {
+	{ 4800000000ULL, 1, 0, 0, 0x7d, 0x7d, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 2,
+	  0, 0x13, 0x18, 1, 0, 0x20, 0x0c, 1, 0, },
+	{ 4000000000ULL, 1, 1, 0, 0x68, 0x68, 1, 1, 0, 0, 0, 1, 1, 1, 1, 9, 0, 1, 1,
+	  0, 2, 3, 1, 0, 0x20, 0x0c, 1, 0, },
+	{ 2400000000ULL, 1, 0, 0, 0x7d, 0x7d, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 2,
+	  0, 0x13, 0x18, 1, 0, 0x20, 0x0c, 1, 0, },
+	{ 1800000000ULL, 1, 0, 0, 0x7d, 0x7d, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 2,
+	  0, 0x13, 0x18, 1, 0, 0x20, 0x0c, 1, 0, },
+	{ 900000000ULL, 1, 0, 0, 0x7d, 0x7d, 1, 1, 3, 0, 0, 0, 0, 1, 1, 1, 0, 0, 2,
+	  0, 0x13, 0x18, 1, 0, 0x20, 0x0c, 1, 0, },
+};
+
 static const struct ropll_config rk_hdptx_tmds_ropll_cfg[] = {
 	{ 594000000ULL, 124, 124, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
 	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
@@ -532,6 +581,110 @@ static const struct reg_sequence rk_hdptx_common_cmn_init_seq[] = {
 	REG_SEQ0(CMN_REG(009a), 0x11),
 };
 
+static const struct reg_sequence rk_hdptx_frl_lcpll_cmn_init_seq[] = {
+	REG_SEQ0(CMN_REG(0011), 0x00),
+	REG_SEQ0(CMN_REG(0017), 0x00),
+	REG_SEQ0(CMN_REG(0025), 0x10),
+	REG_SEQ0(CMN_REG(0026), 0x53),
+	REG_SEQ0(CMN_REG(0027), 0x01),
+	REG_SEQ0(CMN_REG(0028), 0x0d),
+	REG_SEQ0(CMN_REG(002e), 0x02),
+	REG_SEQ0(CMN_REG(002f), 0x0d),
+	REG_SEQ0(CMN_REG(0030), 0x00),
+	REG_SEQ0(CMN_REG(0031), 0x20),
+	REG_SEQ0(CMN_REG(0032), 0x30),
+	REG_SEQ0(CMN_REG(0033), 0x0b),
+	REG_SEQ0(CMN_REG(0034), 0x23),
+	REG_SEQ0(CMN_REG(003d), 0x00),
+	REG_SEQ0(CMN_REG(0042), 0xb8),
+	REG_SEQ0(CMN_REG(0046), 0xff),
+	REG_SEQ0(CMN_REG(0048), 0x44),
+	REG_SEQ0(CMN_REG(004e), 0x14),
+	REG_SEQ0(CMN_REG(0051), 0x00),
+	REG_SEQ0(CMN_REG(0055), 0x00),
+	REG_SEQ0(CMN_REG(0059), 0x11),
+	REG_SEQ0(CMN_REG(005a), 0x03),
+	REG_SEQ0(CMN_REG(005c), 0x05),
+	REG_SEQ0(CMN_REG(005d), 0x0c),
+	REG_SEQ0(CMN_REG(005e), 0x07),
+	REG_SEQ0(CMN_REG(0060), 0x01),
+	REG_SEQ0(CMN_REG(0064), 0x07),
+	REG_SEQ0(CMN_REG(0065), 0x00),
+	REG_SEQ0(CMN_REG(0069), 0x00),
+	REG_SEQ0(CMN_REG(006b), 0x04),
+	REG_SEQ0(CMN_REG(006c), 0x00),
+	REG_SEQ0(CMN_REG(0070), 0x01),
+	REG_SEQ0(CMN_REG(0073), 0x30),
+	REG_SEQ0(CMN_REG(0074), 0x00),
+	REG_SEQ0(CMN_REG(0081), 0x09),
+	REG_SEQ0(CMN_REG(0086), 0x01),
+	REG_SEQ0(CMN_REG(0087), 0x0c),
+	REG_SEQ0(CMN_REG(0089), 0x02),
+	REG_SEQ0(CMN_REG(0095), 0x00),
+	REG_SEQ0(CMN_REG(0097), 0x00),
+	REG_SEQ0(CMN_REG(0099), 0x00),
+	REG_SEQ0(CMN_REG(009b), 0x10),
+};
+
+static const struct reg_sequence rk_hdptx_frl_lcpll_ropll_cmn_init_seq[] = {
+	REG_SEQ0(CMN_REG(0008), 0xd0),
+	REG_SEQ0(CMN_REG(0011), 0x00),
+	REG_SEQ0(CMN_REG(0017), 0x00),
+	REG_SEQ0(CMN_REG(001e), 0x35),
+	REG_SEQ0(CMN_REG(0020), 0x6b),
+	REG_SEQ0(CMN_REG(0021), 0x6b),
+	REG_SEQ0(CMN_REG(0022), 0x11),
+	REG_SEQ0(CMN_REG(0024), 0x00),
+	REG_SEQ0(CMN_REG(0025), 0x10),
+	REG_SEQ0(CMN_REG(0026), 0x53),
+	REG_SEQ0(CMN_REG(0027), 0x15),
+	REG_SEQ0(CMN_REG(0028), 0x0d),
+	REG_SEQ0(CMN_REG(002a), 0x09),
+	REG_SEQ0(CMN_REG(002b), 0x01),
+	REG_SEQ0(CMN_REG(002c), 0x02),
+	REG_SEQ0(CMN_REG(002d), 0x02),
+	REG_SEQ0(CMN_REG(002e), 0x0d),
+	REG_SEQ0(CMN_REG(002f), 0x61),
+	REG_SEQ0(CMN_REG(0030), 0x00),
+	REG_SEQ0(CMN_REG(0031), 0x20),
+	REG_SEQ0(CMN_REG(0032), 0x30),
+	REG_SEQ0(CMN_REG(0033), 0x0b),
+	REG_SEQ0(CMN_REG(0034), 0x23),
+	REG_SEQ0(CMN_REG(0037), 0x00),
+	REG_SEQ0(CMN_REG(003d), 0xc0),
+	REG_SEQ0(CMN_REG(0042), 0xb8),
+	REG_SEQ0(CMN_REG(0046), 0xff),
+	REG_SEQ0(CMN_REG(0048), 0x44),
+	REG_SEQ0(CMN_REG(004e), 0x14),
+	REG_SEQ0(CMN_REG(0054), 0x19),
+	REG_SEQ0(CMN_REG(0058), 0x19),
+	REG_SEQ0(CMN_REG(0059), 0x11),
+	REG_SEQ0(CMN_REG(005b), 0x30),
+	REG_SEQ0(CMN_REG(005c), 0x25),
+	REG_SEQ0(CMN_REG(005d), 0x14),
+	REG_SEQ0(CMN_REG(005e), 0x0e),
+	REG_SEQ0(CMN_REG(0063), 0x01),
+	REG_SEQ0(CMN_REG(0064), 0x0e),
+	REG_SEQ0(CMN_REG(0068), 0x00),
+	REG_SEQ0(CMN_REG(0069), 0x02),
+	REG_SEQ0(CMN_REG(006b), 0x00),
+	REG_SEQ0(CMN_REG(006f), 0x00),
+	REG_SEQ0(CMN_REG(0073), 0x02),
+	REG_SEQ0(CMN_REG(0074), 0x00),
+	REG_SEQ0(CMN_REG(007a), 0x00),
+	REG_SEQ0(CMN_REG(0081), 0x09),
+	REG_SEQ0(CMN_REG(0086), 0x11),
+	REG_SEQ0(CMN_REG(0087), 0x0c),
+	REG_SEQ0(CMN_REG(0089), 0x00),
+	REG_SEQ0(CMN_REG(0095), 0x03),
+	REG_SEQ0(CMN_REG(0097), 0x00),
+	REG_SEQ0(CMN_REG(0099), 0x00),
+	REG_SEQ0(CMN_REG(009b), 0x10),
+	REG_SEQ0(CMN_REG(009e), 0x03),
+	REG_SEQ0(CMN_REG(009f), 0xff),
+	REG_SEQ0(CMN_REG(00a0), 0x60),
+};
+
 static const struct reg_sequence rk_hdptx_tmds_cmn_init_seq[] = {
 	REG_SEQ0(CMN_REG(0008), 0x00),
 	REG_SEQ0(CMN_REG(0011), 0x01),
@@ -585,6 +738,16 @@ static const struct reg_sequence rk_hdptx_common_sb_init_seq[] = {
 	REG_SEQ0(SB_REG(0117), 0x00),
 };
 
+static const struct reg_sequence rk_hdptx_frl_lntop_init_seq[] = {
+	REG_SEQ0(LNTOP_REG(0200), 0x04),
+	REG_SEQ0(LNTOP_REG(0201), 0x00),
+	REG_SEQ0(LNTOP_REG(0202), 0x00),
+	REG_SEQ0(LNTOP_REG(0203), 0xf0),
+	REG_SEQ0(LNTOP_REG(0204), 0xff),
+	REG_SEQ0(LNTOP_REG(0205), 0xff),
+	REG_SEQ0(LNTOP_REG(0206), 0x05),
+};
+
 static const struct reg_sequence rk_hdptx_tmds_lntop_highbr_seq[] = {
 	REG_SEQ0(LNTOP_REG(0201), 0x00),
 	REG_SEQ0(LNTOP_REG(0202), 0x00),
@@ -656,6 +819,38 @@ static const struct reg_sequence rk_hdptx_common_lane_init_seq[] = {
 	REG_SEQ0(LANE_REG(0620), 0xa0),
 };
 
+static const struct reg_sequence rk_hdptx_frl_lane_init_seq[] = {
+	REG_SEQ0(LANE_REG(0312), 0x3c),
+	REG_SEQ0(LANE_REG(0412), 0x3c),
+	REG_SEQ0(LANE_REG(0512), 0x3c),
+	REG_SEQ0(LANE_REG(0612), 0x3c),
+	REG_SEQ0(LANE_REG(0303), 0x2f),
+	REG_SEQ0(LANE_REG(0403), 0x2f),
+	REG_SEQ0(LANE_REG(0503), 0x2f),
+	REG_SEQ0(LANE_REG(0603), 0x2f),
+	REG_SEQ0(LANE_REG(0305), 0x03),
+	REG_SEQ0(LANE_REG(0405), 0x03),
+	REG_SEQ0(LANE_REG(0505), 0x03),
+	REG_SEQ0(LANE_REG(0605), 0x03),
+	REG_SEQ0(LANE_REG(0306), 0xfc),
+	REG_SEQ0(LANE_REG(0406), 0xfc),
+	REG_SEQ0(LANE_REG(0506), 0xfc),
+	REG_SEQ0(LANE_REG(0606), 0xfc),
+	REG_SEQ0(LANE_REG(0305), 0x4f),
+	REG_SEQ0(LANE_REG(0405), 0x4f),
+	REG_SEQ0(LANE_REG(0505), 0x4f),
+	REG_SEQ0(LANE_REG(0605), 0x4f),
+	REG_SEQ0(LANE_REG(0304), 0x14),
+	REG_SEQ0(LANE_REG(0404), 0x14),
+	REG_SEQ0(LANE_REG(0504), 0x14),
+	REG_SEQ0(LANE_REG(0604), 0x14),
+	/* Keep Inter-Pair Skew in the limits */
+	REG_SEQ0(LANE_REG(031e), 0x02),
+	REG_SEQ0(LANE_REG(041e), 0x02),
+	REG_SEQ0(LANE_REG(051e), 0x02),
+	REG_SEQ0(LANE_REG(061e), 0x02),
+};
+
 static const struct reg_sequence rk_hdptx_tmds_lane_init_seq[] = {
 	REG_SEQ0(LANE_REG(0312), 0x00),
 	REG_SEQ0(LANE_REG(0412), 0x00),
@@ -820,7 +1015,12 @@ static int rk_hdptx_post_enable_lane(struct rk_hdptx_phy *hdptx)
 	       HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN;
 	regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);
 
-	regmap_write(hdptx->regmap, LNTOP_REG(0207), 0x0f);
+	/* 3 lanes FRL mode */
+	if (hdptx->hdmi_cfg.rate == FRL_6G3L_RATE ||
+	    hdptx->hdmi_cfg.rate == FRL_3G3L_RATE)
+		regmap_write(hdptx->regmap, LNTOP_REG(0207), 0x07);
+	else
+		regmap_write(hdptx->regmap, LNTOP_REG(0207), 0x0f);
 
 	ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS, val,
 				       (val & HDPTX_O_PHY_RDY) &&
@@ -964,6 +1164,80 @@ static bool rk_hdptx_phy_clk_pll_calc(unsigned long long rate,
 	return true;
 }
 
+static int rk_hdptx_frl_lcpll_cmn_config(struct rk_hdptx_phy *hdptx)
+{
+	const struct lcpll_config *cfg = NULL;
+	int i;
+
+	dev_dbg(hdptx->dev, "%s rate=%llu\n", __func__, hdptx->hdmi_cfg.rate);
+
+	for (i = 0; i < ARRAY_SIZE(rk_hdptx_frl_lcpll_cfg); i++) {
+		if (hdptx->hdmi_cfg.rate == rk_hdptx_frl_lcpll_cfg[i].rate) {
+			cfg = &rk_hdptx_frl_lcpll_cfg[i];
+			break;
+		}
+	}
+
+	if (!cfg) {
+		dev_err(hdptx->dev, "%s cannot find pll cfg for rate=%llu\n",
+			__func__, hdptx->hdmi_cfg.rate);
+		return -EINVAL;
+	}
+
+	rk_hdptx_pre_power_up(hdptx);
+
+	regmap_write(hdptx->grf, GRF_HDPTX_CON0, LC_REF_CLK_SEL << 16);
+
+	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_cmn_init_seq);
+	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_frl_lcpll_cmn_init_seq);
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0008),
+			   LCPLL_EN_MASK | LCPLL_LCVCO_MODE_EN_MASK,
+			   FIELD_PREP(LCPLL_EN_MASK, 1) |
+			   FIELD_PREP(LCPLL_LCVCO_MODE_EN_MASK, cfg->lcvco_mode_en));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(001e),
+			   LCPLL_PI_EN_MASK | LCPLL_100M_CLK_EN_MASK,
+			   FIELD_PREP(LCPLL_PI_EN_MASK, cfg->pi_en) |
+			   FIELD_PREP(LCPLL_100M_CLK_EN_MASK, cfg->clk_en_100m));
+
+	regmap_write(hdptx->regmap, CMN_REG(0020), cfg->pms_mdiv);
+	regmap_write(hdptx->regmap, CMN_REG(0021), cfg->pms_mdiv_afc);
+	regmap_write(hdptx->regmap, CMN_REG(0022),
+		     (cfg->pms_pdiv << 4) | cfg->pms_refdiv);
+	regmap_write(hdptx->regmap, CMN_REG(0023),
+		     (cfg->pms_sdiv << 4) | cfg->pms_sdiv);
+	regmap_write(hdptx->regmap, CMN_REG(002a), cfg->sdm_deno);
+	regmap_write(hdptx->regmap, CMN_REG(002b), cfg->sdm_num_sign);
+	regmap_write(hdptx->regmap, CMN_REG(002c), cfg->sdm_num);
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(002d), LCPLL_SDC_N_MASK,
+			   FIELD_PREP(LCPLL_SDC_N_MASK, cfg->sdc_n));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_POSTDIV_SEL_MASK,
+			   FIELD_PREP(PLL_PCG_POSTDIV_SEL_MASK, cfg->pms_sdiv));
+	regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_CLK_SEL_MASK,
+			   FIELD_PREP(PLL_PCG_CLK_SEL_MASK, (hdptx->hdmi_cfg.bpc - 8) >> 1));
+
+	return rk_hdptx_post_enable_pll(hdptx);
+}
+
+static int rk_hdptx_frl_lcpll_ropll_cmn_config(struct rk_hdptx_phy *hdptx)
+{
+	dev_dbg(hdptx->dev, "%s rate=%llu\n", __func__, hdptx->hdmi_cfg.rate);
+
+	rk_hdptx_pre_power_up(hdptx);
+
+	/* ROPLL input reference clock from LCPLL (cascade mode) */
+	regmap_write(hdptx->grf, GRF_HDPTX_CON0,
+		     (LC_REF_CLK_SEL << 16) | LC_REF_CLK_SEL);
+
+	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_cmn_init_seq);
+	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_frl_lcpll_ropll_cmn_init_seq);
+
+	return rk_hdptx_post_enable_pll(hdptx);
+}
+
 static int rk_hdptx_tmds_ropll_cmn_config(struct rk_hdptx_phy *hdptx)
 {
 	const struct ropll_config *cfg = NULL;
@@ -995,6 +1269,8 @@ static int rk_hdptx_tmds_ropll_cmn_config(struct rk_hdptx_phy *hdptx)
 
 	rk_hdptx_pre_power_up(hdptx);
 
+	regmap_write(hdptx->grf, GRF_HDPTX_CON0, LC_REF_CLK_SEL << 16);
+
 	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_cmn_init_seq);
 	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_tmds_cmn_init_seq);
 
@@ -1033,6 +1309,28 @@ static int rk_hdptx_tmds_ropll_cmn_config(struct rk_hdptx_phy *hdptx)
 	return rk_hdptx_post_enable_pll(hdptx);
 }
 
+static int rk_hdptx_pll_cmn_config(struct rk_hdptx_phy *hdptx)
+{
+	if (hdptx->hdmi_cfg.rate <= HDMI20_MAX_RATE)
+		return rk_hdptx_tmds_ropll_cmn_config(hdptx);
+
+	if (hdptx->hdmi_cfg.rate == FRL_8G4L_RATE)
+		return rk_hdptx_frl_lcpll_ropll_cmn_config(hdptx);
+
+	return rk_hdptx_frl_lcpll_cmn_config(hdptx);
+}
+
+static int rk_hdptx_frl_lcpll_mode_config(struct rk_hdptx_phy *hdptx)
+{
+	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_sb_init_seq);
+	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_frl_lntop_init_seq);
+
+	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_lane_init_seq);
+	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_frl_lane_init_seq);
+
+	return rk_hdptx_post_enable_lane(hdptx);
+}
+
 static int rk_hdptx_tmds_ropll_mode_config(struct rk_hdptx_phy *hdptx)
 {
 	rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_sb_init_seq);
@@ -1109,7 +1407,7 @@ static int rk_hdptx_phy_consumer_get(struct rk_hdptx_phy *hdptx)
 	if (mode == PHY_MODE_DP) {
 		rk_hdptx_dp_reset(hdptx);
 	} else {
-		ret = rk_hdptx_tmds_ropll_cmn_config(hdptx);
+		ret = rk_hdptx_pll_cmn_config(hdptx);
 		if (ret)
 			goto dec_usage;
 	}
@@ -1410,7 +1708,7 @@ static int rk_hdptx_phy_power_on(struct phy *phy)
 	int ret, lane;
 
 	if (mode != PHY_MODE_DP) {
-		if (!hdptx->hdmi_cfg.rate) {
+		if (!hdptx->hdmi_cfg.rate && hdptx->hdmi_cfg.mode != PHY_MODE_HDMI_FRL) {
 			/*
 			 * FIXME: Temporary workaround to setup TMDS char rate
 			 * from the RK DW HDMI QP bridge driver.
@@ -1456,7 +1754,11 @@ static int rk_hdptx_phy_power_on(struct phy *phy)
 		regmap_write(hdptx->grf, GRF_HDPTX_CON0,
 			     HDPTX_MODE_SEL << 16 | FIELD_PREP(HDPTX_MODE_SEL, 0x0));
 
-		ret = rk_hdptx_tmds_ropll_mode_config(hdptx);
+		if (hdptx->hdmi_cfg.mode == PHY_MODE_HDMI_FRL)
+			ret = rk_hdptx_frl_lcpll_mode_config(hdptx);
+		else
+			ret = rk_hdptx_tmds_ropll_mode_config(hdptx);
+
 		if (ret)
 			rk_hdptx_phy_consumer_put(hdptx, true);
 	}
@@ -1477,16 +1779,49 @@ static int rk_hdptx_phy_verify_hdmi_config(struct rk_hdptx_phy *hdptx,
 {
 	int i;
 
-	if (!hdmi_in->tmds_char_rate || hdmi_in->tmds_char_rate > HDMI20_MAX_RATE)
-		return -EINVAL;
+	if (hdptx->hdmi_cfg.mode == PHY_MODE_HDMI_FRL) {
+		unsigned long long frl_rate = 100000000ULL * hdmi_in->frl.lanes *
+					      hdmi_in->frl.rate_per_lane;
 
-	for (i = 0; i < ARRAY_SIZE(rk_hdptx_tmds_ropll_cfg); i++)
-		if (hdmi_in->tmds_char_rate == rk_hdptx_tmds_ropll_cfg[i].rate)
+		switch (hdmi_in->frl.rate_per_lane) {
+		case 3:
+		case 6:
+		case 8:
+		case 10:
+		case 12:
 			break;
+		default:
+			return -EINVAL;
+		}
 
-	if (i == ARRAY_SIZE(rk_hdptx_tmds_ropll_cfg) &&
-	    !rk_hdptx_phy_clk_pll_calc(hdmi_in->tmds_char_rate, NULL))
-		return -EINVAL;
+		if (!hdmi_in->frl.lanes || hdmi_in->frl.lanes > 4)
+			return -EINVAL;
+
+		if (frl_rate != FRL_8G4L_RATE) {
+			for (i = 0; i < ARRAY_SIZE(rk_hdptx_frl_lcpll_cfg); i++)
+				if (frl_rate == rk_hdptx_frl_lcpll_cfg[i].rate)
+					break;
+			if (i == ARRAY_SIZE(rk_hdptx_frl_lcpll_cfg))
+				return -EINVAL;
+		}
+
+		if (hdmi_out)
+			hdmi_out->rate = frl_rate;
+	} else {
+		if (!hdmi_in->tmds_char_rate || hdmi_in->tmds_char_rate > HDMI20_MAX_RATE)
+			return -EINVAL;
+
+		for (i = 0; i < ARRAY_SIZE(rk_hdptx_tmds_ropll_cfg); i++)
+			if (hdmi_in->tmds_char_rate == rk_hdptx_tmds_ropll_cfg[i].rate)
+				break;
+
+		if (i == ARRAY_SIZE(rk_hdptx_tmds_ropll_cfg) &&
+		    !rk_hdptx_phy_clk_pll_calc(hdmi_in->tmds_char_rate, NULL))
+			return -EINVAL;
+
+		if (hdmi_out)
+			hdmi_out->rate = hdmi_in->tmds_char_rate;
+	}
 
 	switch (hdmi_in->bpc) {
 	case 0:
@@ -1499,10 +1834,8 @@ static int rk_hdptx_phy_verify_hdmi_config(struct rk_hdptx_phy *hdptx,
 		return -EINVAL;
 	}
 
-	if (hdmi_out) {
-		hdmi_out->rate = hdmi_in->tmds_char_rate;
+	if (hdmi_out)
 		hdmi_out->bpc = hdmi_in->bpc ?: 8;
-	}
 
 	return 0;
 }
@@ -1762,6 +2095,31 @@ static int rk_hdptx_phy_set_voltages(struct rk_hdptx_phy *hdptx,
 	return 0;
 }
 
+static int rk_hdptx_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
+{
+	struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy);
+
+	if (mode == PHY_MODE_DP)
+		return 0;
+
+	if (mode != PHY_MODE_HDMI) {
+		dev_err(&phy->dev, "invalid PHY mode: %d\n", mode);
+		return -EINVAL;
+	}
+
+	switch (submode) {
+	case PHY_MODE_HDMI_TMDS:
+	case PHY_MODE_HDMI_FRL:
+		hdptx->hdmi_cfg.mode = submode;
+		break;
+	default:
+		dev_err(&phy->dev, "invalid HDMI mode: %d\n", submode);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int rk_hdptx_phy_configure(struct phy *phy, union phy_configure_opts *opts)
 {
 	struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy);
@@ -1829,6 +2187,7 @@ static int rk_hdptx_phy_validate(struct phy *phy, enum phy_mode mode,
 static const struct phy_ops rk_hdptx_phy_ops = {
 	.power_on  = rk_hdptx_phy_power_on,
 	.power_off = rk_hdptx_phy_power_off,
+	.set_mode = rk_hdptx_phy_set_mode,
 	.configure = rk_hdptx_phy_configure,
 	.validate  = rk_hdptx_phy_validate,
 	.owner	   = THIS_MODULE,
@@ -1857,17 +2216,62 @@ static void rk_hdptx_phy_clk_unprepare(struct clk_hw *hw)
 
 static u64 rk_hdptx_phy_clk_calc_rate_from_pll_cfg(struct rk_hdptx_phy *hdptx)
 {
+	struct lcpll_config lcpll_hw;
 	struct ropll_config ropll_hw;
 	u64 fout, sdm;
 	u32 mode, val;
-	int ret;
+	int ret, i;
 
 	ret = regmap_read(hdptx->regmap, CMN_REG(0008), &mode);
 	if (ret)
 		return 0;
 
-	if (mode & LCPLL_LCVCO_MODE_EN_MASK)
+	if (mode & LCPLL_LCVCO_MODE_EN_MASK) {
+		ret = regmap_read(hdptx->regmap, CMN_REG(0020), &val);
+		if (ret)
+			return 0;
+		lcpll_hw.pms_mdiv = val;
+
+		ret = regmap_read(hdptx->regmap, CMN_REG(0023), &val);
+		if (ret)
+			return 0;
+		lcpll_hw.pms_sdiv = val & 0xf;
+
+		ret = regmap_read(hdptx->regmap, CMN_REG(002B), &val);
+		if (ret)
+			return 0;
+		lcpll_hw.sdm_num_sign = val;
+
+		ret = regmap_read(hdptx->regmap, CMN_REG(002C), &val);
+		if (ret)
+			return 0;
+		lcpll_hw.sdm_num = val;
+
+		ret = regmap_read(hdptx->regmap, CMN_REG(002A), &val);
+		if (ret)
+			return 0;
+		lcpll_hw.sdm_deno = val;
+
+		ret = regmap_read(hdptx->regmap, CMN_REG(002D), &val);
+		if (ret)
+			return 0;
+		lcpll_hw.sdc_n = (val & LCPLL_SDC_N_MASK) >> 1;
+
+		for (i = 0; i < ARRAY_SIZE(rk_hdptx_frl_lcpll_cfg); i++) {
+			const struct lcpll_config *cfg = &rk_hdptx_frl_lcpll_cfg[i];
+
+			if (cfg->pms_mdiv == lcpll_hw.pms_mdiv &&
+			    cfg->pms_sdiv == lcpll_hw.pms_sdiv &&
+			    cfg->sdm_num_sign == lcpll_hw.sdm_num_sign &&
+			    cfg->sdm_num == lcpll_hw.sdm_num &&
+			    cfg->sdm_deno == lcpll_hw.sdm_deno &&
+			    cfg->sdc_n == lcpll_hw.sdc_n)
+				return cfg->rate;
+		}
+
+		dev_dbg(hdptx->dev, "%s no FRL match found\n", __func__);
 		return 0;
+	}
 
 	ret = regmap_read(hdptx->regmap, CMN_REG(0051), &val);
 	if (ret)
@@ -1944,6 +2348,9 @@ static unsigned long rk_hdptx_phy_clk_recalc_rate(struct clk_hw *hw,
 
 	rate = rk_hdptx_phy_clk_calc_rate_from_pll_cfg(hdptx);
 
+	if (hdptx->hdmi_cfg.mode == PHY_MODE_HDMI_FRL)
+		return rate;
+
 	return DIV_ROUND_CLOSEST_ULL(rate * 8, hdptx->hdmi_cfg.bpc);
 }
 
@@ -1952,6 +2359,9 @@ static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
 {
 	struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);
 
+	if (hdptx->hdmi_cfg.mode == PHY_MODE_HDMI_FRL)
+		return hdptx->hdmi_cfg.rate;
+
 	/*
 	 * FIXME: Temporarily allow altering TMDS char rate via CCF.
 	 * To be dropped as soon as the RK DW HDMI QP bridge driver
@@ -1980,23 +2390,26 @@ static int rk_hdptx_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate,
 				     unsigned long parent_rate)
 {
 	struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);
-	unsigned long long tmds_rate = DIV_ROUND_CLOSEST_ULL(rate * hdptx->hdmi_cfg.bpc, 8);
+	unsigned long long link_rate = rate;
+
+	if (hdptx->hdmi_cfg.mode != PHY_MODE_HDMI_FRL)
+		link_rate = DIV_ROUND_CLOSEST_ULL(rate * hdptx->hdmi_cfg.bpc, 8);
 
-	/* Revert any unlikely TMDS char rate change since round_rate() */
-	if (hdptx->hdmi_cfg.rate != tmds_rate) {
+	/* Revert any unlikely link rate change since round_rate() */
+	if (hdptx->hdmi_cfg.rate != link_rate) {
 		dev_warn(hdptx->dev, "Reverting unexpected rate change from %llu to %llu\n",
-			 tmds_rate, hdptx->hdmi_cfg.rate);
-		hdptx->hdmi_cfg.rate = tmds_rate;
+			 link_rate, hdptx->hdmi_cfg.rate);
+		hdptx->hdmi_cfg.rate = link_rate;
 	}
 
 	/*
-	 * The TMDS char rate would be normally programmed in HW during
+	 * The link rate would be normally programmed in HW during
 	 * phy_ops.power_on() or clk_ops.prepare() callbacks, but it might
 	 * happen that the former gets fired too late, i.e. after this call,
 	 * while the latter being executed only once, i.e. when clock remains
 	 * in the prepared state during rate changes.
 	 */
-	return rk_hdptx_tmds_ropll_cmn_config(hdptx);
+	return rk_hdptx_pll_cmn_config(hdptx);
 }
 
 static const struct clk_ops hdptx_phy_clk_ops = {

-- 
2.50.1



From cristian.ciocaltea at collabora.com  Mon Aug 18 12:07:09 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Mon, 18 Aug 2025 22:07:09 +0300
Subject: [PATCH v2 01/14] phy: hdmi: Add HDMI 2.1 FRL configuration
 options
In-Reply-To: <3d796f6c-d1d0-4499-8e63-bd37bfcc7c3a@oss.qualcomm.com>
References: <20250805-phy-hdptx-frl-v2-0-d118bd4b6e0b@collabora.com>
 <20250805-phy-hdptx-frl-v2-1-d118bd4b6e0b@collabora.com>
 <3d796f6c-d1d0-4499-8e63-bd37bfcc7c3a@oss.qualcomm.com>
Message-ID: <a3632629-188f-4645-a8b9-825075684194@collabora.com>

Hi Dmitry,

On 8/16/25 1:23 AM, Dmitry Baryshkov wrote:
> On 05/08/2025 14:56, Cristian Ciocaltea wrote:
>> Add support for configuring the Fixed Rate Link (FRL) mode for HDMI
>> PHYs.
>>
>> For improved clarity, also rename existing HDMI mode to HDMI_TMDS.
>> Since this mode is currently not being used explicitly, no further
>> changes are needed.
> 
> 
> I'd say, this need some explanation, especially for those who don't have access 
> to the HDMI standard. Please mention that FRL is an alternative to the traditional TMDS mode, etc.

Done in v3 [1].

> 
>>
>> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
>> ---
>>   include/linux/phy/phy-hdmi.h | 14 ++++++++++++--
>>   include/linux/phy/phy.h      |  3 ++-
>>   2 files changed, 14 insertions(+), 3 deletions(-)
>>
>> diff --git a/include/linux/phy/phy-hdmi.h b/include/linux/phy/phy-hdmi.h
>> index f0ec963c6e84f1b7728acafc824dff191c6b873d..0b26472d8defcc9ded142d4283e29861dc2b3746 100644
>> --- a/include/linux/phy/phy-hdmi.h
>> +++ b/include/linux/phy/phy-hdmi.h
>> @@ -6,16 +6,26 @@
>>   #ifndef __PHY_HDMI_H_
>>   #define __PHY_HDMI_H_
>>   +#include <linux/types.h>
>> +
>>   /**
>>    * struct phy_configure_opts_hdmi - HDMI configuration set
>> - * @tmds_char_rate: HDMI TMDS Character Rate in Hertz.
>>    * @bpc: Bits per color channel.
>> + * @tmds_char_rate: HDMI TMDS Character Rate in Hertz.
>> + * @frl.rate_per_lane: HDMI FRL Rate per Lane in Gbps.
>> + * @frl.lanes: HDMI FRL lanes count.
>>    *
>>    * This structure is used to represent the configuration state of a HDMI phy.
>>    */
>>   struct phy_configure_opts_hdmi {
>> -    unsigned long long tmds_char_rate;
>>       unsigned int bpc;
>> +    union {
>> +        unsigned long long tmds_char_rate;
>> +        struct {
>> +            u8 rate_per_lane;
>> +            u8 lanes;
>> +        } frl;
>> +    };
>>   };
>>     #endif /* __PHY_HDMI_H_ */
>> diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
>> index 13add0c2c40721fe9ca3f0350d13c035cd25af45..04c84c1dbd6dac55fd04c54203cff4f9d939d970 100644
>> --- a/include/linux/phy/phy.h
>> +++ b/include/linux/phy/phy.h
>> @@ -44,7 +44,8 @@ enum phy_mode {
>>       PHY_MODE_SATA,
>>       PHY_MODE_LVDS,
>>       PHY_MODE_DP,
>> -    PHY_MODE_HDMI,
>> +    PHY_MODE_HDMI_TMDS,
>> +    PHY_MODE_HDMI_FRL,
> 
> I'd maybe suggest keeping PHY_MODE_HDMI and having two submodes: one for TMDS (default), one for FRL.

Also done in v3 [1].

Thank you for the review!

Regards,
Cristian

> 
>>   };
>>     enum phy_media {
>>

[1] https://lore.kernel.org/all/20250818-phy-hdptx-frl-v3-0-c79997d8bb2b at collabora.com/


From devnull+michael.riesch.collabora.com at kernel.org  Mon Aug 18 16:00:35 2025
From: devnull+michael.riesch.collabora.com at kernel.org (Michael Riesch via B4 Relay)
Date: Tue, 19 Aug 2025 01:00:35 +0200
Subject: [PATCH v2 1/7] dt-bindings: soc: rockchip: add rk3588 csidphy grf
 syscon
In-Reply-To: <20250616-rk3588-csi-dphy-v2-0-7a94f079b712@collabora.com>
References: <20250616-rk3588-csi-dphy-v2-0-7a94f079b712@collabora.com>
Message-ID: <20250616-rk3588-csi-dphy-v2-1-7a94f079b712@collabora.com>

From: Michael Riesch <michael.riesch at collabora.com>

Add CSIDPHY GRF syscon compatible for the Rockchip RK3588.

Acked-by: Rob Herring (Arm) <robh at kernel.org>
Signed-off-by: Michael Riesch <michael.riesch at collabora.com>
---
 Documentation/devicetree/bindings/soc/rockchip/grf.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/soc/rockchip/grf.yaml b/Documentation/devicetree/bindings/soc/rockchip/grf.yaml
index 1ab0b092e2a5..b6e04e6491e9 100644
--- a/Documentation/devicetree/bindings/soc/rockchip/grf.yaml
+++ b/Documentation/devicetree/bindings/soc/rockchip/grf.yaml
@@ -47,6 +47,7 @@ properties:
               - rockchip,rk3576-vop-grf
               - rockchip,rk3588-bigcore0-grf
               - rockchip,rk3588-bigcore1-grf
+              - rockchip,rk3588-csidphy-grf
               - rockchip,rk3588-dcphy-grf
               - rockchip,rk3588-hdptxphy-grf
               - rockchip,rk3588-ioc

-- 
2.39.5




From devnull+michael.riesch.collabora.com at kernel.org  Mon Aug 18 16:00:34 2025
From: devnull+michael.riesch.collabora.com at kernel.org (Michael Riesch via B4 Relay)
Date: Tue, 19 Aug 2025 01:00:34 +0200
Subject: [PATCH v2 0/7] phy: rockchip: phy-rockchip-inno-csidphy: add
 support for rk3588 variant
Message-ID: <20250616-rk3588-csi-dphy-v2-0-7a94f079b712@collabora.com>

Habidere,

The Rockchip RK3588 features two MIPI CSI-2 DPHYs (not to be confused with
the two combo MIPI DSI/CSI CPHY/DPHY blocks). The CSI-2 DPHYs can be
supported using the existing phy-rockchip-inno-csidphy driver, the notable
differences being
 - the control bits in the GRF
 - the additional reset line
This patch series adds support for this variant.

As you may have guessed, this is part of the efforts to bring the support
for the RK3588 Video Capture (VICAP) unit mainline.

Looking forward to your comments!

Signed-off-by: Michael Riesch <michael.riesch at collabora.com>
---
Changes in v2:
- rebased onto v6.17-rc1
- added patch that makes 'power-domains' non-required (Diederik)
- added patch that allows for different sets of resets (Neil)
- introduced name for additional reset line (Neil)
- fixed example in bindings (Rob, Diederik)
- Link to v1: https://lore.kernel.org/r/20250616-rk3588-csi-dphy-v1-0-84eb3b2a736c at collabora.com

---
Michael Riesch (7):
      dt-bindings: soc: rockchip: add rk3588 csidphy grf syscon
      dt-bindings: phy: rockchip-inno-csi-dphy: make power-domains non-required
      dt-bindings: phy: rockchip-inno-csi-dphy: add rk3588 variant
      phy: rockchip: phy-rockchip-inno-csidphy: allow writes to grf register 0
      phy: rockchip: phy-rockchip-inno-csidphy: allow for different reset lines
      phy: rockchip: phy-rockchip-inno-csidphy: add support for rk3588 variant
      arm64: dts: rockchip: add mipi csi-2 dphy nodes to rk3588

 .../bindings/phy/rockchip-inno-csi-dphy.yaml       | 61 ++++++++++++++++++--
 .../devicetree/bindings/soc/rockchip/grf.yaml      |  1 +
 arch/arm64/boot/dts/rockchip/rk3588-base.dtsi      | 33 +++++++++++
 drivers/phy/rockchip/phy-rockchip-inno-csidphy.c   | 67 ++++++++++++++++++++--
 4 files changed, 151 insertions(+), 11 deletions(-)
---
base-commit: 8f5ae30d69d7543eee0d70083daf4de8fe15d585
change-id: 20250616-rk3588-csi-dphy-c9ed2ad4cd9f

Best regards,
-- 
Michael Riesch <michael.riesch at collabora.com>




From devnull+michael.riesch.collabora.com at kernel.org  Mon Aug 18 16:00:37 2025
From: devnull+michael.riesch.collabora.com at kernel.org (Michael Riesch via B4 Relay)
Date: Tue, 19 Aug 2025 01:00:37 +0200
Subject: [PATCH v2 3/7] dt-bindings: phy: rockchip-inno-csi-dphy: add
 rk3588 variant
In-Reply-To: <20250616-rk3588-csi-dphy-v2-0-7a94f079b712@collabora.com>
References: <20250616-rk3588-csi-dphy-v2-0-7a94f079b712@collabora.com>
Message-ID: <20250616-rk3588-csi-dphy-v2-3-7a94f079b712@collabora.com>

From: Michael Riesch <michael.riesch at collabora.com>

The Rockchip RK3588 variant of the CSI-2 DPHY features two reset lines.
Add the variant and allow for the additional reset.

Signed-off-by: Michael Riesch <michael.riesch at collabora.com>
---
 .../bindings/phy/rockchip-inno-csi-dphy.yaml       | 60 ++++++++++++++++++++--
 1 file changed, 56 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/rockchip-inno-csi-dphy.yaml b/Documentation/devicetree/bindings/phy/rockchip-inno-csi-dphy.yaml
index 42da616ae2e3..10197cc9dc47 100644
--- a/Documentation/devicetree/bindings/phy/rockchip-inno-csi-dphy.yaml
+++ b/Documentation/devicetree/bindings/phy/rockchip-inno-csi-dphy.yaml
@@ -21,6 +21,7 @@ properties:
       - rockchip,rk3326-csi-dphy
       - rockchip,rk3368-csi-dphy
       - rockchip,rk3568-csi-dphy
+      - rockchip,rk3588-csi-dphy
 
   reg:
     maxItems: 1
@@ -39,18 +40,50 @@ properties:
     maxItems: 1
 
   resets:
-    items:
-      - description: exclusive PHY reset line
+    minItems: 1
+    maxItems: 2
 
   reset-names:
-    items:
-      - const: apb
+    minItems: 1
+    maxItems: 2
 
   rockchip,grf:
     $ref: /schemas/types.yaml#/definitions/phandle
     description:
       Some additional phy settings are access through GRF regs.
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - rockchip,px30-csi-dphy
+              - rockchip,rk1808-csi-dphy
+              - rockchip,rk3326-csi-dphy
+              - rockchip,rk3368-csi-dphy
+              - rockchip,rk3568-csi-dphy
+    then:
+      properties:
+        resets:
+          items:
+            - description: exclusive PHY reset line
+
+        reset-names:
+          items:
+            - const: apb
+    else:
+      properties:
+        resets:
+          items:
+            - description: APB reset line
+            - description: PHY reset line
+
+        reset-names:
+          items:
+            - const: apb
+            - const: phy
+
 required:
   - compatible
   - reg
@@ -77,3 +110,22 @@ examples:
         reset-names = "apb";
         rockchip,grf = <&grf>;
     };
+  - |
+    #include <dt-bindings/clock/rockchip,rk3588-cru.h>
+    #include <dt-bindings/reset/rockchip,rk3588-cru.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        phy at fedc0000 {
+            compatible = "rockchip,rk3588-csi-dphy";
+            reg = <0x0 0xfedc0000 0x0 0x8000>;
+            clocks = <&cru PCLK_CSIPHY0>;
+            clock-names = "pclk";
+            #phy-cells = <0>;
+            resets = <&cru SRST_P_CSIPHY0>, <&cru SRST_CSIPHY0>;
+            reset-names = "apb", "phy";
+            rockchip,grf = <&csidphy0_grf>;
+        };
+    };

-- 
2.39.5




From devnull+michael.riesch.collabora.com at kernel.org  Mon Aug 18 16:00:41 2025
From: devnull+michael.riesch.collabora.com at kernel.org (Michael Riesch via B4 Relay)
Date: Tue, 19 Aug 2025 01:00:41 +0200
Subject: [PATCH v2 7/7] arm64: dts: rockchip: add mipi csi-2 dphy nodes to
 rk3588
In-Reply-To: <20250616-rk3588-csi-dphy-v2-0-7a94f079b712@collabora.com>
References: <20250616-rk3588-csi-dphy-v2-0-7a94f079b712@collabora.com>
Message-ID: <20250616-rk3588-csi-dphy-v2-7-7a94f079b712@collabora.com>

From: Michael Riesch <michael.riesch at collabora.com>

The Rockchip RK3588 features two MIPI CSI-2 DPHYs. Add the device
tree nodes for them.

Signed-off-by: Michael Riesch <michael.riesch at collabora.com>
---
 arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 33 +++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
index 70f03e68ba55..eedf93247e9c 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
@@ -621,6 +621,16 @@ php_grf: syscon at fd5b0000 {
 		reg = <0x0 0xfd5b0000 0x0 0x1000>;
 	};
 
+	csidphy0_grf: syscon at fd5b4000 {
+		compatible = "rockchip,rk3588-csidphy-grf", "syscon";
+		reg = <0x0 0xfd5b4000 0x0 0x1000>;
+	};
+
+	csidphy1_grf: syscon at fd5b5000 {
+		compatible = "rockchip,rk3588-csidphy-grf", "syscon";
+		reg = <0x0 0xfd5b5000 0x0 0x1000>;
+	};
+
 	pipe_phy0_grf: syscon at fd5bc000 {
 		compatible = "rockchip,rk3588-pipe-phy-grf", "syscon";
 		reg = <0x0 0xfd5bc000 0x0 0x100>;
@@ -3052,6 +3062,29 @@ mipidcphy1: phy at fedb0000 {
 			 <&cru SRST_S_MIPI_DCPHY1>;
 		reset-names = "m_phy", "apb", "grf", "s_phy";
 		#phy-cells = <1>;
+	};
+
+	csi_dphy0: phy at fedc0000 {
+		compatible = "rockchip,rk3588-csi-dphy";
+		reg = <0x0 0xfedc0000 0x0 0x8000>;
+		clocks = <&cru PCLK_CSIPHY0>;
+		clock-names = "pclk";
+		#phy-cells = <0>;
+		resets = <&cru SRST_P_CSIPHY0>, <&cru SRST_CSIPHY0>;
+		reset-names = "apb", "phy";
+		rockchip,grf = <&csidphy0_grf>;
+		status = "disabled";
+	};
+
+	csi_dphy1: phy at fedc8000 {
+		compatible = "rockchip,rk3588-csi-dphy";
+		reg = <0x0 0xfedc8000 0x0 0x8000>;
+		clocks = <&cru PCLK_CSIPHY1>;
+		clock-names = "pclk";
+		#phy-cells = <0>;
+		resets = <&cru SRST_P_CSIPHY1>, <&cru SRST_CSIPHY1>;
+		reset-names = "apb", "phy";
+		rockchip,grf = <&csidphy1_grf>;
 		status = "disabled";
 	};
 

-- 
2.39.5




From devnull+michael.riesch.collabora.com at kernel.org  Mon Aug 18 16:00:36 2025
From: devnull+michael.riesch.collabora.com at kernel.org (Michael Riesch via B4 Relay)
Date: Tue, 19 Aug 2025 01:00:36 +0200
Subject: [PATCH v2 2/7] dt-bindings: phy: rockchip-inno-csi-dphy: make
 power-domains non-required
In-Reply-To: <20250616-rk3588-csi-dphy-v2-0-7a94f079b712@collabora.com>
References: <20250616-rk3588-csi-dphy-v2-0-7a94f079b712@collabora.com>
Message-ID: <20250616-rk3588-csi-dphy-v2-2-7a94f079b712@collabora.com>

From: Michael Riesch <michael.riesch at collabora.com>

There are variants of the Rockchip Innosilicon CSI DPHY (e.g., the RK3568
variant) that are powered on by default as they are part of the ALIVE power
domain.
Remove 'power-domains' from the required properties in order to avoid false
negatives.

Fixes: 22c8e0a69b7f ("dt-bindings: phy: add compatible for rk356x to rockchip-inno-csi-dphy")
Cc: stable at kernel.org
Signed-off-by: Michael Riesch <michael.riesch at collabora.com>
---
 Documentation/devicetree/bindings/phy/rockchip-inno-csi-dphy.yaml | 1 -
 1 file changed, 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/phy/rockchip-inno-csi-dphy.yaml b/Documentation/devicetree/bindings/phy/rockchip-inno-csi-dphy.yaml
index 5ac994b3c0aa..42da616ae2e3 100644
--- a/Documentation/devicetree/bindings/phy/rockchip-inno-csi-dphy.yaml
+++ b/Documentation/devicetree/bindings/phy/rockchip-inno-csi-dphy.yaml
@@ -57,7 +57,6 @@ required:
   - clocks
   - clock-names
   - '#phy-cells'
-  - power-domains
   - resets
   - reset-names
   - rockchip,grf

-- 
2.39.5




From devnull+michael.riesch.collabora.com at kernel.org  Mon Aug 18 16:00:40 2025
From: devnull+michael.riesch.collabora.com at kernel.org (Michael Riesch via B4 Relay)
Date: Tue, 19 Aug 2025 01:00:40 +0200
Subject: [PATCH v2 6/7] phy: rockchip: phy-rockchip-inno-csidphy: add
 support for rk3588 variant
In-Reply-To: <20250616-rk3588-csi-dphy-v2-0-7a94f079b712@collabora.com>
References: <20250616-rk3588-csi-dphy-v2-0-7a94f079b712@collabora.com>
Message-ID: <20250616-rk3588-csi-dphy-v2-6-7a94f079b712@collabora.com>

From: Michael Riesch <michael.riesch at collabora.com>

The Rockchip RK3588 MIPI CSI-2 DPHY can be supported using the existing
phy-rockchip-inno-csidphy driver, the notable differences being
 - the control bits in the GRF
 - the additional reset line
Add support for this variant.

Signed-off-by: Michael Riesch <michael.riesch at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-inno-csidphy.c | 28 ++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/drivers/phy/rockchip/phy-rockchip-inno-csidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-csidphy.c
index 6c4ddcd7e5de..c79fb53d8ee5 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-csidphy.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-csidphy.c
@@ -30,6 +30,8 @@
 #define RK3568_GRF_VI_CON0		0x0340
 #define RK3568_GRF_VI_CON1		0x0344
 
+#define RK3588_CSIDPHY_GRF_CON0		0x0000
+
 /* PHY */
 #define CSIDPHY_CTRL_LANE_ENABLE		0x00
 #define CSIDPHY_CTRL_LANE_ENABLE_CK		BIT(6)
@@ -117,6 +119,12 @@ static const struct dphy_reg rk3568_grf_dphy_regs[] = {
 	[GRF_DPHY_CSIPHY_CLKLANE_EN] = PHY_REG(RK3568_GRF_VI_CON0, 1, 8),
 };
 
+static const struct dphy_reg rk3588_grf_dphy_regs[] = {
+	[GRF_DPHY_CSIPHY_FORCERXMODE] = PHY_REG(RK3588_CSIDPHY_GRF_CON0, 4, 0),
+	[GRF_DPHY_CSIPHY_DATALANE_EN] = PHY_REG(RK3588_CSIDPHY_GRF_CON0, 4, 4),
+	[GRF_DPHY_CSIPHY_CLKLANE_EN] = PHY_REG(RK3588_CSIDPHY_GRF_CON0, 1, 8),
+};
+
 struct hsfreq_range {
 	u32 range_h;
 	u8 cfg_bit;
@@ -183,6 +191,11 @@ static const char *const rk3368_reset_names[] = {
 	"apb"
 };
 
+static const char *const rk3588_reset_names[] = {
+	"apb",
+	"phy"
+};
+
 static void rockchip_inno_csidphy_ths_settle(struct rockchip_inno_csidphy *priv,
 					     int hsfreq, int offset)
 {
@@ -390,6 +403,17 @@ static const struct dphy_drv_data rk3568_mipidphy_drv_data = {
 	.resets_num = ARRAY_SIZE(rk3368_reset_names),
 };
 
+static const struct dphy_drv_data rk3588_mipidphy_drv_data = {
+	.pwrctl_offset = -1,
+	.ths_settle_offset = RK3568_CSIDPHY_CLK_WR_THS_SETTLE,
+	.calib_offset = RK3568_CSIDPHY_CLK_CALIB_EN,
+	.hsfreq_ranges = rk1808_mipidphy_hsfreq_ranges,
+	.num_hsfreq_ranges = ARRAY_SIZE(rk1808_mipidphy_hsfreq_ranges),
+	.grf_regs = rk3588_grf_dphy_regs,
+	.resets = rk3588_reset_names,
+	.resets_num = ARRAY_SIZE(rk3588_reset_names),
+};
+
 static const struct of_device_id rockchip_inno_csidphy_match_id[] = {
 	{
 		.compatible = "rockchip,px30-csi-dphy",
@@ -411,6 +435,10 @@ static const struct of_device_id rockchip_inno_csidphy_match_id[] = {
 		.compatible = "rockchip,rk3568-csi-dphy",
 		.data = &rk3568_mipidphy_drv_data,
 	},
+	{
+		.compatible = "rockchip,rk3588-csi-dphy",
+		.data = &rk3588_mipidphy_drv_data,
+	},
 	{}
 };
 MODULE_DEVICE_TABLE(of, rockchip_inno_csidphy_match_id);

-- 
2.39.5




From devnull+michael.riesch.collabora.com at kernel.org  Mon Aug 18 16:00:39 2025
From: devnull+michael.riesch.collabora.com at kernel.org (Michael Riesch via B4 Relay)
Date: Tue, 19 Aug 2025 01:00:39 +0200
Subject: [PATCH v2 5/7] phy: rockchip: phy-rockchip-inno-csidphy: allow for
 different reset lines
In-Reply-To: <20250616-rk3588-csi-dphy-v2-0-7a94f079b712@collabora.com>
References: <20250616-rk3588-csi-dphy-v2-0-7a94f079b712@collabora.com>
Message-ID: <20250616-rk3588-csi-dphy-v2-5-7a94f079b712@collabora.com>

From: Michael Riesch <michael.riesch at collabora.com>

The RK3588 MIPI CSI-2 DPHY variant requires two reset lines. Add support
for different sets of reset lines to the phy-rockchip-inno-csidphy driver
as preparation for the introduction of the RK3588 variant.

Signed-off-by: Michael Riesch <michael.riesch at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-inno-csidphy.c | 34 +++++++++++++++++++++---
 1 file changed, 30 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-inno-csidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-csidphy.c
index 75533d071025..6c4ddcd7e5de 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-csidphy.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-csidphy.c
@@ -67,6 +67,8 @@
 #define RK1808_CSIDPHY_CLK_CALIB_EN		0x168
 #define RK3568_CSIDPHY_CLK_CALIB_EN		0x168
 
+#define RESETS_MAX				2
+
 /*
  * The higher 16-bit of this register is used for write protection
  * only if BIT(x + 16) set to 1 the BIT(x) can be written.
@@ -127,6 +129,8 @@ struct dphy_drv_data {
 	const struct hsfreq_range *hsfreq_ranges;
 	int num_hsfreq_ranges;
 	const struct dphy_reg *grf_regs;
+	const char *const *resets;
+	unsigned int resets_num;
 };
 
 struct rockchip_inno_csidphy {
@@ -134,7 +138,8 @@ struct rockchip_inno_csidphy {
 	void __iomem *phy_base;
 	struct clk *pclk;
 	struct regmap *grf;
-	struct reset_control *rst;
+	struct reset_control_bulk_data resets[RESETS_MAX];
+	unsigned int resets_num;
 	const struct dphy_drv_data *drv_data;
 	struct phy_configure_opts_mipi_dphy config;
 	u8 hsfreq;
@@ -174,6 +179,10 @@ static const struct hsfreq_range rk3368_mipidphy_hsfreq_ranges[] = {
 	{1249, 0x0c}, {1349, 0x0d}, {1500, 0x0e}
 };
 
+static const char *const rk3368_reset_names[] = {
+	"apb"
+};
+
 static void rockchip_inno_csidphy_ths_settle(struct rockchip_inno_csidphy *priv,
 					     int hsfreq, int offset)
 {
@@ -344,6 +353,8 @@ static const struct dphy_drv_data rk1808_mipidphy_drv_data = {
 	.hsfreq_ranges = rk1808_mipidphy_hsfreq_ranges,
 	.num_hsfreq_ranges = ARRAY_SIZE(rk1808_mipidphy_hsfreq_ranges),
 	.grf_regs = rk1808_grf_dphy_regs,
+	.resets = rk3368_reset_names,
+	.resets_num = ARRAY_SIZE(rk3368_reset_names),
 };
 
 static const struct dphy_drv_data rk3326_mipidphy_drv_data = {
@@ -353,6 +364,8 @@ static const struct dphy_drv_data rk3326_mipidphy_drv_data = {
 	.hsfreq_ranges = rk3326_mipidphy_hsfreq_ranges,
 	.num_hsfreq_ranges = ARRAY_SIZE(rk3326_mipidphy_hsfreq_ranges),
 	.grf_regs = rk3326_grf_dphy_regs,
+	.resets = rk3368_reset_names,
+	.resets_num = ARRAY_SIZE(rk3368_reset_names),
 };
 
 static const struct dphy_drv_data rk3368_mipidphy_drv_data = {
@@ -362,6 +375,8 @@ static const struct dphy_drv_data rk3368_mipidphy_drv_data = {
 	.hsfreq_ranges = rk3368_mipidphy_hsfreq_ranges,
 	.num_hsfreq_ranges = ARRAY_SIZE(rk3368_mipidphy_hsfreq_ranges),
 	.grf_regs = rk3368_grf_dphy_regs,
+	.resets = rk3368_reset_names,
+	.resets_num = ARRAY_SIZE(rk3368_reset_names),
 };
 
 static const struct dphy_drv_data rk3568_mipidphy_drv_data = {
@@ -371,6 +386,8 @@ static const struct dphy_drv_data rk3568_mipidphy_drv_data = {
 	.hsfreq_ranges = rk1808_mipidphy_hsfreq_ranges,
 	.num_hsfreq_ranges = ARRAY_SIZE(rk1808_mipidphy_hsfreq_ranges),
 	.grf_regs = rk3568_grf_dphy_regs,
+	.resets = rk3368_reset_names,
+	.resets_num = ARRAY_SIZE(rk3368_reset_names),
 };
 
 static const struct of_device_id rockchip_inno_csidphy_match_id[] = {
@@ -404,6 +421,7 @@ static int rockchip_inno_csidphy_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct phy_provider *phy_provider;
 	struct phy *phy;
+	int ret;
 
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
@@ -435,10 +453,18 @@ static int rockchip_inno_csidphy_probe(struct platform_device *pdev)
 		return PTR_ERR(priv->pclk);
 	}
 
-	priv->rst = devm_reset_control_get(dev, "apb");
-	if (IS_ERR(priv->rst)) {
+	if (priv->drv_data->resets_num > RESETS_MAX) {
+		dev_err(dev, "invalid number of resets\n");
+		return -EINVAL;
+	}
+	priv->resets_num = priv->drv_data->resets_num;
+	for (unsigned int i = 0; i < priv->resets_num; i++)
+		priv->resets[i].id = priv->drv_data->resets[i];
+	ret = devm_reset_control_bulk_get_exclusive(dev, priv->resets_num,
+						    priv->resets);
+	if (ret) {
 		dev_err(dev, "failed to get system reset control\n");
-		return PTR_ERR(priv->rst);
+		return ret;
 	}
 
 	phy = devm_phy_create(dev, NULL, &rockchip_inno_csidphy_ops);

-- 
2.39.5




From devnull+michael.riesch.collabora.com at kernel.org  Mon Aug 18 16:00:38 2025
From: devnull+michael.riesch.collabora.com at kernel.org (Michael Riesch via B4 Relay)
Date: Tue, 19 Aug 2025 01:00:38 +0200
Subject: [PATCH v2 4/7] phy: rockchip: phy-rockchip-inno-csidphy: allow
 writes to grf register 0
In-Reply-To: <20250616-rk3588-csi-dphy-v2-0-7a94f079b712@collabora.com>
References: <20250616-rk3588-csi-dphy-v2-0-7a94f079b712@collabora.com>
Message-ID: <20250616-rk3588-csi-dphy-v2-4-7a94f079b712@collabora.com>

From: Michael Riesch <michael.riesch at collabora.com>

The driver for the Rockchip MIPI CSI-2 DPHY uses GRF register offset
value 0 to sort out undefined registers. However, the RK3588 CSIDPHY GRF
this offset is perfectly fine (in fact, register 0 is the only one in
this register file).
Introduce a boolean variable to indicate valid registers and allow writes
to register 0.

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>
Signed-off-by: Michael Riesch <michael.riesch at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-inno-csidphy.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-inno-csidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-csidphy.c
index 2ab99e1d47eb..75533d071025 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-csidphy.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-csidphy.c
@@ -87,10 +87,11 @@ struct dphy_reg {
 	u32 offset;
 	u32 mask;
 	u32 shift;
+	u8 valid;
 };
 
 #define PHY_REG(_offset, _width, _shift) \
-	{ .offset = _offset, .mask = BIT(_width) - 1, .shift = _shift, }
+	{ .offset = _offset, .mask = BIT(_width) - 1, .shift = _shift, .valid = 1, }
 
 static const struct dphy_reg rk1808_grf_dphy_regs[] = {
 	[GRF_DPHY_CSIPHY_FORCERXMODE] = PHY_REG(RK1808_GRF_PD_VI_CON_OFFSET, 4, 0),
@@ -145,7 +146,7 @@ static inline void write_grf_reg(struct rockchip_inno_csidphy *priv,
 	const struct dphy_drv_data *drv_data = priv->drv_data;
 	const struct dphy_reg *reg = &drv_data->grf_regs[index];
 
-	if (reg->offset)
+	if (reg->valid)
 		regmap_write(priv->grf, reg->offset,
 			     HIWORD_UPDATE(value, reg->mask, reg->shift));
 }

-- 
2.39.5




From andre.przywara at arm.com  Mon Aug 18 17:15:22 2025
From: andre.przywara at arm.com (Andre Przywara)
Date: Tue, 19 Aug 2025 01:15:22 +0100
Subject: [PATCH] phy: sun4i-usb: drop num_phys assumption
Message-ID: <20250819001522.13011-1-andre.przywara@arm.com>

So far we set a number of expected Allwinner USB PHY instances for any
given compatible string, and would fail if we do not find every PHY
described properly in the DT (missing reset/PMU/clocks).
This is somewhat redundant, as the DT only describes the resources for
the implemented PHYs, but goes in line with being strict about firmware
descriptions, and rather fixing things in the driver code, based on the
compatible string.
However this causes issues when we make a mistake, like we did recently
on the A523: there are actually three USB PHYs, not two, as we assumed.
Changing the number in the driver and the compatible string would cause
all kinds of compatibility issues, both with older and newer DTs.

To avoid problems with newer kernels and older or newer DTs, we can change
the driver code to deduce the number of PHY instances from what's
described in the DT. This has the added advantage of not requiring new
compatible strings for new SoCs when just the number of PHYs change, which
already happened and might occur again in the future.

Drop the num_phys member from the config struct, and remove the fixed
number of PHYs from each SoC's config description. Then enumerate the
usb<x>_reset properties for all of the maximum four PHY instances, and
just stop once we cannot find such a property anymore.
The binding describes the reset property as mandatory for each PHY
instance, and each DT in the kernel tree matches exactly the num_phys
value in the current driver code, so we can rely on that.

Apart from being more future proof, this will solve the A523 mishap:
Older DTs would just describe two PHYs, whereas newer ones would feature
all three of them. In any case we would get a valid number, matching the
other nodes in the DT. Older kernels would always enumerate two PHYs,
which at least does not cause any regressions.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
Hi,

this is in response to Mikhail's patch series for adding USB3.0 support
for the Allwinner A523 SoC, which revealed the problem with the number
of PHYs begin wrong:
https://lore.kernel.org/linux-sunxi/20250816143117.4b86ecc6 at minigeek.lan/

Regression tested on A64 and H6.

Cheers,
Andre

 drivers/phy/allwinner/phy-sun4i-usb.c | 38 +++++++++------------------
 1 file changed, 13 insertions(+), 25 deletions(-)

diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c
index 8873aed3a52aa..59d38d88efb08 100644
--- a/drivers/phy/allwinner/phy-sun4i-usb.c
+++ b/drivers/phy/allwinner/phy-sun4i-usb.c
@@ -97,7 +97,6 @@
 #define POLL_TIME			msecs_to_jiffies(250)
 
 struct sun4i_usb_phy_cfg {
-	int num_phys;
 	int hsic_index;
 	u32 disc_thresh;
 	u32 hci_phy_ctl_clear;
@@ -115,6 +114,7 @@ struct sun4i_usb_phy_data {
 	const struct sun4i_usb_phy_cfg *cfg;
 	enum usb_dr_mode dr_mode;
 	spinlock_t reg_lock; /* guard access to phyctl reg */
+	int num_phys;
 	struct sun4i_usb_phy {
 		struct phy *phy;
 		void __iomem *pmu;
@@ -686,7 +686,7 @@ static struct phy *sun4i_usb_phy_xlate(struct device *dev,
 {
 	struct sun4i_usb_phy_data *data = dev_get_drvdata(dev);
 
-	if (args->args[0] >= data->cfg->num_phys)
+	if (args->args[0] >= data->num_phys)
 		return ERR_PTR(-ENODEV);
 
 	if (data->cfg->missing_phys & BIT(args->args[0]))
@@ -779,13 +779,22 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	for (i = 0; i < data->cfg->num_phys; i++) {
+	for (i = 0; i < MAX_PHYS; i++) {
 		struct sun4i_usb_phy *phy = data->phys + i;
 		char name[32];
 
 		if (data->cfg->missing_phys & BIT(i))
 			continue;
 
+		snprintf(name, sizeof(name), "usb%d_reset", i);
+		phy->reset = devm_reset_control_get(dev, name);
+		if (IS_ERR(phy->reset)) {
+			if (PTR_ERR(phy->reset) == -ENOENT)
+				break;
+			dev_err(dev, "failed to get reset %s\n", name);
+			return PTR_ERR(phy->reset);
+		}
+
 		snprintf(name, sizeof(name), "usb%d_vbus", i);
 		phy->vbus = devm_regulator_get_optional(dev, name);
 		if (IS_ERR(phy->vbus)) {
@@ -828,13 +837,6 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
 			}
 		}
 
-		snprintf(name, sizeof(name), "usb%d_reset", i);
-		phy->reset = devm_reset_control_get(dev, name);
-		if (IS_ERR(phy->reset)) {
-			dev_err(dev, "failed to get reset %s\n", name);
-			return PTR_ERR(phy->reset);
-		}
-
 		if (i || data->cfg->phy0_dual_route) { /* No pmu for musb */
 			snprintf(name, sizeof(name), "pmu%d", i);
 			phy->pmu = devm_platform_ioremap_resource_byname(pdev, name);
@@ -851,6 +853,7 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
 		phy->index = i;
 		phy_set_drvdata(phy->phy, &data->phys[i]);
 	}
+	data->num_phys = i;
 
 	data->id_det_irq = gpiod_to_irq(data->id_det_gpio);
 	if (data->id_det_irq > 0) {
@@ -901,28 +904,24 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
 }
 
 static const struct sun4i_usb_phy_cfg suniv_f1c100s_cfg = {
-	.num_phys = 1,
 	.disc_thresh = 3,
 	.phyctl_offset = REG_PHYCTL_A10,
 	.dedicated_clocks = true,
 };
 
 static const struct sun4i_usb_phy_cfg sun4i_a10_cfg = {
-	.num_phys = 3,
 	.disc_thresh = 3,
 	.phyctl_offset = REG_PHYCTL_A10,
 	.dedicated_clocks = false,
 };
 
 static const struct sun4i_usb_phy_cfg sun5i_a13_cfg = {
-	.num_phys = 2,
 	.disc_thresh = 2,
 	.phyctl_offset = REG_PHYCTL_A10,
 	.dedicated_clocks = false,
 };
 
 static const struct sun4i_usb_phy_cfg sun6i_a31_cfg = {
-	.num_phys = 3,
 	.disc_thresh = 3,
 	.phyctl_offset = REG_PHYCTL_A10,
 	.dedicated_clocks = true,
@@ -930,14 +929,12 @@ static const struct sun4i_usb_phy_cfg sun6i_a31_cfg = {
 };
 
 static const struct sun4i_usb_phy_cfg sun7i_a20_cfg = {
-	.num_phys = 3,
 	.disc_thresh = 2,
 	.phyctl_offset = REG_PHYCTL_A10,
 	.dedicated_clocks = false,
 };
 
 static const struct sun4i_usb_phy_cfg sun8i_a23_cfg = {
-	.num_phys = 2,
 	.disc_thresh = 3,
 	.phyctl_offset = REG_PHYCTL_A10,
 	.dedicated_clocks = true,
@@ -945,7 +942,6 @@ static const struct sun4i_usb_phy_cfg sun8i_a23_cfg = {
 };
 
 static const struct sun4i_usb_phy_cfg sun8i_a33_cfg = {
-	.num_phys = 2,
 	.disc_thresh = 3,
 	.phyctl_offset = REG_PHYCTL_A33,
 	.dedicated_clocks = true,
@@ -953,7 +949,6 @@ static const struct sun4i_usb_phy_cfg sun8i_a33_cfg = {
 };
 
 static const struct sun4i_usb_phy_cfg sun8i_a83t_cfg = {
-	.num_phys = 3,
 	.hsic_index = 2,
 	.phyctl_offset = REG_PHYCTL_A33,
 	.dedicated_clocks = true,
@@ -961,7 +956,6 @@ static const struct sun4i_usb_phy_cfg sun8i_a83t_cfg = {
 };
 
 static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = {
-	.num_phys = 4,
 	.disc_thresh = 3,
 	.phyctl_offset = REG_PHYCTL_A33,
 	.dedicated_clocks = true,
@@ -970,7 +964,6 @@ static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = {
 };
 
 static const struct sun4i_usb_phy_cfg sun8i_r40_cfg = {
-	.num_phys = 3,
 	.disc_thresh = 3,
 	.phyctl_offset = REG_PHYCTL_A33,
 	.dedicated_clocks = true,
@@ -979,7 +972,6 @@ static const struct sun4i_usb_phy_cfg sun8i_r40_cfg = {
 };
 
 static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = {
-	.num_phys = 1,
 	.disc_thresh = 3,
 	.phyctl_offset = REG_PHYCTL_A33,
 	.dedicated_clocks = true,
@@ -988,7 +980,6 @@ static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = {
 };
 
 static const struct sun4i_usb_phy_cfg sun20i_d1_cfg = {
-	.num_phys = 2,
 	.phyctl_offset = REG_PHYCTL_A33,
 	.dedicated_clocks = true,
 	.hci_phy_ctl_clear = PHY_CTL_SIDDQ,
@@ -997,7 +988,6 @@ static const struct sun4i_usb_phy_cfg sun20i_d1_cfg = {
 };
 
 static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = {
-	.num_phys = 2,
 	.disc_thresh = 3,
 	.phyctl_offset = REG_PHYCTL_A33,
 	.dedicated_clocks = true,
@@ -1006,7 +996,6 @@ static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = {
 };
 
 static const struct sun4i_usb_phy_cfg sun50i_h6_cfg = {
-	.num_phys = 4,
 	.phyctl_offset = REG_PHYCTL_A33,
 	.dedicated_clocks = true,
 	.phy0_dual_route = true,
@@ -1015,7 +1004,6 @@ static const struct sun4i_usb_phy_cfg sun50i_h6_cfg = {
 };
 
 static const struct sun4i_usb_phy_cfg sun50i_h616_cfg = {
-	.num_phys = 4,
 	.disc_thresh = 3,
 	.phyctl_offset = REG_PHYCTL_A33,
 	.dedicated_clocks = true,
-- 
2.46.3



From dmitry.baryshkov at oss.qualcomm.com  Mon Aug 18 17:42:04 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Tue, 19 Aug 2025 03:42:04 +0300
Subject: [PATCH v3 01/14] phy: hdmi: Add HDMI 2.1 FRL configuration
 options
In-Reply-To: <20250818-phy-hdptx-frl-v3-1-c79997d8bb2b@collabora.com>
References: <20250818-phy-hdptx-frl-v3-0-c79997d8bb2b@collabora.com>
 <20250818-phy-hdptx-frl-v3-1-c79997d8bb2b@collabora.com>
Message-ID: <3f857197-1cd1-4c18-88e9-e8c00d95af82@oss.qualcomm.com>



On 18/08/2025 21:59, Cristian Ciocaltea wrote:
> The HDMI 2.1 specification introduced the Fixed Rate Link (FRL) mode,
> aiming to replace the older Transition-Minimized Differential Signaling
> (TMDS) mode used in previous HDMI versions to support much higher
> bandwidths (up to 48 Gbps) for modern video and audio formats.
> 
> FRL has been designed to support ultra high resolution formats at high
> refresh rates like 8K at 60Hz or 4K at 120Hz, and eliminates the need for
> dynamic bandwidth adjustments, which reduces latency.  It operates with
> 3 or 4 lanes at different link rates: 3Gbps, 6Gbps, 8Gbps, 10Gbps or
> 12Gbps.
> 
> Add support for configuring the FRL mode for HDMI PHYs.

Could you please point out corresponding DRM patches? They might be WIP 
or incomplete. I'd like to see how this works on the consumer side.

> 
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
> ---
>   include/linux/phy/phy-hdmi.h | 19 +++++++++++++++++--
>   1 file changed, 17 insertions(+), 2 deletions(-)
> 
> diff --git a/include/linux/phy/phy-hdmi.h b/include/linux/phy/phy-hdmi.h
> index f0ec963c6e84f1b7728acafc824dff191c6b873d..83330d359e3ae345554f20429519da14506b8ab5 100644
> --- a/include/linux/phy/phy-hdmi.h
> +++ b/include/linux/phy/phy-hdmi.h
> @@ -6,16 +6,31 @@
>   #ifndef __PHY_HDMI_H_
>   #define __PHY_HDMI_H_
>   
> +#include <linux/types.h>
> +
> +enum phy_mode_hdmi {
> +	PHY_MODE_HDMI_TMDS,
> +	PHY_MODE_HDMI_FRL,

There is no unified approach for PHY submode names. Nevertheless I'd 
suggest something like PHY_HDMI_MODE_TMDS / _FRL. It follows more 
closely the networking / USB submodes. An alternative might be to use 
PHY_SUBMODE_HDMI_TMDS / _FRL.

But it's really a nit and/or bikeschedding.

> +};
> +
>   /**
>    * struct phy_configure_opts_hdmi - HDMI configuration set
> - * @tmds_char_rate: HDMI TMDS Character Rate in Hertz.
>    * @bpc: Bits per color channel.
> + * @tmds_char_rate: HDMI TMDS Character Rate in Hertz.
> + * @frl.rate_per_lane: HDMI FRL Rate per Lane in Gbps.

This works nicely until HDMI Forum adds an rate not being even Gbps. Is 
there a reason for not using ULL and bps following the tmds_char_rate 
design?

> + * @frl.lanes: HDMI FRL lanes count.
>    *
>    * This structure is used to represent the configuration state of a HDMI phy.
>    */
>   struct phy_configure_opts_hdmi {
> -	unsigned long long tmds_char_rate;
>   	unsigned int bpc;
> +	union {
> +		unsigned long long tmds_char_rate;
> +		struct {
> +			u8 rate_per_lane;
> +			u8 lanes;
> +		} frl;
> +	};
>   };
>   
>   #endif /* __PHY_HDMI_H_ */
> 

-- 
With best wishes
Dmitry



From dmitry.baryshkov at oss.qualcomm.com  Mon Aug 18 18:08:58 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Tue, 19 Aug 2025 04:08:58 +0300
Subject: [PATCH V2 1/2] phy: qcom-qmp-ufs: Add regulator load voting for
 UFS QMP Phy
In-Reply-To: <20250818124110.8136-2-quic_nitirawa@quicinc.com>
References: <20250818124110.8136-1-quic_nitirawa@quicinc.com>
 <20250818124110.8136-2-quic_nitirawa@quicinc.com>
Message-ID: <jpuesvbjupjp3hmdiwwpx6c3yblf5e6nqm3tdp7vnjehkuyort@7u7c5lw622dz>

On Mon, Aug 18, 2025 at 06:11:09PM +0530, Nitin Rawat wrote:
> On some SoCs, regulators are shared between the QMP UFS PHY and other
> IP blocks. Hence convey maximum load requirement for UFS PHY to the

s/maximum//

> regulator framework as supply's capabilities or mode(Low Power Mode
> or High Power Mode) change depending on the maximum potential load
> at any given time, which the regulator driver must be aware of.
> This helps to ensure stable operation and proper power management,
> set the regulator load before enabling the regulators.
> 
> This patch adds:
> 

Documentation/process/submitting-patches.rst, "[This patch] makes xyzzy
do frotz".

> - vreg_load_uA field to qmp_phy_cfg structure for load value arrays.
> - Enhanced qmp_ufs_vreg_init() to set init_load_uA when loads are
>   specified.
> 
> Configurations without specific load requirements will continue
> to work unchanged, as init_load_uA remains zero-initialized when
> vreg_load_uA is not provided.
> 
> Signed-off-by: Nitin Rawat <quic_nitirawa at quicinc.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> index 9c69c77d10c8..f7a4a8334026 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> @@ -1110,6 +1110,9 @@ struct qmp_phy_cfg {
>  	const char * const *vreg_list;
>  	int num_vregs;
> 
> +	/* regulator load values in same order as vreg_list */
> +	const int *vreg_load_ua;
> +
>  	/* array of registers with different offsets */
>  	const unsigned int *regs;
> 
> @@ -1901,8 +1904,11 @@ static int qmp_ufs_vreg_init(struct qmp_ufs *qmp)
>  	if (!qmp->vregs)
>  		return -ENOMEM;
> 
> -	for (i = 0; i < num; i++)
> +	for (i = 0; i < num; i++) {
>  		qmp->vregs[i].supply = cfg->vreg_list[i];
> +		if (cfg->vreg_load_ua)
> +			qmp->vregs[i].init_load_uA = cfg->vreg_load_ua[i];

Please rewrite the driver to use devm_regulator_bulk_get_const().

> +	}
> 
>  	return devm_regulator_bulk_get(dev, num, qmp->vregs);
>  }
> --
> 2.48.1
> 

-- 
With best wishes
Dmitry


From lkp at intel.com  Mon Aug 18 20:31:35 2025
From: lkp at intel.com (kernel test robot)
Date: Tue, 19 Aug 2025 11:31:35 +0800
Subject: [PATCH v1 2/2] phy: mediatek: tphy: Add software role switching
In-Reply-To: <20250814234825.810-2-me@adomerle.pw>
References: <20250814234825.810-2-me@adomerle.pw>
Message-ID: <202508191054.otlyeeg5-lkp@intel.com>

Hi Arseniy,

kernel test robot noticed the following build errors:

[auto build test ERROR on robh/for-next]
[also build test ERROR on linus/master v6.17-rc2 next-20250818]
[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/Arseniy-Velikanov/phy-mediatek-tphy-Add-software-role-switching/20250815-075416
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
patch link:    https://lore.kernel.org/r/20250814234825.810-2-me%40adomerle.pw
patch subject: [PATCH v1 2/2] phy: mediatek: tphy: Add software role switching
config: arm64-randconfig-001-20250819 (https://download.01.org/0day-ci/archive/20250819/202508191054.otlyeeg5-lkp at intel.com/config)
compiler: aarch64-linux-gcc (GCC) 14.3.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250819/202508191054.otlyeeg5-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/202508191054.otlyeeg5-lkp at intel.com/

All errors (new ones prefixed by >>):

   aarch64-linux-ld: Unexpected GOT/PLT entries detected!
   aarch64-linux-ld: Unexpected run-time procedure linkages detected!
   aarch64-linux-ld: drivers/phy/mediatek/phy-mtk-tphy.o: in function `u2_phy_software_role_switch_init':
>> phy-mtk-tphy.c:(.text+0x31d4): undefined reference to `usb_get_role_switch_default_mode'

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


From claudiu.beznea at tuxon.dev  Mon Aug 18 22:21:14 2025
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Tue, 19 Aug 2025 08:21:14 +0300
Subject: [PATCH v4 4/8] dt-bindings: reset: renesas,rzg2l-usbphy-ctrl:
 Document RZ/G3S support
In-Reply-To: <20250813232100.GA950521-robh@kernel.org>
References: <20250808061806.2729274-1-claudiu.beznea.uj@bp.renesas.com>
 <20250808061806.2729274-5-claudiu.beznea.uj@bp.renesas.com>
 <20250813232100.GA950521-robh@kernel.org>
Message-ID: <f71ba698-6c8e-42c7-ac04-3b67cd774784@tuxon.dev>

Hi, Rob,

On 8/14/25 02:21, Rob Herring wrote:
> On Fri, Aug 08, 2025 at 09:18:02AM +0300, Claudiu wrote:
>> From: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
>>
>> The Renesas USB PHY hardware block needs to have the PWRRDY bit in the
>> system controller set before applying any other settings. The PWRRDY bit
>> must be controlled during power-on, power-off, and system suspend/resume
>> sequences as follows:
>> - during power-on/resume, it must be set to zero before enabling clocks and
>>    modules
>> - during power-off/suspend, it must be set to one after disabling clocks
>>    and modules
>>
>> Add the renesas,sysc-pwrrdy device tree property, which allows the
>> reset-rzg2l-usbphy-ctrl driver to parse, map, and control the system
>> controller PWRRDY bit at the appropriate time. Along with it add a new
>> compatible for the RZ/G3S SoC.
>>
>> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
>> ---
>>
>> Changes in v4:
>> - dropped blank line from compatible section
>> - s/renesas,sysc-signals/renesas,sysc-pwrrdy/g
>> - dropped description from renesas,sysc-pwrrdy
>> - updated description of renesas,sysc-pwrrdy items
>> - updated patch description
>>
>> Changes in v3:
>> - none; this patch is new
>>
>>   .../reset/renesas,rzg2l-usbphy-ctrl.yaml      | 40 ++++++++++++++++---
>>   1 file changed, 34 insertions(+), 6 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml b/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml
>> index b0b20af15313..c1d5f3228aa9 100644
>> --- a/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml
>> +++ b/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml
>> @@ -15,12 +15,14 @@ description:
>>   
>>   properties:
>>     compatible:
>> -    items:
>> -      - enum:
>> -          - renesas,r9a07g043-usbphy-ctrl # RZ/G2UL and RZ/Five
>> -          - renesas,r9a07g044-usbphy-ctrl # RZ/G2{L,LC}
>> -          - renesas,r9a07g054-usbphy-ctrl # RZ/V2L
>> -      - const: renesas,rzg2l-usbphy-ctrl
>> +    oneOf:
>> +      - items:
>> +          - enum:
>> +              - renesas,r9a07g043-usbphy-ctrl # RZ/G2UL and RZ/Five
>> +              - renesas,r9a07g044-usbphy-ctrl # RZ/G2{L,LC}
>> +              - renesas,r9a07g054-usbphy-ctrl # RZ/V2L
>> +          - const: renesas,rzg2l-usbphy-ctrl
>> +      - const: renesas,r9a08g045-usbphy-ctrl # RZ/G3S
>>   
>>     reg:
>>       maxItems: 1
>> @@ -48,6 +50,19 @@ properties:
>>       $ref: /schemas/regulator/regulator.yaml#
>>       unevaluatedProperties: false
>>   
>> +  renesas,sysc-pwrrdy:
>> +    description: The system controller PWRRDY indicates to the USB PHY if the
>> +                 power supply is ready. PWRRDY needs to be set during power-on
>> +                 before applying any other settings. It also needs to
>> +                 be set before powering off the USB.
> 
> Where did this odd formatting come from?

I formatted it like this by mistake.

> If copied from somewhere else,
> patches reformatting them welcome.
> 
>      description:
>        The system controller PWRRDY indicates to the USB PHY if the power
>        supply is ready. PWRRDY needs to be set during power-on before applying
>        any other settings. It also needs to be set before powering off the USB.

OK

> 
> 
>> +    $ref: /schemas/types.yaml#/definitions/phandle-array
>> +    items:
>> +      - items:
>> +          - description: System controller phandle required by USB PHY CTRL
>> +                         driver to set PWRRDY
> 
> Indent by 2 more than 'description'

OK


Thank you,
Claudiu

> 
> With that,
> 
> Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
> 
>> +          - description: Register offset associated with PWRRDY
>> +          - description: Register bitmask associated with PWRRDY
>> +
>>   required:
>>     - compatible
>>     - reg
>> @@ -57,6 +72,19 @@ required:
>>     - '#reset-cells'
>>     - regulator-vbus
>>   
>> +allOf:
>> +  - if:
>> +      properties:
>> +        compatible:
>> +          contains:
>> +            const: renesas,r9a08g045-usbphy-ctrl
>> +    then:
>> +      required:
>> +        - renesas,sysc-pwrrdy
>> +    else:
>> +      properties:
>> +        renesas,sysc-pwrrdy: false
>> +
>>   additionalProperties: false
>>   
>>   examples:
>> -- 
>> 2.43.0
>>



From pritam.sutar at samsung.com  Mon Aug 18 00:41:48 2025
From: pritam.sutar at samsung.com (Pritam Manohar Sutar)
Date: Mon, 18 Aug 2025 13:11:48 +0530
Subject: [PATCH v5 6/6] phy: exynos5-usbdrd: support SS combo phy for
 ExynosAutov920
In-Reply-To: <aJtN7uVUV3YhfY5-@vaman>
References: <20250805115216.3798121-1-pritam.sutar@samsung.com>
	<CGME20250805114323epcas5p39bf73c5e0a9382ff54b1832724804cc9@epcas5p3.samsung.com>
	<20250805115216.3798121-7-pritam.sutar@samsung.com> <aJtN7uVUV3YhfY5-@vaman>
Message-ID: <038a01dc1013$900a2800$b01e7800$@samsung.com>

Hi Vinod, 

> -----Original Message-----
> From: Vinod Koul <vkoul at kernel.org>
> Sent: 12 August 2025 07:52 PM
> To: Pritam Manohar Sutar <pritam.sutar at samsung.com>
> Cc: kishon at kernel.org; robh at kernel.org; krzk+dt at kernel.org;
> conor+dt at kernel.org; alim.akhtar at samsung.com; andre.draszik at linaro.org;
> peter.griffin at linaro.org; kauschluss at disroot.org;
> ivo.ivanov.ivanov1 at gmail.com; igor.belwon at mentallysanemainliners.org;
> m.szyprowski at samsung.com; s.nawrocki at samsung.com; linux-
> phy at lists.infradead.org; devicetree at vger.kernel.org; linux-
> kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-
> samsung-soc at vger.kernel.org; rosa.pila at samsung.com;
> dev.tailor at samsung.com; faraz.ata at samsung.com;
> muhammed.ali at samsung.com; selvarasu.g at samsung.com
> Subject: Re: [PATCH v5 6/6] phy: exynos5-usbdrd: support SS combo phy for
> ExynosAutov920
> 
> On 05-08-25, 17:22, Pritam Manohar Sutar wrote:
> > Add required change in phy driver to support combo SS phy for this SoC.
> >
> > Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
> > ---
> >  drivers/phy/samsung/phy-exynos5-usbdrd.c    | 327
> +++++++++++++++++++-
> >  include/linux/soc/samsung/exynos-regs-pmu.h |   1 +
> >  2 files changed, 324 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c
> > b/drivers/phy/samsung/phy-exynos5-usbdrd.c
> > index c22f4de7d094..1108f0c07755 100644
> > --- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
> > +++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
> > @@ -273,6 +273,36 @@
> >  #define EXYNOSAUTOV920_DRD_HSPPLLTUNE		0x110
> >  #define HSPPLLTUNE_FSEL				GENMASK(18, 16)
> >
> > +/* ExynosAutov920 phy usb31drd port reg */
> > +#define EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL	0x000
> > +#define PHY_RST_CTRL_PIPE_LANE0_RESET_N_OVRD_EN	BIT(5)
> > +#define PHY_RST_CTRL_PIPE_LANE0_RESET_N		BIT(4)
> > +#define PHY_RST_CTRL_PHY_RESET_OVRD_EN		BIT(1)
> > +#define PHY_RST_CTRL_PHY_RESET			BIT(0)
> > +
> > +#define EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0
> 	0x0004
> > +#define PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR
> 	GENMASK(31, 16)
> > +#define PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK		BIT(8)
> > +#define PHY_CR_PARA_CON0_PHY0_CR_PARA_ACK		BIT(4)
> > +#define PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL		BIT(0)
> > +
> > +#define EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON1
> 	0x0008
> > +
> > +#define EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2
> 	0x000c
> > +#define PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_EN		BIT(0)
> > +#define PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_DATA
> 	GENMASK(31, 16)
> > +
> > +#define EXYNOSAUTOV920_USB31DRD_PHY_CONFIG0	0x100
> > +#define PHY_CONFIG0_PHY0_PMA_PWR_STABLE		BIT(14)
> > +#define PHY_CONFIG0_PHY0_PCS_PWR_STABLE		BIT(13)
> > +#define PHY_CONFIG0_PHY0_ANA_PWR_EN		BIT(1)
> > +
> > +#define EXYNOSAUTOV920_USB31DRD_PHY_CONFIG7	0x11c
> > +#define PHY_CONFIG7_PHY_TEST_POWERDOWN		BIT(24)
> > +
> > +#define EXYNOSAUTOV920_USB31DRD_PHY_CONFIG4	0x110
> > +#define PHY_CONFIG4_PIPE_RX0_SRIS_MODE_EN	BIT(2)
> > +
> >  /* Exynos9 - GS101 */
> >  #define EXYNOS850_DRD_SECPMACTL			0x48
> >  #define SECPMACTL_PMA_ROPLL_REF_CLK_SEL
> 	GENMASK(13, 12)
> > @@ -2077,6 +2107,253 @@ static const struct
> exynos5_usbdrd_phy_drvdata exynos990_usbdrd_phy = {
> >  	.n_regulators		= ARRAY_SIZE(exynos5_regulator_names),
> >  };
> >
> > +static void
> > +exynosautov920_usb31drd_cr_clk(struct exynos5_usbdrd_phy *phy_drd,
> > +bool high) {
> > +	void __iomem *reg_phy = phy_drd->reg_phy;
> > +	u32 reg = 0;
> 
> again..
> 
> > +
> > +	reg = readl(reg_phy +
> EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
> > +	if (high)
> > +		reg |= PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK;
> > +	else
> > +		reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK;
> > +
> > +	writel(reg, reg_phy +
> EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
> > +	fsleep(1);
> > +}
> > +
> > +static void
> > +exynosautov920_usb31drd_port_phy_ready(struct exynos5_usbdrd_phy
> > +*phy_drd) {
> > +	struct device *dev = phy_drd->dev;
> > +	void __iomem *reg_phy = phy_drd->reg_phy;
> > +	static const unsigned int timeout_us = 20000;
> > +	static const unsigned int sleep_us = 40;
> > +	u32 reg = 0;
> 
> here too
> 
> > +	int err;
> > +
> > +	/* Clear cr_para_con */
> > +	reg &= ~(PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK |
> > +			PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR);
> > +	reg |= PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL;
> > +	writel(reg, reg_phy +
> EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
> > +	writel(0x0, reg_phy +
> EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON1);
> > +	writel(0x0, reg_phy +
> EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2);
> > +
> > +	exynosautov920_usb31drd_cr_clk(phy_drd, true);
> > +	exynosautov920_usb31drd_cr_clk(phy_drd, false);
> > +
> > +	/*
> > +	 * The maximum time from phy reset de-assertion to de-assertion of
> > +	 * tx/rx_ack can be as high as 5ms in fast simulation mode.
> > +	 * Time to phy ready is < 20ms
> > +	 */
> > +	err = readl_poll_timeout(reg_phy +
> > +
> 	EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0,
> > +			reg, !(reg &
> PHY_CR_PARA_CON0_PHY0_CR_PARA_ACK),
> > +			sleep_us, timeout_us);
> > +	if (err)
> > +		dev_err(dev, "timed out waiting for rx/tx_ack: %#.8x\n",
> reg);
> > +
> > +	reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK;
> > +	writel(reg, reg_phy +
> EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
> > +}
> > +
> > +static void
> > +exynosautov920_usb31drd_cr_write(struct exynos5_usbdrd_phy
> *phy_drd,
> > +				 u16 addr, u16 data)
> > +{
> > +	struct device *dev = phy_drd->dev;
> > +	void __iomem *reg_phy = phy_drd->reg_phy;
> > +	u32 cnt = 0;
> > +	u32 reg = 0;
> 
> this one, former is okay
> 
> > +
> > +	/* Pre Clocking */
> > +	reg = readl(reg_phy +
> EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
> > +	reg |= PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL;
> > +	writel(reg, reg_phy +
> EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
> > +
> > +	/*
> > +	 * tx clks must be available prior to assertion of tx req.
> > +	 * tx pstate p2 to p0 transition directly is not permitted.
> > +	 * tx clk ready must be asserted synchronously on tx clk prior
> > +	 * to internal transmit clk alignment sequence in the phy
> > +	 * when entering from p2 to p1 to p0.
> > +	 */
> > +	do {
> > +		exynosautov920_usb31drd_cr_clk(phy_drd, true);
> > +		exynosautov920_usb31drd_cr_clk(phy_drd, false);
> > +		cnt++;
> > +	} while (cnt < 15);
> > +
> > +	reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL;
> > +	writel(reg, reg_phy +
> EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
> > +
> > +	/*
> > +	 * tx data path is active when tx lane is in p0 state
> > +	 * and tx data en asserted. enable cr_para_wr_en.
> > +	 */
> > +	reg = readl(reg_phy +
> EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2);
> > +	reg &= ~PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_DATA;
> > +	reg |=
> FIELD_PREP(PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_DATA, data) |
> > +		PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_EN;
> > +	writel(reg, reg_phy +
> EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2);
> > +
> > +	/* write addr */
> > +	reg = readl(reg_phy +
> EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
> > +	reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR;
> > +	reg |= FIELD_PREP(PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR,
> addr) |
> > +		PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK |
> > +		PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL;
> > +	writel(reg, reg_phy +
> EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
> > +
> > +	/* check cr_para_ack*/
> > +	cnt = 0;
> > +	do {
> > +		/*
> > +		 * data symbols are captured by phy on rising edge of the
> > +		 * tx_clk when tx data enabled.
> > +		 * completion of the write cycle is acknowledged by
assertion
> > +		 * of the cr_para_ack.
> > +		 */
> > +		exynosautov920_usb31drd_cr_clk(phy_drd, true);
> > +		reg = readl(reg_phy +
> EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
> > +		if ((reg & PHY_CR_PARA_CON0_PHY0_CR_PARA_ACK))
> > +			break;
> > +
> > +		exynosautov920_usb31drd_cr_clk(phy_drd, false);
> > +
> > +		/*
> > +		 * wait for minimum of 10 cr_para_clk cycles after phy reset
> > +		 * is negated, before accessing control regs to allow for
> > +		 * internal resets.
> > +		 */
> > +		cnt++;
> > +	} while (cnt < 10);
> > +
> > +	if (cnt == 10)
> > +		dev_dbg(dev, "CR write failed to 0x%04x\n", addr);
> 
> Not error?

This is only for debugging purpose. It is not considered as error. 

> --
> ~Vinod


Will address other comments in next version of the patch-set (v6).

Thank you.

Regards,
Pritam



From claudiu.beznea at tuxon.dev  Mon Aug 18 22:42:05 2025
From: claudiu.beznea at tuxon.dev (Claudiu)
Date: Tue, 19 Aug 2025 08:42:05 +0300
Subject: [PATCH v5 0/7] Add initial USB support for the Renesas RZ/G3S SoC
Message-ID: <20250819054212.486426-1-claudiu.beznea.uj@bp.renesas.com>

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:
- patches 1-2/7		- fixes on bindings and driver for USB PHY
- patches 3-5/7		- updates the rzg2l-usbphy-ctrl driver and documentation
			  with support for setting PWRRDY though SYSC
- patches 6-7/7		- add device tree support

Merge strategy, if any:
- patches 1-2/7 can go through the PHY tree
- patches 3-5/7 can go through the reset tree
- patches 6-7/7 can go through Renesas tree

Thank you,
Claudiu Beznea

Changes in v5:
- dropped patch "soc: renesas: rz-sysc: Add syscon/regmap support" as it
  already modified and pubished also at [2] with the latest review comments
  addressed
- fixed the documentation

Changes in v4:
- replaced "renesas,sysc-signals" DT property with "renesas,sysc-pwrrdy"
- dropped the "renesas,sysc-signals" property from USB PHY (as proposed
  in v3) and let only the USB PHY CTRL driver to handle it as on RZ/G3S
  the USB PHY CTRL driver needs to be probed before any other USB driver
- dropped the signal abstraction from SYSC driver as there is no need
  for reference counting it now
- adjusted the "soc: renesas: rz-sysc: Add syscon/regmap support" to
  comply with the latest review comments

Changes in v3:
- as the basics of the SYSC driver was integrated, only the signal support
  was preserved in this series, in a separate patch; patch 01/12 was
  adjusted (by addressing the review comments received at [1]) as it is
  necessary to build the signal support on top of it
- after long discussions with the internal HW team it has been confirmed
  that the relation b/w individual USB specific HW blocks and signals
  is like:

                                   ????????????????????????????????
                                   ?                              ???? CPG_CLKON_USB.CLK0_ON
                                   ?     USB CH0                  ?
    ????????????????????????????   ?????????????????????????????? ???? CPG_CLKON_USB.CLK2_ON
    ?                 ??????????   ??host controller registers  ? ?
    ?                 ?        ?   ??function controller registers?
    ?                 ? PHY0   ?????????????????????????????????? ?
    ?     USB PHY     ?        ?   ????????????????????????????????
    ?                 ??????????                ?
    ?                          ?    CPG_BUS_PERI_COM_MSTOP.MSTOP{6, 5}_ON
    ????????????????? ??????????
    ??USBPHY control? ?        ?
    ??  registers   ? ? PHY1   ?   ????????????????????????????????
    ????????????????? ?        ?????     USB CH1                  ?
    ?                 ??????????   ?????????????????????????????? ???? CPG_CLKON_USB.CLK1_ON
    ????????????????????????????   ?? host controller registers ? ?
      ?       ?         ?          ?????????????????????????????? ?
      ?       ?         ?          ????????????????????????????????
      ?       ?         ?                       ?
      ?       ?         ?           CPG_BUS_PERI_COM_MSTOP.MSTOP7_ON
      ?PWRRDY ?         ?
      ?       ?   CPG_CLK_ON_USB.CLK3_ON
      ?       ?
      ?  CPG_BUS_PERI_COM_MSTOP.MSTOP4_ON
      ?
    ??????
    ?SYSC?
    ??????

  where:
  - CPG_CLKON_USB.CLK.CLKX_ON is the register bit controlling the clock X
      of different USB blocks, X in {0, 1, 2, 3}
  - CPG_BUS_PERI_COM_MSTOP.MSTOPX_ON is the register bit controlling the
    MSTOP of different USB blocks, X in {4, 5, 6, 7}
  - USB PHY is the USB PHY block exposing 2 ports, port0 and port1, used
    by the USB CH0, USB CH1
  - SYSC is the system controller block controlling the PWRRDY signal
  - USB CHx are individual USB block with host and function capabilities
    (USB CH0 have both host and function capabilities, USB CH1 has only
    host capabilities)

  Due to this, the PWRRDY signal was also passed to the reset-rzg2l-usbphy-ctrl
  reset driver (as it controls the USBPHY control registers) and these
  are in the USB PHY block controlled by PWRRDY signal.

  The PWRRDY signal need to be de-asserted on probe before enabling the module
  clocks and the module MSTOP. To avoid any violation of this configuration
  sequence, the PWRRDY signal is now controlled by USB PHY driver and the
  reset-rzg2l-usbphy-ctrl driver.

  As the PHYs gets reset signals from the USB reset controller driver, the
  reset-rzg2l-usbphy-ctrl is probed before the USB PHY driver and thus,
  in theory, we can drop the signal support (reference counting of the
  USB PWRRDY) and configure the USB PWRRDY just in the reset-rzg2l-usbphy-ctrl.

  However, to have a proper description of the diagram described above in 
  device tree and ensure the configuration sequence b/w PRWRDY, CLK and MSTOP
  is preserved, the PWRRDY signal is controlled in this series in all the
  drivers that work with registers from the USB PHY block.

  Please provide your feedback on this solution.

Thank you,
Claudiu

[1] https://lore.kernel.org/all/20250330214945.185725-2-john.madieu.xa at bp.renesas.com/
[2] https://lore.kernel.org/all/20250818162859.9661-2-john.madieu.xa at bp.renesas.com/

Changes in v2:
- dropped v1 patches already applied
- added fixes patches (07/14 and 09/14)
- dropped the approach of handling the USB PWRRDY though a reset controller
  driver and introduced the signal concept for the SYSC driver; because
  of this, most of the work done in v1 was dropped
- per patch changes are listed in individual patches, if any

Christophe JAILLET (1):
  phy: renesas: rcar-gen3-usb2: Fix an error handling path in
    rcar_gen3_phy_usb2_probe()

Claudiu Beznea (6):
  dt-bindings: phy: renesas,usb2-phy: Mark resets as required for RZ/G3S
  dt-bindings: reset: renesas,rzg2l-usbphy-ctrl: Document RZ/G3S support
  reset: rzg2l-usbphy-ctrl: Add support for USB PWRRDY
  reset: rzg2l-usbphy-ctrl: Add support for RZ/G3S SoC
  arm64: dts: renesas: r9a08g045: Add USB support
  arm64: dts: renesas: rzg3s-smarc: Enable USB support

 .../bindings/phy/renesas,usb2-phy.yaml        |   1 +
 .../reset/renesas,rzg2l-usbphy-ctrl.yaml      |  41 +++++-
 arch/arm64/boot/dts/renesas/r9a08g045.dtsi    | 118 ++++++++++++++++++
 arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi  |  57 +++++++++
 drivers/phy/renesas/phy-rcar-gen3-usb2.c      |  11 +-
 drivers/reset/Kconfig                         |   1 +
 drivers/reset/reset-rzg2l-usbphy-ctrl.c       |  70 +++++++++++
 7 files changed, 292 insertions(+), 7 deletions(-)

-- 
2.43.0



From claudiu.beznea at tuxon.dev  Mon Aug 18 22:42:06 2025
From: claudiu.beznea at tuxon.dev (Claudiu)
Date: Tue, 19 Aug 2025 08:42:06 +0300
Subject: [PATCH v5 1/7] dt-bindings: phy: renesas,usb2-phy: Mark resets as required for RZ/G3S
In-Reply-To: <20250819054212.486426-1-claudiu.beznea.uj@bp.renesas.com>
References: <20250819054212.486426-1-claudiu.beznea.uj@bp.renesas.com>
Message-ID: <20250819054212.486426-2-claudiu.beznea.uj@bp.renesas.com>

From: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>

The reset lines are mandatory for the Renesas RZ/G3S platform and must be
explicitly defined in device tree.

Fixes: f3c849855114 ("dt-bindings: phy: renesas,usb2-phy: Document RZ/G3S phy bindings")
Reviewed-by: Geert Uytterhoeven <geert+renesas at glider.be>
Acked-by: Conor Dooley <conor.dooley at microchip.com>
Signed-off-by: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
---

Changes in v5:
- none

Changes in v4:
- none

Changes in v3:
- collected tags
- rebased on top of latest version of renesas,usb2-phy.yaml;
  Conor, Geert: I kept your tags; please let me know if you consider it
  otherwise

Changes in v2:
- none; this patch is new

 Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml b/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml
index f45c5f039ae8..52d777057281 100644
--- a/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml
@@ -112,6 +112,7 @@ allOf:
           contains:
             enum:
               - renesas,usb2-phy-r9a09g057
+              - renesas,usb2-phy-r9a08g045
               - renesas,rzg2l-usb2-phy
     then:
       properties:
-- 
2.43.0



From claudiu.beznea at tuxon.dev  Mon Aug 18 22:42:07 2025
From: claudiu.beznea at tuxon.dev (Claudiu)
Date: Tue, 19 Aug 2025 08:42:07 +0300
Subject: [PATCH v5 2/7] phy: renesas: rcar-gen3-usb2: Fix an error handling path in rcar_gen3_phy_usb2_probe()
In-Reply-To: <20250819054212.486426-1-claudiu.beznea.uj@bp.renesas.com>
References: <20250819054212.486426-1-claudiu.beznea.uj@bp.renesas.com>
Message-ID: <20250819054212.486426-3-claudiu.beznea.uj@bp.renesas.com>

From: Christophe JAILLET <christophe.jaillet at 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>
Reviewed-by: Biju Das <biju.das.jz at bp.renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas at glider.be>
[claudiu.beznea: removed "struct reset_control *rstc = data;" from
 rcar_gen3_reset_assert()]
Signed-off-by: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
---

Changes in v5:
- none

Changes in v4:
- none

Changes in v3:
- collected tags

Changes in v2:
- none; this patch is new; re-spinned the Christophe's work at
  https://lore.kernel.org/all/TYCPR01MB113329930BA5E2149C9BE2A1986672 at TYCPR01MB11332.jpnprd01.prod.outlook.com/


 drivers/phy/renesas/phy-rcar-gen3-usb2.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index 47beb94cd424..d61c171d454f 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -699,6 +699,11 @@ static enum usb_dr_mode rcar_gen3_get_dr_mode(struct device_node *np)
 	return candidate;
 }
 
+static void rcar_gen3_reset_assert(void *data)
+{
+	reset_control_assert(data);
+}
+
 static int rcar_gen3_phy_usb2_init_bus(struct rcar_gen3_chan *channel)
 {
 	struct device *dev = channel->dev;
@@ -717,6 +722,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;
@@ -860,7 +870,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.43.0



From claudiu.beznea at tuxon.dev  Mon Aug 18 22:42:08 2025
From: claudiu.beznea at tuxon.dev (Claudiu)
Date: Tue, 19 Aug 2025 08:42:08 +0300
Subject: [PATCH v5 3/7] dt-bindings: reset: renesas,rzg2l-usbphy-ctrl: Document RZ/G3S support
In-Reply-To: <20250819054212.486426-1-claudiu.beznea.uj@bp.renesas.com>
References: <20250819054212.486426-1-claudiu.beznea.uj@bp.renesas.com>
Message-ID: <20250819054212.486426-4-claudiu.beznea.uj@bp.renesas.com>

From: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>

The Renesas USB PHY hardware block needs to have the PWRRDY bit in the
system controller set before applying any other settings. The PWRRDY bit
must be controlled during power-on, power-off, and system suspend/resume
sequences as follows:
- during power-on/resume, it must be set to zero before enabling clocks and
  modules
- during power-off/suspend, it must be set to one after disabling clocks
  and modules

Add the renesas,sysc-pwrrdy device tree property, which allows the
reset-rzg2l-usbphy-ctrl driver to parse, map, and control the system
controller PWRRDY bit at the appropriate time. Along with it add a new
compatible for the RZ/G3S SoC.

Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
Signed-off-by: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
---

Changes in v5:
- fixed description formatting
- collected tags

Changes in v4:
- dropped blank line from compatible section
- s/renesas,sysc-signals/renesas,sysc-pwrrdy/g
- dropped description from renesas,sysc-pwrrdy
- updated description of renesas,sysc-pwrrdy items
- updated patch description

Changes in v3:
- none; this patch is new

 .../reset/renesas,rzg2l-usbphy-ctrl.yaml      | 41 ++++++++++++++++---
 1 file changed, 35 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml b/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml
index b0b20af15313..c83469a1b379 100644
--- a/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml
+++ b/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml
@@ -15,12 +15,14 @@ description:
 
 properties:
   compatible:
-    items:
-      - enum:
-          - renesas,r9a07g043-usbphy-ctrl # RZ/G2UL and RZ/Five
-          - renesas,r9a07g044-usbphy-ctrl # RZ/G2{L,LC}
-          - renesas,r9a07g054-usbphy-ctrl # RZ/V2L
-      - const: renesas,rzg2l-usbphy-ctrl
+    oneOf:
+      - items:
+          - enum:
+              - renesas,r9a07g043-usbphy-ctrl # RZ/G2UL and RZ/Five
+              - renesas,r9a07g044-usbphy-ctrl # RZ/G2{L,LC}
+              - renesas,r9a07g054-usbphy-ctrl # RZ/V2L
+          - const: renesas,rzg2l-usbphy-ctrl
+      - const: renesas,r9a08g045-usbphy-ctrl # RZ/G3S
 
   reg:
     maxItems: 1
@@ -48,6 +50,20 @@ properties:
     $ref: /schemas/regulator/regulator.yaml#
     unevaluatedProperties: false
 
+  renesas,sysc-pwrrdy:
+    description:
+      The system controller PWRRDY indicates to the USB PHY if the power supply
+      is ready. PWRRDY needs to be set during power-on before applying any
+      other settings. It also needs to be set before powering off the USB.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    items:
+      - items:
+          - description:
+              System controller phandle required by USB PHY CTRL driver to set
+              PWRRDY
+          - description: Register offset associated with PWRRDY
+          - description: Register bitmask associated with PWRRDY
+
 required:
   - compatible
   - reg
@@ -57,6 +73,19 @@ required:
   - '#reset-cells'
   - regulator-vbus
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: renesas,r9a08g045-usbphy-ctrl
+    then:
+      required:
+        - renesas,sysc-pwrrdy
+    else:
+      properties:
+        renesas,sysc-pwrrdy: false
+
 additionalProperties: false
 
 examples:
-- 
2.43.0



From claudiu.beznea at tuxon.dev  Mon Aug 18 22:42:09 2025
From: claudiu.beznea at tuxon.dev (Claudiu)
Date: Tue, 19 Aug 2025 08:42:09 +0300
Subject: [PATCH v5 4/7] reset: rzg2l-usbphy-ctrl: Add support for USB PWRRDY
In-Reply-To: <20250819054212.486426-1-claudiu.beznea.uj@bp.renesas.com>
References: <20250819054212.486426-1-claudiu.beznea.uj@bp.renesas.com>
Message-ID: <20250819054212.486426-5-claudiu.beznea.uj@bp.renesas.com>

From: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>

On the Renesas RZ/G3S SoC, the USB PHY block has an input signal called
PWRRDY. This signal is managed by the system controller and must be
de-asserted after powering on the area where USB PHY resides and asserted
before powering it off.

On power-on the USB PWRRDY signal need to be de-asserted before enabling
clock and switching the module to normal state (through MSTOP support). The
power-on configuration sequence must be:

1/ PWRRDY=0
2/ CLK_ON=1
3/ MSTOP=0

On power-off the configuration sequence should be:

1/ MSTOP=1
2/ CLK_ON=0
3/ PWRRDY=1

The CLK_ON and MSTOP functionalities are controlled by clock drivers.

After long discussions with the internal HW team, it has been confirmed
that the HW connection b/w USB PHY block, the USB channels, the system
controller, clock, MSTOP, PWRRDY signal is as follows:

                               ????????????????????????????????
                               ?                              ???? CPG_CLKON_USB.CLK0_ON
                               ?     USB CH0                  ?
????????????????????????????   ?????????????????????????????? ???? CPG_CLKON_USB.CLK2_ON
?                 ??????????   ??host controller registers  ? ?
?                 ?        ?   ??function controller registers?
?                 ? PHY0   ?????????????????????????????????? ?
?     USB PHY     ?        ?   ????????????????????????????????
?                 ??????????                ?
?                          ?    CPG_BUS_PERI_COM_MSTOP.MSTOP{6, 5}_ON
????????????????? ??????????
??USHPHY control? ?        ?
??  registers   ? ? PHY1   ?   ????????????????????????????????
????????????????? ?        ?????     USB CH1                  ?
?                 ??????????   ?????????????????????????????? ???? CPG_CLKON_USB.CLK1_ON
????????????????????????????   ?? host controller registers ? ?
  ?       ?         ?          ?????????????????????????????? ?
  ?       ?         ?          ????????????????????????????????
  ?       ?         ?                       ?
  ?       ?         ?           CPG_BUS_PERI_COM_MSTOP.MSTOP7_ON
  ?PWRRDY ?         ?
  ?       ?   CPG_CLK_ON_USB.CLK3_ON
  ?       ?
  ?  CPG_BUS_PERI_COM_MSTOP.MSTOP4_ON
  ?
??????
?SYSC?
??????

where:
- CPG_CLKON_USB.CLK.CLKX_ON is the register bit controlling the clock X
  of different USB blocks, X in {0, 1, 2, 3}
- CPG_BUS_PERI_COM_MSTOP.MSTOPX_ON is the register bit controlling the
  MSTOP of different USB blocks, X in {4, 5, 6, 7}
- USB PHY is the USB PHY block exposing 2 ports, port0 and port1, used
  by the USB CH0, USB CH1
- SYSC is the system controller block controlling the PWRRDY signal
- USB CHx are individual USB block with host and function capabilities
  (USB CH0 have both host and function capabilities, USB CH1 has only
  host capabilities)

The USBPHY control registers are controlled though the
reset-rzg2l-usbphy-ctrl driver. The USB PHY ports are controlled by
phy_rcar_gen3_usb2 (drivers/phy/renesas/phy-rcar-gen3-usb2.c file). The
USB PHY ports request resets from the reset-rzg2l-usbphy-ctrl driver.

The connection b/w the system controller and the USB PHY CTRL driver is
implemented through the renesas,sysc-pwrrdy device tree property
proposed in this patch. This property specifies the register offset and the
bitmask required to control the PWRRDY signal.

Since the USB PHY CTRL driver needs to be probed before any other
USB-specific driver on RZ/G3S, control of PWRRDY is passed exclusively
to it. This guarantees the correct configuration sequence between clocks,
MSTOP bits, and the PWRRDY bit. At the same time, changes are kept minimal
by avoiding modifications to the USB PHY driver to also handle the PWRRDY
itself.

Signed-off-by: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
---

Changes in v5:
- none

Changes in v4:
- updated patch description
- updated rzg2l_usbphy_ctrl_pwrrdy_init() to map directly the
  "renesas,sysc-pwrrdy" as the SYSC signal abstraction was dropped
  in this version, along with rz_sysc_get_signal_map()
- dropped priv member of rzg2l_usbphy_ctrl_pwrrdy_init() as it is
  not needed in this version
- shift left !power_on with pwrrdy->mask as this is how the
  regmap_update_bits() needs the last member to be
- selected MFD_SYSCON

Changes in v3:
- none; this patch is new

 drivers/reset/Kconfig                   |  1 +
 drivers/reset/reset-rzg2l-usbphy-ctrl.c | 66 +++++++++++++++++++++++++
 2 files changed, 67 insertions(+)

diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 78b7078478d4..329730cbcfb9 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -237,6 +237,7 @@ config RESET_RASPBERRYPI
 config RESET_RZG2L_USBPHY_CTRL
 	tristate "Renesas RZ/G2L USBPHY control driver"
 	depends on ARCH_RZG2L || COMPILE_TEST
+	select MFD_SYSCON
 	help
 	  Support for USBPHY Control found on RZ/G2L family. It mainly
 	  controls reset and power down of the USB/PHY.
diff --git a/drivers/reset/reset-rzg2l-usbphy-ctrl.c b/drivers/reset/reset-rzg2l-usbphy-ctrl.c
index 8a7f167e405e..3856072b23a3 100644
--- a/drivers/reset/reset-rzg2l-usbphy-ctrl.c
+++ b/drivers/reset/reset-rzg2l-usbphy-ctrl.c
@@ -13,6 +13,7 @@
 #include <linux/regmap.h>
 #include <linux/reset.h>
 #include <linux/reset-controller.h>
+#include <linux/mfd/syscon.h>
 
 #define RESET			0x000
 #define VBENCTL			0x03c
@@ -41,6 +42,18 @@ struct rzg2l_usbphy_ctrl_priv {
 
 #define rcdev_to_priv(x)	container_of(x, struct rzg2l_usbphy_ctrl_priv, rcdev)
 
+/**
+ * struct rzg2l_usbphy_ctrl_pwrrdy - SYSC PWRRDY signal descriptor
+ * @regmap: SYSC regmap
+ * @offset: offset into the SYSC address space for accessing PWRRDY
+ * @mask: mask into the register at offset for accessing PWRRDY
+ */
+struct rzg2l_usbphy_ctrl_pwrrdy {
+	struct regmap *regmap;
+	u32 offset;
+	u32 mask;
+};
+
 static int rzg2l_usbphy_ctrl_assert(struct reset_controller_dev *rcdev,
 				    unsigned long id)
 {
@@ -91,6 +104,8 @@ static int rzg2l_usbphy_ctrl_status(struct reset_controller_dev *rcdev,
 	return !!(readl(priv->base + RESET) & port_mask);
 }
 
+#define RZG2L_USBPHY_CTRL_PWRRDY	1
+
 static const struct of_device_id rzg2l_usbphy_ctrl_match_table[] = {
 	{ .compatible = "renesas,rzg2l-usbphy-ctrl" },
 	{ /* Sentinel */ }
@@ -110,6 +125,53 @@ static const struct regmap_config rzg2l_usb_regconf = {
 	.max_register = 1,
 };
 
+static void rzg2l_usbphy_ctrl_set_pwrrdy(struct rzg2l_usbphy_ctrl_pwrrdy *pwrrdy,
+					 bool power_on)
+{
+	regmap_update_bits(pwrrdy->regmap, pwrrdy->offset, pwrrdy->mask,
+			   !power_on << pwrrdy->mask);
+}
+
+static void rzg2l_usbphy_ctrl_pwrrdy_off(void *data)
+{
+	rzg2l_usbphy_ctrl_set_pwrrdy(data, false);
+}
+
+static int rzg2l_usbphy_ctrl_pwrrdy_init(struct device *dev)
+{
+	struct rzg2l_usbphy_ctrl_pwrrdy *pwrrdy;
+	struct of_phandle_args args;
+	struct regmap *regmap;
+	const int *data;
+	int ret;
+
+	data = device_get_match_data(dev);
+	if (data != (int *)RZG2L_USBPHY_CTRL_PWRRDY)
+		return 0;
+
+	ret = of_parse_phandle_with_fixed_args(dev->of_node, "renesas,sysc-pwrrdy", 2,
+					       0, &args);
+	if (ret)
+		return ret;
+
+	regmap = syscon_node_to_regmap(args.np);
+	of_node_put(args.np);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	pwrrdy = devm_kzalloc(dev, sizeof(*pwrrdy), GFP_KERNEL);
+	if (!pwrrdy)
+		return -ENOMEM;
+
+	pwrrdy->regmap = regmap;
+	pwrrdy->offset = args.args[0];
+	pwrrdy->mask = args.args[1];
+
+	rzg2l_usbphy_ctrl_set_pwrrdy(pwrrdy, true);
+
+	return devm_add_action_or_reset(dev, rzg2l_usbphy_ctrl_pwrrdy_off, pwrrdy);
+}
+
 static int rzg2l_usbphy_ctrl_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -132,6 +194,10 @@ static int rzg2l_usbphy_ctrl_probe(struct platform_device *pdev)
 	if (IS_ERR(regmap))
 		return PTR_ERR(regmap);
 
+	error = rzg2l_usbphy_ctrl_pwrrdy_init(dev);
+	if (error)
+		return error;
+
 	priv->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
 	if (IS_ERR(priv->rstc))
 		return dev_err_probe(dev, PTR_ERR(priv->rstc),
-- 
2.43.0



From claudiu.beznea at tuxon.dev  Mon Aug 18 22:42:10 2025
From: claudiu.beznea at tuxon.dev (Claudiu)
Date: Tue, 19 Aug 2025 08:42:10 +0300
Subject: [PATCH v5 5/7] reset: rzg2l-usbphy-ctrl: Add support for RZ/G3S SoC
In-Reply-To: <20250819054212.486426-1-claudiu.beznea.uj@bp.renesas.com>
References: <20250819054212.486426-1-claudiu.beznea.uj@bp.renesas.com>
Message-ID: <20250819054212.486426-6-claudiu.beznea.uj@bp.renesas.com>

From: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>

The Renesas RZ/G3S SoC USB PHY HW block receives as input the USB PWRRDY
signal from the system controller. Add support for the Renesas RZ/G3S SoC.

Signed-off-by: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
---

Changes in v5:
- none

Changes in v4:
- none

Changes in v3:
- none; this patch is new

 drivers/reset/reset-rzg2l-usbphy-ctrl.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/reset/reset-rzg2l-usbphy-ctrl.c b/drivers/reset/reset-rzg2l-usbphy-ctrl.c
index 3856072b23a3..924c614f84cd 100644
--- a/drivers/reset/reset-rzg2l-usbphy-ctrl.c
+++ b/drivers/reset/reset-rzg2l-usbphy-ctrl.c
@@ -108,6 +108,10 @@ static int rzg2l_usbphy_ctrl_status(struct reset_controller_dev *rcdev,
 
 static const struct of_device_id rzg2l_usbphy_ctrl_match_table[] = {
 	{ .compatible = "renesas,rzg2l-usbphy-ctrl" },
+	{
+		.compatible = "renesas,r9a08g045-usbphy-ctrl",
+		.data = (void *)RZG2L_USBPHY_CTRL_PWRRDY
+	},
 	{ /* Sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, rzg2l_usbphy_ctrl_match_table);
-- 
2.43.0



From claudiu.beznea at tuxon.dev  Mon Aug 18 22:42:11 2025
From: claudiu.beznea at tuxon.dev (Claudiu)
Date: Tue, 19 Aug 2025 08:42:11 +0300
Subject: [PATCH v5 6/7] arm64: dts: renesas: r9a08g045: Add USB support
In-Reply-To: <20250819054212.486426-1-claudiu.beznea.uj@bp.renesas.com>
References: <20250819054212.486426-1-claudiu.beznea.uj@bp.renesas.com>
Message-ID: <20250819054212.486426-7-claudiu.beznea.uj@bp.renesas.com>

From: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>

Add USB nodes for the Renesas RZ/G3S SoC. This consists of PHY reset,
host and device support.

Signed-off-by: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
---

Changes in v5:
- none

Changes in v4:
- dropped renesas,sysc-signals from usb2_phy0, usb2_phy1 nodes
- s/renesas,sysc-signals/renesas,sysc-pwrrdy/g

Changes in v3:
- changed the nodes order to keep similar nodes toghether

Changes in v2:
- this was patch 14/16 in v1
- added renesas,sysc-signal properties to USB PHYs
- collected tags
- Geert: I kept your tag; please let me know if you consider otherwise 

 arch/arm64/boot/dts/renesas/r9a08g045.dtsi | 118 +++++++++++++++++++++
 1 file changed, 118 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r9a08g045.dtsi b/arch/arm64/boot/dts/renesas/r9a08g045.dtsi
index 0364f89776e6..b7ad6db0174b 100644
--- a/arch/arm64/boot/dts/renesas/r9a08g045.dtsi
+++ b/arch/arm64/boot/dts/renesas/r9a08g045.dtsi
@@ -681,6 +681,124 @@ eth1: ethernet at 11c40000 {
 			status = "disabled";
 		};
 
+		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-domains = <&cpg>;
+			#reset-cells = <1>;
+			renesas,sysc-pwrrdy = <&sysc 0xd70 0x1>;
+			status = "disabled";
+
+			usb0_vbus_otg: regulator-vbus {
+				regulator-name = "vbus";
+			};
+		};
+
+		ohci0: usb at 11e10000 {
+			compatible = "generic-ohci";
+			reg = <0 0x11e10000 0 0x100>;
+			interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A08G045_USB_PCLK>,
+				 <&cpg CPG_MOD R9A08G045_USB_U2H0_HCLK>;
+			resets = <&phyrst 0>,
+				 <&cpg R9A08G045_USB_U2H0_HRESETN>;
+			phys = <&usb2_phy0 1>;
+			phy-names = "usb";
+			power-domains = <&cpg>;
+			status = "disabled";
+		};
+
+		ohci1: usb at 11e30000 {
+			compatible = "generic-ohci";
+			reg = <0 0x11e30000 0 0x100>;
+			interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A08G045_USB_PCLK>,
+				 <&cpg CPG_MOD R9A08G045_USB_U2H1_HCLK>;
+			resets = <&phyrst 1>,
+				 <&cpg R9A08G045_USB_U2H1_HRESETN>;
+			phys = <&usb2_phy1 1>;
+			phy-names = "usb";
+			power-domains = <&cpg>;
+			status = "disabled";
+		};
+
+		ehci0: usb at 11e10100 {
+			compatible = "generic-ehci";
+			reg = <0 0x11e10100 0 0x100>;
+			interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A08G045_USB_PCLK>,
+				 <&cpg CPG_MOD R9A08G045_USB_U2H0_HCLK>;
+			resets = <&phyrst 0>,
+				 <&cpg R9A08G045_USB_U2H0_HRESETN>;
+			phys = <&usb2_phy0 2>;
+			phy-names = "usb";
+			companion = <&ohci0>;
+			power-domains = <&cpg>;
+			status = "disabled";
+		};
+
+		ehci1: usb at 11e30100 {
+			compatible = "generic-ehci";
+			reg = <0 0x11e30100 0 0x100>;
+			interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A08G045_USB_PCLK>,
+				 <&cpg CPG_MOD R9A08G045_USB_U2H1_HCLK>;
+			resets = <&phyrst 1>,
+				 <&cpg R9A08G045_USB_U2H1_HRESETN>;
+			phys = <&usb2_phy1 2>;
+			phy-names = "usb";
+			companion = <&ohci1>;
+			power-domains = <&cpg>;
+			status = "disabled";
+		};
+
+		usb2_phy0: usb-phy at 11e10200 {
+			compatible = "renesas,usb2-phy-r9a08g045";
+			reg = <0 0x11e10200 0 0x700>;
+			interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A08G045_USB_PCLK>,
+				 <&cpg CPG_MOD R9A08G045_USB_U2H0_HCLK>;
+			resets = <&phyrst 0>,
+				 <&cpg R9A08G045_USB_U2H0_HRESETN>;
+			#phy-cells = <1>;
+			power-domains = <&cpg>;
+			status = "disabled";
+		};
+
+		usb2_phy1: usb-phy at 11e30200 {
+			compatible = "renesas,usb2-phy-r9a08g045";
+			reg = <0 0x11e30200 0 0x700>;
+			interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A08G045_USB_PCLK>,
+				 <&cpg CPG_MOD R9A08G045_USB_U2H1_HCLK>;
+			resets = <&phyrst 1>,
+				 <&cpg R9A08G045_USB_U2H1_HRESETN>;
+			#phy-cells = <1>;
+			power-domains = <&cpg>;
+			status = "disabled";
+		};
+
+		hsusb: usb at 11e20000 {
+			compatible = "renesas,usbhs-r9a08g045",
+				     "renesas,rzg2l-usbhs";
+			reg = <0 0x11e20000 0 0x10000>;
+			interrupts = <GIC_SPI 85 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD R9A08G045_USB_PCLK>,
+				 <&cpg CPG_MOD R9A08G045_USB_U2P_EXR_CPUCLK>;
+			resets = <&phyrst 0>,
+				 <&cpg R9A08G045_USB_U2P_EXL_SYSRST>;
+			renesas,buswait = <7>;
+			phys = <&usb2_phy0 3>;
+			phy-names = "usb";
+			power-domains = <&cpg>;
+			status = "disabled";
+		};
+
 		gic: interrupt-controller at 12400000 {
 			compatible = "arm,gic-v3";
 			#interrupt-cells = <3>;
-- 
2.43.0



From claudiu.beznea at tuxon.dev  Mon Aug 18 22:42:12 2025
From: claudiu.beznea at tuxon.dev (Claudiu)
Date: Tue, 19 Aug 2025 08:42:12 +0300
Subject: [PATCH v5 7/7] arm64: dts: renesas: rzg3s-smarc: Enable USB support
In-Reply-To: <20250819054212.486426-1-claudiu.beznea.uj@bp.renesas.com>
References: <20250819054212.486426-1-claudiu.beznea.uj@bp.renesas.com>
Message-ID: <20250819054212.486426-8-claudiu.beznea.uj@bp.renesas.com>

From: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>

Enable USB support (host, device, USB PHYs).

Reviewed-by: Geert Uytterhoeven <geert+renesas at glider.be>
Signed-off-by: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
---

Changes in v5:
- none

Changes in v4:
- none

Changes in v3:
- collected tags

Changes in v2:
- this was patch 15/16 in v1:
- dropped sysc enablement as it is now done in SoC dtsi file

 arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi | 57 ++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi b/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi
index 5e044a4d0234..5586dd43c4d5 100644
--- a/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi
+++ b/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi
@@ -92,6 +92,20 @@ &audio_clk2 {
 	clock-frequency = <12288000>;
 };
 
+&ehci0 {
+	dr_mode = "otg";
+	status = "okay";
+};
+
+&ehci1 {
+	status = "okay";
+};
+
+&hsusb {
+	dr_mode = "otg";
+	status = "okay";
+};
+
 &i2c0 {
 	status = "okay";
 
@@ -132,6 +146,15 @@ power-monitor at 44 {
 	};
 };
 
+&ohci0 {
+	dr_mode = "otg";
+	status = "okay";
+};
+
+&ohci1 {
+	status = "okay";
+};
+
 &pinctrl {
 	audio_clock_pins: audio-clock {
 		pins = "AUDIO_CLK1", "AUDIO_CLK2";
@@ -207,6 +230,27 @@ ssi3_pins: ssi3 {
 			 <RZG2L_PORT_PINMUX(18, 4, 8)>, /* TXD */
 			 <RZG2L_PORT_PINMUX(18, 5, 8)>; /* RXD */
 	};
+
+	usb0_pins: usb0 {
+		peri {
+			pinmux = <RZG2L_PORT_PINMUX(5, 0, 1)>, /* VBUS */
+				 <RZG2L_PORT_PINMUX(5, 2, 1)>; /* OVC */
+		};
+
+		otg {
+			pinmux = <RZG2L_PORT_PINMUX(5, 3, 1)>; /* OTG_ID */
+			bias-pull-up;
+		};
+	};
+
+	usb1_pins: usb1 {
+		pinmux = <RZG2L_PORT_PINMUX(5, 4, 5)>, /* OVC */
+			 <RZG2L_PORT_PINMUX(6, 0, 1)>; /* VBUS */
+	};
+};
+
+&phyrst {
+	status = "okay";
 };
 
 &scif0 {
@@ -242,3 +286,16 @@ &ssi3 {
 	pinctrl-0 = <&ssi3_pins>, <&audio_clock_pins>;
 	status = "okay";
 };
+
+&usb2_phy0 {
+	pinctrl-0 = <&usb0_pins>;
+	pinctrl-names = "default";
+	vbus-supply = <&usb0_vbus_otg>;
+	status = "okay";
+};
+
+&usb2_phy1 {
+	pinctrl-0 = <&usb1_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+};
-- 
2.43.0



From biju.das.jz at bp.renesas.com  Mon Aug 18 22:49:32 2025
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Tue, 19 Aug 2025 05:49:32 +0000
Subject: [PATCH v5 2/7] phy: renesas: rcar-gen3-usb2: Fix an error
 handling path in rcar_gen3_phy_usb2_probe()
In-Reply-To: <20250819054212.486426-3-claudiu.beznea.uj@bp.renesas.com>
References: <20250819054212.486426-1-claudiu.beznea.uj@bp.renesas.com>
 <20250819054212.486426-3-claudiu.beznea.uj@bp.renesas.com>
Message-ID: <TY3PR01MB1134647BC6436CA61E0A200F98630A@TY3PR01MB11346.jpnprd01.prod.outlook.com>

Hi Claudiu, Christophe,

Thanks for the patch.

> -----Original Message-----
> From: Claudiu <claudiu.beznea at tuxon.dev>
> Sent: 19 August 2025 06:42
> Subject: [PATCH v5 2/7] phy: renesas: rcar-gen3-usb2: Fix an error handling path in
> rcar_gen3_phy_usb2_probe()
> 
> From: Christophe JAILLET <christophe.jaillet at 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>
> Reviewed-by: Biju Das <biju.das.jz at bp.renesas.com>
> Reviewed-by: Geert Uytterhoeven <geert+renesas at glider.be>
> [claudiu.beznea: removed "struct reset_control *rstc = data;" from  rcar_gen3_reset_assert()]
> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
> ---
> 
> Changes in v5:
> - none
> 
> Changes in v4:
> - none
> 
> Changes in v3:
> - collected tags
> 
> Changes in v2:
> - none; this patch is new; re-spinned the Christophe's work at
> 
> https://lore.kernel.org/all/TYCPR01MB113329930BA5E2149C9BE2A1986672 at TYCPR01MB11332.jpnprd01.prod.outloo
> k.com/
> 
> 
>  drivers/phy/renesas/phy-rcar-gen3-usb2.c | 11 ++++++++++-
>  1 file changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> index 47beb94cd424..d61c171d454f 100644
> --- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> +++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> @@ -699,6 +699,11 @@ static enum usb_dr_mode rcar_gen3_get_dr_mode(struct device_node *np)
>  	return candidate;
>  }
> 
> +static void rcar_gen3_reset_assert(void *data) {
> +	reset_control_assert(data);
> +}
> +
>  static int rcar_gen3_phy_usb2_init_bus(struct rcar_gen3_chan *channel)  {
>  	struct device *dev = channel->dev;
> @@ -717,6 +722,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);

Now 'rstc' can be removed from struct rcar_gen3_chan and use the local rstc pointer
as context variable here.

Cheers,
Biju

> +	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;
> @@ -860,7 +870,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.43.0



From pritam.sutar at samsung.com  Mon Aug 18 22:40:58 2025
From: pritam.sutar at samsung.com (Pritam Manohar Sutar)
Date: Tue, 19 Aug 2025 11:10:58 +0530
Subject: [PATCH v5 4/6] phy: exynos5-usbdrd: support HS combo phy for
 ExynosAutov920
In-Reply-To: <aJtNGGjKy762BLcX@vaman>
References: <20250805115216.3798121-1-pritam.sutar@samsung.com>
	<CGME20250805114316epcas5p49b78db499c2e37a1fe68f4b2f0be62a7@epcas5p4.samsung.com>
	<20250805115216.3798121-5-pritam.sutar@samsung.com> <aJtNGGjKy762BLcX@vaman>
Message-ID: <008401dc10cb$d97ebec0$8c7c3c40$@samsung.com>

Hi Vinod,

> -----Original Message-----
> From: Vinod Koul <vkoul at kernel.org>
> Sent: 12 August 2025 07:48 PM
> To: Pritam Manohar Sutar <pritam.sutar at samsung.com>
> Cc: kishon at kernel.org; robh at kernel.org; krzk+dt at kernel.org;
> conor+dt at kernel.org; alim.akhtar at samsung.com; andre.draszik at linaro.org;
> peter.griffin at linaro.org; kauschluss at disroot.org;
> ivo.ivanov.ivanov1 at gmail.com; igor.belwon at mentallysanemainliners.org;
> m.szyprowski at samsung.com; s.nawrocki at samsung.com; linux-
> phy at lists.infradead.org; devicetree at vger.kernel.org; linux-
> kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
linux-samsung-
> soc at vger.kernel.org; rosa.pila at samsung.com; dev.tailor at samsung.com;
> faraz.ata at samsung.com; muhammed.ali at samsung.com;
> selvarasu.g at samsung.com
> Subject: Re: [PATCH v5 4/6] phy: exynos5-usbdrd: support HS combo phy for
> ExynosAutov920
> 
> On 05-08-25, 17:22, Pritam Manohar Sutar wrote:
> > Support UTMI+ combo phy for this SoC which is somewhat simmilar to
> > what the existing Exynos850 support does. The difference is that some
> > register offsets and bit fields are defferent from Exynos850.
> >
> > Add required change in phy driver to support combo HS phy for this SoC.
> >
> > Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
> > ---
> >  drivers/phy/samsung/phy-exynos5-usbdrd.c | 210
> > +++++++++++++++++++++++
> >  1 file changed, 210 insertions(+)
> >
> > diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c
> > b/drivers/phy/samsung/phy-exynos5-usbdrd.c
> > index 5400dd23e500..c22f4de7d094 100644
> > --- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
> > +++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
> > @@ -41,6 +41,13 @@
> >  #define EXYNOS2200_CLKRST_LINK_PCLK_SEL		BIT(1)
> >
> >  #define EXYNOS2200_DRD_UTMI			0x10
> > +
> > +/* ExynosAutov920 bits */
> > +#define UTMICTL_FORCE_UTMI_SUSPEND		BIT(13)
> > +#define UTMICTL_FORCE_UTMI_SLEEP		BIT(12)
> > +#define UTMICTL_FORCE_DPPULLDOWN		BIT(9)
> > +#define UTMICTL_FORCE_DMPULLDOWN		BIT(8)
> > +
> >  #define EXYNOS2200_UTMI_FORCE_VBUSVALID		BIT(1)
> >  #define EXYNOS2200_UTMI_FORCE_BVALID		BIT(0)
> >
> > @@ -250,6 +257,22 @@
> >  #define EXYNOS850_DRD_HSP_TEST			0x5c
> >  #define HSP_TEST_SIDDQ				BIT(24)
> >
> > +#define EXYNOSAUTOV920_DRD_HSP_CLKRST		0x100
> > +#define HSPCLKRST_PHY20_SW_PORTRESET		BIT(3)
> > +#define HSPCLKRST_PHY20_SW_POR			BIT(1)
> > +#define HSPCLKRST_PHY20_SW_POR_SEL		BIT(0)
> > +
> > +#define EXYNOSAUTOV920_DRD_HSPCTL		0x104
> > +#define HSPCTRL_VBUSVLDEXTSEL			BIT(13)
> > +#define HSPCTRL_VBUSVLDEXT			BIT(12)
> > +#define HSPCTRL_EN_UTMISUSPEND			BIT(9)
> > +#define HSPCTRL_COMMONONN			BIT(8)
> > +
> > +#define EXYNOSAUTOV920_DRD_HSP_TEST		0x10c
> > +
> > +#define EXYNOSAUTOV920_DRD_HSPPLLTUNE		0x110
> > +#define HSPPLLTUNE_FSEL				GENMASK(18, 16)
> > +
> >  /* Exynos9 - GS101 */
> >  #define EXYNOS850_DRD_SECPMACTL			0x48
> >  #define SECPMACTL_PMA_ROPLL_REF_CLK_SEL		GENMASK(13,
> 12)
> > @@ -2054,6 +2077,139 @@ static const struct exynos5_usbdrd_phy_drvdata
> exynos990_usbdrd_phy = {
> >  	.n_regulators		= ARRAY_SIZE(exynos5_regulator_names),
> >  };
> >
> > +static void
> > +exynosautov920_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd) {
> > +	void __iomem *reg_phy = phy_drd->reg_phy;
> > +	u32 reg;
> > +
> > +	/*
> > +	 * Disable HWACG (hardware auto clock gating control). This
> > +	 * forces QACTIVE signal in Q-Channel interface to HIGH level,
> > +	 * to make sure the PHY clock is not gated by the hardware.
> > +	 */
> > +	reg = readl(reg_phy + EXYNOS850_DRD_LINKCTRL);
> > +	reg |= LINKCTRL_FORCE_QACT;
> > +	writel(reg, reg_phy + EXYNOS850_DRD_LINKCTRL);
> 
> maybe add a read-modify-write helper, this is user a lot here

Used this convention for readability purpose. Other SoCs are also using 
convention in this file. 

Moreover, noted this and will consider to clean-up this file later.

> 
> > +
> > +	/* De-assert link reset */
> > +	reg = readl(reg_phy + EXYNOS2200_DRD_CLKRST);
> > +	reg &= ~CLKRST_LINK_SW_RST;
> > +	writel(reg, reg_phy + EXYNOS2200_DRD_CLKRST);
> > +
> > +	/* Set PHY POR High */
> > +	reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSP_CLKRST);
> > +	reg |= HSPCLKRST_PHY20_SW_POR | HSPCLKRST_PHY20_SW_POR_SEL;
> > +	writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSP_CLKRST);
> > +
> > +	/* Enable UTMI+ */
> > +	reg = readl(reg_phy + EXYNOS2200_DRD_UTMI);
> > +	reg &= ~(UTMICTL_FORCE_UTMI_SUSPEND |
> UTMICTL_FORCE_UTMI_SLEEP |
> > +		UTMICTL_FORCE_DPPULLDOWN |
> UTMICTL_FORCE_DMPULLDOWN);
> > +	writel(reg, reg_phy + EXYNOS2200_DRD_UTMI);
> > +
> > +	/* set phy clock & control HS phy */
> > +	reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSPCTL);
> > +	reg |= HSPCTRL_EN_UTMISUSPEND | HSPCTRL_COMMONONN;
> > +	writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSPCTL);
> > +
> > +	fsleep(100);
> > +
> > +	/* Set VBUS Valid and DP-Pull up control by VBUS pad usage */
> > +	reg = readl(reg_phy + EXYNOS850_DRD_LINKCTRL);
> > +	reg |= FIELD_PREP_CONST(LINKCTRL_BUS_FILTER_BYPASS, 0xf);
> > +	writel(reg, reg_phy + EXYNOS850_DRD_LINKCTRL);
> > +
> > +	reg = readl(reg_phy + EXYNOS2200_DRD_UTMI);
> > +	reg |= EXYNOS2200_UTMI_FORCE_VBUSVALID |
> EXYNOS2200_UTMI_FORCE_BVALID;
> > +	writel(reg, reg_phy + EXYNOS2200_DRD_UTMI);
> > +
> > +	reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSPCTL);
> > +	reg |= HSPCTRL_VBUSVLDEXTSEL | HSPCTRL_VBUSVLDEXT;
> > +	writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSPCTL);
> > +
> > +	/* Setting FSEL for refference clock */
> > +	reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSPPLLTUNE);
> > +	reg &= ~HSPPLLTUNE_FSEL;
> 
> Empty line here please

Will add empty line.

> 
> > +	switch (phy_drd->extrefclk) {
> > +	case EXYNOS5_FSEL_50MHZ:
> > +		reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 7);
> > +		break;
> > +	case EXYNOS5_FSEL_26MHZ:
> > +		reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 6);
> > +		break;
> > +	case EXYNOS5_FSEL_24MHZ:
> > +		reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 2);
> > +		break;
> > +	case EXYNOS5_FSEL_20MHZ:
> > +		reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 1);
> > +		break;
> > +	case EXYNOS5_FSEL_19MHZ2:
> > +		reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 0);
> > +		break;
> > +	default:
> > +		dev_warn(phy_drd->dev, "unsupported ref clk: %#.2x\n",
> > +			 phy_drd->extrefclk);
> 
> but we still continue?

This SoC supports 19.2Mhz refclk and it sets default reg value for this
refclk if it does not find clk.

> --
> ~Vinod

Thank you,

Regards,
Pritam



From claudiu.beznea at tuxon.dev  Mon Aug 18 23:01:20 2025
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Tue, 19 Aug 2025 09:01:20 +0300
Subject: [PATCH v5 2/7] phy: renesas: rcar-gen3-usb2: Fix an error
 handling path in rcar_gen3_phy_usb2_probe()
In-Reply-To: <TY3PR01MB1134647BC6436CA61E0A200F98630A@TY3PR01MB11346.jpnprd01.prod.outlook.com>
References: <20250819054212.486426-1-claudiu.beznea.uj@bp.renesas.com>
 <20250819054212.486426-3-claudiu.beznea.uj@bp.renesas.com>
 <TY3PR01MB1134647BC6436CA61E0A200F98630A@TY3PR01MB11346.jpnprd01.prod.outlook.com>
Message-ID: <bc053bca-8dd9-4a50-a352-290b38a329b0@tuxon.dev>

Hi, Biju,

On 8/19/25 08:49, Biju Das wrote:
> Hi Claudiu, Christophe,
> 
> Thanks for the patch.
> 
>> -----Original Message-----
>> From: Claudiu <claudiu.beznea at tuxon.dev>
>> Sent: 19 August 2025 06:42
>> Subject: [PATCH v5 2/7] phy: renesas: rcar-gen3-usb2: Fix an error handling path in
>> rcar_gen3_phy_usb2_probe()
>>
>> From: Christophe JAILLET <christophe.jaillet at 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>
>> Reviewed-by: Biju Das <biju.das.jz at bp.renesas.com>
>> Reviewed-by: Geert Uytterhoeven <geert+renesas at glider.be>
>> [claudiu.beznea: removed "struct reset_control *rstc = data;" from  rcar_gen3_reset_assert()]
>> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
>> ---
>>
>> Changes in v5:
>> - none
>>
>> Changes in v4:
>> - none
>>
>> Changes in v3:
>> - collected tags
>>
>> Changes in v2:
>> - none; this patch is new; re-spinned the Christophe's work at
>>
>> https://lore.kernel.org/all/TYCPR01MB113329930BA5E2149C9BE2A1986672 at TYCPR01MB11332.jpnprd01.prod.outloo
>> k.com/
>>
>>
>>   drivers/phy/renesas/phy-rcar-gen3-usb2.c | 11 ++++++++++-
>>   1 file changed, 10 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
>> index 47beb94cd424..d61c171d454f 100644
>> --- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
>> +++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
>> @@ -699,6 +699,11 @@ static enum usb_dr_mode rcar_gen3_get_dr_mode(struct device_node *np)
>>   	return candidate;
>>   }
>>
>> +static void rcar_gen3_reset_assert(void *data) {
>> +	reset_control_assert(data);
>> +}
>> +
>>   static int rcar_gen3_phy_usb2_init_bus(struct rcar_gen3_chan *channel)  {
>>   	struct device *dev = channel->dev;
>> @@ -717,6 +722,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);
> 
> Now 'rstc' can be removed from struct rcar_gen3_chan and use the local rstc pointer
> as context variable here.

I can drop it now but it will be added later (after this series) along with 
suspend to RAM support. That is the reason I preferred to still keep it.

Thank you,
Claudiu

> 
> Cheers,
> Biju
> 
>> +	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;
>> @@ -860,7 +870,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.43.0
> 



From robh at kernel.org  Mon Aug 18 23:29:17 2025
From: robh at kernel.org (Rob Herring (Arm))
Date: Tue, 19 Aug 2025 01:29:17 -0500
Subject: [PATCH v5 1/7] dt-bindings: phy: renesas,usb2-phy: Mark resets
 as required for RZ/G3S
In-Reply-To: <20250819054212.486426-2-claudiu.beznea.uj@bp.renesas.com>
References: <20250819054212.486426-1-claudiu.beznea.uj@bp.renesas.com>
 <20250819054212.486426-2-claudiu.beznea.uj@bp.renesas.com>
Message-ID: <175558495459.3265640.2032619822487575179.robh@kernel.org>


On Tue, 19 Aug 2025 08:42:06 +0300, Claudiu wrote:
> From: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
> 
> The reset lines are mandatory for the Renesas RZ/G3S platform and must be
> explicitly defined in device tree.
> 
> Fixes: f3c849855114 ("dt-bindings: phy: renesas,usb2-phy: Document RZ/G3S phy bindings")
> Reviewed-by: Geert Uytterhoeven <geert+renesas at glider.be>
> Acked-by: Conor Dooley <conor.dooley at microchip.com>
> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
> ---
> 
> Changes in v5:
> - none
> 
> Changes in v4:
> - none
> 
> Changes in v3:
> - collected tags
> - rebased on top of latest version of renesas,usb2-phy.yaml;
>   Conor, Geert: I kept your tags; please let me know if you consider it
>   otherwise
> 
> Changes in v2:
> - none; this patch is new
> 
>  Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:


doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20250819054212.486426-2-claudiu.beznea.uj at bp.renesas.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 robh at kernel.org  Mon Aug 18 23:29:18 2025
From: robh at kernel.org (Rob Herring (Arm))
Date: Tue, 19 Aug 2025 01:29:18 -0500
Subject: [PATCH v5 3/7] dt-bindings: reset: renesas,rzg2l-usbphy-ctrl:
 Document RZ/G3S support
In-Reply-To: <20250819054212.486426-4-claudiu.beznea.uj@bp.renesas.com>
References: <20250819054212.486426-1-claudiu.beznea.uj@bp.renesas.com>
 <20250819054212.486426-4-claudiu.beznea.uj@bp.renesas.com>
Message-ID: <175558495586.3265727.15591420113777968646.robh@kernel.org>


On Tue, 19 Aug 2025 08:42:08 +0300, Claudiu wrote:
> From: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
> 
> The Renesas USB PHY hardware block needs to have the PWRRDY bit in the
> system controller set before applying any other settings. The PWRRDY bit
> must be controlled during power-on, power-off, and system suspend/resume
> sequences as follows:
> - during power-on/resume, it must be set to zero before enabling clocks and
>   modules
> - during power-off/suspend, it must be set to one after disabling clocks
>   and modules
> 
> Add the renesas,sysc-pwrrdy device tree property, which allows the
> reset-rzg2l-usbphy-ctrl driver to parse, map, and control the system
> controller PWRRDY bit at the appropriate time. Along with it add a new
> compatible for the RZ/G3S SoC.
> 
> Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
> ---
> 
> Changes in v5:
> - fixed description formatting
> - collected tags
> 
> Changes in v4:
> - dropped blank line from compatible section
> - s/renesas,sysc-signals/renesas,sysc-pwrrdy/g
> - dropped description from renesas,sysc-pwrrdy
> - updated description of renesas,sysc-pwrrdy items
> - updated patch description
> 
> Changes in v3:
> - none; this patch is new
> 
>  .../reset/renesas,rzg2l-usbphy-ctrl.yaml      | 41 ++++++++++++++++---
>  1 file changed, 35 insertions(+), 6 deletions(-)
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:


doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20250819054212.486426-4-claudiu.beznea.uj at bp.renesas.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  Mon Aug 18 23:34:03 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 19 Aug 2025 08:34:03 +0200
Subject: [PATCH v3 11/12] PCI: exynos: Add support for Tesla FSD SoC
In-Reply-To: <20250818182544.GA534647@bhelgaas>
References: <20250818182544.GA534647@bhelgaas>
Message-ID: <29287880-9436-4acd-b3f9-b4d9eb726896@kernel.org>

On 18/08/2025 20:25, Bjorn Helgaas wrote:
> [+to Krzysztof]
> 
> On Mon, Aug 18, 2025 at 03:00:00PM +0530, Shradha Todi wrote:
>>> On Mon, Aug 11, 2025 at 09:16:37PM +0530, Shradha Todi wrote:
>>>> Add host and endpoint controller driver support for FSD SoC.
> 
>>> It's kind of unfortunate that the driver uses "ep" everywhere for
>>> struct exynos_pcie pointers.  It's going to be confusing because "ep"
>>> is also commonly used for endpoint-related things, e.g., struct
>>> dw_pcie_ep pointers.  Maybe it's not worth changing; I dunno.
>>
>> I did try to rename the structure and the pointers 
>> (https://lore.kernel.org/all/20230214121333.1837-9-shradha.t at samsung.com/)
>> But the intention was different back then and so the idea was rejected.
>> I could add a patch to only rename the pointers to something less
>> confusing like "exy_pci"
> 
> The patch you mention did several renames:
> 
>   s/to_exynos_pcie/to_samsung_pcie/
>   s/struct exynos_pcie/struct samsung_pcie/
>   s/struct exynos_pcie *ep/struct samsung_pcie *sp/
> 
> I'm only concerned about the confusion of "ep" being used both for
> "struct exynos_pcie *" and for "struct dw_pcie_ep *".
> 
> It would still be sort of an annoying patch to do something like this:
> 
>   s/struct exynos_pcie *ep/struct exynos_pcie *pcie/
> 
> But 'git grep "struct .*_pcie \*.*=" drivers/pci/controller/' says
> using "pcie" in this way is quite common, so maybe it would be worth
> doing.
> 
> What do you think, Krzysztof?

I think you want other Krzysztof, but nevertheless, the reasoning there
"Changing it to samsung_pcie for making it
generic."
is wrong. The naming of these structures do not matter, they are not
less generic. This is rather churn, which will affect backporting for
ZERO readability increase. Why zero? Because calling all this "exynos"
is the same as calling all this "samsung". It just does not matter.

However s/ep/pcie/ in variable name makes sense if that's more common.


Best regards,
Krzysztof


From biju.das.jz at bp.renesas.com  Mon Aug 18 23:34:12 2025
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Tue, 19 Aug 2025 06:34:12 +0000
Subject: [PATCH v5 2/7] phy: renesas: rcar-gen3-usb2: Fix an error
 handling path in rcar_gen3_phy_usb2_probe()
In-Reply-To: <bc053bca-8dd9-4a50-a352-290b38a329b0@tuxon.dev>
References: <20250819054212.486426-1-claudiu.beznea.uj@bp.renesas.com>
 <20250819054212.486426-3-claudiu.beznea.uj@bp.renesas.com>
 <TY3PR01MB1134647BC6436CA61E0A200F98630A@TY3PR01MB11346.jpnprd01.prod.outlook.com>
 <bc053bca-8dd9-4a50-a352-290b38a329b0@tuxon.dev>
Message-ID: <TY3PR01MB11346CA32F5E4B4329C46112D8630A@TY3PR01MB11346.jpnprd01.prod.outlook.com>

Hi Claudiu,

> -----Original Message-----
> From: claudiu beznea <claudiu.beznea at tuxon.dev>
> Sent: 19 August 2025 07:01
> Subject: Re: [PATCH v5 2/7] phy: renesas: rcar-gen3-usb2: Fix an error handling path in
> rcar_gen3_phy_usb2_probe()
> 
> Hi, Biju,
> 
> On 8/19/25 08:49, Biju Das wrote:
> > Hi Claudiu, Christophe,
> >
> > Thanks for the patch.
> >
> >> -----Original Message-----
> >> From: Claudiu <claudiu.beznea at tuxon.dev>
> >> Sent: 19 August 2025 06:42
> >> Subject: [PATCH v5 2/7] phy: renesas: rcar-gen3-usb2: Fix an error
> >> handling path in
> >> rcar_gen3_phy_usb2_probe()
> >>
> >> From: Christophe JAILLET <christophe.jaillet at 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>
> >> Reviewed-by: Biju Das <biju.das.jz at bp.renesas.com>
> >> Reviewed-by: Geert Uytterhoeven <geert+renesas at glider.be>
> >> [claudiu.beznea: removed "struct reset_control *rstc = data;" from
> >> rcar_gen3_reset_assert()]
> >> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
> >> ---
> >>
> >> Changes in v5:
> >> - none
> >>
> >> Changes in v4:
> >> - none
> >>
> >> Changes in v3:
> >> - collected tags
> >>
> >> Changes in v2:
> >> - none; this patch is new; re-spinned the Christophe's work at
> >>
> >> https://lore.kernel.org/all/TYCPR01MB113329930BA5E2149C9BE2A1986672 at T
> >> YCPR01MB11332.jpnprd01.prod.outloo
> >> k.com/
> >>
> >>
> >>   drivers/phy/renesas/phy-rcar-gen3-usb2.c | 11 ++++++++++-
> >>   1 file changed, 10 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> >> b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> >> index 47beb94cd424..d61c171d454f 100644
> >> --- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> >> +++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> >> @@ -699,6 +699,11 @@ static enum usb_dr_mode rcar_gen3_get_dr_mode(struct device_node *np)
> >>   	return candidate;
> >>   }
> >>
> >> +static void rcar_gen3_reset_assert(void *data) {
> >> +	reset_control_assert(data);
> >> +}
> >> +
> >>   static int rcar_gen3_phy_usb2_init_bus(struct rcar_gen3_chan *channel)  {
> >>   	struct device *dev = channel->dev; @@ -717,6 +722,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);
> >
> > Now 'rstc' can be removed from struct rcar_gen3_chan and use the local
> > rstc pointer as context variable here.
> 
> I can drop it now but it will be added later (after this series) along with suspend to RAM support.
> That is the reason I preferred to still keep it.

There is a fixes tag which will be propagated to stable kernel. 
If you don't have any plan to send new series, then it is OK I guess??

Cheers,
Biju

From vkoul at kernel.org  Mon Aug 18 23:54:42 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Tue, 19 Aug 2025 12:24:42 +0530
Subject: [PATCH v5 6/6] phy: exynos5-usbdrd: support SS combo phy for
 ExynosAutov920
In-Reply-To: <038a01dc1013$900a2800$b01e7800$@samsung.com>
References: <20250805115216.3798121-1-pritam.sutar@samsung.com>
 <CGME20250805114323epcas5p39bf73c5e0a9382ff54b1832724804cc9@epcas5p3.samsung.com>
 <20250805115216.3798121-7-pritam.sutar@samsung.com>
 <aJtN7uVUV3YhfY5-@vaman>
 <038a01dc1013$900a2800$b01e7800$@samsung.com>
Message-ID: <aKQfsgRXL-Nj8CkC@vaman>

On 18-08-25, 13:11, Pritam Manohar Sutar wrote:

> > > +	/* check cr_para_ack*/
> > > +	cnt = 0;
> > > +	do {
> > > +		/*
> > > +		 * data symbols are captured by phy on rising edge of the
> > > +		 * tx_clk when tx data enabled.
> > > +		 * completion of the write cycle is acknowledged by
> assertion
> > > +		 * of the cr_para_ack.
> > > +		 */
> > > +		exynosautov920_usb31drd_cr_clk(phy_drd, true);
> > > +		reg = readl(reg_phy +
> > EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
> > > +		if ((reg & PHY_CR_PARA_CON0_PHY0_CR_PARA_ACK))
> > > +			break;
> > > +
> > > +		exynosautov920_usb31drd_cr_clk(phy_drd, false);
> > > +
> > > +		/*
> > > +		 * wait for minimum of 10 cr_para_clk cycles after phy reset
> > > +		 * is negated, before accessing control regs to allow for
> > > +		 * internal resets.
> > > +		 */
> > > +		cnt++;
> > > +	} while (cnt < 10);
> > > +
> > > +	if (cnt == 10)
> > > +		dev_dbg(dev, "CR write failed to 0x%04x\n", addr);
> > 
> > Not error?
> 
> This is only for debugging purpose. It is not considered as error. 

Write failed is not an error? If this code is only for debug, pls drop
it. 

-- 
~Vinod


From mwalle at kernel.org  Mon Aug 18 23:56:22 2025
From: mwalle at kernel.org (Michael Walle)
Date: Tue, 19 Aug 2025 08:56:22 +0200
Subject: [PATCH v3] phy: ti: gmii-sel: Always write the RGMII ID setting
Message-ID: <20250819065622.1019537-1-mwalle@kernel.org>

Some SoCs are just validated with the TX delay enabled. With commit
ca13b249f291 ("net: ethernet: ti: am65-cpsw: fixup PHY mode for fixed
RGMII TX delay"), the network driver will patch the delay setting on the
fly assuming that the TX delay setting is fixed. In reality, the TX
delay is configurable and just skipped in the documentation. There are
bootloaders, which will disable the TX delay and this will lead to a
transmit path which doesn't add any delays at all.
Fix that by always writing the RGMII_ID setting and report an error for
unsupported RGMII delay modes.

This is safe to do and shouldn't break any boards in mainline because
the fixed delay is only introduced for gmii-sel compatibles which are
used together with the am65-cpsw-nuss driver and also contains the
commit above.

Fixes: ca13b249f291 ("net: ethernet: ti: am65-cpsw: fixup PHY mode for fixed RGMII TX delay")
Signed-off-by: Michael Walle <mwalle at kernel.org>
---
v3:
 - simplify the logic. Thanks Matthias.
 - reworded the commit message

v2:
 - reject invalid PHY modes. Thanks Matthias.
 - add a paragraph to the commit message that this patch shouldn't
   break any existing boards. Thanks Andrew.

 drivers/phy/ti/phy-gmii-sel.c | 47 +++++++++++++++++++++++++++++------
 1 file changed, 39 insertions(+), 8 deletions(-)

diff --git a/drivers/phy/ti/phy-gmii-sel.c b/drivers/phy/ti/phy-gmii-sel.c
index ff5d5e29629f..50adabb867cb 100644
--- a/drivers/phy/ti/phy-gmii-sel.c
+++ b/drivers/phy/ti/phy-gmii-sel.c
@@ -34,6 +34,7 @@ enum {
 	PHY_GMII_SEL_PORT_MODE = 0,
 	PHY_GMII_SEL_RGMII_ID_MODE,
 	PHY_GMII_SEL_RMII_IO_CLK_EN,
+	PHY_GMII_SEL_FIXED_TX_DELAY,
 	PHY_GMII_SEL_LAST,
 };
 
@@ -127,6 +128,11 @@ static int phy_gmii_sel_mode(struct phy *phy, enum phy_mode mode, int submode)
 		goto unsupported;
 	}
 
+	/* With a fixed delay, some modes are not supported at all. */
+	if (soc_data->features & BIT(PHY_GMII_SEL_FIXED_TX_DELAY) &&
+	    rgmii_id != 0)
+		return -EINVAL;
+
 	if_phy->phy_if_mode = submode;
 
 	dev_dbg(dev, "%s id:%u mode:%u rgmii_id:%d rmii_clk_ext:%d\n",
@@ -210,25 +216,46 @@ struct phy_gmii_sel_soc_data phy_gmii_sel_soc_dm814 = {
 
 static const
 struct reg_field phy_gmii_sel_fields_am654[][PHY_GMII_SEL_LAST] = {
-	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x0, 0, 2), },
-	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x4, 0, 2), },
-	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x8, 0, 2), },
-	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0xC, 0, 2), },
-	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x10, 0, 2), },
-	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x14, 0, 2), },
-	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x18, 0, 2), },
-	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x1C, 0, 2), },
+	{
+		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x0, 0, 2),
+		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x0, 4, 4),
+	}, {
+		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x4, 0, 2),
+		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x4, 4, 4),
+	}, {
+		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x8, 0, 2),
+		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x8, 4, 4),
+	}, {
+		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0xC, 0, 2),
+		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0xC, 4, 4),
+	}, {
+		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x10, 0, 2),
+		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x10, 4, 4),
+	}, {
+		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x14, 0, 2),
+		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x14, 4, 4),
+	}, {
+		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x18, 0, 2),
+		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x18, 4, 4),
+	}, {
+		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x1C, 0, 2),
+		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x1C, 4, 4),
+	},
 };
 
 static const
 struct phy_gmii_sel_soc_data phy_gmii_sel_soc_am654 = {
 	.use_of_data = true,
+	.features = BIT(PHY_GMII_SEL_RGMII_ID_MODE) |
+		    BIT(PHY_GMII_SEL_FIXED_TX_DELAY),
 	.regfields = phy_gmii_sel_fields_am654,
 };
 
 static const
 struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw5g_soc_j7200 = {
 	.use_of_data = true,
+	.features = BIT(PHY_GMII_SEL_RGMII_ID_MODE) |
+		    BIT(PHY_GMII_SEL_FIXED_TX_DELAY),
 	.regfields = phy_gmii_sel_fields_am654,
 	.extra_modes = BIT(PHY_INTERFACE_MODE_QSGMII) | BIT(PHY_INTERFACE_MODE_SGMII) |
 		       BIT(PHY_INTERFACE_MODE_USXGMII),
@@ -239,6 +266,8 @@ struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw5g_soc_j7200 = {
 static const
 struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw9g_soc_j721e = {
 	.use_of_data = true,
+	.features = BIT(PHY_GMII_SEL_RGMII_ID_MODE) |
+		    BIT(PHY_GMII_SEL_FIXED_TX_DELAY),
 	.regfields = phy_gmii_sel_fields_am654,
 	.extra_modes = BIT(PHY_INTERFACE_MODE_QSGMII) | BIT(PHY_INTERFACE_MODE_SGMII),
 	.num_ports = 8,
@@ -248,6 +277,8 @@ struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw9g_soc_j721e = {
 static const
 struct phy_gmii_sel_soc_data phy_gmii_sel_cpsw9g_soc_j784s4 = {
 	.use_of_data = true,
+	.features = BIT(PHY_GMII_SEL_RGMII_ID_MODE) |
+		    BIT(PHY_GMII_SEL_FIXED_TX_DELAY),
 	.regfields = phy_gmii_sel_fields_am654,
 	.extra_modes = BIT(PHY_INTERFACE_MODE_QSGMII) | BIT(PHY_INTERFACE_MODE_SGMII) |
 		       BIT(PHY_INTERFACE_MODE_USXGMII),
-- 
2.39.5



From ziyue.zhang at oss.qualcomm.com  Tue Aug 19 00:16:45 2025
From: ziyue.zhang at oss.qualcomm.com (Ziyue Zhang)
Date: Tue, 19 Aug 2025 15:16:45 +0800
Subject: [PATCH v5 0/3] Add Equalization Settings for 8.0 GT/s and 32.0 GT/s and Add PCIe Lane Equalization Preset Properties for 8.0 GT/s and 16.0 GT/s
Message-ID: <20250819071649.1531437-1-ziyue.zhang@oss.qualcomm.com>

This series adds add equalization settings for 8.0 GT/s and 32.0 GT/s,
and add PCIe lane equalization preset properties for 8.0 GT/s and
16.0 GT/s for sa8775p ride platform, which fix AER errors.

While equalization settings for 16 GT/s have already been set, this
update adds the required equalization settings for PCIe operating at
8.0 GT/s and 32.0 GT/s, including the configuration of shadow registers,
ensuring optimal performance and stability.

The DT change for sa8775p add PCIe lane equalization preset properties
for 8 GT/s and 16 GT/s data rates used in lane equalization procedure.

Signed-off-by: Ziyue Zhang <ziyue.zhang at oss.qualcomm.com>

Changes in v5:
- Add support for 32.0 GT/s
- Add warning print for speed higher than 32.0 GT/s (Mani)
- Link to v4: https://lore.kernel.org/all/20250714082110.3890821-1-ziyue.zhang at oss.qualcomm.com/

Changes in v4:
- Bail out early if the link speed > 16 GT/s and use pci->max_link_speed directly (Mani)
- Fix the build warning. (Bjorn)
- Link to v3: https://lore.kernel.org/all/8ccd3731-8dbc-4972-a79a-ba78e90ec4a8 at quicinc.com/

Changes in v3:
- Delte TODO tag and warn print in pcie-qcom-common.c. (Bjorn)
- Refined the commit message for better readability. (Bjorn)
- Link to v2: https://lore.kernel.org/all/20250611100319.464803-1-quic_ziyuzhan at quicinc.com/

Changes in v2:
- Update code in pcie-qcom-common.c make it easier to read. (Neil)
- Fix the compile error.
- Link to v1: https://lore.kernel.org/all/20250604091946.1890602-1-quic_ziyuzhan at quicinc.com

Ziyue Zhang (3):
  PCI: qcom: Add equalization settings for 8.0 GT/s and 32.0 GT/s
  PCI: qcom: fix macro typo for CURSOR
  arm64: dts: qcom: lemans: Add PCIe lane equalization preset properties

 arch/arm64/boot/dts/qcom/lemans.dtsi          |  7 +++
 drivers/pci/controller/dwc/pcie-designware.h  |  5 +-
 drivers/pci/controller/dwc/pcie-qcom-common.c | 58 +++++++++++--------
 drivers/pci/controller/dwc/pcie-qcom-common.h |  2 +-
 drivers/pci/controller/dwc/pcie-qcom-ep.c     |  6 +-
 drivers/pci/controller/dwc/pcie-qcom.c        |  6 +-
 6 files changed, 50 insertions(+), 34 deletions(-)


base-commit: 3ac864c2d9bb8608ee236e89bf561811613abfce
-- 
2.43.0



From ziyue.zhang at oss.qualcomm.com  Tue Aug 19 00:16:46 2025
From: ziyue.zhang at oss.qualcomm.com (Ziyue Zhang)
Date: Tue, 19 Aug 2025 15:16:46 +0800
Subject: [PATCH v5 1/3] PCI: qcom: Add equalization settings for 8.0 GT/s and 32.0 GT/s
In-Reply-To: <20250819071649.1531437-1-ziyue.zhang@oss.qualcomm.com>
References: <20250819071649.1531437-1-ziyue.zhang@oss.qualcomm.com>
Message-ID: <20250819071649.1531437-2-ziyue.zhang@oss.qualcomm.com>

Add lane equalization setting for 8.0 GT/s and 32.0 GT/s to enhance link
stability and avoid AER Correctable Errors reported on some platforms
(eg. SA8775P).

8.0 GT/s, 16.0 GT/s and 32.0 GT/s require the same equalization setting.
This setting is programmed into a group of shadow registers, which can be
switched to configure equalization for different speeds by writing 00b,
01b and 10b to `RATE_SHADOW_SEL`.

Hence program equalization registers in a loop using link speed as index,
so that equalization setting can be programmed for 8.0 GT/s, 16.0 GT/s
and 32.0 GT/s.

Co-developed-by: Qiang Yu <qiang.yu at oss.qualcomm.com>
Signed-off-by: Qiang Yu <qiang.yu at oss.qualcomm.com>
Signed-off-by: Ziyue Zhang <ziyue.zhang at oss.qualcomm.com>
---
 drivers/pci/controller/dwc/pcie-designware.h  |  1 -
 drivers/pci/controller/dwc/pcie-qcom-common.c | 58 +++++++++++--------
 drivers/pci/controller/dwc/pcie-qcom-common.h |  2 +-
 drivers/pci/controller/dwc/pcie-qcom-ep.c     |  6 +-
 drivers/pci/controller/dwc/pcie-qcom.c        |  6 +-
 5 files changed, 41 insertions(+), 32 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index b5e7e18138a6..11de844428e5 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -123,7 +123,6 @@
 #define GEN3_RELATED_OFF_GEN3_EQ_DISABLE	BIT(16)
 #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_SHIFT	24
 #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK	GENMASK(25, 24)
-#define GEN3_RELATED_OFF_RATE_SHADOW_SEL_16_0GT	0x1
 
 #define GEN3_EQ_CONTROL_OFF			0x8A8
 #define GEN3_EQ_CONTROL_OFF_FB_MODE		GENMASK(3, 0)
diff --git a/drivers/pci/controller/dwc/pcie-qcom-common.c b/drivers/pci/controller/dwc/pcie-qcom-common.c
index 3aad19b56da8..cb98e66d81d9 100644
--- a/drivers/pci/controller/dwc/pcie-qcom-common.c
+++ b/drivers/pci/controller/dwc/pcie-qcom-common.c
@@ -8,9 +8,11 @@
 #include "pcie-designware.h"
 #include "pcie-qcom-common.h"
 
-void qcom_pcie_common_set_16gt_equalization(struct dw_pcie *pci)
+void qcom_pcie_common_set_equalization(struct dw_pcie *pci)
 {
 	u32 reg;
+	u16 speed;
+	struct device *dev = pci->dev;
 
 	/*
 	 * GEN3_RELATED_OFF register is repurposed to apply equalization
@@ -19,32 +21,40 @@ void qcom_pcie_common_set_16gt_equalization(struct dw_pcie *pci)
 	 * determines the data rate for which these equalization settings are
 	 * applied.
 	 */
-	reg = dw_pcie_readl_dbi(pci, GEN3_RELATED_OFF);
-	reg &= ~GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL;
-	reg &= ~GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK;
-	reg |= FIELD_PREP(GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK,
-			  GEN3_RELATED_OFF_RATE_SHADOW_SEL_16_0GT);
-	dw_pcie_writel_dbi(pci, GEN3_RELATED_OFF, reg);
 
-	reg = dw_pcie_readl_dbi(pci, GEN3_EQ_FB_MODE_DIR_CHANGE_OFF);
-	reg &= ~(GEN3_EQ_FMDC_T_MIN_PHASE23 |
-		GEN3_EQ_FMDC_N_EVALS |
-		GEN3_EQ_FMDC_MAX_PRE_CUSROR_DELTA |
-		GEN3_EQ_FMDC_MAX_POST_CUSROR_DELTA);
-	reg |= FIELD_PREP(GEN3_EQ_FMDC_T_MIN_PHASE23, 0x1) |
-		FIELD_PREP(GEN3_EQ_FMDC_N_EVALS, 0xd) |
-		FIELD_PREP(GEN3_EQ_FMDC_MAX_PRE_CUSROR_DELTA, 0x5) |
-		FIELD_PREP(GEN3_EQ_FMDC_MAX_POST_CUSROR_DELTA, 0x5);
-	dw_pcie_writel_dbi(pci, GEN3_EQ_FB_MODE_DIR_CHANGE_OFF, reg);
+	for (speed = PCIE_SPEED_8_0GT; speed <= pcie_link_speed[pci->max_link_speed]; ++speed) {
+		if (speed > PCIE_SPEED_32_0GT) {
+			dev_warn(dev, "Skipped equalization settings for speeds higher than 32.0 GT/s\n");
+			break;
+		}
 
-	reg = dw_pcie_readl_dbi(pci, GEN3_EQ_CONTROL_OFF);
-	reg &= ~(GEN3_EQ_CONTROL_OFF_FB_MODE |
-		GEN3_EQ_CONTROL_OFF_PHASE23_EXIT_MODE |
-		GEN3_EQ_CONTROL_OFF_FOM_INC_INITIAL_EVAL |
-		GEN3_EQ_CONTROL_OFF_PSET_REQ_VEC);
-	dw_pcie_writel_dbi(pci, GEN3_EQ_CONTROL_OFF, reg);
+		reg = dw_pcie_readl_dbi(pci, GEN3_RELATED_OFF);
+		reg &= ~GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL;
+		reg &= ~GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK;
+		reg |= FIELD_PREP(GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK,
+			  speed - PCIE_SPEED_8_0GT);
+		dw_pcie_writel_dbi(pci, GEN3_RELATED_OFF, reg);
+
+		reg = dw_pcie_readl_dbi(pci, GEN3_EQ_FB_MODE_DIR_CHANGE_OFF);
+		reg &= ~(GEN3_EQ_FMDC_T_MIN_PHASE23 |
+			GEN3_EQ_FMDC_N_EVALS |
+			GEN3_EQ_FMDC_MAX_PRE_CUSROR_DELTA |
+			GEN3_EQ_FMDC_MAX_POST_CUSROR_DELTA);
+		reg |= FIELD_PREP(GEN3_EQ_FMDC_T_MIN_PHASE23, 0x1) |
+			FIELD_PREP(GEN3_EQ_FMDC_N_EVALS, 0xd) |
+			FIELD_PREP(GEN3_EQ_FMDC_MAX_PRE_CUSROR_DELTA, 0x5) |
+			FIELD_PREP(GEN3_EQ_FMDC_MAX_POST_CUSROR_DELTA, 0x5);
+		dw_pcie_writel_dbi(pci, GEN3_EQ_FB_MODE_DIR_CHANGE_OFF, reg);
+
+		reg = dw_pcie_readl_dbi(pci, GEN3_EQ_CONTROL_OFF);
+		reg &= ~(GEN3_EQ_CONTROL_OFF_FB_MODE |
+			GEN3_EQ_CONTROL_OFF_PHASE23_EXIT_MODE |
+			GEN3_EQ_CONTROL_OFF_FOM_INC_INITIAL_EVAL |
+			GEN3_EQ_CONTROL_OFF_PSET_REQ_VEC);
+		dw_pcie_writel_dbi(pci, GEN3_EQ_CONTROL_OFF, reg);
+	}
 }
-EXPORT_SYMBOL_GPL(qcom_pcie_common_set_16gt_equalization);
+EXPORT_SYMBOL_GPL(qcom_pcie_common_set_equalization);
 
 void qcom_pcie_common_set_16gt_lane_margining(struct dw_pcie *pci)
 {
diff --git a/drivers/pci/controller/dwc/pcie-qcom-common.h b/drivers/pci/controller/dwc/pcie-qcom-common.h
index 7d88d29e4766..7f5ca2fd9a72 100644
--- a/drivers/pci/controller/dwc/pcie-qcom-common.h
+++ b/drivers/pci/controller/dwc/pcie-qcom-common.h
@@ -8,7 +8,7 @@
 
 struct dw_pcie;
 
-void qcom_pcie_common_set_16gt_equalization(struct dw_pcie *pci);
+void qcom_pcie_common_set_equalization(struct dw_pcie *pci);
 void qcom_pcie_common_set_16gt_lane_margining(struct dw_pcie *pci);
 
 #endif
diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c
index 60afb4d0134c..aeb166f68d55 100644
--- a/drivers/pci/controller/dwc/pcie-qcom-ep.c
+++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c
@@ -511,10 +511,10 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci)
 		goto err_disable_resources;
 	}
 
-	if (pcie_link_speed[pci->max_link_speed] == PCIE_SPEED_16_0GT) {
-		qcom_pcie_common_set_16gt_equalization(pci);
+	qcom_pcie_common_set_equalization(pci);
+
+	if (pcie_link_speed[pci->max_link_speed] == PCIE_SPEED_16_0GT)
 		qcom_pcie_common_set_16gt_lane_margining(pci);
-	}
 
 	/*
 	 * The physical address of the MMIO region which is exposed as the BAR
diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index 294babe1816e..31841ab9498b 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -322,10 +322,10 @@ static int qcom_pcie_start_link(struct dw_pcie *pci)
 {
 	struct qcom_pcie *pcie = to_qcom_pcie(pci);
 
-	if (pcie_link_speed[pci->max_link_speed] == PCIE_SPEED_16_0GT) {
-		qcom_pcie_common_set_16gt_equalization(pci);
+	qcom_pcie_common_set_equalization(pci);
+
+	if (pcie_link_speed[pci->max_link_speed] == PCIE_SPEED_16_0GT)
 		qcom_pcie_common_set_16gt_lane_margining(pci);
-	}
 
 	/* Enable Link Training state machine */
 	if (pcie->cfg->ops->ltssm_enable)
-- 
2.43.0



From ziyue.zhang at oss.qualcomm.com  Tue Aug 19 00:16:48 2025
From: ziyue.zhang at oss.qualcomm.com (Ziyue Zhang)
Date: Tue, 19 Aug 2025 15:16:48 +0800
Subject: [PATCH v5 3/3] arm64: dts: qcom: lemans: Add PCIe lane equalization preset properties
In-Reply-To: <20250819071649.1531437-1-ziyue.zhang@oss.qualcomm.com>
References: <20250819071649.1531437-1-ziyue.zhang@oss.qualcomm.com>
Message-ID: <20250819071649.1531437-4-ziyue.zhang@oss.qualcomm.com>

Add PCIe lane equalization preset properties with all values set to 5 for
8.0 GT/s and 16.0 GT/s data rates to enhance link stability.

Co-developed-by: Qiang Yu <qiang.yu at oss.qualcomm.com>
Signed-off-by: Qiang Yu <qiang.yu at oss.qualcomm.com>
Signed-off-by: Ziyue Zhang <ziyue.zhang at oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
Acked-by: Manivannan Sadhasivam <mani at kernel.org>
---
 arch/arm64/boot/dts/qcom/lemans.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/lemans.dtsi b/arch/arm64/boot/dts/qcom/lemans.dtsi
index 64f5378c6a47..c7a09c3605a7 100644
--- a/arch/arm64/boot/dts/qcom/lemans.dtsi
+++ b/arch/arm64/boot/dts/qcom/lemans.dtsi
@@ -7657,6 +7657,10 @@ pcie0: pcie at 1c00000 {
 		phys = <&pcie0_phy>;
 		phy-names = "pciephy";
 
+		eq-presets-8gts = /bits/ 16 <0x5555 0x5555>;
+		eq-presets-16gts = /bits/ 8 <0x55 0x55>;
+
+
 		status = "disabled";
 
 		pcieport0: pcie at 0 {
@@ -7827,6 +7831,9 @@ pcie1: pcie at 1c10000 {
 		phys = <&pcie1_phy>;
 		phy-names = "pciephy";
 
+		eq-presets-8gts = /bits/ 16 <0x5555 0x5555 0x5555 0x5555>;
+		eq-presets-16gts = /bits/ 8 <0x55 0x55 0x55 0x55>;
+
 		status = "disabled";
 
 		pcie at 0 {
-- 
2.43.0



From ziyue.zhang at oss.qualcomm.com  Tue Aug 19 00:16:47 2025
From: ziyue.zhang at oss.qualcomm.com (Ziyue Zhang)
Date: Tue, 19 Aug 2025 15:16:47 +0800
Subject: [PATCH v5 2/3] PCI: qcom: fix macro typo for CURSOR
In-Reply-To: <20250819071649.1531437-1-ziyue.zhang@oss.qualcomm.com>
References: <20250819071649.1531437-1-ziyue.zhang@oss.qualcomm.com>
Message-ID: <20250819071649.1531437-3-ziyue.zhang@oss.qualcomm.com>

Corrected a typo in the macro name GEN3_EQ_FMDC_MAX_PRE_CURSOR_DELTA and
GEN3_EQ_FMDC_MAX_POST_CURSOR_DELTA to ensure consistency and avoid
potential issues.

Signed-off-by: Ziyue Zhang <ziyue.zhang at oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
---
 drivers/pci/controller/dwc/pcie-designware.h  | 4 ++--
 drivers/pci/controller/dwc/pcie-qcom-common.c | 8 ++++----
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index 11de844428e5..266f91045577 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -133,8 +133,8 @@
 #define GEN3_EQ_FB_MODE_DIR_CHANGE_OFF		0x8AC
 #define GEN3_EQ_FMDC_T_MIN_PHASE23		GENMASK(4, 0)
 #define GEN3_EQ_FMDC_N_EVALS			GENMASK(9, 5)
-#define GEN3_EQ_FMDC_MAX_PRE_CUSROR_DELTA	GENMASK(13, 10)
-#define GEN3_EQ_FMDC_MAX_POST_CUSROR_DELTA	GENMASK(17, 14)
+#define GEN3_EQ_FMDC_MAX_PRE_CURSOR_DELTA	GENMASK(13, 10)
+#define GEN3_EQ_FMDC_MAX_POST_CURSOR_DELTA	GENMASK(17, 14)
 
 #define PCIE_PORT_MULTI_LANE_CTRL	0x8C0
 #define PORT_MLTI_UPCFG_SUPPORT		BIT(7)
diff --git a/drivers/pci/controller/dwc/pcie-qcom-common.c b/drivers/pci/controller/dwc/pcie-qcom-common.c
index cb98e66d81d9..852ef4d3bb56 100644
--- a/drivers/pci/controller/dwc/pcie-qcom-common.c
+++ b/drivers/pci/controller/dwc/pcie-qcom-common.c
@@ -38,12 +38,12 @@ void qcom_pcie_common_set_equalization(struct dw_pcie *pci)
 		reg = dw_pcie_readl_dbi(pci, GEN3_EQ_FB_MODE_DIR_CHANGE_OFF);
 		reg &= ~(GEN3_EQ_FMDC_T_MIN_PHASE23 |
 			GEN3_EQ_FMDC_N_EVALS |
-			GEN3_EQ_FMDC_MAX_PRE_CUSROR_DELTA |
-			GEN3_EQ_FMDC_MAX_POST_CUSROR_DELTA);
+			GEN3_EQ_FMDC_MAX_PRE_CURSOR_DELTA |
+			GEN3_EQ_FMDC_MAX_POST_CURSOR_DELTA);
 		reg |= FIELD_PREP(GEN3_EQ_FMDC_T_MIN_PHASE23, 0x1) |
 			FIELD_PREP(GEN3_EQ_FMDC_N_EVALS, 0xd) |
-			FIELD_PREP(GEN3_EQ_FMDC_MAX_PRE_CUSROR_DELTA, 0x5) |
-			FIELD_PREP(GEN3_EQ_FMDC_MAX_POST_CUSROR_DELTA, 0x5);
+			FIELD_PREP(GEN3_EQ_FMDC_MAX_PRE_CURSOR_DELTA, 0x5) |
+			FIELD_PREP(GEN3_EQ_FMDC_MAX_POST_CURSOR_DELTA, 0x5);
 		dw_pcie_writel_dbi(pci, GEN3_EQ_FB_MODE_DIR_CHANGE_OFF, reg);
 
 		reg = dw_pcie_readl_dbi(pci, GEN3_EQ_CONTROL_OFF);
-- 
2.43.0



From Aleksandar.Gerasimovski at belden.com  Tue Aug 19 00:43:12 2025
From: Aleksandar.Gerasimovski at belden.com (Aleksandar Gerasimovski)
Date: Tue, 19 Aug 2025 07:43:12 +0000
Subject: [PATCH] phy: ti: gmii-sel: fix rgmii_id mode config
In-Reply-To: <20250725084640.845760-1-aleksandar.gerasimovski@belden.com>
References: <20250725084640.845760-1-aleksandar.gerasimovski@belden.com>
Message-ID: <SA1PR18MB56924713F249FD6D042909379930A@SA1PR18MB5692.namprd18.prod.outlook.com>

Hi there,

Any opinion about the patch? Or maybe I missed the active maintainers of this driver?

Regards,
Aleksandar

-----Original Message-----
From: Aleksandar Gerasimovski <aleksandar.gerasimovski at belden.com> 
Sent: Friday, July 25, 2025 10:47 AM
To: linux-kernel at vger.kernel.org; afd at ti.com; s-vadapalli at ti.com
Cc: Aleksandar Gerasimovski <Aleksandar.Gerasimovski at belden.com>
Subject: [PATCH] phy: ti: gmii-sel: fix rgmii_id mode config

Without setting this bit the RGMII_ID link does not work reliably, we have found this thanks to the U-boot cpsw-nuss driver that is setting it. The bit is undocumented in the AM64x reference manual (see CTRLMMR_ENET1_CTRL register).

This problem is not visible if the Kernel is booted by a U-boot with enabled networking, in our case we see the problem as the U-boot networking is not used, and it is disabled.

Signed-off-by: Aleksandar Gerasimovski <aleksandar.gerasimovski at belden.com>
---
 drivers/phy/ti/phy-gmii-sel.c | 41 ++++++++++++++++++++++++++++-------
 1 file changed, 33 insertions(+), 8 deletions(-)

diff --git a/drivers/phy/ti/phy-gmii-sel.c b/drivers/phy/ti/phy-gmii-sel.c index ff5d5e29629f..60a1312acf33 100644
--- a/drivers/phy/ti/phy-gmii-sel.c
+++ b/drivers/phy/ti/phy-gmii-sel.c
@@ -210,19 +210,44 @@ struct phy_gmii_sel_soc_data phy_gmii_sel_soc_dm814 = {
 
 static const
 struct reg_field phy_gmii_sel_fields_am654[][PHY_GMII_SEL_LAST] = {
-	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x0, 0, 2), },
-	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x4, 0, 2), },
-	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x8, 0, 2), },
-	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0xC, 0, 2), },
-	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x10, 0, 2), },
-	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x14, 0, 2), },
-	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x18, 0, 2), },
-	{ [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x1C, 0, 2), },
+	{
+		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x0, 0, 2),
+		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0, 4, 4),
+	},
+	{
+		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x4, 0, 2),
+		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x4, 4, 4),
+	},
+	{
+		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x8, 0, 2),
+		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x8, 4, 4),
+	},
+	{
+		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0xC, 0, 2),
+		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0xC, 4, 4),
+	},
+	{
+		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x10, 0, 2),
+		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x10, 4, 4),
+	},
+	{
+		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x14, 0, 2),
+		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x14, 4, 4),
+	},
+	{
+		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x18, 0, 2),
+		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x18, 4, 4),
+	},
+	{
+		[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x1C, 0, 2),
+		[PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x1C, 4, 4),
+	},
 };
 
 static const
 struct phy_gmii_sel_soc_data phy_gmii_sel_soc_am654 = {
 	.use_of_data = true,
+	.features = BIT(PHY_GMII_SEL_RGMII_ID_MODE),
 	.regfields = phy_gmii_sel_fields_am654,  };
 
--
2.34.1

**********************************************************************
DISCLAIMER:
Privileged and/or Confidential information may be contained in this message. If you are not the addressee of this message, you may not copy, use or deliver this message to anyone. In such event, you should destroy the message and kindly notify the sender by reply e-mail. It is understood that opinions or conclusions that do not relate to the official business of the company are neither given nor endorsed by the company. Thank You.


From pritam.sutar at samsung.com  Tue Aug 19 00:44:30 2025
From: pritam.sutar at samsung.com (Pritam Manohar Sutar)
Date: Tue, 19 Aug 2025 13:14:30 +0530
Subject: [PATCH v5 6/6] phy: exynos5-usbdrd: support SS combo phy for
 ExynosAutov920
In-Reply-To: <aKQfsgRXL-Nj8CkC@vaman>
References: <20250805115216.3798121-1-pritam.sutar@samsung.com>
	<CGME20250805114323epcas5p39bf73c5e0a9382ff54b1832724804cc9@epcas5p3.samsung.com>
	<20250805115216.3798121-7-pritam.sutar@samsung.com> <aJtN7uVUV3YhfY5-@vaman>
	<038a01dc1013$900a2800$b01e7800$@samsung.com> <aKQfsgRXL-Nj8CkC@vaman>
Message-ID: <003401dc10dd$1b39c560$51ad5020$@samsung.com>

Hi Vinod, 

> -----Original Message-----
> From: Vinod Koul <vkoul at kernel.org>
> Sent: 19 August 2025 12:25 PM
> To: Pritam Manohar Sutar <pritam.sutar at samsung.com>
> Cc: kishon at kernel.org; robh at kernel.org; krzk+dt at kernel.org;
> conor+dt at kernel.org; alim.akhtar at samsung.com; andre.draszik at linaro.org;
> peter.griffin at linaro.org; kauschluss at disroot.org;
> ivo.ivanov.ivanov1 at gmail.com; igor.belwon at mentallysanemainliners.org;
> m.szyprowski at samsung.com; s.nawrocki at samsung.com; linux-
> phy at lists.infradead.org; devicetree at vger.kernel.org; linux-
> kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
linux-samsung-
> soc at vger.kernel.org; rosa.pila at samsung.com; dev.tailor at samsung.com;
> faraz.ata at samsung.com; muhammed.ali at samsung.com;
> selvarasu.g at samsung.com
> Subject: Re: [PATCH v5 6/6] phy: exynos5-usbdrd: support SS combo phy for
> ExynosAutov920
> 
> On 18-08-25, 13:11, Pritam Manohar Sutar wrote:
> 
> > > > +	/* check cr_para_ack*/
> > > > +	cnt = 0;
> > > > +	do {
> > > > +		/*
> > > > +		 * data symbols are captured by phy on rising edge
of the
> > > > +		 * tx_clk when tx data enabled.
> > > > +		 * completion of the write cycle is acknowledged by
> > assertion
> > > > +		 * of the cr_para_ack.
> > > > +		 */
> > > > +		exynosautov920_usb31drd_cr_clk(phy_drd, true);
> > > > +		reg = readl(reg_phy +
> > > EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
> > > > +		if ((reg & PHY_CR_PARA_CON0_PHY0_CR_PARA_ACK))
> > > > +			break;
> > > > +
> > > > +		exynosautov920_usb31drd_cr_clk(phy_drd, false);
> > > > +
> > > > +		/*
> > > > +		 * wait for minimum of 10 cr_para_clk cycles after
phy reset
> > > > +		 * is negated, before accessing control regs to
allow for
> > > > +		 * internal resets.
> > > > +		 */
> > > > +		cnt++;
> > > > +	} while (cnt < 10);
> > > > +
> > > > +	if (cnt == 10)
> > > > +		dev_dbg(dev, "CR write failed to 0x%04x\n", addr);
> > >
> > > Not error?
> >
> > This is only for debugging purpose. It is not considered as error.
> 
> Write failed is not an error? If this code is only for debug, pls drop it.

Sure. will drop it. 

> 
> --
> ~Vinod

Regards,
Pritam



From s-vadapalli at ti.com  Tue Aug 19 02:27:44 2025
From: s-vadapalli at ti.com (s-vadapalli at ti.com)
Date: Tue, 19 Aug 2025 14:57:44 +0530
Subject: [PATCH] phy: ti: gmii-sel: fix rgmii_id mode config
In-Reply-To: <SA1PR18MB56924713F249FD6D042909379930A@SA1PR18MB5692.namprd18.prod.outlook.com>
References: <20250725084640.845760-1-aleksandar.gerasimovski@belden.com>
 <SA1PR18MB56924713F249FD6D042909379930A@SA1PR18MB5692.namprd18.prod.outlook.com>
Message-ID: <6aacb0e2-d1a5-4184-88d6-af9a1079bb37@ti.com>

On Tue, Aug 19, 2025 at 07:43:12AM +0000, Aleksandar Gerasimovski wrote:

Hello Aleksandar,

> Hi there,
> 
> Any opinion about the patch? Or maybe I missed the active maintainers of this driver?

There is a v3 patch for this already at:
https://lore.kernel.org/r/20250819065622.1019537-1-mwalle at kernel.org/

Regards,
Siddharth.


From maxime.chevallier at bootlin.com  Tue Aug 19 02:45:44 2025
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 19 Aug 2025 11:45:44 +0200
Subject: [PATCH v3] phy: ti: gmii-sel: Always write the RGMII ID setting
In-Reply-To: <20250819065622.1019537-1-mwalle@kernel.org>
References: <20250819065622.1019537-1-mwalle@kernel.org>
Message-ID: <6d664b4b-080f-442e-bb7e-4d220a16ccf4@bootlin.com>



On 19/08/2025 08:56, Michael Walle wrote:
> Some SoCs are just validated with the TX delay enabled. With commit
> ca13b249f291 ("net: ethernet: ti: am65-cpsw: fixup PHY mode for fixed
> RGMII TX delay"), the network driver will patch the delay setting on the
> fly assuming that the TX delay setting is fixed. In reality, the TX
> delay is configurable and just skipped in the documentation. There are
> bootloaders, which will disable the TX delay and this will lead to a
> transmit path which doesn't add any delays at all.
> Fix that by always writing the RGMII_ID setting and report an error for
> unsupported RGMII delay modes.
>
> This is safe to do and shouldn't break any boards in mainline because
> the fixed delay is only introduced for gmii-sel compatibles which are
> used together with the am65-cpsw-nuss driver and also contains the
> commit above.
>
> Fixes: ca13b249f291 ("net: ethernet: ti: am65-cpsw: fixup PHY mode for fixed RGMII TX delay")
> Signed-off-by: Michael Walle <mwalle at kernel.org>

Reviewed-by: Maxime Chevallier <maxime.chevallier at bootlin.com>

Maxime



From wenbin.yao at oss.qualcomm.com  Tue Aug 19 02:52:04 2025
From: wenbin.yao at oss.qualcomm.com (Wenbin Yao)
Date: Tue, 19 Aug 2025 02:52:04 -0700
Subject: [PATCH 0/4] PCI: qcom: Add support for Glymur PCIe Gen5x4
Message-ID: <20250819-glymur_pcie5-v1-0-2ea09f83cbb0@oss.qualcomm.com>

Glymur is the next generation compute SoC of Qualcomm. This patch series
aims to add support for the fifth PCIe instance on it. The fifth PCIe
instance on Glymur has a Gen5 4-lane PHY. Patch [1/4] documents PHY as a
separate compatible and Patch [2/4] documents controller as a separate
compatible. Patch [3/4] describles the new PCS offsets in a dedicated
header file. Patch [4/4] adds configuration and compatible for PHY.

The device tree changes and whatever driver patches that are not part of
this patch series will be posted separately after official announcement of
the SOC.

Signed-off-by: Wenbin Yao <wenbin.yao at oss.qualcomm.com>
---
Prudhvi Yarlagadda (4):
      dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Document the Glymur QMP PCIe PHY
      dt-bindings: PCI: qcom: Document the Glymur PCIe Controller
      phy: qcom-qmp: pcs: Add v8.50 register offsets
      phy: qcom: qmp-pcie: Add support for Glymur PCIe Gen5x4 PHY

 .../bindings/pci/qcom,pcie-x1e80100.yaml           |  7 +++++-
 .../bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml   |  3 +++
 drivers/phy/qualcomm/phy-qcom-qmp-pcie.c           | 29 ++++++++++++++++++++++
 drivers/phy/qualcomm/phy-qcom-qmp-pcs-v8_50.h      | 13 ++++++++++
 drivers/phy/qualcomm/phy-qcom-qmp.h                |  2 ++
 5 files changed, 53 insertions(+), 1 deletion(-)
---
base-commit: 886e5e7b0432360842303d587bb4a65d10741ae8
change-id: 20250818-glymur_pcie5-db4ef032e233

Best regards,
-- 
Wenbin Yao <wenbin.yao at oss.qualcomm.com>



From wenbin.yao at oss.qualcomm.com  Tue Aug 19 02:52:05 2025
From: wenbin.yao at oss.qualcomm.com (Wenbin Yao)
Date: Tue, 19 Aug 2025 02:52:05 -0700
Subject: [PATCH 1/4] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Document
 the Glymur QMP PCIe PHY
In-Reply-To: <20250819-glymur_pcie5-v1-0-2ea09f83cbb0@oss.qualcomm.com>
References: <20250819-glymur_pcie5-v1-0-2ea09f83cbb0@oss.qualcomm.com>
Message-ID: <20250819-glymur_pcie5-v1-1-2ea09f83cbb0@oss.qualcomm.com>

From: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>

The fifth PCIe instance on Glymur has a Gen5 4-lane PHY. Document it as a
separate compatible.

Signed-off-by: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
Signed-off-by: Wenbin Yao <wenbin.yao at oss.qualcomm.com>
---
 Documentation/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 b6f140bf5b3b2f79b5c96e591ec0edb76cd45fa5..61e0e2f7ec7f9cb08447e4cd9503698c0a2d383a 100644
--- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
@@ -16,6 +16,7 @@ description:
 properties:
   compatible:
     enum:
+      - qcom,glymur-qmp-gen5x4-pcie-phy
       - qcom,qcs615-qmp-gen3x1-pcie-phy
       - qcom,qcs8300-qmp-gen4x2-pcie-phy
       - qcom,sa8775p-qmp-gen4x2-pcie-phy
@@ -176,6 +177,7 @@ allOf:
         compatible:
           contains:
             enum:
+              - qcom,glymur-qmp-gen5x4-pcie-phy
               - qcom,sa8775p-qmp-gen4x2-pcie-phy
               - qcom,sa8775p-qmp-gen4x4-pcie-phy
               - qcom,sc8280xp-qmp-gen3x1-pcie-phy
@@ -211,6 +213,7 @@ allOf:
         compatible:
           contains:
             enum:
+              - qcom,glymur-qmp-gen5x4-pcie-phy
               - qcom,sm8550-qmp-gen4x2-pcie-phy
               - qcom,sm8650-qmp-gen4x2-pcie-phy
               - qcom,x1e80100-qmp-gen4x2-pcie-phy

-- 
2.34.1



From wenbin.yao at oss.qualcomm.com  Tue Aug 19 02:52:06 2025
From: wenbin.yao at oss.qualcomm.com (Wenbin Yao)
Date: Tue, 19 Aug 2025 02:52:06 -0700
Subject: [PATCH 2/4] dt-bindings: PCI: qcom: Document the Glymur PCIe
 Controller
In-Reply-To: <20250819-glymur_pcie5-v1-0-2ea09f83cbb0@oss.qualcomm.com>
References: <20250819-glymur_pcie5-v1-0-2ea09f83cbb0@oss.qualcomm.com>
Message-ID: <20250819-glymur_pcie5-v1-2-2ea09f83cbb0@oss.qualcomm.com>

From: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>

On the Qualcomm Glymur platform the PCIe host is compatible with the DWC
controller present on the X1E80100 platform. So document the PCIe
controllers found on Glymur and use the X1E80100 compatible string as a
fallback in the schema.

Signed-off-by: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
Signed-off-by: Wenbin Yao <wenbin.yao at oss.qualcomm.com>
---
 Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml
index 257068a1826492a7071600d03ca0c99babb75bd9..8600f2c74cb81bcb924fa2035d992c3bd147db31 100644
--- a/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml
+++ b/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml
@@ -16,7 +16,12 @@ description:
 
 properties:
   compatible:
-    const: qcom,pcie-x1e80100
+    oneOf:
+      - const: qcom,pcie-x1e80100
+      - items:
+          - enum:
+              - qcom,glymur-pcie
+          - const: qcom,pcie-x1e80100
 
   reg:
     minItems: 6

-- 
2.34.1



From wenbin.yao at oss.qualcomm.com  Tue Aug 19 02:52:07 2025
From: wenbin.yao at oss.qualcomm.com (Wenbin Yao)
Date: Tue, 19 Aug 2025 02:52:07 -0700
Subject: [PATCH 3/4] phy: qcom-qmp: pcs: Add v8.50 register offsets
In-Reply-To: <20250819-glymur_pcie5-v1-0-2ea09f83cbb0@oss.qualcomm.com>
References: <20250819-glymur_pcie5-v1-0-2ea09f83cbb0@oss.qualcomm.com>
Message-ID: <20250819-glymur_pcie5-v1-3-2ea09f83cbb0@oss.qualcomm.com>

From: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>

The new Glymur SoC bumps up the HW version of QMP phy to v8.50 for PCIE
g5x4. Add the new PCS offsets in a dedicated header file.

Signed-off-by: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
Signed-off-by: Wenbin Yao <wenbin.yao at oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-pcs-v8_50.h | 13 +++++++++++++
 drivers/phy/qualcomm/phy-qcom-qmp.h           |  2 ++
 2 files changed, 15 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v8_50.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v8_50.h
new file mode 100644
index 0000000000000000000000000000000000000000..325c127e8eb7ad842018dce51d09a6ee54ed86ff
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v8_50.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#ifndef QCOM_PHY_QMP_PCS_V8_50_H_
+#define QCOM_PHY_QMP_PCS_V8_50_H_
+
+#define QPHY_V8_50_PCS_STATUS1			0x010
+#define QPHY_V8_50_PCS_START_CONTROL			0x05c
+#define QPHY_V8_50_PCS_POWER_DOWN_CONTROL			0x64
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.h b/drivers/phy/qualcomm/phy-qcom-qmp.h
index f58c82b2dd23e1bda616d67ab7993794b997063b..da2a7ad2cdccef1308a2b7aa71a2e5cf8bd7c1d7 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.h
@@ -58,6 +58,8 @@
 
 #include "phy-qcom-qmp-pcs-v8.h"
 
+#include "phy-qcom-qmp-pcs-v8_50.h"
+
 /* QPHY_SW_RESET bit */
 #define SW_RESET				BIT(0)
 /* QPHY_POWER_DOWN_CONTROL */

-- 
2.34.1



From wenbin.yao at oss.qualcomm.com  Tue Aug 19 02:52:08 2025
From: wenbin.yao at oss.qualcomm.com (Wenbin Yao)
Date: Tue, 19 Aug 2025 02:52:08 -0700
Subject: [PATCH 4/4] phy: qcom: qmp-pcie: Add support for Glymur PCIe
 Gen5x4 PHY
In-Reply-To: <20250819-glymur_pcie5-v1-0-2ea09f83cbb0@oss.qualcomm.com>
References: <20250819-glymur_pcie5-v1-0-2ea09f83cbb0@oss.qualcomm.com>
Message-ID: <20250819-glymur_pcie5-v1-4-2ea09f83cbb0@oss.qualcomm.com>

From: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>

Add support for Gen5 x4 PCIe QMP PHY found on Glymur platform.

Signed-off-by: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
Signed-off-by: Wenbin Yao <wenbin.yao at oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index 95830dcfdec9b1f68fd55d1cc3c102985cfafcc1..e422cf6932d261074ed3419ed8806e9ed212c26c 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -93,6 +93,12 @@ static const unsigned int pciephy_v6_regs_layout[QPHY_LAYOUT_SIZE] = {
 	[QPHY_PCS_POWER_DOWN_CONTROL]	= QPHY_V6_PCS_POWER_DOWN_CONTROL,
 };
 
+static const unsigned int pciephy_v8_50_regs_layout[QPHY_LAYOUT_SIZE] = {
+	[QPHY_START_CTRL]		= QPHY_V8_50_PCS_START_CONTROL,
+	[QPHY_PCS_STATUS]		= QPHY_V8_50_PCS_STATUS1,
+	[QPHY_PCS_POWER_DOWN_CONTROL]   = QPHY_V8_50_PCS_POWER_DOWN_CONTROL,
+};
+
 static const struct qmp_phy_init_tbl msm8998_pcie_serdes_tbl[] = {
 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
@@ -3229,6 +3235,10 @@ static const struct qmp_pcie_offsets qmp_pcie_offsets_v6_30 = {
 	.ln_shrd	= 0x8000,
 };
 
+static const struct qmp_pcie_offsets qmp_pcie_offsets_v8_50 = {
+	.pcs        = 0x9000,
+};
+
 static const struct qmp_phy_cfg ipq8074_pciephy_cfg = {
 	.lanes			= 1,
 
@@ -4258,6 +4268,22 @@ static const struct qmp_phy_cfg qmp_v6_gen4x4_pciephy_cfg = {
 	.phy_status             = PHYSTATUS_4_20,
 };
 
+static const struct qmp_phy_cfg glymur_qmp_gen5x4_pciephy_cfg = {
+	.lanes = 4,
+
+	.offsets        = &qmp_pcie_offsets_v8_50,
+
+	.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_v8_50_regs_layout,
+
+	.pwrdn_ctrl     = SW_PWRDN | REFCLK_DRV_DSBL,
+	.phy_status     = PHYSTATUS_4_20,
+};
+
 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;
@@ -5114,6 +5140,9 @@ static const struct of_device_id qmp_pcie_of_match_table[] = {
 	}, {
 		.compatible = "qcom,x1p42100-qmp-gen4x4-pcie-phy",
 		.data = &qmp_v6_gen4x4_pciephy_cfg,
+	}, {
+		.compatible = "qcom,glymur-qmp-gen5x4-pcie-phy",
+		.data = &glymur_qmp_gen5x4_pciephy_cfg,
 	},
 	{ },
 };

-- 
2.34.1



From shradha.t at samsung.com  Tue Aug 19 04:18:59 2025
From: shradha.t at samsung.com (Shradha Todi)
Date: Tue, 19 Aug 2025 16:48:59 +0530
Subject: [PATCH v3 11/12] PCI: exynos: Add support for Tesla FSD SoC
In-Reply-To: <29287880-9436-4acd-b3f9-b4d9eb726896@kernel.org>
References: <20250818182544.GA534647@bhelgaas>
	<CGME20250819063415epcas5p3e0bebab838b913e90bd07adf23c410f1@epcas5p3.samsung.com>
	<29287880-9436-4acd-b3f9-b4d9eb726896@kernel.org>
Message-ID: <00b401dc10fb$11bb1020$35313060$@samsung.com>



> -----Original Message-----
> From: Krzysztof Kozlowski <krzk at kernel.org>
> Sent: 19 August 2025 12:04
> To: Bjorn Helgaas <helgaas at kernel.org>; Shradha Todi <shradha.t at samsung.com>; Krzysztof
> Kozlowski <krzysztof.kozlowski at linaro.org>
> Cc: linux-pci at vger.kernel.org; devicetree at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> linux-samsung-soc at vger.kernel.org; linux-kernel at vger.kernel.org; linux-phy at lists.infradead.org;
> mani at kernel.org; lpieralisi at kernel.org; kwilczynski at kernel.org; robh at kernel.org;
> bhelgaas at google.com; jingoohan1 at gmail.com; krzk+dt at kernel.org; conor+dt at kernel.org;
> alim.akhtar at samsung.com; vkoul at kernel.org; kishon at kernel.org; arnd at arndb.de;
> m.szyprowski at samsung.com; jh80.chung at samsung.com; pankaj.dubey at samsung.com
> Subject: Re: [PATCH v3 11/12] PCI: exynos: Add support for Tesla FSD SoC
> 
> On 18/08/2025 20:25, Bjorn Helgaas wrote:
> > [+to Krzysztof]
> >
> > On Mon, Aug 18, 2025 at 03:00:00PM +0530, Shradha Todi wrote:
> >>> On Mon, Aug 11, 2025 at 09:16:37PM +0530, Shradha Todi wrote:
> >>>> Add host and endpoint controller driver support for FSD SoC.
> >
> >>> It's kind of unfortunate that the driver uses "ep" everywhere for
> >>> struct exynos_pcie pointers.  It's going to be confusing because "ep"
> >>> is also commonly used for endpoint-related things, e.g., struct
> >>> dw_pcie_ep pointers.  Maybe it's not worth changing; I dunno.
> >>
> >> I did try to rename the structure and the pointers
> >> (https://lore.kernel.org/all/20230214121333.1837-9-shradha.t at samsung.com/)
> >> But the intention was different back then and so the idea was rejected.
> >> I could add a patch to only rename the pointers to something less
> >> confusing like "exy_pci"
> >
> > The patch you mention did several renames:
> >
> >   s/to_exynos_pcie/to_samsung_pcie/
> >   s/struct exynos_pcie/struct samsung_pcie/
> >   s/struct exynos_pcie *ep/struct samsung_pcie *sp/
> >
> > I'm only concerned about the confusion of "ep" being used both for
> > "struct exynos_pcie *" and for "struct dw_pcie_ep *".
> >
> > It would still be sort of an annoying patch to do something like this:
> >
> >   s/struct exynos_pcie *ep/struct exynos_pcie *pcie/
> >
> > But 'git grep "struct .*_pcie \*.*=" drivers/pci/controller/' says
> > using "pcie" in this way is quite common, so maybe it would be worth
> > doing.
> >
> > What do you think, Krzysztof?
> 
> I think you want other Krzysztof, but nevertheless, the reasoning there
> "Changing it to samsung_pcie for making it
> generic."
> is wrong. The naming of these structures do not matter, they are not
> less generic. This is rather churn, which will affect backporting for
> ZERO readability increase. Why zero? Because calling all this "exynos"
> is the same as calling all this "samsung". It just does not matter.
> 
> However s/ep/pcie/ in variable name makes sense if that's more common.
> 

I will add a patch in the series to do that.

> 
> Best regards,
> Krzysztof



From cristian.ciocaltea at collabora.com  Tue Aug 19 04:20:26 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 19 Aug 2025 14:20:26 +0300
Subject: [PATCH v3 01/14] phy: hdmi: Add HDMI 2.1 FRL configuration
 options
In-Reply-To: <3f857197-1cd1-4c18-88e9-e8c00d95af82@oss.qualcomm.com>
References: <20250818-phy-hdptx-frl-v3-0-c79997d8bb2b@collabora.com>
 <20250818-phy-hdptx-frl-v3-1-c79997d8bb2b@collabora.com>
 <3f857197-1cd1-4c18-88e9-e8c00d95af82@oss.qualcomm.com>
Message-ID: <d4624c04-93c3-4db4-a45d-ed111901a5fc@collabora.com>

On 8/19/25 3:42 AM, Dmitry Baryshkov wrote:
> 
> 
> On 18/08/2025 21:59, Cristian Ciocaltea wrote:
>> The HDMI 2.1 specification introduced the Fixed Rate Link (FRL) mode,
>> aiming to replace the older Transition-Minimized Differential Signaling
>> (TMDS) mode used in previous HDMI versions to support much higher
>> bandwidths (up to 48 Gbps) for modern video and audio formats.
>>
>> FRL has been designed to support ultra high resolution formats at high
>> refresh rates like 8K at 60Hz or 4K at 120Hz, and eliminates the need for
>> dynamic bandwidth adjustments, which reduces latency.  It operates with
>> 3 or 4 lanes at different link rates: 3Gbps, 6Gbps, 8Gbps, 10Gbps or
>> 12Gbps.
>>
>> Add support for configuring the FRL mode for HDMI PHYs.
> 
> Could you please point out corresponding DRM patches? 
> They might be WIP or incomplete. I'd like to see how this works on the consumer side.

Sure, please check the top-most commits prefixed with [WIP-FRL] in [1].  In
particular, phy_set_mode_ext() is being called in [2].

>>
>> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
>> ---
>>   include/linux/phy/phy-hdmi.h | 19 +++++++++++++++++--
>>   1 file changed, 17 insertions(+), 2 deletions(-)
>>
>> diff --git a/include/linux/phy/phy-hdmi.h b/include/linux/phy/phy-hdmi.h
>> index f0ec963c6e84f1b7728acafc824dff191c6b873d..83330d359e3ae345554f20429519da14506b8ab5 100644
>> --- a/include/linux/phy/phy-hdmi.h
>> +++ b/include/linux/phy/phy-hdmi.h
>> @@ -6,16 +6,31 @@
>>   #ifndef __PHY_HDMI_H_
>>   #define __PHY_HDMI_H_
>>   +#include <linux/types.h>
>> +
>> +enum phy_mode_hdmi {
>> +    PHY_MODE_HDMI_TMDS,
>> +    PHY_MODE_HDMI_FRL,
> 
> There is no unified approach for PHY submode names. Nevertheless I'd suggest something like PHY_HDMI_MODE_TMDS / _FRL. 
> It follows more closely the networking / USB submodes. An alternative might be to use PHY_SUBMODE_HDMI_TMDS / _FRL.

I'd go for PHY_HDMI_MODE_{TMDS|FRL} and I should probably also rename the
enum to phy_hdmi_mode.

> But it's really a nit and/or bikeschedding.

No worries, let's handle this.

>> +};
>> +
>>   /**
>>    * struct phy_configure_opts_hdmi - HDMI configuration set
>> - * @tmds_char_rate: HDMI TMDS Character Rate in Hertz.
>>    * @bpc: Bits per color channel.
>> + * @tmds_char_rate: HDMI TMDS Character Rate in Hertz.
>> + * @frl.rate_per_lane: HDMI FRL Rate per Lane in Gbps.
> 
> This works nicely until HDMI Forum adds an rate not being even Gbps. 
> Is there a reason for not using ULL and bps following the tmds_char_rate design?

This is for consistency with the related members of struct drm_hdmi_info:

    /** @max_frl_rate_per_lane: support fixed rate link */
    u8 max_frl_rate_per_lane;

    /** @max_lanes: supported by sink */
    u8 max_lanes;

>> + * @frl.lanes: HDMI FRL lanes count.
>>    *
>>    * This structure is used to represent the configuration state of a HDMI phy.
>>    */
>>   struct phy_configure_opts_hdmi {
>> -    unsigned long long tmds_char_rate;
>>       unsigned int bpc;
>> +    union {
>> +        unsigned long long tmds_char_rate;
>> +        struct {
>> +            u8 rate_per_lane;
>> +            u8 lanes;
>> +        } frl;
>> +    };
>>   };
>>     #endif /* __PHY_HDMI_H_ */
>>
> 

[1] https://gitlab.collabora.com/cristicc/linux-next/-/commits/rk3588-hdmi-frl
[2] https://gitlab.collabora.com/cristicc/linux-next/-/commit/86dd2cbbccdc71a3b5db87fdf876370dc3b6f2df#90498bf5e199fded685141134e7c623ef4f4411c_132_215 



From shradha.t at samsung.com  Tue Aug 19 04:39:34 2025
From: shradha.t at samsung.com (Shradha Todi)
Date: Tue, 19 Aug 2025 17:09:34 +0530
Subject: [PATCH v3 11/12] PCI: exynos: Add support for Tesla FSD SoC
In-Reply-To: <20250818182544.GA534647@bhelgaas>
References: <CGME20250818182551epcas5p33fbe099df79778031b489f0902cceed3@epcas5p3.samsung.com>
	<20250818182544.GA534647@bhelgaas>
Message-ID: <00b501dc10fd$f1fecc10$d5fc6430$@samsung.com>

> > > > +static irqreturn_t fsd_pcie_irq_handler(int irq, void *arg)
> > > > +{
> > > > +	u32 val;
> > > > +	struct exynos_pcie *ep = arg;
> > > > +	struct dw_pcie *pci = &ep->pci;
> > > > +	struct dw_pcie_rp *pp = &pci->pp;
> > > > +
> > > > +	val = readl(ep->elbi_base + FSD_IRQ2_STS);
> > > > +	if ((val & FSD_IRQ_MSI_ENABLE) == FSD_IRQ_MSI_ENABLE) {
> > > > +		val &= FSD_IRQ_MSI_ENABLE;
> > > > +		writel(val, ep->elbi_base + FSD_IRQ2_STS);
> > >
> > > This looks weird because FSD_IRQ_MSI_ENABLE sounds like an *enable*
> > > bit, but here you're treating it as a *status* bit.
> > >
> > > As far as I can tell, you set FSD_IRQ_MSI_ENABLE once at probe-time in
> > > fsd_pcie_msi_init(), then you clear it here in an IRQ handler, and it
> > > will never be set again.  That seems wrong; am I missing something?
> >
> > Actually the status IRQ and enable IRQ registers are different offsets
> > but the bit position for MSI remains same in both cases so I just reused
> > the macro.
> 
> Ah, that's what I missed, thanks!  At probe-time, fsd_pcie_msi_init()
> enables it in FSD_IRQ2_EN.  Here you clear it in FSD_IRQ2_STS.
> 
> > But I understand that it's confusing so I will add another
> > macro for FSD_IRQ_MSI_STATUS or just rename the macro to
> > FSD_IRQ_MSI to re-use.
> 
> Using the same name just because a similar bit happens to be at the
> same position in two different registers is definitely confusing.  I
> think it will be better to have two macros, one for FSD_IRQ2_STS and
> another for FSD_IRQ2_EN, e.g.,
> 
>   #define FSD_IRQ2_STS                         0x008
>   #define   FSD_IRQ2_STS_MSI                   BIT(17)
>   #define FSD_IRQ2_EN                          0x018
>   #define   FSD_IRQ2_EN_MSI                    BIT(17)
> 
> Another question about the test:
> 
>   if ((val & FSD_IRQ_MSI_ENABLE) == FSD_IRQ_MSI_ENABLE) {
> 
> This assumes there are no other bits in FSD_IRQ2_STS that could be
> set.  I would have expected a test like this:
> 
>   if (val & FSD_IRQ_MSI_ENABLE) {
> 

Thanks for pointing this out. FSD_IRQ_MSI_ENABLE is a single-bit, so there
is no functional difference in the two statements. I didn't have a specific
reason for using "== FSD_IRQ_MSI_ENABLE".
But I see that "val & FSD_IRQ_MSI_ENABLE" would have been the more
standard way to write this. I will update this for clarity.

> Is there a reason to restrict it to the case when *only*
> FSD_IRQ_MSI_ENABLE is set?
> 
> Bjorn



From robh at kernel.org  Tue Aug 19 05:32:25 2025
From: robh at kernel.org (Rob Herring (Arm))
Date: Tue, 19 Aug 2025 07:32:25 -0500
Subject: [PATCH 1/4] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy:
 Document the Glymur QMP PCIe PHY
In-Reply-To: <20250819-glymur_pcie5-v1-1-2ea09f83cbb0@oss.qualcomm.com>
References: <20250819-glymur_pcie5-v1-0-2ea09f83cbb0@oss.qualcomm.com>
 <20250819-glymur_pcie5-v1-1-2ea09f83cbb0@oss.qualcomm.com>
Message-ID: <175560674306.26088.17838769805587892599.robh@kernel.org>


On Tue, 19 Aug 2025 02:52:05 -0700, Wenbin Yao wrote:
> From: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
> 
> The fifth PCIe instance on Glymur has a Gen5 4-lane PHY. Document it as a
> separate compatible.
> 
> Signed-off-by: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
> Signed-off-by: Wenbin Yao <wenbin.yao at oss.qualcomm.com>
> ---
>  Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml | 3 +++
>  1 file changed, 3 insertions(+)
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:


doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20250819-glymur_pcie5-v1-1-2ea09f83cbb0 at oss.qualcomm.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 robh at kernel.org  Tue Aug 19 05:32:27 2025
From: robh at kernel.org (Rob Herring (Arm))
Date: Tue, 19 Aug 2025 07:32:27 -0500
Subject: [PATCH 2/4] dt-bindings: PCI: qcom: Document the Glymur PCIe
 Controller
In-Reply-To: <20250819-glymur_pcie5-v1-2-2ea09f83cbb0@oss.qualcomm.com>
References: <20250819-glymur_pcie5-v1-0-2ea09f83cbb0@oss.qualcomm.com>
 <20250819-glymur_pcie5-v1-2-2ea09f83cbb0@oss.qualcomm.com>
Message-ID: <175560674407.26155.2834845935745858066.robh@kernel.org>


On Tue, 19 Aug 2025 02:52:06 -0700, Wenbin Yao wrote:
> From: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
> 
> On the Qualcomm Glymur platform the PCIe host is compatible with the DWC
> controller present on the X1E80100 platform. So document the PCIe
> controllers found on Glymur and use the X1E80100 compatible string as a
> fallback in the schema.
> 
> Signed-off-by: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
> Signed-off-by: Wenbin Yao <wenbin.yao at oss.qualcomm.com>
> ---
>  Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:


doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20250819-glymur_pcie5-v1-2-2ea09f83cbb0 at oss.qualcomm.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 wsa+renesas at sang-engineering.com  Wed Aug 13 09:14:46 2025
From: wsa+renesas at sang-engineering.com (Wolfram Sang)
Date: Wed, 13 Aug 2025 18:14:46 +0200
Subject: [PATCH 00/21] treewide: remove unneeded 'fast_io' parameter in regmap_config
Message-ID: <20250813161517.4746-1-wsa+renesas@sang-engineering.com>

While working on a driver using regmap with MMIO, I wondered if I need
to set 'fast_io' in the config. Turned out I don't need to, so I added
documentation for it with commit ffc72771ff6e ("regmap: Annotate that
MMIO implies fast IO").

This series fixes the existing users in the tree which needlessly set
the flag. They have been found using this coccinelle script:

===

@ match @
expression dev, clk, regs;
identifier config;
@@

(
	regmap_init_mmio(dev, regs, &config)
|
	devm_regmap_init_mmio(dev, regs, &config)
|
	regmap_init_mmio_clk(dev, clk, regs, &config)
|
	devm_regmap_init_mmio_clk(dev, clk, regs, &config)
)

@ fix depends on match @
identifier match.config;
@@

	struct regmap_config config = {
-	.fast_io = true,
	};

===

It misses occasions where 'config' is an expression and not an
identifier. These are rare, though, I can fix them manually later. The
advantage of this approach is that it produces no false positives to the
best of my knowledge.

Please apply individually per subsystem. There are no dependencies and
buildbot is happy. Patches are based on 6.17-rc1

Happy hacking,

   Wolfram


Wolfram Sang (21):
  bus: remove unneeded 'fast_io' parameter in regmap_config
  clk: remove unneeded 'fast_io' parameter in regmap_config
  gpio: remove unneeded 'fast_io' parameter in regmap_config
  drm: remove unneeded 'fast_io' parameter in regmap_config
  iio: remove unneeded 'fast_io' parameter in regmap_config
  Input: remove unneeded 'fast_io' parameter in regmap_config
  mailbox: remove unneeded 'fast_io' parameter in regmap_config
  media: remove unneeded 'fast_io' parameter in regmap_config
  mfd: remove unneeded 'fast_io' parameter in regmap_config
  mmc: remove unneeded 'fast_io' parameter in regmap_config
  peci: remove unneeded 'fast_io' parameter in regmap_config
  phy: remove unneeded 'fast_io' parameter in regmap_config
  pinctrl: remove unneeded 'fast_io' parameter in regmap_config
  pmdomain: remove unneeded 'fast_io' parameter in regmap_config
  regulator: remove unneeded 'fast_io' parameter in regmap_config
  reset: remove unneeded 'fast_io' parameter in regmap_config
  rtc: remove unneeded 'fast_io' parameter in regmap_config
  soc: remove unneeded 'fast_io' parameter in regmap_config
  spi: remove unneeded 'fast_io' parameter in regmap_config
  thermal: remove unneeded 'fast_io' parameter in regmap_config
  ASoC: remove unneeded 'fast_io' parameter in regmap_config

 drivers/bus/bt1-apb.c                             | 1 -
 drivers/clk/actions/owl-common.c                  | 1 -
 drivers/clk/clk-axm5516.c                         | 1 -
 drivers/clk/nxp/clk-lpc32xx.c                     | 1 -
 drivers/clk/qcom/a53-pll.c                        | 1 -
 drivers/clk/qcom/a7-pll.c                         | 1 -
 drivers/clk/qcom/apss-ipq-pll.c                   | 1 -
 drivers/clk/qcom/clk-cbf-8996.c                   | 1 -
 drivers/clk/qcom/clk-cpu-8996.c                   | 1 -
 drivers/clk/qcom/hfpll.c                          | 1 -
 drivers/clk/qcom/ipq-cmn-pll.c                    | 1 -
 drivers/clk/thead/clk-th1520-ap.c                 | 1 -
 drivers/gpio/gpio-mvebu.c                         | 1 -
 drivers/gpio/gpio-sifive.c                        | 1 -
 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi2.c    | 1 -
 drivers/gpu/drm/imx/dc/dc-cf.c                    | 1 -
 drivers/gpu/drm/imx/dc/dc-de.c                    | 1 -
 drivers/gpu/drm/imx/dc/dc-ed.c                    | 2 --
 drivers/gpu/drm/imx/dc/dc-fg.c                    | 1 -
 drivers/gpu/drm/imx/dc/dc-fl.c                    | 1 -
 drivers/gpu/drm/imx/dc/dc-fw.c                    | 2 --
 drivers/gpu/drm/imx/dc/dc-ic.c                    | 1 -
 drivers/gpu/drm/imx/dc/dc-lb.c                    | 2 --
 drivers/gpu/drm/imx/dc/dc-tc.c                    | 1 -
 drivers/gpu/drm/imx/ipuv3/imx-tve.c               | 2 --
 drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c  | 1 -
 drivers/iio/adc/sun4i-gpadc-iio.c                 | 1 -
 drivers/input/touchscreen/fsl-imx25-tcq.c         | 1 -
 drivers/mailbox/qcom-apcs-ipc-mailbox.c           | 1 -
 drivers/media/cec/platform/stm32/stm32-cec.c      | 1 -
 drivers/mfd/exynos-lpass.c                        | 1 -
 drivers/mfd/fsl-imx25-tsadc.c                     | 1 -
 drivers/mfd/stm32-lptimer.c                       | 1 -
 drivers/mfd/sun4i-gpadc.c                         | 1 -
 drivers/mmc/host/sdhci_am654.c                    | 1 -
 drivers/peci/controller/peci-npcm.c               | 1 -
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 1 -
 drivers/phy/rockchip/phy-rockchip-usbdp.c         | 1 -
 drivers/phy/ti/phy-am654-serdes.c                 | 1 -
 drivers/phy/ti/phy-j721e-wiz.c                    | 1 -
 drivers/pinctrl/pinctrl-rp1.c                     | 1 -
 drivers/pmdomain/imx/gpc.c                        | 1 -
 drivers/regulator/qcom-refgen-regulator.c         | 1 -
 drivers/reset/reset-intel-gw.c                    | 1 -
 drivers/reset/reset-qcom-pdc.c                    | 1 -
 drivers/reset/reset-th1520.c                      | 1 -
 drivers/rtc/rtc-meson.c                           | 1 -
 drivers/soc/qcom/llcc-qcom.c                      | 1 -
 drivers/soc/qcom/ramp_controller.c                | 1 -
 drivers/spi/spi-altera-platform.c                 | 1 -
 drivers/thermal/armada_thermal.c                  | 1 -
 drivers/thermal/sun8i_thermal.c                   | 1 -
 sound/soc/fsl/fsl_sai.c                           | 1 -
 53 files changed, 57 deletions(-)

-- 
2.47.2



From broonie at kernel.org  Wed Aug 13 14:28:28 2025
From: broonie at kernel.org (Mark Brown)
Date: Wed, 13 Aug 2025 22:28:28 +0100
Subject: (subset) [PATCH 00/21] treewide: remove unneeded 'fast_io'
 parameter in regmap_config
In-Reply-To: <20250813161517.4746-1-wsa+renesas@sang-engineering.com>
References: <20250813161517.4746-1-wsa+renesas@sang-engineering.com>
Message-ID: <175512050873.352044.97744864083041762.b4-ty@kernel.org>

On Wed, 13 Aug 2025 18:14:46 +0200, Wolfram Sang wrote:
> While working on a driver using regmap with MMIO, I wondered if I need
> to set 'fast_io' in the config. Turned out I don't need to, so I added
> documentation for it with commit ffc72771ff6e ("regmap: Annotate that
> MMIO implies fast IO").
> 
> This series fixes the existing users in the tree which needlessly set
> the flag. They have been found using this coccinelle script:
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git for-next

Thanks!

[15/21] regulator: remove unneeded 'fast_io' parameter in regmap_config
        commit: 37533933bfe92cd5a99ef4743f31dac62ccc8de0

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark



From broonie at kernel.org  Thu Aug 14 04:13:54 2025
From: broonie at kernel.org (Mark Brown)
Date: Thu, 14 Aug 2025 12:13:54 +0100
Subject: (subset) [PATCH 00/21] treewide: remove unneeded 'fast_io'
 parameter in regmap_config
In-Reply-To: <20250813161517.4746-1-wsa+renesas@sang-engineering.com>
References: <20250813161517.4746-1-wsa+renesas@sang-engineering.com>
Message-ID: <175517003454.17441.365944262533574232.b4-ty@kernel.org>

On Wed, 13 Aug 2025 18:14:46 +0200, Wolfram Sang wrote:
> While working on a driver using regmap with MMIO, I wondered if I need
> to set 'fast_io' in the config. Turned out I don't need to, so I added
> documentation for it with commit ffc72771ff6e ("regmap: Annotate that
> MMIO implies fast IO").
> 
> This series fixes the existing users in the tree which needlessly set
> the flag. They have been found using this coccinelle script:
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[19/21] spi: remove unneeded 'fast_io' parameter in regmap_config
        commit: 48124569bbc6bfda1df3e9ee17b19d559f4b1aa3

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark



From broonie at kernel.org  Thu Aug 14 07:18:14 2025
From: broonie at kernel.org (Mark Brown)
Date: Thu, 14 Aug 2025 15:18:14 +0100
Subject: (subset) [PATCH 00/21] treewide: remove unneeded 'fast_io'
 parameter in regmap_config
In-Reply-To: <20250813161517.4746-1-wsa+renesas@sang-engineering.com>
References: <20250813161517.4746-1-wsa+renesas@sang-engineering.com>
Message-ID: <175518109481.47921.1666131365484481268.b4-ty@kernel.org>

On Wed, 13 Aug 2025 18:14:46 +0200, Wolfram Sang wrote:
> While working on a driver using regmap with MMIO, I wondered if I need
> to set 'fast_io' in the config. Turned out I don't need to, so I added
> documentation for it with commit ffc72771ff6e ("regmap: Annotate that
> MMIO implies fast IO").
> 
> This series fixes the existing users in the tree which needlessly set
> the flag. They have been found using this coccinelle script:
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[21/21] ASoC: remove unneeded 'fast_io' parameter in regmap_config
        commit: d578faf7096affc036fd16333f1bfbe4991a22f7

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark



From andersson at kernel.org  Fri Aug 15 07:42:02 2025
From: andersson at kernel.org (Bjorn Andersson)
Date: Fri, 15 Aug 2025 09:42:02 -0500
Subject: (subset) [PATCH 00/21] treewide: remove unneeded 'fast_io' parameter in regmap_config
In-Reply-To: <20250813161517.4746-1-wsa+renesas@sang-engineering.com>
References: <20250813161517.4746-1-wsa+renesas@sang-engineering.com>
Message-ID: <175526892008.370600.8859545110801188375.b4-ty@kernel.org>


On Wed, 13 Aug 2025 18:14:46 +0200, Wolfram Sang wrote:
> While working on a driver using regmap with MMIO, I wondered if I need
> to set 'fast_io' in the config. Turned out I don't need to, so I added
> documentation for it with commit ffc72771ff6e ("regmap: Annotate that
> MMIO implies fast IO").
> 
> This series fixes the existing users in the tree which needlessly set
> the flag. They have been found using this coccinelle script:
> 
> [...]

Applied, thanks!

[18/21] soc: remove unneeded 'fast_io' parameter in regmap_config
        commit: 5d8a9c8401648d338d072a488d455ed4611c5d4b

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


From robh at kernel.org  Tue Aug 19 06:37:44 2025
From: robh at kernel.org (Rob Herring)
Date: Tue, 19 Aug 2025 08:37:44 -0500
Subject: [PATCH v5 1/7] dt-bindings: phy: renesas,usb2-phy: Mark resets
 as required for RZ/G3S
In-Reply-To: <175558495459.3265640.2032619822487575179.robh@kernel.org>
References: <20250819054212.486426-1-claudiu.beznea.uj@bp.renesas.com>
 <20250819054212.486426-2-claudiu.beznea.uj@bp.renesas.com>
 <175558495459.3265640.2032619822487575179.robh@kernel.org>
Message-ID: <20250819133744.GA87211-robh@kernel.org>

On Tue, Aug 19, 2025 at 01:29:17AM -0500, Rob Herring (Arm) wrote:
> 
> On Tue, 19 Aug 2025 08:42:06 +0300, Claudiu wrote:
> > From: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
> > 
> > The reset lines are mandatory for the Renesas RZ/G3S platform and must be
> > explicitly defined in device tree.
> > 
> > Fixes: f3c849855114 ("dt-bindings: phy: renesas,usb2-phy: Document RZ/G3S phy bindings")
> > Reviewed-by: Geert Uytterhoeven <geert+renesas at glider.be>
> > Acked-by: Conor Dooley <conor.dooley at microchip.com>
> > Signed-off-by: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
> > ---
> > 
> > Changes in v5:
> > - none
> > 
> > Changes in v4:
> > - none
> > 
> > Changes in v3:
> > - collected tags
> > - rebased on top of latest version of renesas,usb2-phy.yaml;
> >   Conor, Geert: I kept your tags; please let me know if you consider it
> >   otherwise
> > 
> > Changes in v2:
> > - none; this patch is new
> > 
> >  Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> 
> My bot found errors running 'make dt_binding_check' on your patch:
> 
> yamllint warnings/errors:
> 
> dtschema/dtc warnings/errors:
> 
> 
> doc reference errors (make refcheckdocs):
> 
> See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20250819054212.486426-2-claudiu.beznea.uj at bp.renesas.com

No issue here. The QCom folks have broken "make dt_binding_check" in 
linux-next...

Rob


From luyulin at eswincomputing.com  Tue Aug 19 06:47:22 2025
From: luyulin at eswincomputing.com (Yulin Lu)
Date: Tue, 19 Aug 2025 21:47:22 +0800
Subject: [PATCH v2 0/3] ESWIN EIC7700 sata phy driver and yaml,
Message-ID: <20250819134722.220-1-luyulin@eswincomputing.com>

From: luyulin <luyulin at eswincomputing.com>

  Implements support for the Eswin EIC7700 SoC sata phy.
  Implements the calling sequence to interface with dwc-ahci,
  ensuring correct hardware execution order.
  Integration with the Linux phy subsystem for consistency and
  scalability.
  Add documentation for ahci and sata phy on the ESWIN EIC7700
  SoC platform.

  Supported chips:
    Eswin EIC7700 SoC.

  Test:
    Tested this patch on the Sifive HiFive Premier P550 (which uses
    the EIC7700 SoC). Based on this driver, the SATA device read/write
    operations are functioning normally, supporting SATA 1.5 Gb/s,
    3.0 Gb/s, and 6.0 Gb/s speeds, so this verifies that this sata
    driver patch is working properly.

  This series depends on the vendor prefix patch [1] and config option patch [2].
  [1] https://lore.kernel.org/all/20250616112316.3833343-4-pinkesh.vaghela at einfochips.com/
  [2] https://lore.kernel.org/all/20250616112316.3833343-3-pinkesh.vaghela at einfochips.com/

Updates:

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

luyulin (3):
  dt-bindings: ata: eswin: Document for EIC7700 SoC ahci
  dt-bindings: phy: eswin: Document for EIC7700 SoC SATA
  phy: eswin: Create eswin directory and add EIC7700 SATA PHY driver

 .../bindings/ata/eswin,eic7700-ahci.yaml      |  92 ++++++++
 .../bindings/phy/eswin,eic7700-sata-phy.yaml  |  36 ++++
 drivers/phy/Kconfig                           |   1 +
 drivers/phy/Makefile                          |   1 +
 drivers/phy/eswin/Kconfig                     |  14 ++
 drivers/phy/eswin/Makefile                    |   2 +
 drivers/phy/eswin/phy-eic7700-sata.c          | 197 ++++++++++++++++++
 7 files changed, 343 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/ata/eswin,eic7700-ahci.yaml
 create mode 100644 Documentation/devicetree/bindings/phy/eswin,eic7700-sata-phy.yaml
 create mode 100644 drivers/phy/eswin/Kconfig
 create mode 100644 drivers/phy/eswin/Makefile
 create mode 100644 drivers/phy/eswin/phy-eic7700-sata.c

-- 
2.25.1



From luyulin at eswincomputing.com  Tue Aug 19 06:54:13 2025
From: luyulin at eswincomputing.com (Yulin Lu)
Date: Tue, 19 Aug 2025 21:54:13 +0800
Subject: [PATCH v2 1/3] dt-bindings: ata: eswin: Document for EIC7700 SoC ahci
In-Reply-To: <20250819134722.220-1-luyulin@eswincomputing.com>
References: <20250819134722.220-1-luyulin@eswincomputing.com>
Message-ID: <20250819135413.386-1-luyulin@eswincomputing.com>

From: luyulin <luyulin at eswincomputing.com>

Add document for the SATA AHCI controller on the EIC7700 SoC platform,
including descriptions of its hardware configurations.

Signed-off-by: luyulin <luyulin at eswincomputing.com>
---
 .../bindings/ata/eswin,eic7700-ahci.yaml      | 92 +++++++++++++++++++
 1 file changed, 92 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/ata/eswin,eic7700-ahci.yaml

diff --git a/Documentation/devicetree/bindings/ata/eswin,eic7700-ahci.yaml b/Documentation/devicetree/bindings/ata/eswin,eic7700-ahci.yaml
new file mode 100644
index 000000000000..9ef58c9c2f28
--- /dev/null
+++ b/Documentation/devicetree/bindings/ata/eswin,eic7700-ahci.yaml
@@ -0,0 +1,92 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/ata/eswin,eic7700-ahci.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Eswin EIC7700 SoC SATA Controller
+
+maintainers:
+  - Yulin Lu <luyulin at eswincomputing.com>
+  - Huan He <hehuan1 at eswincomputing.com>
+
+description:
+  This document defines device tree bindings for the Synopsys DWC
+  implementation of the AHCI SATA controller found in Eswin's
+  Eic7700 SoC platform.
+
+select:
+  properties:
+    compatible:
+      const: eswin,eic7700-ahci
+  required:
+    - compatible
+
+allOf:
+  - $ref: snps,dwc-ahci-common.yaml#
+
+properties:
+  compatible:
+    items:
+      - const: eswin,eic7700-ahci
+      - const: snps,dwc-ahci
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  ports-implemented:
+    const: 1
+
+  clocks:
+    minItems: 2
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: pclk
+      - const: aclk
+
+  resets:
+    maxItems: 1
+
+  reset-names:
+    const: arst
+
+  phys:
+    maxItems: 1
+
+  phy-names:
+    const: sata-phy
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+  - phys
+  - phy-names
+  - ports-implemented
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    sata at 50420000 {
+        compatible = "eswin,eic7700-ahci", "snps,dwc-ahci";
+        reg = <0x50420000 0x10000>;
+        interrupt-parent = <&plic>;
+        interrupts = <58>;
+        ports-implemented = <0x1>;
+        clocks = <&gate_clk_hsp_cfgclk>, <&gate_clk_hsp_aclk>;
+        clock-names = "pclk", "aclk";
+        resets = <&reset 96>;
+        reset-names = "arst";
+        phys = <&sata_phy>;
+        phy-names = "sata-phy";
+    };
-- 
2.25.1



From luyulin at eswincomputing.com  Tue Aug 19 06:58:33 2025
From: luyulin at eswincomputing.com (Yulin Lu)
Date: Tue, 19 Aug 2025 21:58:33 +0800
Subject: [PATCH v2 2/3] dt-bindings: phy: eswin: Document for EIC7700 SoC SATA PHY
In-Reply-To: <20250819134722.220-1-luyulin@eswincomputig.com>
References: <20250819134722.220-1-luyulin@eswincomputig.com>
Message-ID: <20250819135833.1227-1-luyulin@eswincomputing.com>

From: luyulin <luyulin at eswincomputing.com>

Add document for the SATA phy on the EIC7700 SoC platform,
describing its usage.

Signed-off-by: luyulin <luyulin at eswincomputing.com>
---
 .../bindings/phy/eswin,eic7700-sata-phy.yaml  | 36 +++++++++++++++++++
 1 file changed, 36 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/eswin,eic7700-sata-phy.yaml

diff --git a/Documentation/devicetree/bindings/phy/eswin,eic7700-sata-phy.yaml b/Documentation/devicetree/bindings/phy/eswin,eic7700-sata-phy.yaml
new file mode 100644
index 000000000000..d914cb4402d8
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/eswin,eic7700-sata-phy.yaml
@@ -0,0 +1,36 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/eswin,eic7700-sata-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Eswin EIC7700 SoC SATA PHY
+
+maintainers:
+  - Yulin Lu <luyulin at eswincomputing.com>
+  - Huan He <hehuan1 at eswincomputing.com>
+
+properties:
+  compatible:
+    const: eswin,eic7700-sata-phy
+
+  "#phy-cells":
+    const: 0
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - "#phy-cells"
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    sata-phy at 50440300 {
+        compatible = "eswin,eic7700-sata-phy";
+        reg = <0x50440300 0x40>;
+        #phy-cells = <0>;
+    };
-- 
2.25.1



From luyulin at eswincomputing.com  Tue Aug 19 07:00:43 2025
From: luyulin at eswincomputing.com (Yulin Lu)
Date: Tue, 19 Aug 2025 22:00:43 +0800
Subject: [PATCH v2 3/3] phy: eswin: Create eswin directory and add EIC7700 SATA PHY driver
In-Reply-To: <20250819134722.220-1-luyulin@eswincomputing.com>
References: <20250819134722.220-1-luyulin@eswincomputing.com>
Message-ID: <20250819140043.1862-1-luyulin@eswincomputing.com>

From: luyulin <luyulin at eswincomputing.com>

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

Signed-off-by: luyulin <luyulin at eswincomputing.com>
---
 drivers/phy/Kconfig                  |   1 +
 drivers/phy/Makefile                 |   1 +
 drivers/phy/eswin/Kconfig            |  14 ++
 drivers/phy/eswin/Makefile           |   2 +
 drivers/phy/eswin/phy-eic7700-sata.c | 197 +++++++++++++++++++++++++++
 5 files changed, 215 insertions(+)
 create mode 100644 drivers/phy/eswin/Kconfig
 create mode 100644 drivers/phy/eswin/Makefile
 create mode 100644 drivers/phy/eswin/phy-eic7700-sata.c

diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 58c911e1b2d2..e82ebcfe534a 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -105,6 +105,7 @@ source "drivers/phy/allwinner/Kconfig"
 source "drivers/phy/amlogic/Kconfig"
 source "drivers/phy/broadcom/Kconfig"
 source "drivers/phy/cadence/Kconfig"
+source "drivers/phy/eswin/Kconfig"
 source "drivers/phy/freescale/Kconfig"
 source "drivers/phy/hisilicon/Kconfig"
 source "drivers/phy/ingenic/Kconfig"
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index c670a8dac468..ed7444949259 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -17,6 +17,7 @@ obj-y					+= allwinner/	\
 					   amlogic/	\
 					   broadcom/	\
 					   cadence/	\
+					   eswin/	\
 					   freescale/	\
 					   hisilicon/	\
 					   ingenic/	\
diff --git a/drivers/phy/eswin/Kconfig b/drivers/phy/eswin/Kconfig
new file mode 100644
index 000000000000..3fcd76582c3b
--- /dev/null
+++ b/drivers/phy/eswin/Kconfig
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Phy drivers for Eswin platforms
+#
+config PHY_EIC7700_SATA
+	tristate "eic7700 Sata SerDes/PHY driver"
+	depends on ARCH_ESWIN || COMPILE_TEST
+	depends on HAS_IOMEM
+	select GENERIC_PHY
+	help
+	  Enable this to support SerDes/Phy found on ESWIN's
+	  EIC7700 SoC.This Phy supports SATA 1.5 Gb/s,
+	  SATA 3.0 Gb/s, SATA 6.0 Gb/s speeds.
+	  It supports one SATA host port to accept one SATA device.
diff --git a/drivers/phy/eswin/Makefile b/drivers/phy/eswin/Makefile
new file mode 100644
index 000000000000..db08c66be812
--- /dev/null
+++ b/drivers/phy/eswin/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_PHY_EIC7700_SATA)	+= phy-eic7700-sata.o
diff --git a/drivers/phy/eswin/phy-eic7700-sata.c b/drivers/phy/eswin/phy-eic7700-sata.c
new file mode 100644
index 000000000000..8a757839e868
--- /dev/null
+++ b/drivers/phy/eswin/phy-eic7700-sata.c
@@ -0,0 +1,197 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ESWIN SATA PHY driver
+ *
+ * Copyright 2024, Beijing ESWIN Computing Technology Co., Ltd..
+ * All rights reserved.
+ *
+ * Authors: Yulin Lu <luyulin at eswincomputing.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+
+#define SATA_CLK_CTRL			0x0
+#define SATA_AXI_LP_CTRL		0x08
+#define SATA_MPLL_CTRL			0x20
+#define SATA_PHY_CTRL0			0x28
+#define SATA_PHY_CTRL1			0x2c
+#define SATA_REF_CTRL1			0x38
+#define SATA_REG_CTRL			0x34
+#define SATA_LOS_IDEN			0x3c
+#define SATA_RESET_CTRL			0x40
+#define SATA_CLK_RST_SOURCE_PHY		BIT(0)
+#define SATA_SYS_CLK_EN			BIT(28)
+#define SATA_PHY_RESET			BIT(0)
+#define SATA_PORT_RESET			BIT(1)
+#define SATA_LOS_LEVEL			0x9
+#define SATA_LOS_BIAS			(0x02 << 16)
+#define SATA_REF_REPEATCLK_EN		BIT(0)
+#define SATA_REF_USE_PAD		BIT(20)
+#define SATA_P0_AMPLITUDE_GEN1		0x42
+#define SATA_P0_AMPLITUDE_GEN2		(0x46 << 8)
+#define SATA_P0_AMPLITUDE_GEN3		(0x73 << 16)
+#define SATA_P0_PHY_TX_PREEMPH_GEN1	0x05
+#define SATA_P0_PHY_TX_PREEMPH_GEN2	(0x05 << 8)
+#define SATA_P0_PHY_TX_PREEMPH_GEN3	(0x08 << 16)
+#define SATA_MPLL_MULTIPLIER		(0x3c << 16)
+#define SATA_M_CSYSREQ			BIT(0)
+#define SATA_S_CSYSREQ			BIT(16)
+#define SATA_P0_PHY_STAT		0x24
+#define SATA_P0_PHY_READY		BIT(0)
+
+#define PHY_READY_TIMEOUT		(usecs_to_jiffies(4000))
+
+struct eic7700_sata_phy {
+	struct phy *phy;
+	void __iomem *regs;
+};
+
+static int wait_for_phy_ready(void __iomem *base, u32 reg, u32 checkbit,
+			      u32 status)
+{
+	unsigned long start = jiffies;
+	unsigned long timeout = start + PHY_READY_TIMEOUT;
+
+	while (time_before(start, timeout)) {
+		if ((readl(base + reg) & checkbit) == status)
+			return 0;
+		usleep_range(50, 70);
+	}
+
+	return -EFAULT;
+}
+
+static int eic7700_sata_phy_init(struct phy *phy)
+{
+	struct eic7700_sata_phy *sata_phy = phy_get_drvdata(phy);
+	u32 val = 0;
+	int ret = 0;
+
+	/*
+	 * The SATA_CLK_CTRL register offset controls the pmalive, rxoob,
+	 * and rbc clocks gate provided by the PHY through the HSP bus,
+	 * and it is not registered in the clock tree.
+	 */
+	val = readl(sata_phy->regs + SATA_CLK_CTRL);
+	val |= SATA_SYS_CLK_EN;
+	writel(val, sata_phy->regs + SATA_CLK_CTRL);
+
+	writel(SATA_CLK_RST_SOURCE_PHY, sata_phy->regs + SATA_REF_CTRL1);
+	writel(SATA_P0_AMPLITUDE_GEN1 | SATA_P0_AMPLITUDE_GEN2 |
+	       SATA_P0_AMPLITUDE_GEN3, sata_phy->regs + SATA_PHY_CTRL0);
+	writel(SATA_P0_PHY_TX_PREEMPH_GEN1 | SATA_P0_PHY_TX_PREEMPH_GEN2 |
+	       SATA_P0_PHY_TX_PREEMPH_GEN3, sata_phy->regs + SATA_PHY_CTRL1);
+	writel(SATA_LOS_LEVEL | SATA_LOS_BIAS,
+	       sata_phy->regs + SATA_LOS_IDEN);
+	writel(SATA_M_CSYSREQ | SATA_S_CSYSREQ,
+	       sata_phy->regs + SATA_AXI_LP_CTRL);
+	writel(SATA_REF_REPEATCLK_EN | SATA_REF_USE_PAD,
+	       sata_phy->regs + SATA_REG_CTRL);
+	writel(SATA_MPLL_MULTIPLIER, sata_phy->regs + SATA_MPLL_CTRL);
+	usleep_range(15, 20);
+
+	/*
+	 * The SATA_RESET_CTRL register offset controls reset/deassert
+	 * for both the port and the PHY through the HSP bus,
+	 * and it is not registered in the reset tree.
+	 */
+	val = readl(sata_phy->regs + SATA_RESET_CTRL);
+	val &= ~(SATA_PHY_RESET | SATA_PORT_RESET);
+	writel(val, sata_phy->regs + SATA_RESET_CTRL);
+
+	ret = wait_for_phy_ready(sata_phy->regs, SATA_P0_PHY_STAT,
+				 SATA_P0_PHY_READY, 1);
+	if (ret < 0)
+		dev_err(&sata_phy->phy->dev,
+			"PHY READY check failed\n");
+	return ret;
+}
+
+static int eic7700_sata_phy_exit(struct phy *phy)
+{
+	struct eic7700_sata_phy *sata_phy = phy_get_drvdata(phy);
+	u32 val = 0;
+
+	val = readl(sata_phy->regs + SATA_RESET_CTRL);
+	val |= SATA_PHY_RESET | SATA_PORT_RESET;
+	writel(val, sata_phy->regs + SATA_RESET_CTRL);
+
+	val = readl(sata_phy->regs + SATA_CLK_CTRL);
+	val &= ~SATA_SYS_CLK_EN;
+	writel(val, sata_phy->regs + SATA_CLK_CTRL);
+
+	return 0;
+}
+
+static const struct phy_ops eic7700_sata_phy_ops = {
+	.init		= eic7700_sata_phy_init,
+	.exit		= eic7700_sata_phy_exit,
+	.owner		= THIS_MODULE,
+};
+
+static int eic7700_sata_phy_probe(struct platform_device *pdev)
+{
+	struct eic7700_sata_phy *sata_phy;
+	struct device *dev = &pdev->dev;
+	struct phy_provider *phy_provider;
+	u32 val = 0;
+	int ret = 0;
+
+	sata_phy = devm_kzalloc(dev, sizeof(*sata_phy), GFP_KERNEL);
+	if (!sata_phy)
+		return -ENOMEM;
+
+	sata_phy->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(sata_phy->regs))
+		return PTR_ERR(sata_phy->regs);
+
+	dev_set_drvdata(dev, sata_phy);
+
+	sata_phy->phy = devm_phy_create(dev, NULL, &eic7700_sata_phy_ops);
+	if (IS_ERR(sata_phy->phy)) {
+		dev_err(dev, "failed to create PHY\n");
+		ret = PTR_ERR(sata_phy->phy);
+		goto clk_disable;
+	}
+
+	phy_set_drvdata(sata_phy->phy, sata_phy);
+
+	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;
+	}
+
+	return 0;
+
+clk_disable:
+	val = readl(sata_phy->regs + SATA_CLK_CTRL);
+	val &= ~SATA_SYS_CLK_EN;
+	writel(val, sata_phy->regs + SATA_CLK_CTRL);
+
+	return ret;
+}
+
+static const struct of_device_id eic7700_sata_phy_of_match[] = {
+	{ .compatible = "eswin,eic7700-sata-phy" },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, eic7700_sata_phy_of_match);
+
+static struct platform_driver eic7700_sata_phy_driver = {
+	.probe	= eic7700_sata_phy_probe,
+	.driver = {
+		.of_match_table	= eic7700_sata_phy_of_match,
+		.name  = "eswin,sata-phy",
+		.suppress_bind_attrs = true,
+	}
+};
+module_platform_driver(eic7700_sata_phy_driver);
+
+MODULE_DESCRIPTION("SATA PHY driver for the ESWIN EIC7700 SoC");
+MODULE_AUTHOR("Yulin Lu <luyulin at eswincomputing.com>");
+MODULE_LICENSE("GPL");
-- 
2.25.1



From robh at kernel.org  Tue Aug 19 07:25:55 2025
From: robh at kernel.org (Rob Herring)
Date: Tue, 19 Aug 2025 09:25:55 -0500
Subject: [PATCH v2 1/3] dt-bindings: ata: eswin: Document for EIC7700 SoC ahci
In-Reply-To: <20250819135413.386-1-luyulin@eswincomputing.com>
References: <20250819134722.220-1-luyulin@eswincomputing.com> <20250819135413.386-1-luyulin@eswincomputing.com>
Message-ID: <CAL_JsqKFotNLZZXwiy7S6K8qXLdGRAnsa-1zvZRDQBE39Gf5kg@mail.gmail.com>

On Tue, Aug 19, 2025 at 8:54?AM Yulin Lu <luyulin at eswincomputing.com> wrote:
>
> From: luyulin <luyulin at eswincomputing.com>

Please fix your name.

>
> Add document for the SATA AHCI controller on the EIC7700 SoC platform,
> including descriptions of its hardware configurations.
>
> Signed-off-by: luyulin <luyulin at eswincomputing.com>

And here.

> ---
>  .../bindings/ata/eswin,eic7700-ahci.yaml      | 92 +++++++++++++++++++
>  1 file changed, 92 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/ata/eswin,eic7700-ahci.yaml
>
> diff --git a/Documentation/devicetree/bindings/ata/eswin,eic7700-ahci.yaml b/Documentation/devicetree/bindings/ata/eswin,eic7700-ahci.yaml
> new file mode 100644
> index 000000000000..9ef58c9c2f28
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/ata/eswin,eic7700-ahci.yaml
> @@ -0,0 +1,92 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/ata/eswin,eic7700-ahci.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Eswin EIC7700 SoC SATA Controller
> +
> +maintainers:
> +  - Yulin Lu <luyulin at eswincomputing.com>
> +  - Huan He <hehuan1 at eswincomputing.com>
> +
> +description:
> +  This document defines device tree bindings for the Synopsys DWC
> +  implementation of the AHCI SATA controller found in Eswin's
> +  Eic7700 SoC platform.
> +
> +select:
> +  properties:
> +    compatible:
> +      const: eswin,eic7700-ahci
> +  required:
> +    - compatible
> +
> +allOf:
> +  - $ref: snps,dwc-ahci-common.yaml#
> +
> +properties:
> +  compatible:
> +    items:
> +      - const: eswin,eic7700-ahci
> +      - const: snps,dwc-ahci
> +
> +  reg:
> +    maxItems: 1

Drop. snps,dwc-ahci-common.yaml already defines this.

> +
> +  interrupts:
> +    maxItems: 1

Drop. snps,dwc-ahci-common.yaml already defines this.

> +
> +  ports-implemented:
> +    const: 1

Really, your firmware should initialize the DWC specific register that
sets this and is discoverable via a standard AHCI register.

> +
> +  clocks:
> +    minItems: 2
> +    maxItems: 2
> +
> +  clock-names:
> +    items:
> +      - const: pclk
> +      - const: aclk
> +
> +  resets:
> +    maxItems: 1
> +
> +  reset-names:
> +    const: arst
> +
> +  phys:
> +    maxItems: 1

Drop. ahci-common.yaml already defines this.

> +
> +  phy-names:
> +    const: sata-phy

Drop. ahci-common.yaml already defines this.

> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - clocks
> +  - clock-names
> +  - resets
> +  - reset-names
> +  - phys
> +  - phy-names
> +  - ports-implemented
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    sata at 50420000 {
> +        compatible = "eswin,eic7700-ahci", "snps,dwc-ahci";
> +        reg = <0x50420000 0x10000>;
> +        interrupt-parent = <&plic>;
> +        interrupts = <58>;
> +        ports-implemented = <0x1>;
> +        clocks = <&gate_clk_hsp_cfgclk>, <&gate_clk_hsp_aclk>;
> +        clock-names = "pclk", "aclk";
> +        resets = <&reset 96>;
> +        reset-names = "arst";
> +        phys = <&sata_phy>;
> +        phy-names = "sata-phy";
> +    };
> --
> 2.25.1
>
>


From helgaas at kernel.org  Tue Aug 19 08:07:27 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 19 Aug 2025 10:07:27 -0500
Subject: [PATCH v3 11/12] PCI: exynos: Add support for Tesla FSD SoC
In-Reply-To: <00b501dc10fd$f1fecc10$d5fc6430$@samsung.com>
Message-ID: <20250819150727.GA586493@bhelgaas>

On Tue, Aug 19, 2025 at 05:09:34PM +0530, Shradha Todi wrote:
> ...

> > Another question about the test:
> > 
> >   if ((val & FSD_IRQ_MSI_ENABLE) == FSD_IRQ_MSI_ENABLE) {
> > 
> > This assumes there are no other bits in FSD_IRQ2_STS that could be
> > set.  I would have expected a test like this:
> > 
> >   if (val & FSD_IRQ_MSI_ENABLE) {
> 
> Thanks for pointing this out. FSD_IRQ_MSI_ENABLE is a single-bit, so there
> is no functional difference in the two statements. I didn't have a specific
> reason for using "== FSD_IRQ_MSI_ENABLE".
> But I see that "val & FSD_IRQ_MSI_ENABLE" would have been the more
> standard way to write this. I will update this for clarity.

Oof, sorry, I don't know what I was thinking.  You're right, it's OK
as is.  But "val & FSD_IRQ_MSI_ENABLE" *is* shorter and more
idiomatic, so I think preferable anyway.

Bjorn


From dmitry.baryshkov at oss.qualcomm.com  Tue Aug 19 11:41:11 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Tue, 19 Aug 2025 21:41:11 +0300
Subject: [PATCH 3/4] phy: qcom-qmp: pcs: Add v8.50 register offsets
In-Reply-To: <20250819-glymur_pcie5-v1-3-2ea09f83cbb0@oss.qualcomm.com>
References: <20250819-glymur_pcie5-v1-0-2ea09f83cbb0@oss.qualcomm.com>
 <20250819-glymur_pcie5-v1-3-2ea09f83cbb0@oss.qualcomm.com>
Message-ID: <kssxh6n7ml7zizll7ifo3ihcwtsa5lnixgwtpbmqh5tt4tiqsq@pex6pl7kcklf>

On Tue, Aug 19, 2025 at 02:52:07AM -0700, Wenbin Yao wrote:
> From: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
> 
> The new Glymur SoC bumps up the HW version of QMP phy to v8.50 for PCIE
> g5x4. Add the new PCS offsets in a dedicated header file.
> 
> Signed-off-by: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
> Signed-off-by: Wenbin Yao <wenbin.yao at oss.qualcomm.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-pcs-v8_50.h | 13 +++++++++++++
>  drivers/phy/qualcomm/phy-qcom-qmp.h           |  2 ++
>  2 files changed, 15 insertions(+)
> 

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>


-- 
With best wishes
Dmitry


From dmitry.baryshkov at oss.qualcomm.com  Tue Aug 19 11:43:20 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Tue, 19 Aug 2025 21:43:20 +0300
Subject: [PATCH 4/4] phy: qcom: qmp-pcie: Add support for Glymur PCIe
 Gen5x4 PHY
In-Reply-To: <20250819-glymur_pcie5-v1-4-2ea09f83cbb0@oss.qualcomm.com>
References: <20250819-glymur_pcie5-v1-0-2ea09f83cbb0@oss.qualcomm.com>
 <20250819-glymur_pcie5-v1-4-2ea09f83cbb0@oss.qualcomm.com>
Message-ID: <6zlydkdgmowqg7cv5eeoaf7mrpnhzokyvhh5xasvznqaxnhdji@xol3jiz2lzld>

On Tue, Aug 19, 2025 at 02:52:08AM -0700, Wenbin Yao wrote:
> From: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
> 
> Add support for Gen5 x4 PCIe QMP PHY found on Glymur platform.
> 
> Signed-off-by: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
> Signed-off-by: Wenbin Yao <wenbin.yao at oss.qualcomm.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 29 +++++++++++++++++++++++++++++
>  1 file changed, 29 insertions(+)
> 
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
> index 95830dcfdec9b1f68fd55d1cc3c102985cfafcc1..e422cf6932d261074ed3419ed8806e9ed212c26c 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
> @@ -93,6 +93,12 @@ static const unsigned int pciephy_v6_regs_layout[QPHY_LAYOUT_SIZE] = {
>  	[QPHY_PCS_POWER_DOWN_CONTROL]	= QPHY_V6_PCS_POWER_DOWN_CONTROL,
>  };
>  
> +static const unsigned int pciephy_v8_50_regs_layout[QPHY_LAYOUT_SIZE] = {
> +	[QPHY_START_CTRL]		= QPHY_V8_50_PCS_START_CONTROL,
> +	[QPHY_PCS_STATUS]		= QPHY_V8_50_PCS_STATUS1,
> +	[QPHY_PCS_POWER_DOWN_CONTROL]   = QPHY_V8_50_PCS_POWER_DOWN_CONTROL,
> +};
> +
>  static const struct qmp_phy_init_tbl msm8998_pcie_serdes_tbl[] = {
>  	QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
>  	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
> @@ -3229,6 +3235,10 @@ static const struct qmp_pcie_offsets qmp_pcie_offsets_v6_30 = {
>  	.ln_shrd	= 0x8000,
>  };
>  
> +static const struct qmp_pcie_offsets qmp_pcie_offsets_v8_50 = {
> +	.pcs        = 0x9000,

Even if the driver uses only PCS regs for 8.50 currently, I'd suggest
describing the whole picture here. Otherwise it might backfire later, if
we add offsets for other blocks later and they won't match the ones used
for Glymur.

> +};
> +
>  static const struct qmp_phy_cfg ipq8074_pciephy_cfg = {
>  	.lanes			= 1,
>  
> @@ -4258,6 +4268,22 @@ static const struct qmp_phy_cfg qmp_v6_gen4x4_pciephy_cfg = {
>  	.phy_status             = PHYSTATUS_4_20,
>  };
>  
> +static const struct qmp_phy_cfg glymur_qmp_gen5x4_pciephy_cfg = {
> +	.lanes = 4,
> +
> +	.offsets        = &qmp_pcie_offsets_v8_50,
> +
> +	.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_v8_50_regs_layout,
> +
> +	.pwrdn_ctrl     = SW_PWRDN | REFCLK_DRV_DSBL,
> +	.phy_status     = PHYSTATUS_4_20,
> +};
> +
>  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;
> @@ -5114,6 +5140,9 @@ static const struct of_device_id qmp_pcie_of_match_table[] = {
>  	}, {
>  		.compatible = "qcom,x1p42100-qmp-gen4x4-pcie-phy",
>  		.data = &qmp_v6_gen4x4_pciephy_cfg,
> +	}, {
> +		.compatible = "qcom,glymur-qmp-gen5x4-pcie-phy",
> +		.data = &glymur_qmp_gen5x4_pciephy_cfg,
>  	},
>  	{ },
>  };
> 
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry


From robh at kernel.org  Tue Aug 19 12:42:13 2025
From: robh at kernel.org (Rob Herring (Arm))
Date: Tue, 19 Aug 2025 14:42:13 -0500
Subject: [PATCH 1/4] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy:
 Document the Glymur QMP PCIe PHY
In-Reply-To: <20250819-glymur_pcie5-v1-1-2ea09f83cbb0@oss.qualcomm.com>
References: <20250819-glymur_pcie5-v1-0-2ea09f83cbb0@oss.qualcomm.com>
 <20250819-glymur_pcie5-v1-1-2ea09f83cbb0@oss.qualcomm.com>
Message-ID: <175563253013.1213233.1800125828083070871.robh@kernel.org>


On Tue, 19 Aug 2025 02:52:05 -0700, Wenbin Yao wrote:
> From: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
> 
> The fifth PCIe instance on Glymur has a Gen5 4-lane PHY. Document it as a
> separate compatible.
> 
> Signed-off-by: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
> Signed-off-by: Wenbin Yao <wenbin.yao at oss.qualcomm.com>
> ---
>  Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml | 3 +++
>  1 file changed, 3 insertions(+)
> 

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



From robh at kernel.org  Tue Aug 19 12:43:05 2025
From: robh at kernel.org (Rob Herring (Arm))
Date: Tue, 19 Aug 2025 14:43:05 -0500
Subject: [PATCH 2/4] dt-bindings: PCI: qcom: Document the Glymur PCIe
 Controller
In-Reply-To: <20250819-glymur_pcie5-v1-2-2ea09f83cbb0@oss.qualcomm.com>
References: <20250819-glymur_pcie5-v1-0-2ea09f83cbb0@oss.qualcomm.com>
 <20250819-glymur_pcie5-v1-2-2ea09f83cbb0@oss.qualcomm.com>
Message-ID: <175563258518.1214404.14197292755881169254.robh@kernel.org>


On Tue, 19 Aug 2025 02:52:06 -0700, Wenbin Yao wrote:
> From: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
> 
> On the Qualcomm Glymur platform the PCIe host is compatible with the DWC
> controller present on the X1E80100 platform. So document the PCIe
> controllers found on Glymur and use the X1E80100 compatible string as a
> fallback in the schema.
> 
> Signed-off-by: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
> Signed-off-by: Wenbin Yao <wenbin.yao at oss.qualcomm.com>
> ---
>  Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 

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



From quic_nitirawa at quicinc.com  Tue Aug 19 15:28:24 2025
From: quic_nitirawa at quicinc.com (Nitin Rawat)
Date: Wed, 20 Aug 2025 03:58:24 +0530
Subject: [PATCH V3 0/2] Add regulator load support for QMP UFS PHY
Message-ID: <20250819222832.8471-1-quic_nitirawa@quicinc.com>

The series improves regulator handling in the QMP UFS PHY driver and
adds load configuration support for SM8650 and SM8750 platforms.

On some SoCs, regulators are shared between the UFS PHY and other IP
blocks. To maintain stability and power efficiency, the regulator
framework needs to know the UFS PHY's peak load, as it determines the
regulator's operating mode.

The first update replaces devm_regulator_bulk_get() with
devm_regulator_bulk_get_const(), converts the regulator name array to
a bulk data structure, and uses the init_load_uA field to automatically
apply regulator_set_load() before the first enable.

The second update adds platform-specific load settings for SM8650 and
SM8750 to ensure proper power management where regulators are shared.

Changes from v2:
1. Addressed Dmitry's comment to replace devm_regulator_bulk_get() with
   devm_regulator_bulk_get_const.
2. inline the qmp_ufs_vreg_init() function

Changes from v1:
1. Addressed comments to move load configuration from device tree to
   hardcoded, per-compatible data within the driver.
2. Accordingly updated commit text to reflect the same.
3. Addressed Manivannan's comment to avoid initialization of load.

Nitin Rawat (2):
  phy: qcom-qmp-ufs: Add regulator load voting for UFS QMP PHY
  phy: qcom-qmp-ufs: Add regulator loads for SM8650 and SM8750

 drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 48 ++++++++++++-------------
 1 file changed, 23 insertions(+), 25 deletions(-)

--
2.48.1



From quic_nitirawa at quicinc.com  Tue Aug 19 15:28:25 2025
From: quic_nitirawa at quicinc.com (Nitin Rawat)
Date: Wed, 20 Aug 2025 03:58:25 +0530
Subject: [PATCH V3 1/2] phy: qcom-qmp-ufs: Add regulator load voting for UFS QMP PHY
In-Reply-To: <20250819222832.8471-1-quic_nitirawa@quicinc.com>
References: <20250819222832.8471-1-quic_nitirawa@quicinc.com>
Message-ID: <20250819222832.8471-2-quic_nitirawa@quicinc.com>

On certain SoCs, power regulators are shared between the QMP UFS PHY
and other IP blocks. To ensure proper operation, the regulator
framework must be informed of the UFS PHY's load requirements.
This is essential because the regulator's operating mode?whether Low
Power or High Power?depends on the maximum expected load at any given
time, which the regulator driver needs to manage accordingly.

To support this, replace devm_regulator_bulk_get() with
devm_regulator_bulk_get_const() and inline the qmp_ufs_vreg_init()
function. additionally replace the array of regulator names with a
bulk regulator data structure, and utilize the init_load_uA field
provided by the regulator framework. This ensures that
regulator_set_load() is automatically invoked before the
first enable operation.

Signed-off-by: Nitin Rawat <quic_nitirawa at quicinc.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 29 +++++++------------------
 1 file changed, 8 insertions(+), 21 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
index 9c69c77d10c8..aaa88ca0ef07 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
@@ -1107,7 +1107,7 @@ struct qmp_phy_cfg {
 	const struct qmp_phy_cfg_tbls tbls_hs_overlay[NUM_OVERLAY];

 	/* regulators to be requested */
-	const char * const *vreg_list;
+	const struct regulator_bulk_data *vreg_list;
 	int num_vregs;

 	/* array of registers with different offsets */
@@ -1164,9 +1164,10 @@ static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
 	readl(base + offset);
 }

-/* list of regulators */
-static const char * const qmp_phy_vreg_l[] = {
-	"vdda-phy", "vdda-pll",
+/* Default regulator bulk data (no load used) */
+static const struct regulator_bulk_data qmp_phy_vreg_l[] = {
+	{ .supply = "vdda-phy" },
+	{ .supply = "vdda-pll" },
 };

 static const struct qmp_ufs_offsets qmp_ufs_offsets = {
@@ -1890,22 +1891,6 @@ static const struct phy_ops qcom_qmp_ufs_phy_ops = {
 	.owner		= THIS_MODULE,
 };

-static int qmp_ufs_vreg_init(struct qmp_ufs *qmp)
-{
-	const struct qmp_phy_cfg *cfg = qmp->cfg;
-	struct device *dev = qmp->dev;
-	int num = cfg->num_vregs;
-	int i;
-
-	qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL);
-	if (!qmp->vregs)
-		return -ENOMEM;
-
-	for (i = 0; i < num; i++)
-		qmp->vregs[i].supply = cfg->vreg_list[i];
-
-	return devm_regulator_bulk_get(dev, num, qmp->vregs);
-}

 static int qmp_ufs_clk_init(struct qmp_ufs *qmp)
 {
@@ -2068,7 +2053,9 @@ static int qmp_ufs_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;

-	ret = qmp_ufs_vreg_init(qmp);
+	ret = devm_regulator_bulk_get_const(dev, qmp->cfg->num_vregs,
+					    qmp->cfg->vreg_list,
+					    &qmp->vregs);
 	if (ret)
 		return ret;

--
2.48.1



From quic_nitirawa at quicinc.com  Tue Aug 19 15:28:26 2025
From: quic_nitirawa at quicinc.com (Nitin Rawat)
Date: Wed, 20 Aug 2025 03:58:26 +0530
Subject: [PATCH V3 2/2] phy: qcom-qmp-ufs: Add regulator loads for SM8650 and SM8750
In-Reply-To: <20250819222832.8471-1-quic_nitirawa@quicinc.com>
References: <20250819222832.8471-1-quic_nitirawa@quicinc.com>
Message-ID: <20250819222832.8471-3-quic_nitirawa@quicinc.com>

Add regulator load voting support for SM8650 and SM8750 platforms by
introducing dedicated regulator bulk data arrays with their load
values.

The load requirements are:
- SM8650: vdda-phy (205mA), vdda-pll (17.5mA)
- SM8750: vdda-phy (213mA), vdda-pll (18.3mA)

This ensures stable operation and proper power management for these
platforms where regulators are shared between the QMP USB PHY and
other IP blocks by setting appropriate regulator load currents during PHY
operations.

Configurations without specific load requirements will continue to work
unchanged, as init_load_uA remains zero-initialized when .init_load_uA
is not provided.

Signed-off-by: Nitin Rawat <quic_nitirawa at quicinc.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
index aaa88ca0ef07..1c3ce0fa6adf 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
@@ -1170,6 +1170,17 @@ static const struct regulator_bulk_data qmp_phy_vreg_l[] = {
 	{ .supply = "vdda-pll" },
 };

+/* Regulator bulk data with load values for specific configurations */
+static const struct regulator_bulk_data sm8650_ufsphy_vreg_l[] = {
+	{ .supply = "vdda-phy", .init_load_uA = 205000 },
+	{ .supply = "vdda-pll", .init_load_uA = 17500 },
+};
+
+static const struct regulator_bulk_data sm8750_ufsphy_vreg_l[] = {
+	{ .supply = "vdda-phy", .init_load_uA = 213000 },
+	{ .supply = "vdda-pll", .init_load_uA = 18300 },
+};
+
 static const struct qmp_ufs_offsets qmp_ufs_offsets = {
 	.serdes		= 0,
 	.pcs		= 0xc00,
@@ -1638,8 +1649,8 @@ static const struct qmp_phy_cfg sm8650_ufsphy_cfg = {
 		.max_gear	= UFS_HS_G5,
 	},

-	.vreg_list		= qmp_phy_vreg_l,
-	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
+	.vreg_list		= sm8650_ufsphy_vreg_l,
+	.num_vregs		= ARRAY_SIZE(sm8650_ufsphy_vreg_l),
 	.regs			= ufsphy_v6_regs_layout,
 };

@@ -1676,8 +1687,8 @@ static const struct qmp_phy_cfg sm8750_ufsphy_cfg = {
 		.max_gear	= UFS_HS_G5,
 	},

-	.vreg_list		= qmp_phy_vreg_l,
-	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
+	.vreg_list		= sm8750_ufsphy_vreg_l,
+	.num_vregs		= ARRAY_SIZE(sm8750_ufsphy_vreg_l),
 	.regs			= ufsphy_v6_regs_layout,

 };
--
2.48.1



From dmitry.baryshkov at oss.qualcomm.com  Tue Aug 19 17:48:58 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Wed, 20 Aug 2025 03:48:58 +0300
Subject: [PATCH V3 1/2] phy: qcom-qmp-ufs: Add regulator load voting for
 UFS QMP PHY
In-Reply-To: <20250819222832.8471-2-quic_nitirawa@quicinc.com>
References: <20250819222832.8471-1-quic_nitirawa@quicinc.com>
 <20250819222832.8471-2-quic_nitirawa@quicinc.com>
Message-ID: <agsqq6fwrj5paejfaefgtcz57gnxwni3l3plxpslcxdhzshuda@lypqqueqcfkd>

On Wed, Aug 20, 2025 at 03:58:25AM +0530, Nitin Rawat wrote:
> On certain SoCs, power regulators are shared between the QMP UFS PHY
> and other IP blocks. To ensure proper operation, the regulator
> framework must be informed of the UFS PHY's load requirements.
> This is essential because the regulator's operating mode?whether Low
> Power or High Power?depends on the maximum expected load at any given
> time, which the regulator driver needs to manage accordingly.
> 
> To support this, replace devm_regulator_bulk_get() with
> devm_regulator_bulk_get_const() and inline the qmp_ufs_vreg_init()
> function. additionally replace the array of regulator names with a
> bulk regulator data structure, and utilize the init_load_uA field
> provided by the regulator framework. This ensures that
> regulator_set_load() is automatically invoked before the
> first enable operation.
> 
> Signed-off-by: Nitin Rawat <quic_nitirawa at quicinc.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 29 +++++++------------------
>  1 file changed, 8 insertions(+), 21 deletions(-)
> 

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>


-- 
With best wishes
Dmitry


From dmitry.baryshkov at oss.qualcomm.com  Tue Aug 19 17:49:31 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Wed, 20 Aug 2025 03:49:31 +0300
Subject: [PATCH V3 2/2] phy: qcom-qmp-ufs: Add regulator loads for SM8650
 and SM8750
In-Reply-To: <20250819222832.8471-3-quic_nitirawa@quicinc.com>
References: <20250819222832.8471-1-quic_nitirawa@quicinc.com>
 <20250819222832.8471-3-quic_nitirawa@quicinc.com>
Message-ID: <ger4kizeltjwalfuwu4dpfjiskrv2okgo5c7d6n3pb24yaxgfo@nkcndblyx3il>

On Wed, Aug 20, 2025 at 03:58:26AM +0530, Nitin Rawat wrote:
> Add regulator load voting support for SM8650 and SM8750 platforms by
> introducing dedicated regulator bulk data arrays with their load
> values.
> 
> The load requirements are:
> - SM8650: vdda-phy (205mA), vdda-pll (17.5mA)
> - SM8750: vdda-phy (213mA), vdda-pll (18.3mA)
> 
> This ensures stable operation and proper power management for these
> platforms where regulators are shared between the QMP USB PHY and
> other IP blocks by setting appropriate regulator load currents during PHY
> operations.
> 
> Configurations without specific load requirements will continue to work
> unchanged, as init_load_uA remains zero-initialized when .init_load_uA
> is not provided.

Can we please get configuration for the rest of the platforms?

> 
> Signed-off-by: Nitin Rawat <quic_nitirawa at quicinc.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 19 +++++++++++++++----
>  1 file changed, 15 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> index aaa88ca0ef07..1c3ce0fa6adf 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> @@ -1170,6 +1170,17 @@ static const struct regulator_bulk_data qmp_phy_vreg_l[] = {
>  	{ .supply = "vdda-pll" },
>  };
> 
> +/* Regulator bulk data with load values for specific configurations */
> +static const struct regulator_bulk_data sm8650_ufsphy_vreg_l[] = {
> +	{ .supply = "vdda-phy", .init_load_uA = 205000 },
> +	{ .supply = "vdda-pll", .init_load_uA = 17500 },
> +};
> +
> +static const struct regulator_bulk_data sm8750_ufsphy_vreg_l[] = {
> +	{ .supply = "vdda-phy", .init_load_uA = 213000 },
> +	{ .supply = "vdda-pll", .init_load_uA = 18300 },
> +};
> +
>  static const struct qmp_ufs_offsets qmp_ufs_offsets = {
>  	.serdes		= 0,
>  	.pcs		= 0xc00,
> @@ -1638,8 +1649,8 @@ static const struct qmp_phy_cfg sm8650_ufsphy_cfg = {
>  		.max_gear	= UFS_HS_G5,
>  	},
> 
> -	.vreg_list		= qmp_phy_vreg_l,
> -	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
> +	.vreg_list		= sm8650_ufsphy_vreg_l,
> +	.num_vregs		= ARRAY_SIZE(sm8650_ufsphy_vreg_l),
>  	.regs			= ufsphy_v6_regs_layout,
>  };
> 
> @@ -1676,8 +1687,8 @@ static const struct qmp_phy_cfg sm8750_ufsphy_cfg = {
>  		.max_gear	= UFS_HS_G5,
>  	},
> 
> -	.vreg_list		= qmp_phy_vreg_l,
> -	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
> +	.vreg_list		= sm8750_ufsphy_vreg_l,
> +	.num_vregs		= ARRAY_SIZE(sm8750_ufsphy_vreg_l),
>  	.regs			= ufsphy_v6_regs_layout,
> 
>  };
> --
> 2.48.1
> 

-- 
With best wishes
Dmitry


From wenbin.yao at oss.qualcomm.com  Tue Aug 19 23:17:44 2025
From: wenbin.yao at oss.qualcomm.com (Wenbin Yao (Consultant))
Date: Wed, 20 Aug 2025 14:17:44 +0800
Subject: [PATCH 4/4] phy: qcom: qmp-pcie: Add support for Glymur PCIe
 Gen5x4 PHY
In-Reply-To: <6zlydkdgmowqg7cv5eeoaf7mrpnhzokyvhh5xasvznqaxnhdji@xol3jiz2lzld>
References: <20250819-glymur_pcie5-v1-0-2ea09f83cbb0@oss.qualcomm.com>
 <20250819-glymur_pcie5-v1-4-2ea09f83cbb0@oss.qualcomm.com>
 <6zlydkdgmowqg7cv5eeoaf7mrpnhzokyvhh5xasvznqaxnhdji@xol3jiz2lzld>
Message-ID: <33468410-69e5-4144-88e0-cc34a736c0e4@oss.qualcomm.com>

On 8/20/2025 2:43 AM, Dmitry Baryshkov wrote:
> On Tue, Aug 19, 2025 at 02:52:08AM -0700, Wenbin Yao wrote:
>> From: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
>>
>> Add support for Gen5 x4 PCIe QMP PHY found on Glymur platform.
>>
>> Signed-off-by: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
>> Signed-off-by: Wenbin Yao <wenbin.yao at oss.qualcomm.com>
>> ---
>>   drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 29 +++++++++++++++++++++++++++++
>>   1 file changed, 29 insertions(+)
>>
>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
>> index 95830dcfdec9b1f68fd55d1cc3c102985cfafcc1..e422cf6932d261074ed3419ed8806e9ed212c26c 100644
>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
>> @@ -93,6 +93,12 @@ static const unsigned int pciephy_v6_regs_layout[QPHY_LAYOUT_SIZE] = {
>>   	[QPHY_PCS_POWER_DOWN_CONTROL]	= QPHY_V6_PCS_POWER_DOWN_CONTROL,
>>   };
>>   
>> +static const unsigned int pciephy_v8_50_regs_layout[QPHY_LAYOUT_SIZE] = {
>> +	[QPHY_START_CTRL]		= QPHY_V8_50_PCS_START_CONTROL,
>> +	[QPHY_PCS_STATUS]		= QPHY_V8_50_PCS_STATUS1,
>> +	[QPHY_PCS_POWER_DOWN_CONTROL]   = QPHY_V8_50_PCS_POWER_DOWN_CONTROL,
>> +};
>> +
>>   static const struct qmp_phy_init_tbl msm8998_pcie_serdes_tbl[] = {
>>   	QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
>>   	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
>> @@ -3229,6 +3235,10 @@ static const struct qmp_pcie_offsets qmp_pcie_offsets_v6_30 = {
>>   	.ln_shrd	= 0x8000,
>>   };
>>   
>> +static const struct qmp_pcie_offsets qmp_pcie_offsets_v8_50 = {
>> +	.pcs        = 0x9000,
> Even if the driver uses only PCS regs for 8.50 currently, I'd suggest
> describing the whole picture here. Otherwise it might backfire later, if
> we add offsets for other blocks later and they won't match the ones used
> for Glymur.

OK?will add them.

>
>> +};
>> +
>>   static const struct qmp_phy_cfg ipq8074_pciephy_cfg = {
>>   	.lanes			= 1,
>>   
>> @@ -4258,6 +4268,22 @@ static const struct qmp_phy_cfg qmp_v6_gen4x4_pciephy_cfg = {
>>   	.phy_status             = PHYSTATUS_4_20,
>>   };
>>   
>> +static const struct qmp_phy_cfg glymur_qmp_gen5x4_pciephy_cfg = {
>> +	.lanes = 4,
>> +
>> +	.offsets        = &qmp_pcie_offsets_v8_50,
>> +
>> +	.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_v8_50_regs_layout,
>> +
>> +	.pwrdn_ctrl     = SW_PWRDN | REFCLK_DRV_DSBL,
>> +	.phy_status     = PHYSTATUS_4_20,
>> +};
>> +
>>   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;
>> @@ -5114,6 +5140,9 @@ static const struct of_device_id qmp_pcie_of_match_table[] = {
>>   	}, {
>>   		.compatible = "qcom,x1p42100-qmp-gen4x4-pcie-phy",
>>   		.data = &qmp_v6_gen4x4_pciephy_cfg,
>> +	}, {
>> +		.compatible = "qcom,glymur-qmp-gen5x4-pcie-phy",
>> +		.data = &glymur_qmp_gen5x4_pciephy_cfg,
>>   	},
>>   	{ },
>>   };
>>
>> -- 
>> 2.34.1
>>
-- 
With best wishes
Wenbin



From quic_nitirawa at quicinc.com  Tue Aug 19 23:37:57 2025
From: quic_nitirawa at quicinc.com (Nitin Rawat)
Date: Wed, 20 Aug 2025 12:07:57 +0530
Subject: [PATCH V3 2/2] phy: qcom-qmp-ufs: Add regulator loads for SM8650
 and SM8750
In-Reply-To: <ger4kizeltjwalfuwu4dpfjiskrv2okgo5c7d6n3pb24yaxgfo@nkcndblyx3il>
References: <20250819222832.8471-1-quic_nitirawa@quicinc.com>
 <20250819222832.8471-3-quic_nitirawa@quicinc.com>
 <ger4kizeltjwalfuwu4dpfjiskrv2okgo5c7d6n3pb24yaxgfo@nkcndblyx3il>
Message-ID: <b453b8ff-a460-4ccd-9019-aed746a7d52d@quicinc.com>



On 8/20/2025 6:19 AM, Dmitry Baryshkov wrote:
> On Wed, Aug 20, 2025 at 03:58:26AM +0530, Nitin Rawat wrote:
>> Add regulator load voting support for SM8650 and SM8750 platforms by
>> introducing dedicated regulator bulk data arrays with their load
>> values.
>>
>> The load requirements are:
>> - SM8650: vdda-phy (205mA), vdda-pll (17.5mA)
>> - SM8750: vdda-phy (213mA), vdda-pll (18.3mA)
>>
>> This ensures stable operation and proper power management for these
>> platforms where regulators are shared between the QMP USB PHY and
>> other IP blocks by setting appropriate regulator load currents during PHY
>> operations.
>>
>> Configurations without specific load requirements will continue to work
>> unchanged, as init_load_uA remains zero-initialized when .init_load_uA
>> is not provided.
> 
> Can we please get configuration for the rest of the platforms?

Hi Dmitry,

If you're okay with it, can I merge the configuration for the remaining 
platforms in the next patch series after I complete testing on all 
remaining platforms.

Regards,
Nitin

> 
>>
>> Signed-off-by: Nitin Rawat <quic_nitirawa at quicinc.com>
>> ---
>>   drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 19 +++++++++++++++----
>>   1 file changed, 15 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
>> index aaa88ca0ef07..1c3ce0fa6adf 100644
>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
>> @@ -1170,6 +1170,17 @@ static const struct regulator_bulk_data qmp_phy_vreg_l[] = {
>>   	{ .supply = "vdda-pll" },
>>   };
>>
>> +/* Regulator bulk data with load values for specific configurations */
>> +static const struct regulator_bulk_data sm8650_ufsphy_vreg_l[] = {
>> +	{ .supply = "vdda-phy", .init_load_uA = 205000 },
>> +	{ .supply = "vdda-pll", .init_load_uA = 17500 },
>> +};
>> +
>> +static const struct regulator_bulk_data sm8750_ufsphy_vreg_l[] = {
>> +	{ .supply = "vdda-phy", .init_load_uA = 213000 },
>> +	{ .supply = "vdda-pll", .init_load_uA = 18300 },
>> +};
>> +
>>   static const struct qmp_ufs_offsets qmp_ufs_offsets = {
>>   	.serdes		= 0,
>>   	.pcs		= 0xc00,
>> @@ -1638,8 +1649,8 @@ static const struct qmp_phy_cfg sm8650_ufsphy_cfg = {
>>   		.max_gear	= UFS_HS_G5,
>>   	},
>>
>> -	.vreg_list		= qmp_phy_vreg_l,
>> -	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
>> +	.vreg_list		= sm8650_ufsphy_vreg_l,
>> +	.num_vregs		= ARRAY_SIZE(sm8650_ufsphy_vreg_l),
>>   	.regs			= ufsphy_v6_regs_layout,
>>   };
>>
>> @@ -1676,8 +1687,8 @@ static const struct qmp_phy_cfg sm8750_ufsphy_cfg = {
>>   		.max_gear	= UFS_HS_G5,
>>   	},
>>
>> -	.vreg_list		= qmp_phy_vreg_l,
>> -	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
>> +	.vreg_list		= sm8750_ufsphy_vreg_l,
>> +	.num_vregs		= ARRAY_SIZE(sm8750_ufsphy_vreg_l),
>>   	.regs			= ufsphy_v6_regs_layout,
>>
>>   };
>> --
>> 2.48.1
>>
> 



From krzk at kernel.org  Wed Aug 20 00:58:46 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 20 Aug 2025 09:58:46 +0200
Subject: [PATCH v2 2/3] dt-bindings: phy: eswin: Document for EIC7700 SoC
 SATA PHY
In-Reply-To: <20250819135833.1227-1-luyulin@eswincomputing.com>
References: <20250819134722.220-1-luyulin@eswincomputig.com>
 <20250819135833.1227-1-luyulin@eswincomputing.com>
Message-ID: <20250820-cheerful-avocet-of-tempest-43244e@kuoka>

On Tue, Aug 19, 2025 at 09:58:33PM +0800, Yulin Lu wrote:
> From: luyulin <luyulin at eswincomputing.com>
> 
> Add document for the SATA phy on the EIC7700 SoC platform,
> describing its usage.
> 
> Signed-off-by: luyulin <luyulin at eswincomputing.com>

Don't use login as full name.

All other patches are missing, changelog missing, cover letter missing.

Best regards,
Krzysztof



From luyulin at eswincomputing.com  Wed Aug 20 02:27:58 2025
From: luyulin at eswincomputing.com (Yulin Lu)
Date: Wed, 20 Aug 2025 17:27:58 +0800
Subject: [PATCH v2 2/3] dt-bindings: phy: eswin: Document for EIC7700 SoC SATA PHY
In-Reply-To: <20250819134722.220-1-luyulin@eswincomputing.com>
References: <20250819134722.220-1-luyulin@eswincomputing.com>
Message-ID: <20250820092758.803-1-luyulin@eswincomputing.com>

Add document for the SATA phy on the EIC7700 SoC platform,
describing its usage.

Signed-off-by: Yulin Lu <luyulin at eswincomputing.com>
---
 .../bindings/phy/eswin,eic7700-sata-phy.yaml  | 36 +++++++++++++++++++
 1 file changed, 36 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/eswin,eic7700-sata-phy.yaml

diff --git a/Documentation/devicetree/bindings/phy/eswin,eic7700-sata-phy.yaml b/Documentation/devicetree/bindings/phy/eswin,eic7700-sata-phy.yaml
new file mode 100644
index 000000000000..d914cb4402d8
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/eswin,eic7700-sata-phy.yaml
@@ -0,0 +1,36 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/eswin,eic7700-sata-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Eswin EIC7700 SoC SATA PHY
+
+maintainers:
+  - Yulin Lu <luyulin at eswincomputing.com>
+  - Huan He <hehuan1 at eswincomputing.com>
+
+properties:
+  compatible:
+    const: eswin,eic7700-sata-phy
+
+  "#phy-cells":
+    const: 0
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - "#phy-cells"
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    sata-phy at 50440300 {
+        compatible = "eswin,eic7700-sata-phy";
+        reg = <0x50440300 0x40>;
+        #phy-cells = <0>;
+    };
-- 
2.25.1



From xiangxu.yin at oss.qualcomm.com  Wed Aug 20 02:34:42 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Wed, 20 Aug 2025 17:34:42 +0800
Subject: [PATCH v3 00/14] Add DisplayPort support for QCS615 platform
Message-ID: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>

This series aims to extend the USB-C PHY to support DP mode and enable
DisplayPort on the Qualcomm QCS615 platform.

The devicetree modification for DisplayPort on QCS615 will be provided
in a future patch.

Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
---
Changes in v3:

- Renamed qcom,qcs615-qmp-dp-phy.yaml in v2 to qcom,qcs615-qmp-dp-phy.yaml in v3 for QCS615 USB3+DP PHY.
- Updated patch [v3,02/14] to revise binding title, description, and property order. [Krzysztof]
- Updated commit messages in patch [v3,01/14] and [v3,13/14] to reflect the DTSI rename and clarify compatibility. [Krzysztof]
- Added USB3+DP mode implementation in patches [v3,003?012], organized in logical chunks. [Dmitry]
- Dropped patch [v2,03/13] to maintain full backward compatibility with USBC.
- Link to v2: https://lore.kernel.org/all/20250722-add-displayport-support-for-qcs615-platform-v2-0-42b4037171f8 at oss.qualcomm.com/

Changes in v2:

- Add new binding qcom,qcs615-qmp-dp-phy.yaml for QCS615 standalone DP
- Split DP PHY driver into patches 4-11 by logical chunks [Dmitry]
- Update DP PHY configuration flow to align with QMP Combo PHY implementation [Dmitry]
- Update all hex values to lowercase [Dmitry]
- Remove redundant comments in DP PHY driver [Krzysztof]
- Remove invalid USBC type define [Dmitry]
- Move lane_map, max_dp_lanes, max_dp_link_rate parsing logic to dp_link [Dmitry]
- Add TCSR-based mutex logic for DP and USB PHY coexistence [Dmitry]
- Drop patches 6?8 and remove related binding properties as rejected upstream
- Link to v1: https://lore.kernel.org/all/20241129-add-displayport-support-for-qcs615-platform-v1-0-09a4338d93ef at quicinc.com/

---
Xiangxu Yin (14):
      dt-bindings: display/msm: dp-controller: Add sm6150
      dt-bindings: phy: Add QMP USB3+DP PHY for QCS615
      phy: qcom: qmp-usbc: Rename USB-specific ops to prepare for DP support
      phy: qcom: qmp-usbc: Add USBC PHY type enum
      phy: qcom: qmp-usbc: Add DP-related fields for USB/DP switchable PHY
      phy: qcom: qmp-usbc: Add QCS615 DP PHY configuration and init data
      phy: qcom: qmp-usbc: Move reset and regulator config into PHY cfg
      phy: qcom: qmp-usbc: Add DP PHY configuration support for QCS615
      phy: qcom: qmp-usbc: Add DP PHY ops for USB/DP switchable Type-C PHYs
      phy: qcom: qmp-usbc: Add TCSR parsing and USB/DP mode mutex handling
      phy: qcom: qmp-usbc: Finalize USB/DP switchable PHY support
      phy: qcom: qmp-usbc: Add QCS615 DP PHY compatible
      drm/msm/dp: Add DisplayPort support for sm6150
      drm/msm/dp: Add support for lane mapping configuration

 .../bindings/display/msm/dp-controller.yaml        |    1 +
 .../bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml   |  108 ++
 drivers/gpu/drm/msm/dp/dp_ctrl.c                   |   10 +-
 drivers/gpu/drm/msm/dp/dp_display.c                |    1 +
 drivers/gpu/drm/msm/dp/dp_link.c                   |   71 ++
 drivers/gpu/drm/msm/dp/dp_link.h                   |    5 +
 drivers/gpu/drm/msm/dp/dp_panel.c                  |   78 +-
 drivers/gpu/drm/msm/dp/dp_panel.h                  |    3 -
 drivers/phy/qualcomm/phy-qcom-qmp-dp-phy.h         |    1 +
 drivers/phy/qualcomm/phy-qcom-qmp-usbc.c           | 1165 +++++++++++++++++---
 10 files changed, 1234 insertions(+), 209 deletions(-)
---
base-commit: 958469723b0df2a5efa229f9c4464c8962c35baf
change-id: 20250820-add-displayport-support-for-qcs615-platform-895e4ae0e310

Best regards,
-- 
Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>



From xiangxu.yin at oss.qualcomm.com  Wed Aug 20 02:34:43 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Wed, 20 Aug 2025 17:34:43 +0800
Subject: [PATCH v3 01/14] dt-bindings: display/msm: dp-controller: Add
 sm6150
In-Reply-To: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
Message-ID: <20250820-add-displayport-support-for-qcs615-platform-v3-1-a43bd25ec39c@oss.qualcomm.com>

Add DisplayPort controller for Qualcomm SM6150 SoC.
While SM6150 currently shares the same configuration as SC7180,
its hardware capabilities differ. Explicitly listing it ensures clarity
and avoids potential issues if SC7180 support evolves in the future.

Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.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 9923b065323bbab99de5079b674a0317f3074373..996d0132e084d401db85014a1a4e445d00d62ed8 100644
--- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
@@ -27,6 +27,7 @@ properties:
           - qcom,sc8280xp-dp
           - qcom,sc8280xp-edp
           - qcom,sdm845-dp
+          - qcom,sm6150-dp
           - qcom,sm8350-dp
           - qcom,sm8650-dp
       - items:

-- 
2.34.1



From xiangxu.yin at oss.qualcomm.com  Wed Aug 20 02:34:44 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Wed, 20 Aug 2025 17:34:44 +0800
Subject: [PATCH v3 02/14] dt-bindings: phy: Add QMP USB3+DP PHY for QCS615
In-Reply-To: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
Message-ID: <20250820-add-displayport-support-for-qcs615-platform-v3-2-a43bd25ec39c@oss.qualcomm.com>

Add device tree binding documentation for the Qualcomm QMP USB3+DP PHY
on QCS615 Platform. This PHY supports both USB3 and DP functionality
over USB-C, with PHY mode switching capability. It does not support
combo mode.

Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
---
 .../bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml   | 108 +++++++++++++++++++++
 1 file changed, 108 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..c2b1fbab2930f0653f4ddb95f7b54d8fe994f92d
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml
@@ -0,0 +1,108 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/qcom,qcs615-qmp-usb3dp-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm QMP USB3-DP PHY controller (DP, QCS615)
+
+maintainers:
+  - Vinod Koul <vkoul at kernel.org>
+
+description:
+  The QMP PHY controller supports physical layer functionality for both
+  USB3 and DisplayPort over USB-C. While it enables mode switching
+  between USB3 and DisplayPort, but does not support combo mode.
+
+properties:
+  compatible:
+    enum:
+      - qcom,qcs615-qmp-usb3-dp-phy
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: cfg_ahb
+      - const: ref
+
+  resets:
+    maxItems: 2
+
+  reset-names:
+    items:
+      - const: phy_phy
+      - const: dp_phy
+
+  vdda-phy-supply: true
+
+  vdda-pll-supply: true
+
+  "#clock-cells":
+    const: 1
+    description:
+      See include/dt-bindings/phy/phy-qcom-qmp.h
+
+  "#phy-cells":
+    const: 1
+    description:
+      See include/dt-bindings/phy/phy-qcom-qmp.h
+
+  qcom,tcsr-reg:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    items:
+      - items:
+          - description: phandle to TCSR hardware block
+          - description: offset of the VLS CLAMP register
+      - items:
+          - description: phandle to TCSR hardware block
+          - description: offset of the DP PHY mode register
+    description: Clamp and PHY mode register present in the TCSR
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+  - vdda-phy-supply
+  - vdda-pll-supply
+  - "#clock-cells"
+  - "#phy-cells"
+  - qcom,tcsr-reg
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,qcs615-gcc.h>
+    #include <dt-bindings/clock/qcom,rpmh.h>
+
+    phy at 88e8000 {
+      compatible = "qcom,qcs615-qmp-usb3-dp-phy";
+      reg = <0x88e8000 0x2000>;
+
+      clocks = <&gcc GCC_AHB2PHY_WEST_CLK>,
+               <&gcc GCC_USB3_SEC_CLKREF_CLK>;
+      clock-names = "cfg_ahb",
+                    "ref";
+
+      resets = <&gcc GCC_USB3PHY_PHY_SEC_BCR >,
+               <&gcc GCC_USB3_DP_PHY_SEC_BCR>;
+      reset-names = "phy_phy",
+                    "dp_phy";
+
+      vdda-phy-supply = <&vreg_l11a>;
+      vdda-pll-supply = <&vreg_l5a>;
+
+      #clock-cells = <1>;
+      #phy-cells = <1>;
+
+      qcom,tcsr-reg = <&tcsr 0xbff0>,
+                      <&tcsr 0xb24c>;
+    };

-- 
2.34.1



From xiangxu.yin at oss.qualcomm.com  Wed Aug 20 02:34:45 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Wed, 20 Aug 2025 17:34:45 +0800
Subject: [PATCH v3 03/14] phy: qcom: qmp-usbc: Rename USB-specific ops to
 prepare for DP support
In-Reply-To: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
Message-ID: <20250820-add-displayport-support-for-qcs615-platform-v3-3-a43bd25ec39c@oss.qualcomm.com>

To support following DisplayPort (DP) mode over the Type-C PHY, rename
USB-specific functions and ops to clearly separate them from common or
DP-related logic.

This is a preparatory cleanup to enable USB + DP dual mode.

Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 50 ++++++++++++++++----------------
 1 file changed, 25 insertions(+), 25 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
index 5e7fcb26744a4401c3076960df9c0dcbec7fdef7..e484caec2be20121cfe287c507b17af28fb9f211 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
@@ -454,7 +454,7 @@ static const struct qmp_phy_cfg sdm660_usb3phy_cfg = {
 	.regs			= qmp_v3_usb3phy_regs_layout_qcm2290,
 };
 
-static int qmp_usbc_init(struct phy *phy)
+static int qmp_usbc_com_init(struct phy *phy)
 {
 	struct qmp_usbc *qmp = phy_get_drvdata(phy);
 	const struct qmp_phy_cfg *cfg = qmp->cfg;
@@ -504,7 +504,7 @@ static int qmp_usbc_init(struct phy *phy)
 	return ret;
 }
 
-static int qmp_usbc_exit(struct phy *phy)
+static int qmp_usbc_com_exit(struct phy *phy)
 {
 	struct qmp_usbc *qmp = phy_get_drvdata(phy);
 	const struct qmp_phy_cfg *cfg = qmp->cfg;
@@ -518,7 +518,7 @@ static int qmp_usbc_exit(struct phy *phy)
 	return 0;
 }
 
-static int qmp_usbc_power_on(struct phy *phy)
+static int qmp_usbc_usb_power_on(struct phy *phy)
 {
 	struct qmp_usbc *qmp = phy_get_drvdata(phy);
 	const struct qmp_phy_cfg *cfg = qmp->cfg;
@@ -566,7 +566,7 @@ static int qmp_usbc_power_on(struct phy *phy)
 	return ret;
 }
 
-static int qmp_usbc_power_off(struct phy *phy)
+static int qmp_usbc_usb_power_off(struct phy *phy)
 {
 	struct qmp_usbc *qmp = phy_get_drvdata(phy);
 	const struct qmp_phy_cfg *cfg = qmp->cfg;
@@ -587,20 +587,20 @@ static int qmp_usbc_power_off(struct phy *phy)
 	return 0;
 }
 
-static int qmp_usbc_enable(struct phy *phy)
+static int qmp_usbc_usb_enable(struct phy *phy)
 {
 	struct qmp_usbc *qmp = phy_get_drvdata(phy);
 	int ret;
 
 	mutex_lock(&qmp->phy_mutex);
 
-	ret = qmp_usbc_init(phy);
+	ret = qmp_usbc_com_init(phy);
 	if (ret)
 		goto out_unlock;
 
-	ret = qmp_usbc_power_on(phy);
+	ret = qmp_usbc_usb_power_on(phy);
 	if (ret) {
-		qmp_usbc_exit(phy);
+		qmp_usbc_com_exit(phy);
 		goto out_unlock;
 	}
 
@@ -611,19 +611,19 @@ static int qmp_usbc_enable(struct phy *phy)
 	return ret;
 }
 
-static int qmp_usbc_disable(struct phy *phy)
+static int qmp_usbc_usb_disable(struct phy *phy)
 {
 	struct qmp_usbc *qmp = phy_get_drvdata(phy);
 	int ret;
 
 	qmp->usb_init_count--;
-	ret = qmp_usbc_power_off(phy);
+	ret = qmp_usbc_usb_power_off(phy);
 	if (ret)
 		return ret;
-	return qmp_usbc_exit(phy);
+	return qmp_usbc_com_exit(phy);
 }
 
-static int qmp_usbc_set_mode(struct phy *phy, enum phy_mode mode, int submode)
+static int qmp_usbc_usb_set_mode(struct phy *phy, enum phy_mode mode, int submode)
 {
 	struct qmp_usbc *qmp = phy_get_drvdata(phy);
 
@@ -632,10 +632,10 @@ static int qmp_usbc_set_mode(struct phy *phy, enum phy_mode mode, int submode)
 	return 0;
 }
 
-static const struct phy_ops qmp_usbc_phy_ops = {
-	.init		= qmp_usbc_enable,
-	.exit		= qmp_usbc_disable,
-	.set_mode	= qmp_usbc_set_mode,
+static const struct phy_ops qmp_usbc_usb_phy_ops = {
+	.init		= qmp_usbc_usb_enable,
+	.exit		= qmp_usbc_usb_disable,
+	.set_mode	= qmp_usbc_usb_set_mode,
 	.owner		= THIS_MODULE,
 };
 
@@ -865,11 +865,11 @@ static int qmp_usbc_typec_switch_set(struct typec_switch_dev *sw,
 	qmp->orientation = orientation;
 
 	if (qmp->usb_init_count) {
-		qmp_usbc_power_off(qmp->phy);
-		qmp_usbc_exit(qmp->phy);
+		qmp_usbc_usb_power_off(qmp->phy);
+		qmp_usbc_com_exit(qmp->phy);
 
-		qmp_usbc_init(qmp->phy);
-		qmp_usbc_power_on(qmp->phy);
+		qmp_usbc_com_init(qmp->phy);
+		qmp_usbc_usb_power_on(qmp->phy);
 	}
 
 	mutex_unlock(&qmp->phy_mutex);
@@ -907,7 +907,7 @@ static int qmp_usbc_typec_switch_register(struct qmp_usbc *qmp)
 }
 #endif
 
-static int qmp_usbc_parse_dt_legacy(struct qmp_usbc *qmp, struct device_node *np)
+static int qmp_usbc_parse_usb_dt_legacy(struct qmp_usbc *qmp, struct device_node *np)
 {
 	struct platform_device *pdev = to_platform_device(qmp->dev);
 	struct device *dev = qmp->dev;
@@ -969,7 +969,7 @@ static int qmp_usbc_parse_dt_legacy(struct qmp_usbc *qmp, struct device_node *np
 	return 0;
 }
 
-static int qmp_usbc_parse_dt(struct qmp_usbc *qmp)
+static int qmp_usbc_parse_usb_dt(struct qmp_usbc *qmp)
 {
 	struct platform_device *pdev = to_platform_device(qmp->dev);
 	const struct qmp_phy_cfg *cfg = qmp->cfg;
@@ -1075,10 +1075,10 @@ static int qmp_usbc_probe(struct platform_device *pdev)
 	/* Check for legacy binding with child node. */
 	np = of_get_child_by_name(dev->of_node, "phy");
 	if (np) {
-		ret = qmp_usbc_parse_dt_legacy(qmp, np);
+		ret = qmp_usbc_parse_usb_dt_legacy(qmp, np);
 	} else {
 		np = of_node_get(dev->of_node);
-		ret = qmp_usbc_parse_dt(qmp);
+		ret = qmp_usbc_parse_usb_dt(qmp);
 	}
 	if (ret)
 		goto err_node_put;
@@ -1097,7 +1097,7 @@ static int qmp_usbc_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_node_put;
 
-	qmp->phy = devm_phy_create(dev, np, &qmp_usbc_phy_ops);
+	qmp->phy = devm_phy_create(dev, np, &qmp_usbc_usb_phy_ops);
 	if (IS_ERR(qmp->phy)) {
 		ret = PTR_ERR(qmp->phy);
 		dev_err(dev, "failed to create PHY: %d\n", ret);

-- 
2.34.1



From xiangxu.yin at oss.qualcomm.com  Wed Aug 20 02:34:46 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Wed, 20 Aug 2025 17:34:46 +0800
Subject: [PATCH v3 04/14] phy: qcom: qmp-usbc: Add USBC PHY type enum
In-Reply-To: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
Message-ID: <20250820-add-displayport-support-for-qcs615-platform-v3-4-a43bd25ec39c@oss.qualcomm.com>

Introduce qmp_phy_usbc_type enum and a 'type' field in qmp_phy_cfg to
differentiate between USB-only PHYs and USB/DP switchable PHYs.

Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
index e484caec2be20121cfe287c507b17af28fb9f211..5afe090b546977a11265bbffa7c355feb8c72dfa 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
@@ -284,6 +284,11 @@ static const struct qmp_phy_init_tbl qcm2290_usb3_pcs_tbl[] = {
 	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x88),
 };
 
+enum qmp_phy_usbc_type {
+	QMP_PHY_USBC_USB3_ONLY,
+	QMP_PHY_USBC_USB3_DP,
+};
+
 struct qmp_usbc_offsets {
 	u16 serdes;
 	u16 pcs;
@@ -298,6 +303,7 @@ struct qmp_usbc_offsets {
 /* struct qmp_phy_cfg - per-PHY initialization config */
 struct qmp_phy_cfg {
 	const struct qmp_usbc_offsets *offsets;
+	const enum qmp_phy_usbc_type type;
 
 	/* Init sequence for PHY blocks - serdes, tx, rx, pcs */
 	const struct qmp_phy_init_tbl *serdes_tbl;
@@ -408,6 +414,7 @@ static const struct qmp_usbc_offsets qmp_usbc_offsets_v3_qcm2290 = {
 
 static const struct qmp_phy_cfg msm8998_usb3phy_cfg = {
 	.offsets		= &qmp_usbc_offsets_v3_qcm2290,
+	.type			= QMP_PHY_USBC_USB3_ONLY,
 
 	.serdes_tbl             = msm8998_usb3_serdes_tbl,
 	.serdes_tbl_num         = ARRAY_SIZE(msm8998_usb3_serdes_tbl),
@@ -424,6 +431,7 @@ static const struct qmp_phy_cfg msm8998_usb3phy_cfg = {
 
 static const struct qmp_phy_cfg qcm2290_usb3phy_cfg = {
 	.offsets		= &qmp_usbc_offsets_v3_qcm2290,
+	.type			= QMP_PHY_USBC_USB3_ONLY,
 
 	.serdes_tbl		= qcm2290_usb3_serdes_tbl,
 	.serdes_tbl_num		= ARRAY_SIZE(qcm2290_usb3_serdes_tbl),
@@ -440,6 +448,7 @@ static const struct qmp_phy_cfg qcm2290_usb3phy_cfg = {
 
 static const struct qmp_phy_cfg sdm660_usb3phy_cfg = {
 	.offsets		= &qmp_usbc_offsets_v3_qcm2290,
+	.type			= QMP_PHY_USBC_USB3_ONLY,
 
 	.serdes_tbl		= qcm2290_usb3_serdes_tbl,
 	.serdes_tbl_num		= ARRAY_SIZE(qcm2290_usb3_serdes_tbl),

-- 
2.34.1



From xiangxu.yin at oss.qualcomm.com  Wed Aug 20 02:34:48 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Wed, 20 Aug 2025 17:34:48 +0800
Subject: [PATCH v3 06/14] phy: qcom: qmp-usbc: Add QCS615 DP PHY
 configuration and init data
In-Reply-To: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
Message-ID: <20250820-add-displayport-support-for-qcs615-platform-v3-6-a43bd25ec39c@oss.qualcomm.com>

Introduce QCS615 hardware-specific configuration for DP PHY mode,
including register offsets, initialization tables, voltage swing
and pre-emphasis settings.

Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 139 +++++++++++++++++++++++++++++++
 1 file changed, 139 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
index 6b0e86ec43ded3d850f68f248a74c39f74ecb5bb..61128d606238321d1b573655b3b987226aa2d594 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
@@ -284,6 +284,86 @@ static const struct qmp_phy_init_tbl qcm2290_usb3_pcs_tbl[] = {
 	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x88),
 };
 
+static const struct qmp_phy_init_tbl qcs615_qmp_dp_serdes_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x37),
+	QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06),
+	QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x3f),
+	QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x0e),
+	QMP_PHY_INIT_CFG(QSERDES_COM_BG_CTRL, 0x0f),
+	QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_BUF_ENABLE, 0x06),
+	QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
+	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
+	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
+	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
+	QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
+	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x40),
+	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x08),
+	QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x05),
+	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x0f),
+	QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x02),
+};
+
+static const struct qmp_phy_init_tbl qcs615_qmp_dp_serdes_tbl_rbr[] = {
+	QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x2c),
+	QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x69),
+	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x80),
+	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x07),
+	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xbf),
+	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x21),
+	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0xc6),
+};
+
+static const struct qmp_phy_init_tbl qcs615_qmp_dp_serdes_tbl_hbr[] = {
+	QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x24),
+	QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x69),
+	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x80),
+	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x07),
+	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x3f),
+	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x38),
+	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0xc4),
+};
+
+static const struct qmp_phy_init_tbl qcs615_qmp_dp_serdes_tbl_hbr2[] = {
+	QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x20),
+	QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x8c),
+	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x0a),
+	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x7f),
+	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x70),
+	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0xc4),
+};
+
+static const struct qmp_phy_init_tbl qcs615_qmp_dp_tx_tbl[] = {
+	QMP_PHY_INIT_CFG(QSERDES_V3_TX_TRANSCEIVER_BIAS_EN, 0x1a),
+	QMP_PHY_INIT_CFG(QSERDES_V3_TX_VMODE_CTRL1, 0x40),
+	QMP_PHY_INIT_CFG(QSERDES_V3_TX_PRE_STALL_LDO_BOOST_EN, 0x30),
+	QMP_PHY_INIT_CFG(QSERDES_V3_TX_INTERFACE_SELECT, 0x3d),
+	QMP_PHY_INIT_CFG(QSERDES_V3_TX_CLKBUF_ENABLE, 0x0f),
+	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RESET_TSYNC_EN, 0x03),
+	QMP_PHY_INIT_CFG(QSERDES_V3_TX_TRAN_DRVR_EMP_EN, 0x03),
+	QMP_PHY_INIT_CFG(QSERDES_V3_TX_PARRATE_REC_DETECT_IDLE_EN, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_INTERFACE_MODE, 0x00),
+	QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_EMP_POST1_LVL, 0x2b),
+	QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_DRV_LVL, 0x2f),
+	QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_BAND, 0x4),
+	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x12),
+	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x12),
+};
+
 enum qmp_phy_usbc_type {
 	QMP_PHY_USBC_USB3_ONLY,
 	QMP_PHY_USBC_USB3_DP,
@@ -449,6 +529,34 @@ static const struct qmp_usbc_offsets qmp_usbc_offsets_v3_qcm2290 = {
 	.rx2		= 0x800,
 };
 
+static const struct qmp_usbc_offsets qmp_usbc_usb3dp_offsets_qcs615 = {
+	.serdes		= 0x0,
+	.pcs		= 0xc00,
+	.pcs_misc	= 0xa00,
+	.tx		= 0x200,
+	.rx		= 0x400,
+	.tx2		= 0x600,
+	.rx2		= 0x800,
+	.dp_serdes	= 0x1c00,
+	.dp_txa		= 0x1400,
+	.dp_txb		= 0x1800,
+	.dp_dp_phy	= 0x1000,
+};
+
+static const u8 qmp_dp_pre_emphasis_hbr2_rbr[4][4] = {
+	{0x00, 0x0b, 0x12, 0xff},
+	{0x00, 0x0a, 0x12, 0xff},
+	{0x00, 0x0c, 0xff, 0xff},
+	{0xff, 0xff, 0xff, 0xff}
+};
+
+static const u8 qmp_dp_voltage_swing_hbr2_rbr[4][4] = {
+	{0x07, 0x0f, 0x14, 0xff},
+	{0x11, 0x1d, 0x1f, 0xff},
+	{0x18, 0x1f, 0xff, 0xff},
+	{0xff, 0xff, 0xff, 0xff}
+};
+
 static const struct qmp_phy_cfg msm8998_usb3phy_cfg = {
 	.offsets		= &qmp_usbc_offsets_v3_qcm2290,
 	.type			= QMP_PHY_USBC_USB3_ONLY,
@@ -500,6 +608,37 @@ static const struct qmp_phy_cfg sdm660_usb3phy_cfg = {
 	.regs			= qmp_v3_usb3phy_regs_layout_qcm2290,
 };
 
+static const struct qmp_phy_cfg qcs615_usb3dp_phy_cfg = {
+	.offsets		= &qmp_usbc_usb3dp_offsets_qcs615,
+	.type			= QMP_PHY_USBC_USB3_DP,
+
+	.serdes_tbl		= qcm2290_usb3_serdes_tbl,
+	.serdes_tbl_num		= ARRAY_SIZE(qcm2290_usb3_serdes_tbl),
+	.tx_tbl			= qcm2290_usb3_tx_tbl,
+	.tx_tbl_num		= ARRAY_SIZE(qcm2290_usb3_tx_tbl),
+	.rx_tbl			= qcm2290_usb3_rx_tbl,
+	.rx_tbl_num		= ARRAY_SIZE(qcm2290_usb3_rx_tbl),
+	.pcs_tbl		= qcm2290_usb3_pcs_tbl,
+	.pcs_tbl_num		= ARRAY_SIZE(qcm2290_usb3_pcs_tbl),
+
+	.regs			= qmp_v3_usb3phy_regs_layout_qcm2290,
+
+	.dp_serdes_tbl		= qcs615_qmp_dp_serdes_tbl,
+	.dp_serdes_tbl_num	= ARRAY_SIZE(qcs615_qmp_dp_serdes_tbl),
+	.dp_tx_tbl		= qcs615_qmp_dp_tx_tbl,
+	.dp_tx_tbl_num		= ARRAY_SIZE(qcs615_qmp_dp_tx_tbl),
+
+	.serdes_tbl_rbr		= qcs615_qmp_dp_serdes_tbl_rbr,
+	.serdes_tbl_rbr_num	= ARRAY_SIZE(qcs615_qmp_dp_serdes_tbl_rbr),
+	.serdes_tbl_hbr		= qcs615_qmp_dp_serdes_tbl_hbr,
+	.serdes_tbl_hbr_num	= ARRAY_SIZE(qcs615_qmp_dp_serdes_tbl_hbr),
+	.serdes_tbl_hbr2	= qcs615_qmp_dp_serdes_tbl_hbr2,
+	.serdes_tbl_hbr2_num	= ARRAY_SIZE(qcs615_qmp_dp_serdes_tbl_hbr2),
+
+	.swing_tbl		= &qmp_dp_voltage_swing_hbr2_rbr,
+	.pre_emphasis_tbl	= &qmp_dp_pre_emphasis_hbr2_rbr,
+};
+
 static int qmp_usbc_com_init(struct phy *phy)
 {
 	struct qmp_usbc *qmp = phy_get_drvdata(phy);

-- 
2.34.1



From xiangxu.yin at oss.qualcomm.com  Wed Aug 20 02:34:47 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Wed, 20 Aug 2025 17:34:47 +0800
Subject: [PATCH v3 05/14] phy: qcom: qmp-usbc: Add DP-related fields for
 USB/DP switchable PHY
In-Reply-To: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
Message-ID: <20250820-add-displayport-support-for-qcs615-platform-v3-5-a43bd25ec39c@oss.qualcomm.com>

Extend qmp_usbc_offsets and qmp_phy_cfg with DP-specific fields,
including register offsets, init tables, and callback hooks. Also
update qmp_usbc struct to track DP-related resources and state.
This enables support for USB/DP switchable Type-C PHYs that operate
in either mode.

Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 73 ++++++++++++++++++++++++--------
 1 file changed, 55 insertions(+), 18 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
index 5afe090b546977a11265bbffa7c355feb8c72dfa..6b0e86ec43ded3d850f68f248a74c39f74ecb5bb 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
@@ -298,14 +298,19 @@ struct qmp_usbc_offsets {
 	/* for PHYs with >= 2 lanes */
 	u16 tx2;
 	u16 rx2;
+
+	u16 dp_serdes;
+	u16 dp_txa;
+	u16 dp_txb;
+	u16 dp_dp_phy;
 };
 
-/* struct qmp_phy_cfg - per-PHY initialization config */
+struct qmp_usbc;
 struct qmp_phy_cfg {
 	const struct qmp_usbc_offsets *offsets;
 	const enum qmp_phy_usbc_type type;
 
-	/* Init sequence for PHY blocks - serdes, tx, rx, pcs */
+	/* Init sequence for USB PHY blocks - serdes, tx, rx, pcs */
 	const struct qmp_phy_init_tbl *serdes_tbl;
 	int serdes_tbl_num;
 	const struct qmp_phy_init_tbl *tx_tbl;
@@ -315,6 +320,27 @@ struct qmp_phy_cfg {
 	const struct qmp_phy_init_tbl *pcs_tbl;
 	int pcs_tbl_num;
 
+	/* Init sequence for DP PHY blocks - serdes, tx, rbr, hbr, hbr2 */
+	const struct qmp_phy_init_tbl *dp_serdes_tbl;
+	int dp_serdes_tbl_num;
+	const struct qmp_phy_init_tbl *dp_tx_tbl;
+	int dp_tx_tbl_num;
+	const struct qmp_phy_init_tbl *serdes_tbl_rbr;
+	int serdes_tbl_rbr_num;
+	const struct qmp_phy_init_tbl *serdes_tbl_hbr;
+	int serdes_tbl_hbr_num;
+	const struct qmp_phy_init_tbl *serdes_tbl_hbr2;
+	int serdes_tbl_hbr2_num;
+
+	const u8 (*swing_tbl)[4][4];
+	const u8 (*pre_emphasis_tbl)[4][4];
+
+	/* DP PHY callbacks */
+	void (*dp_aux_init)(struct qmp_usbc *qmp);
+	void (*configure_dp_tx)(struct qmp_usbc *qmp);
+	int (*configure_dp_phy)(struct qmp_usbc *qmp);
+	int (*calibrate_dp_phy)(struct qmp_usbc *qmp);
+
 	/* regulators to be requested */
 	const char * const *vreg_list;
 	int num_vregs;
@@ -335,25 +361,36 @@ struct qmp_usbc {
 	void __iomem *rx;
 	void __iomem *tx2;
 	void __iomem *rx2;
-
-	struct regmap *tcsr_map;
-	u32 vls_clamp_reg;
+	void __iomem *dp_dp_phy;
+	void __iomem *dp_tx;
+	void __iomem *dp_tx2;
+	void __iomem *dp_serdes;
 
 	struct clk *pipe_clk;
+	struct clk_fixed_rate pipe_clk_fixed;
+
+	struct clk_hw dp_link_hw;
+	struct clk_hw dp_pixel_hw;
 	struct clk_bulk_data *clks;
 	int num_clks;
 	int num_resets;
 	struct reset_control_bulk_data *resets;
 	struct regulator_bulk_data *vregs;
 
+	struct regmap *tcsr_map;
+	u32 vls_clamp_reg;
+	u32 dp_phy_mode_reg;
+
 	struct mutex phy_mutex;
 
+	struct phy *usb_phy;
 	enum phy_mode mode;
 	unsigned int usb_init_count;
 
-	struct phy *phy;
-
-	struct clk_fixed_rate pipe_clk_fixed;
+	struct phy *dp_phy;
+	unsigned int dp_aux_cfg;
+	struct phy_configure_opts_dp dp_opts;
+	unsigned int dp_init_count;
 
 	struct typec_switch_dev *sw;
 	enum typec_orientation orientation;
@@ -699,7 +736,7 @@ static int __maybe_unused qmp_usbc_runtime_suspend(struct device *dev)
 
 	dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->mode);
 
-	if (!qmp->phy->init_count) {
+	if (!qmp->usb_init_count && !qmp->dp_init_count) {
 		dev_vdbg(dev, "PHY not initialized, bailing out\n");
 		return 0;
 	}
@@ -719,7 +756,7 @@ static int __maybe_unused qmp_usbc_runtime_resume(struct device *dev)
 
 	dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qmp->mode);
 
-	if (!qmp->phy->init_count) {
+	if (!qmp->usb_init_count && !qmp->dp_init_count) {
 		dev_vdbg(dev, "PHY not initialized, bailing out\n");
 		return 0;
 	}
@@ -874,11 +911,11 @@ static int qmp_usbc_typec_switch_set(struct typec_switch_dev *sw,
 	qmp->orientation = orientation;
 
 	if (qmp->usb_init_count) {
-		qmp_usbc_usb_power_off(qmp->phy);
-		qmp_usbc_com_exit(qmp->phy);
+		qmp_usbc_usb_power_off(qmp->usb_phy);
+		qmp_usbc_com_exit(qmp->usb_phy);
 
-		qmp_usbc_com_init(qmp->phy);
-		qmp_usbc_usb_power_on(qmp->phy);
+		qmp_usbc_com_init(qmp->usb_phy);
+		qmp_usbc_usb_power_on(qmp->usb_phy);
 	}
 
 	mutex_unlock(&qmp->phy_mutex);
@@ -1106,14 +1143,14 @@ static int qmp_usbc_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_node_put;
 
-	qmp->phy = devm_phy_create(dev, np, &qmp_usbc_usb_phy_ops);
-	if (IS_ERR(qmp->phy)) {
-		ret = PTR_ERR(qmp->phy);
+	qmp->usb_phy = devm_phy_create(dev, np, &qmp_usbc_usb_phy_ops);
+	if (IS_ERR(qmp->usb_phy)) {
+		ret = PTR_ERR(qmp->usb_phy);
 		dev_err(dev, "failed to create PHY: %d\n", ret);
 		goto err_node_put;
 	}
 
-	phy_set_drvdata(qmp->phy, qmp);
+	phy_set_drvdata(qmp->usb_phy, qmp);
 
 	of_node_put(np);
 

-- 
2.34.1



From xiangxu.yin at oss.qualcomm.com  Wed Aug 20 02:34:49 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Wed, 20 Aug 2025 17:34:49 +0800
Subject: [PATCH v3 07/14] phy: qcom: qmp-usbc: Move reset and regulator
 config into PHY cfg
In-Reply-To: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
Message-ID: <20250820-add-displayport-support-for-qcs615-platform-v3-7-a43bd25ec39c@oss.qualcomm.com>

Refactor reset and regulator configuration to be managed via qmp_phy_cfg
instead of hardcoded lists. This enables per-PHY customization and
simplifies initialization logic for USB-only and USB/DP switchable PHYs.

Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 108 +++++++++++++++----------------
 1 file changed, 53 insertions(+), 55 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
index 61128d606238321d1b573655b3b987226aa2d594..4e797b7e65da0e3a827efa9a179f1c150c1b8b00 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
@@ -421,8 +421,9 @@ struct qmp_phy_cfg {
 	int (*configure_dp_phy)(struct qmp_usbc *qmp);
 	int (*calibrate_dp_phy)(struct qmp_usbc *qmp);
 
-	/* regulators to be requested */
-	const char * const *vreg_list;
+	const char * const *reset_list;
+	int num_resets;
+	const struct regulator_bulk_data *vreg_list;
 	int num_vregs;
 
 	/* array of registers with different offsets */
@@ -453,7 +454,6 @@ struct qmp_usbc {
 	struct clk_hw dp_pixel_hw;
 	struct clk_bulk_data *clks;
 	int num_clks;
-	int num_resets;
 	struct reset_control_bulk_data *resets;
 	struct regulator_bulk_data *vregs;
 
@@ -514,9 +514,18 @@ static const char * const usb3phy_reset_l[] = {
 	"phy_phy", "phy",
 };
 
-/* list of regulators */
-static const char * const qmp_phy_vreg_l[] = {
-	"vdda-phy", "vdda-pll",
+static const char * const usb3dpphy_reset_l[] = {
+	"phy_phy", "dp_phy",
+};
+
+static const struct regulator_bulk_data qmp_phy_usb_vreg_l[] = {
+	{ .supply = "vdda-phy" },
+	{ .supply = "vdda-pll" },
+};
+
+static const struct regulator_bulk_data qmp_phy_usbdp_vreg_l[] = {
+	{ .supply = "vdda-phy", .init_load_uA = 21800 },
+	{ .supply = "vdda-phy", .init_load_uA = 36000 },
 };
 
 static const struct qmp_usbc_offsets qmp_usbc_offsets_v3_qcm2290 = {
@@ -569,8 +578,10 @@ static const struct qmp_phy_cfg msm8998_usb3phy_cfg = {
 	.rx_tbl_num             = ARRAY_SIZE(msm8998_usb3_rx_tbl),
 	.pcs_tbl                = msm8998_usb3_pcs_tbl,
 	.pcs_tbl_num            = ARRAY_SIZE(msm8998_usb3_pcs_tbl),
-	.vreg_list              = qmp_phy_vreg_l,
-	.num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
+	.reset_list		= usb3phy_reset_l,
+	.num_resets		= ARRAY_SIZE(usb3phy_reset_l),
+	.vreg_list              = qmp_phy_usb_vreg_l,
+	.num_vregs              = ARRAY_SIZE(qmp_phy_usb_vreg_l),
 	.regs                   = qmp_v3_usb3phy_regs_layout,
 };
 
@@ -586,8 +597,10 @@ static const struct qmp_phy_cfg qcm2290_usb3phy_cfg = {
 	.rx_tbl_num		= ARRAY_SIZE(qcm2290_usb3_rx_tbl),
 	.pcs_tbl		= qcm2290_usb3_pcs_tbl,
 	.pcs_tbl_num		= ARRAY_SIZE(qcm2290_usb3_pcs_tbl),
-	.vreg_list		= qmp_phy_vreg_l,
-	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
+	.reset_list		= usb3phy_reset_l,
+	.num_resets		= ARRAY_SIZE(usb3phy_reset_l),
+	.vreg_list		= qmp_phy_usb_vreg_l,
+	.num_vregs		= ARRAY_SIZE(qmp_phy_usb_vreg_l),
 	.regs			= qmp_v3_usb3phy_regs_layout_qcm2290,
 };
 
@@ -603,8 +616,10 @@ static const struct qmp_phy_cfg sdm660_usb3phy_cfg = {
 	.rx_tbl_num		= ARRAY_SIZE(sdm660_usb3_rx_tbl),
 	.pcs_tbl		= qcm2290_usb3_pcs_tbl,
 	.pcs_tbl_num		= ARRAY_SIZE(qcm2290_usb3_pcs_tbl),
-	.vreg_list		= qmp_phy_vreg_l,
-	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
+	.reset_list		= usb3phy_reset_l,
+	.num_resets		= ARRAY_SIZE(usb3phy_reset_l),
+	.vreg_list		= qmp_phy_usb_vreg_l,
+	.num_vregs		= ARRAY_SIZE(qmp_phy_usb_vreg_l),
 	.regs			= qmp_v3_usb3phy_regs_layout_qcm2290,
 };
 
@@ -637,6 +652,11 @@ static const struct qmp_phy_cfg qcs615_usb3dp_phy_cfg = {
 
 	.swing_tbl		= &qmp_dp_voltage_swing_hbr2_rbr,
 	.pre_emphasis_tbl	= &qmp_dp_pre_emphasis_hbr2_rbr,
+
+	.reset_list		= usb3dpphy_reset_l,
+	.num_resets		= ARRAY_SIZE(usb3dpphy_reset_l),
+	.vreg_list		= qmp_phy_usbdp_vreg_l,
+	.num_vregs		= ARRAY_SIZE(qmp_phy_usbdp_vreg_l),
 };
 
 static int qmp_usbc_com_init(struct phy *phy)
@@ -653,13 +673,13 @@ static int qmp_usbc_com_init(struct phy *phy)
 		return ret;
 	}
 
-	ret = reset_control_bulk_assert(qmp->num_resets, qmp->resets);
+	ret = reset_control_bulk_assert(cfg->num_resets, qmp->resets);
 	if (ret) {
 		dev_err(qmp->dev, "reset assert failed\n");
 		goto err_disable_regulators;
 	}
 
-	ret = reset_control_bulk_deassert(qmp->num_resets, qmp->resets);
+	ret = reset_control_bulk_deassert(cfg->num_resets, qmp->resets);
 	if (ret) {
 		dev_err(qmp->dev, "reset deassert failed\n");
 		goto err_disable_regulators;
@@ -682,7 +702,7 @@ static int qmp_usbc_com_init(struct phy *phy)
 	return 0;
 
 err_assert_reset:
-	reset_control_bulk_assert(qmp->num_resets, qmp->resets);
+	reset_control_bulk_assert(cfg->num_resets, qmp->resets);
 err_disable_regulators:
 	regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
 
@@ -694,7 +714,7 @@ static int qmp_usbc_com_exit(struct phy *phy)
 	struct qmp_usbc *qmp = phy_get_drvdata(phy);
 	const struct qmp_phy_cfg *cfg = qmp->cfg;
 
-	reset_control_bulk_assert(qmp->num_resets, qmp->resets);
+	reset_control_bulk_assert(cfg->num_resets, qmp->resets);
 
 	clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks);
 
@@ -921,42 +941,22 @@ static const struct dev_pm_ops qmp_usbc_pm_ops = {
 			   qmp_usbc_runtime_resume, NULL)
 };
 
-static int qmp_usbc_vreg_init(struct qmp_usbc *qmp)
+static int qmp_usbc_reset_init(struct qmp_usbc *qmp)
 {
 	const struct qmp_phy_cfg *cfg = qmp->cfg;
-	struct device *dev = qmp->dev;
-	int num = cfg->num_vregs;
-	int i;
-
-	qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL);
-	if (!qmp->vregs)
-		return -ENOMEM;
-
-	for (i = 0; i < num; i++)
-		qmp->vregs[i].supply = cfg->vreg_list[i];
-
-	return devm_regulator_bulk_get(dev, num, qmp->vregs);
-}
-
-static int qmp_usbc_reset_init(struct qmp_usbc *qmp,
-			      const char *const *reset_list,
-			      int num_resets)
-{
 	struct device *dev = qmp->dev;
 	int i;
 	int ret;
 
-	qmp->resets = devm_kcalloc(dev, num_resets,
+	qmp->resets = devm_kcalloc(dev, cfg->num_resets,
 				   sizeof(*qmp->resets), GFP_KERNEL);
 	if (!qmp->resets)
 		return -ENOMEM;
 
-	for (i = 0; i < num_resets; i++)
-		qmp->resets[i].id = reset_list[i];
+	for (i = 0; i < cfg->num_resets; i++)
+		qmp->resets[i].id = cfg->reset_list[i];
 
-	qmp->num_resets = num_resets;
-
-	ret = devm_reset_control_bulk_get_exclusive(dev, num_resets, qmp->resets);
+	ret = devm_reset_control_bulk_get_exclusive(dev, cfg->num_resets, qmp->resets);
 	if (ret)
 		return dev_err_probe(dev, ret, "failed to get resets\n");
 
@@ -1146,11 +1146,6 @@ static int qmp_usbc_parse_usb_dt_legacy(struct qmp_usbc *qmp, struct device_node
 
 	qmp->num_clks = ret;
 
-	ret = qmp_usbc_reset_init(qmp, usb3phy_legacy_reset_l,
-				 ARRAY_SIZE(usb3phy_legacy_reset_l));
-	if (ret)
-		return ret;
-
 	return 0;
 }
 
@@ -1187,14 +1182,9 @@ static int qmp_usbc_parse_usb_dt(struct qmp_usbc *qmp)
 	qmp->pipe_clk = devm_clk_get(dev, "pipe");
 	if (IS_ERR(qmp->pipe_clk)) {
 		return dev_err_probe(dev, PTR_ERR(qmp->pipe_clk),
-				     "failed to get pipe clock\n");
+					"failed to get pipe clock\n");
 	}
 
-	ret = qmp_usbc_reset_init(qmp, usb3phy_reset_l,
-				 ARRAY_SIZE(usb3phy_reset_l));
-	if (ret)
-		return ret;
-
 	return 0;
 }
 
@@ -1228,6 +1218,7 @@ static int qmp_usbc_probe(struct platform_device *pdev)
 	struct phy_provider *phy_provider;
 	struct device_node *np;
 	struct qmp_usbc *qmp;
+	const struct qmp_phy_cfg *cfg;
 	int ret;
 
 	qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL);
@@ -1239,13 +1230,20 @@ static int qmp_usbc_probe(struct platform_device *pdev)
 
 	qmp->orientation = TYPEC_ORIENTATION_NORMAL;
 
-	qmp->cfg = of_device_get_match_data(dev);
-	if (!qmp->cfg)
+	cfg = of_device_get_match_data(dev);
+	if (!cfg)
 		return -EINVAL;
 
+	qmp->cfg = cfg;
+
 	mutex_init(&qmp->phy_mutex);
 
-	ret = qmp_usbc_vreg_init(qmp);
+	ret = qmp_usbc_reset_init(qmp);
+	if (ret)
+		return ret;
+
+	ret = devm_regulator_bulk_get_const(qmp->dev, cfg->num_vregs,
+					 cfg->vreg_list, &qmp->vregs);
 	if (ret)
 		return ret;
 

-- 
2.34.1



From xiangxu.yin at oss.qualcomm.com  Wed Aug 20 02:34:50 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Wed, 20 Aug 2025 17:34:50 +0800
Subject: [PATCH v3 08/14] phy: qcom: qmp-usbc: Add DP PHY configuration
 support for QCS615
In-Reply-To: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
Message-ID: <20250820-add-displayport-support-for-qcs615-platform-v3-8-a43bd25ec39c@oss.qualcomm.com>

Introduce DisplayPort PHY configuration routines for QCS615, including
aux channel setup, lane control, voltage swing tuning, clock
programming and calibration. These callbacks are registered via
qmp_phy_cfg to enable DP mode on USB/DP switchable Type-C PHYs.

Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-dp-phy.h |   1 +
 drivers/phy/qualcomm/phy-qcom-qmp-usbc.c   | 251 +++++++++++++++++++++++++++++
 2 files changed, 252 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy.h b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy.h
index 0ebd405bcaf0cac8215550bfc9b226f30cc43a59..59885616405f878885d0837838a0bac1899fb69f 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy.h
@@ -25,6 +25,7 @@
 #define QSERDES_DP_PHY_AUX_CFG7				0x03c
 #define QSERDES_DP_PHY_AUX_CFG8				0x040
 #define QSERDES_DP_PHY_AUX_CFG9				0x044
+#define QSERDES_DP_PHY_VCO_DIV				0x068
 
 /* QSERDES COM_BIAS_EN_CLKBUFLR_EN bits */
 # define QSERDES_V3_COM_BIAS_EN				0x0001
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
index 4e797b7e65da0e3a827efa9a179f1c150c1b8b00..1508a4a5f57aff85318485b79528325f28a825a4 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
@@ -28,6 +28,9 @@
 #include "phy-qcom-qmp.h"
 #include "phy-qcom-qmp-pcs-misc-v3.h"
 
+#include "phy-qcom-qmp-dp-phy.h"
+#include "phy-qcom-qmp-dp-phy-v3.h"
+
 #define PHY_INIT_COMPLETE_TIMEOUT		10000
 
 /* set of registers with offsets different per-PHY */
@@ -623,6 +626,11 @@ static const struct qmp_phy_cfg sdm660_usb3phy_cfg = {
 	.regs			= qmp_v3_usb3phy_regs_layout_qcm2290,
 };
 
+static void qcs615_qmp_dp_aux_init(struct qmp_usbc *qmp);
+static void qcs615_qmp_configure_dp_tx(struct qmp_usbc *qmp);
+static int qcs615_qmp_configure_dp_phy(struct qmp_usbc *qmp);
+static int qcs615_qmp_calibrate_dp_phy(struct qmp_usbc *qmp);
+
 static const struct qmp_phy_cfg qcs615_usb3dp_phy_cfg = {
 	.offsets		= &qmp_usbc_usb3dp_offsets_qcs615,
 	.type			= QMP_PHY_USBC_USB3_DP,
@@ -653,6 +661,11 @@ static const struct qmp_phy_cfg qcs615_usb3dp_phy_cfg = {
 	.swing_tbl		= &qmp_dp_voltage_swing_hbr2_rbr,
 	.pre_emphasis_tbl	= &qmp_dp_pre_emphasis_hbr2_rbr,
 
+	.dp_aux_init		= qcs615_qmp_dp_aux_init,
+	.configure_dp_tx	= qcs615_qmp_configure_dp_tx,
+	.configure_dp_phy	= qcs615_qmp_configure_dp_phy,
+	.calibrate_dp_phy	= qcs615_qmp_calibrate_dp_phy,
+
 	.reset_list		= usb3dpphy_reset_l,
 	.num_resets		= ARRAY_SIZE(usb3dpphy_reset_l),
 	.vreg_list		= qmp_phy_usbdp_vreg_l,
@@ -723,6 +736,244 @@ static int qmp_usbc_com_exit(struct phy *phy)
 	return 0;
 }
 
+static void qcs615_qmp_dp_aux_init(struct qmp_usbc *qmp)
+{
+	writel(DP_PHY_PD_CTL_AUX_PWRDN |
+	       DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN |
+	       DP_PHY_PD_CTL_PLL_PWRDN,
+	       qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL);
+
+	writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
+	       DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN |
+	       DP_PHY_PD_CTL_PLL_PWRDN,
+	       qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL);
+
+	writel(0x00, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG0);
+	writel(0x13, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG1);
+	writel(0x00, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG2);
+	writel(0x00, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG3);
+	writel(0x0a, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG4);
+	writel(0x26, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG5);
+	writel(0x0a, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG6);
+	writel(0x03, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG7);
+	writel(0xbb, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG8);
+	writel(0x03, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG9);
+	qmp->dp_aux_cfg = 0;
+
+	writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
+	       PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
+	       PHY_AUX_REQ_ERR_MASK,
+	       qmp->dp_dp_phy + QSERDES_V3_DP_PHY_AUX_INTERRUPT_MASK);
+}
+
+static int qcs615_qmp_configure_dp_swing(struct qmp_usbc *qmp)
+{
+	const struct qmp_phy_cfg *cfg = qmp->cfg;
+	const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts;
+	void __iomem *tx = qmp->dp_tx;
+	void __iomem *tx2 = qmp->dp_tx2;
+	unsigned int v_level = 0, p_level = 0;
+	u8 voltage_swing_cfg, pre_emphasis_cfg;
+	int i;
+
+	if (dp_opts->lanes > 4) {
+		dev_err(qmp->dev, "Invalid lane_num(%d)\n", dp_opts->lanes);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < dp_opts->lanes; i++) {
+		v_level = max(v_level, dp_opts->voltage[i]);
+		p_level = max(p_level, dp_opts->pre[i]);
+	}
+
+	if (v_level > 4 || p_level > 4) {
+		dev_err(qmp->dev, "Invalid v(%d) | p(%d) level)\n",
+			v_level, p_level);
+		return -EINVAL;
+	}
+
+	voltage_swing_cfg = (*cfg->swing_tbl)[v_level][p_level];
+	pre_emphasis_cfg = (*cfg->pre_emphasis_tbl)[v_level][p_level];
+
+	voltage_swing_cfg |= DP_PHY_TXn_TX_DRV_LVL_MUX_EN;
+	pre_emphasis_cfg |= DP_PHY_TXn_TX_EMP_POST1_LVL_MUX_EN;
+
+	if (voltage_swing_cfg == 0xff && pre_emphasis_cfg == 0xff)
+		return -EINVAL;
+
+	writel(voltage_swing_cfg, tx + QSERDES_V3_TX_TX_DRV_LVL);
+	writel(pre_emphasis_cfg, tx + QSERDES_V3_TX_TX_EMP_POST1_LVL);
+	writel(voltage_swing_cfg, tx2 + QSERDES_V3_TX_TX_DRV_LVL);
+	writel(pre_emphasis_cfg, tx2 + QSERDES_V3_TX_TX_EMP_POST1_LVL);
+
+	return 0;
+}
+
+static void qmp_usbc_configure_dp_mode(struct qmp_usbc *qmp)
+{
+	bool reverse = (qmp->orientation == TYPEC_ORIENTATION_REVERSE);
+	u32 val;
+
+	val = DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
+	      DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN;
+
+	writel(val, qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL);
+
+	if (reverse)
+		writel(0xc9, qmp->dp_dp_phy + QSERDES_DP_PHY_MODE);
+	else
+		writel(0xd9, qmp->dp_dp_phy + QSERDES_DP_PHY_MODE);
+}
+
+static int qmp_usbc_configure_dp_clocks(struct qmp_usbc *qmp)
+{
+	const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts;
+	u32 phy_vco_div;
+	unsigned long pixel_freq;
+
+	switch (dp_opts->link_rate) {
+	case 1620:
+		phy_vco_div = 0x1;
+		pixel_freq = 1620000000UL / 2;
+		break;
+	case 2700:
+		phy_vco_div = 0x1;
+		pixel_freq = 2700000000UL / 2;
+		break;
+	case 5400:
+		phy_vco_div = 0x2;
+		pixel_freq = 5400000000UL / 4;
+		break;
+	default:
+		dev_err(qmp->dev, "link rate:%d not supported\n", dp_opts->link_rate);
+		return -EINVAL;
+	}
+	writel(phy_vco_div, qmp->dp_dp_phy + QSERDES_DP_PHY_VCO_DIV);
+
+	clk_set_rate(qmp->dp_link_hw.clk, dp_opts->link_rate * 100000);
+	clk_set_rate(qmp->dp_pixel_hw.clk, pixel_freq);
+
+	return 0;
+}
+
+static void qcs615_qmp_configure_dp_tx(struct qmp_usbc *qmp)
+{
+	void __iomem *tx = qmp->dp_tx;
+	void __iomem *tx2 = qmp->dp_tx2;
+
+	/* program default setting first */
+	writel(0x2a, tx + QSERDES_V3_TX_TX_DRV_LVL);
+	writel(0x20, tx + QSERDES_V3_TX_TX_EMP_POST1_LVL);
+	writel(0x2a, tx2 + QSERDES_V3_TX_TX_DRV_LVL);
+	writel(0x20, tx2 + QSERDES_V3_TX_TX_EMP_POST1_LVL);
+
+	qcs615_qmp_configure_dp_swing(qmp);
+}
+
+static int qcs615_qmp_configure_dp_phy(struct qmp_usbc *qmp)
+{
+	u32 status;
+	int ret;
+
+	qmp_usbc_configure_dp_mode(qmp);
+
+	writel(0x05, qmp->dp_dp_phy + QSERDES_V3_DP_PHY_TX0_TX1_LANE_CTL);
+	writel(0x05, qmp->dp_dp_phy + QSERDES_V3_DP_PHY_TX2_TX3_LANE_CTL);
+
+	ret = qmp_usbc_configure_dp_clocks(qmp);
+	if (ret)
+		return ret;
+
+	writel(0x01, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG);
+	writel(0x05, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG);
+	writel(0x01, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG);
+	writel(0x09, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG);
+
+	writel(0x20, qmp->dp_serdes + QSERDES_COM_RESETSM_CNTRL);
+
+	if (readl_poll_timeout(qmp->dp_serdes + QSERDES_COM_C_READY_STATUS,
+			       status,
+			       ((status & BIT(0)) > 0),
+			       500,
+			       10000)) {
+		dev_err(qmp->dev, "C_READY not ready\n");
+		return -ETIMEDOUT;
+	}
+
+	if (readl_poll_timeout(qmp->dp_serdes + QSERDES_COM_CMN_STATUS,
+			       status,
+			       ((status & BIT(0)) > 0),
+			       500,
+			       10000)){
+		dev_err(qmp->dev, "FREQ_DONE not ready\n");
+		return -ETIMEDOUT;
+	}
+
+	if (readl_poll_timeout(qmp->dp_serdes + QSERDES_COM_CMN_STATUS,
+			       status,
+			       ((status & BIT(1)) > 0),
+			       500,
+			       10000)){
+		dev_err(qmp->dev, "PLL_LOCKED not ready\n");
+		return -ETIMEDOUT;
+	}
+
+	writel(0x19, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG);
+
+	if (readl_poll_timeout(qmp->dp_dp_phy + QSERDES_V3_DP_PHY_STATUS,
+			       status,
+			       ((status & BIT(0)) > 0),
+			       500,
+			       10000)){
+		dev_err(qmp->dev, "TSYNC_DONE not ready\n");
+		return -ETIMEDOUT;
+	}
+
+	if (readl_poll_timeout(qmp->dp_dp_phy + QSERDES_V3_DP_PHY_STATUS,
+			       status,
+			       ((status & BIT(1)) > 0),
+			       500,
+			       10000)){
+		dev_err(qmp->dev, "PHY_READY not ready\n");
+		return -ETIMEDOUT;
+	}
+
+	writel(0x3f, qmp->dp_tx + QSERDES_V3_TX_TRANSCEIVER_BIAS_EN);
+	writel(0x10, qmp->dp_tx + QSERDES_V3_TX_HIGHZ_DRVR_EN);
+	writel(0x0a, qmp->dp_tx + QSERDES_V3_TX_TX_POL_INV);
+	writel(0x3f, qmp->dp_tx2 + QSERDES_V3_TX_TRANSCEIVER_BIAS_EN);
+	writel(0x10, qmp->dp_tx2 + QSERDES_V3_TX_HIGHZ_DRVR_EN);
+	writel(0x0a, qmp->dp_tx2 + QSERDES_V3_TX_TX_POL_INV);
+
+	writel(0x18, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG);
+	writel(0x19, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG);
+
+	if (readl_poll_timeout(qmp->dp_dp_phy + QSERDES_V3_DP_PHY_STATUS,
+			       status,
+			       ((status & BIT(1)) > 0),
+			       500,
+			       10000)){
+		dev_err(qmp->dev, "PHY_READY not ready\n");
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
+static int qcs615_qmp_calibrate_dp_phy(struct qmp_usbc *qmp)
+{
+	static const u8 cfg1_settings[] = {0x13, 0x23, 0x1d};
+	u8 val;
+
+	qmp->dp_aux_cfg++;
+	qmp->dp_aux_cfg %= ARRAY_SIZE(cfg1_settings);
+	val = cfg1_settings[qmp->dp_aux_cfg];
+
+	writel(val, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG1);
+
+	return 0;
+}
+
 static int qmp_usbc_usb_power_on(struct phy *phy)
 {
 	struct qmp_usbc *qmp = phy_get_drvdata(phy);

-- 
2.34.1



From xiangxu.yin at oss.qualcomm.com  Wed Aug 20 02:34:51 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Wed, 20 Aug 2025 17:34:51 +0800
Subject: [PATCH v3 09/14] phy: qcom: qmp-usbc: Add DP PHY ops for USB/DP
 switchable Type-C PHYs
In-Reply-To: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
Message-ID: <20250820-add-displayport-support-for-qcs615-platform-v3-9-a43bd25ec39c@oss.qualcomm.com>

Define qmp_usbc_dp_phy_ops struct to support DP mode on USB/DP
switchable PHYs.

Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 163 +++++++++++++++++++++++++++++++
 1 file changed, 163 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
index 1508a4a5f57aff85318485b79528325f28a825a4..a1495a2029cf038bb65c36e42d0a4f633e544558 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
@@ -22,6 +22,8 @@
 #include <linux/slab.h>
 #include <linux/usb/typec.h>
 #include <linux/usb/typec_mux.h>
+#include <dt-bindings/phy/phy-qcom-qmp.h>
+#include <drm/bridge/aux-bridge.h>
 
 #include "phy-qcom-qmp-common.h"
 
@@ -1088,6 +1090,157 @@ static int qmp_usbc_usb_set_mode(struct phy *phy, enum phy_mode mode, int submod
 	return 0;
 }
 
+static int qmp_usbc_dp_enable(struct phy *phy)
+{
+	struct qmp_usbc *qmp = phy_get_drvdata(phy);
+	const struct qmp_phy_cfg *cfg = qmp->cfg;
+	int ret;
+
+	if (qmp->dp_init_count) {
+		dev_err(qmp->dev, "DP already inited\n");
+		return 0;
+	}
+
+	mutex_lock(&qmp->phy_mutex);
+
+	ret = qmp_usbc_com_init(phy);
+	if (ret)
+		goto dp_init_unlock;
+
+	cfg->dp_aux_init(qmp);
+
+	qmp->dp_init_count++;
+
+dp_init_unlock:
+	mutex_unlock(&qmp->phy_mutex);
+	return ret;
+}
+
+static int qmp_usbc_dp_disable(struct phy *phy)
+{
+	struct qmp_usbc *qmp = phy_get_drvdata(phy);
+
+	mutex_lock(&qmp->phy_mutex);
+
+	qmp_usbc_com_exit(phy);
+
+	qmp->dp_init_count--;
+
+	mutex_unlock(&qmp->phy_mutex);
+
+	return 0;
+}
+
+static int qmp_usbc_dp_configure(struct phy *phy, union phy_configure_opts *opts)
+{
+	const struct phy_configure_opts_dp *dp_opts = &opts->dp;
+	struct qmp_usbc *qmp = phy_get_drvdata(phy);
+	const struct qmp_phy_cfg *cfg = qmp->cfg;
+
+	mutex_lock(&qmp->phy_mutex);
+
+	memcpy(&qmp->dp_opts, dp_opts, sizeof(*dp_opts));
+	if (qmp->dp_opts.set_voltages) {
+		cfg->configure_dp_tx(qmp);
+		qmp->dp_opts.set_voltages = 0;
+	}
+
+	mutex_unlock(&qmp->phy_mutex);
+
+	return 0;
+}
+
+static int qmp_usbc_dp_calibrate(struct phy *phy)
+{
+	struct qmp_usbc *qmp = phy_get_drvdata(phy);
+	const struct qmp_phy_cfg *cfg = qmp->cfg;
+	int ret = 0;
+
+	mutex_lock(&qmp->phy_mutex);
+
+	if (cfg->calibrate_dp_phy) {
+		ret = cfg->calibrate_dp_phy(qmp);
+		if (ret) {
+			dev_err(qmp->dev, "dp calibrate err(%d)\n", ret);
+			mutex_unlock(&qmp->phy_mutex);
+			return ret;
+		}
+	}
+
+	mutex_unlock(&qmp->phy_mutex);
+	return 0;
+}
+
+static int qmp_usbc_dp_serdes_init(struct qmp_usbc *qmp)
+{
+	const struct qmp_phy_cfg *cfg = qmp->cfg;
+	void __iomem *serdes = qmp->dp_serdes;
+	const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts;
+
+	qmp_configure(qmp->dev, serdes, cfg->dp_serdes_tbl,
+		      cfg->dp_serdes_tbl_num);
+
+	switch (dp_opts->link_rate) {
+	case 1620:
+		qmp_configure(qmp->dev, serdes, cfg->serdes_tbl_rbr,
+			      cfg->serdes_tbl_rbr_num);
+		break;
+	case 2700:
+		qmp_configure(qmp->dev, serdes, cfg->serdes_tbl_hbr,
+			      cfg->serdes_tbl_hbr_num);
+		break;
+	case 5400:
+		qmp_configure(qmp->dev, serdes, cfg->serdes_tbl_hbr2,
+			      cfg->serdes_tbl_hbr2_num);
+		break;
+	default:
+		/* Other link rates aren't supported */
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int qmp_usbc_dp_power_on(struct phy *phy)
+{
+	struct qmp_usbc *qmp = phy_get_drvdata(phy);
+	const struct qmp_phy_cfg *cfg = qmp->cfg;
+
+	void __iomem *tx = qmp->dp_tx;
+	void __iomem *tx2 = qmp->dp_tx2;
+
+	mutex_lock(&qmp->phy_mutex);
+
+	qmp_usbc_dp_serdes_init(qmp);
+
+	qmp_configure_lane(qmp->dev, tx, cfg->dp_tx_tbl, cfg->dp_tx_tbl_num, 1);
+	qmp_configure_lane(qmp->dev, tx2, cfg->dp_tx_tbl, cfg->dp_tx_tbl_num, 2);
+
+	/* Configure special DP tx tunings */
+	cfg->configure_dp_tx(qmp);
+
+	/* Configure link rate, swing, etc. */
+	cfg->configure_dp_phy(qmp);
+
+	mutex_unlock(&qmp->phy_mutex);
+
+	return 0;
+}
+
+static int qmp_usbc_dp_power_off(struct phy *phy)
+{
+	struct qmp_usbc *qmp = phy_get_drvdata(phy);
+
+	mutex_lock(&qmp->phy_mutex);
+
+	/* Assert DP PHY power down */
+	writel(DP_PHY_PD_CTL_PSR_PWRDN, qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL);
+
+	mutex_unlock(&qmp->phy_mutex);
+
+	return 0;
+}
+
 static const struct phy_ops qmp_usbc_usb_phy_ops = {
 	.init		= qmp_usbc_usb_enable,
 	.exit		= qmp_usbc_usb_disable,
@@ -1095,6 +1248,16 @@ static const struct phy_ops qmp_usbc_usb_phy_ops = {
 	.owner		= THIS_MODULE,
 };
 
+static const struct phy_ops qmp_usbc_dp_phy_ops = {
+	.init		= qmp_usbc_dp_enable,
+	.exit		= qmp_usbc_dp_disable,
+	.configure	= qmp_usbc_dp_configure,
+	.calibrate	= qmp_usbc_dp_calibrate,
+	.power_on	= qmp_usbc_dp_power_on,
+	.power_off	= qmp_usbc_dp_power_off,
+	.owner		= THIS_MODULE,
+};
+
 static void qmp_usbc_enable_autonomous_mode(struct qmp_usbc *qmp)
 {
 	const struct qmp_phy_cfg *cfg = qmp->cfg;

-- 
2.34.1



From xiangxu.yin at oss.qualcomm.com  Wed Aug 20 02:34:52 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Wed, 20 Aug 2025 17:34:52 +0800
Subject: [PATCH v3 10/14] phy: qcom: qmp-usbc: Add TCSR parsing and USB/DP
 mode mutex handling
In-Reply-To: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
Message-ID: <20250820-add-displayport-support-for-qcs615-platform-v3-10-a43bd25ec39c@oss.qualcomm.com>

Parse TCSR registers to support DP mode signaling via dp_phy_mode_reg.
Introduce mutual exclusion between USB and DP PHY modes to prevent
simultaneous activation. Also update com_init/com_exit to reflect DP
mode initialization and cleanup.

Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 60 +++++++++++++++++++++++++-------
 1 file changed, 47 insertions(+), 13 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
index a1495a2029cf038bb65c36e42d0a4f633e544558..821398653bef23e1915d9d3a3a2950b0bfbefb9a 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
@@ -674,7 +674,7 @@ static const struct qmp_phy_cfg qcs615_usb3dp_phy_cfg = {
 	.num_vregs		= ARRAY_SIZE(qmp_phy_usbdp_vreg_l),
 };
 
-static int qmp_usbc_com_init(struct phy *phy)
+static int qmp_usbc_com_init(struct phy *phy, bool is_dp)
 {
 	struct qmp_usbc *qmp = phy_get_drvdata(phy);
 	const struct qmp_phy_cfg *cfg = qmp->cfg;
@@ -704,15 +704,20 @@ static int qmp_usbc_com_init(struct phy *phy)
 	if (ret)
 		goto err_assert_reset;
 
-	qphy_setbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], SW_PWRDN);
+	if (!is_dp) {
+		qphy_setbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], SW_PWRDN);
 
 #define SW_PORTSELECT_VAL			BIT(0)
 #define SW_PORTSELECT_MUX			BIT(1)
-	/* Use software based port select and switch on typec orientation */
-	val = SW_PORTSELECT_MUX;
-	if (qmp->orientation == TYPEC_ORIENTATION_REVERSE)
-		val |= SW_PORTSELECT_VAL;
-	writel(val, qmp->pcs_misc);
+		/* Use software based port select and switch on typec orientation */
+		val = SW_PORTSELECT_MUX;
+		if (qmp->orientation == TYPEC_ORIENTATION_REVERSE)
+			val |= SW_PORTSELECT_VAL;
+		writel(val, qmp->pcs_misc);
+	}
+
+	if (qmp->tcsr_map && qmp->dp_phy_mode_reg)
+		regmap_write(qmp->tcsr_map, qmp->dp_phy_mode_reg, is_dp);
 
 	return 0;
 
@@ -733,6 +738,9 @@ static int qmp_usbc_com_exit(struct phy *phy)
 
 	clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks);
 
+	if (qmp->tcsr_map && qmp->dp_phy_mode_reg)
+		regmap_write(qmp->tcsr_map, qmp->dp_phy_mode_reg, 0);
+
 	regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
 
 	return 0;
@@ -1045,6 +1053,17 @@ static int qmp_usbc_usb_power_off(struct phy *phy)
 	return 0;
 }
 
+static int qmp_check_mutex_phy(struct qmp_usbc *qmp, bool is_dp)
+{
+	if ((is_dp && qmp->usb_init_count) ||
+	    (!is_dp && qmp->dp_init_count)) {
+		dev_err(qmp->dev, "%s PHY busy\n", is_dp ? "USB" : "DP");
+		return -EBUSY;
+	}
+
+	return 0;
+}
+
 static int qmp_usbc_usb_enable(struct phy *phy)
 {
 	struct qmp_usbc *qmp = phy_get_drvdata(phy);
@@ -1052,7 +1071,11 @@ static int qmp_usbc_usb_enable(struct phy *phy)
 
 	mutex_lock(&qmp->phy_mutex);
 
-	ret = qmp_usbc_com_init(phy);
+	ret = qmp_check_mutex_phy(qmp, false);
+	if (ret)
+		goto out_unlock;
+
+	ret = qmp_usbc_com_init(phy, false);
 	if (ret)
 		goto out_unlock;
 
@@ -1103,7 +1126,11 @@ static int qmp_usbc_dp_enable(struct phy *phy)
 
 	mutex_lock(&qmp->phy_mutex);
 
-	ret = qmp_usbc_com_init(phy);
+	ret = qmp_check_mutex_phy(qmp, true);
+	if (ret)
+		goto dp_init_unlock;
+
+	ret = qmp_usbc_com_init(phy, true);
 	if (ret)
 		goto dp_init_unlock;
 
@@ -1467,7 +1494,7 @@ static int qmp_usbc_typec_switch_set(struct typec_switch_dev *sw,
 		qmp_usbc_usb_power_off(qmp->usb_phy);
 		qmp_usbc_com_exit(qmp->usb_phy);
 
-		qmp_usbc_com_init(qmp->usb_phy);
+		qmp_usbc_com_init(qmp->usb_phy, false);
 		qmp_usbc_usb_power_on(qmp->usb_phy);
 	}
 
@@ -1602,13 +1629,13 @@ static int qmp_usbc_parse_usb_dt(struct qmp_usbc *qmp)
 	return 0;
 }
 
-static int qmp_usbc_parse_vls_clamp(struct qmp_usbc *qmp)
+static int qmp_usbc_parse_tcsr(struct qmp_usbc *qmp)
 {
 	struct of_phandle_args tcsr_args;
 	struct device *dev = qmp->dev;
 	int ret;
 
-	/*  for backwards compatibility ignore if there is no property */
+	/*  for backwards compatibility ignore if there is 1 or no property */
 	ret = of_parse_phandle_with_fixed_args(dev->of_node, "qcom,tcsr-reg", 1, 0,
 					       &tcsr_args);
 	if (ret == -ENOENT)
@@ -1623,6 +1650,13 @@ static int qmp_usbc_parse_vls_clamp(struct qmp_usbc *qmp)
 
 	qmp->vls_clamp_reg = tcsr_args.args[0];
 
+	ret = of_parse_phandle_with_fixed_args(dev->of_node, "qcom,tcsr-reg", 1, 1,
+					       &tcsr_args);
+	if (ret == -ENOENT)
+		return 0;
+
+	qmp->dp_phy_mode_reg = tcsr_args.args[0];
+
 	return 0;
 }
 
@@ -1665,7 +1699,7 @@ static int qmp_usbc_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	ret = qmp_usbc_parse_vls_clamp(qmp);
+	ret = qmp_usbc_parse_tcsr(qmp);
 	if (ret)
 		return ret;
 

-- 
2.34.1



From xiangxu.yin at oss.qualcomm.com  Wed Aug 20 02:34:53 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Wed, 20 Aug 2025 17:34:53 +0800
Subject: [PATCH v3 11/14] phy: qcom: qmp-usbc: Finalize USB/DP switchable
 PHY support
In-Reply-To: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
Message-ID: <20250820-add-displayport-support-for-qcs615-platform-v3-11-a43bd25ec39c@oss.qualcomm.com>

Complete USB/DP switchable PHY integration by adding DP clock
registration, aux bridge setup, and DT parsing. Implement clock
provider logic for USB and DP branches, and extend PHY translation
to support both USB and DP instances.

Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 331 ++++++++++++++++++++++++++++---
 1 file changed, 299 insertions(+), 32 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
index 821398653bef23e1915d9d3a3a2950b0bfbefb9a..74b9f75c8864efe270f394bfbfd748793dada1f5 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
@@ -995,6 +995,11 @@ static int qmp_usbc_usb_power_on(struct phy *phy)
 	qmp_configure(qmp->dev, qmp->serdes, cfg->serdes_tbl,
 		      cfg->serdes_tbl_num);
 
+	if (IS_ERR(qmp->pipe_clk)) {
+		return dev_err_probe(qmp->dev, PTR_ERR(qmp->pipe_clk),
+				     "pipe clock not defined\n");
+	}
+
 	ret = clk_prepare_enable(qmp->pipe_clk);
 	if (ret) {
 		dev_err(qmp->dev, "pipe_clk enable failed err=%d\n", ret);
@@ -1365,11 +1370,13 @@ static int __maybe_unused qmp_usbc_runtime_resume(struct device *dev)
 	if (ret)
 		return ret;
 
-	ret = clk_prepare_enable(qmp->pipe_clk);
-	if (ret) {
-		dev_err(dev, "pipe_clk enable failed, err=%d\n", ret);
-		clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks);
-		return ret;
+	if (!IS_ERR(qmp->pipe_clk)) {
+		ret = clk_prepare_enable(qmp->pipe_clk);
+		if (ret) {
+			dev_err(dev, "pipe_clk enable failed, err=%d\n", ret);
+			clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks);
+			return ret;
+		}
 	}
 
 	qmp_usbc_disable_autonomous_mode(qmp);
@@ -1422,9 +1429,23 @@ static int qmp_usbc_clk_init(struct qmp_usbc *qmp)
 	return devm_clk_bulk_get_optional(dev, num, qmp->clks);
 }
 
-static void phy_clk_release_provider(void *res)
+static struct clk_hw *qmp_usbc_clks_hw_get(struct of_phandle_args *clkspec, void *data)
 {
-	of_clk_del_provider(res);
+	struct qmp_usbc *qmp = data;
+
+	if (clkspec->args_count == 0)
+		return &qmp->pipe_clk_fixed.hw;
+
+	switch (clkspec->args[0]) {
+	case QMP_USB43DP_USB3_PIPE_CLK:
+		return &qmp->pipe_clk_fixed.hw;
+	case QMP_USB43DP_DP_LINK_CLK:
+		return &qmp->dp_link_hw;
+	case QMP_USB43DP_DP_VCO_DIV_CLK:
+		return &qmp->dp_pixel_hw;
+	}
+
+	return ERR_PTR(-EINVAL);
 }
 
 /*
@@ -1453,8 +1474,11 @@ static int phy_pipe_clk_register(struct qmp_usbc *qmp, struct device_node *np)
 
 	ret = of_property_read_string(np, "clock-output-names", &init.name);
 	if (ret) {
-		dev_err(qmp->dev, "%pOFn: No clock-output-names\n", np);
-		return ret;
+		char name[64];
+
+		/* Clock name is not mandatory. */
+		snprintf(name, sizeof(name), "%s::pipe_clk", dev_name(qmp->dev));
+		init.name = name;
 	}
 
 	init.ops = &clk_fixed_rate_ops;
@@ -1463,19 +1487,7 @@ static int phy_pipe_clk_register(struct qmp_usbc *qmp, struct device_node *np)
 	fixed->fixed_rate = 125000000;
 	fixed->hw.init = &init;
 
-	ret = devm_clk_hw_register(qmp->dev, &fixed->hw);
-	if (ret)
-		return ret;
-
-	ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &fixed->hw);
-	if (ret)
-		return ret;
-
-	/*
-	 * Roll a devm action because the clock provider is the child node, but
-	 * the child node is not actually a device.
-	 */
-	return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
+	return devm_clk_hw_register(qmp->dev, &fixed->hw);
 }
 
 #if IS_ENABLED(CONFIG_TYPEC)
@@ -1660,6 +1672,235 @@ static int qmp_usbc_parse_tcsr(struct qmp_usbc *qmp)
 	return 0;
 }
 
+static int qmp_usbc_parse_usb3dp_dt(struct qmp_usbc *qmp)
+{
+	struct platform_device *pdev = to_platform_device(qmp->dev);
+	const struct qmp_phy_cfg *cfg = qmp->cfg;
+	const struct qmp_usbc_offsets *offs = cfg->offsets;
+	struct device *dev = qmp->dev;
+	void __iomem *base;
+	int ret;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	qmp->dp_serdes = base + offs->dp_serdes;
+	qmp->dp_tx = base + offs->dp_txa;
+	qmp->dp_tx2 = base + offs->dp_txb;
+	qmp->dp_dp_phy = base + offs->dp_dp_phy;
+	qmp->serdes = base + offs->serdes;
+	qmp->pcs = base + offs->pcs;
+	if (offs->pcs_misc)
+		qmp->pcs_misc = base + offs->pcs_misc;
+	qmp->tx = base + offs->tx;
+	qmp->rx = base + offs->rx;
+
+	qmp->tx2 = base + offs->tx2;
+	qmp->rx2 = base + offs->rx2;
+
+	ret = qmp_usbc_clk_init(qmp);
+	if (ret)
+		return ret;
+
+	qmp->pipe_clk = devm_clk_get(dev, "pipe");
+	if (IS_ERR(qmp->pipe_clk)) {
+		/* usb3dp allow no pipe clk define */
+		if (cfg->type == QMP_PHY_USBC_USB3_ONLY)
+			return dev_err_probe(dev, PTR_ERR(qmp->pipe_clk),
+						"failed to get pipe clock\n");
+	}
+
+	return 0;
+}
+
+/*
+ * Display Port PLL driver block diagram for branch clocks
+ *
+ *              +------------------------------+
+ *              |         DP_VCO_CLK           |
+ *              |                              |
+ *              |    +-------------------+     |
+ *              |    |   (DP PLL/VCO)    |     |
+ *              |    +---------+---------+     |
+ *              |              v               |
+ *              |   +----------+-----------+   |
+ *              |   | hsclk_divsel_clk_src |   |
+ *              |   +----------+-----------+   |
+ *              +------------------------------+
+ *                              |
+ *          +---------<---------v------------>----------+
+ *          |                                           |
+ * +--------v----------------+                          |
+ * |    dp_phy_pll_link_clk  |                          |
+ * |     link_clk            |                          |
+ * +--------+----------------+                          |
+ *          |                                           |
+ *          |                                           |
+ *          v                                           v
+ * Input to DISPCC block                                |
+ * for link clk, crypto clk                             |
+ * and interface clock                                  |
+ *                                                      |
+ *                                                      |
+ *      +--------<------------+-----------------+---<---+
+ *      |                     |                 |
+ * +----v---------+  +--------v-----+  +--------v------+
+ * | vco_divided  |  | vco_divided  |  | vco_divided   |
+ * |    _clk_src  |  |    _clk_src  |  |    _clk_src   |
+ * |              |  |              |  |               |
+ * |divsel_six    |  |  divsel_two  |  |  divsel_four  |
+ * +-------+------+  +-----+--------+  +--------+------+
+ *         |                 |                  |
+ *         v---->----------v-------------<------v
+ *                         |
+ *              +----------+-----------------+
+ *              |   dp_phy_pll_vco_div_clk   |
+ *              +---------+------------------+
+ *                        |
+ *                        v
+ *              Input to DISPCC block
+ *              for DP pixel clock
+ *
+ */
+static int qmp_dp_pixel_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
+{
+	switch (req->rate) {
+	case 1620000000UL / 2:
+	case 2700000000UL / 2:
+	/* 5.4 and 8.1 GHz are same link rate as 2.7GHz, i.e. div 4 and div 6 */
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+static unsigned long qmp_dp_pixel_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+	const struct qmp_usbc *qmp;
+	const struct phy_configure_opts_dp *dp_opts;
+
+	qmp = container_of(hw, struct qmp_usbc, dp_pixel_hw);
+
+	dp_opts = &qmp->dp_opts;
+
+	switch (dp_opts->link_rate) {
+	case 1620:
+		return 1620000000UL / 2;
+	case 2700:
+		return 2700000000UL / 2;
+	case 5400:
+		return 5400000000UL / 4;
+	default:
+		return 0;
+	}
+}
+
+static const struct clk_ops qmp_dp_pixel_clk_ops = {
+	.determine_rate	= qmp_dp_pixel_clk_determine_rate,
+	.recalc_rate	= qmp_dp_pixel_clk_recalc_rate,
+};
+
+static int qmp_dp_link_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
+{
+	switch (req->rate) {
+	case 162000000:
+	case 270000000:
+	case 540000000:
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+static unsigned long qmp_dp_link_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+	const struct qmp_usbc *qmp;
+	const struct phy_configure_opts_dp *dp_opts;
+
+	qmp = container_of(hw, struct qmp_usbc, dp_link_hw);
+	dp_opts = &qmp->dp_opts;
+
+	switch (dp_opts->link_rate) {
+	case 1620:
+	case 2700:
+	case 5400:
+		return dp_opts->link_rate * 100000;
+	default:
+		return 0;
+	}
+}
+
+static const struct clk_ops qmp_dp_link_clk_ops = {
+	.determine_rate	= qmp_dp_link_clk_determine_rate,
+	.recalc_rate	= qmp_dp_link_clk_recalc_rate,
+};
+
+static int phy_dp_clks_register(struct qmp_usbc *qmp, struct device_node *np)
+{
+	struct clk_init_data init = { };
+	char name[64];
+	int ret;
+
+	snprintf(name, sizeof(name), "%s::link_clk", dev_name(qmp->dev));
+	init.ops = &qmp_dp_link_clk_ops;
+	init.name = name;
+	qmp->dp_link_hw.init = &init;
+	ret = devm_clk_hw_register(qmp->dev, &qmp->dp_link_hw);
+	if (ret < 0) {
+		dev_err(qmp->dev, "link clk reg fail ret=%d\n", ret);
+		return ret;
+	}
+
+	snprintf(name, sizeof(name), "%s::vco_div_clk", dev_name(qmp->dev));
+	init.ops = &qmp_dp_pixel_clk_ops;
+	init.name = name;
+	qmp->dp_pixel_hw.init = &init;
+	ret = devm_clk_hw_register(qmp->dev, &qmp->dp_pixel_hw);
+	if (ret) {
+		dev_err(qmp->dev, "pxl clk reg fail ret=%d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int qmp_usbc_register_clocks(struct qmp_usbc *qmp, struct device_node *np)
+{
+	int ret;
+
+	if (!IS_ERR(qmp->pipe_clk)) {
+		ret = phy_pipe_clk_register(qmp, np);
+		if (ret)
+			return ret;
+	}
+
+	if (qmp->cfg->type == QMP_PHY_USBC_USB3_DP) {
+		ret = phy_dp_clks_register(qmp, np);
+		if (ret)
+			return ret;
+	}
+
+	return devm_of_clk_add_hw_provider(qmp->dev, qmp_usbc_clks_hw_get, qmp);
+}
+
+static struct phy *qmp_usbc_phy_xlate(struct device *dev, const struct of_phandle_args *args)
+{
+	struct qmp_usbc *qmp = dev_get_drvdata(dev);
+
+	if (args->args_count == 0)
+		return qmp->usb_phy;
+
+	switch (args->args[0]) {
+	case QMP_USB43DP_USB3_PHY:
+		return qmp->usb_phy;
+	case QMP_USB43DP_DP_PHY:
+		return qmp->dp_phy;
+	}
+
+	return ERR_PTR(-EINVAL);
+}
+
 static int qmp_usbc_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -1703,16 +1944,32 @@ static int qmp_usbc_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	/* Check for legacy binding with child node. */
-	np = of_get_child_by_name(dev->of_node, "phy");
-	if (np) {
-		ret = qmp_usbc_parse_usb_dt_legacy(qmp, np);
-	} else {
+	if (qmp->cfg->type == QMP_PHY_USBC_USB3_DP) {
 		np = of_node_get(dev->of_node);
-		ret = qmp_usbc_parse_usb_dt(qmp);
+
+		ret = qmp_usbc_parse_usb3dp_dt(qmp);
+		if (ret) {
+			dev_err(qmp->dev, "parse DP dt fail ret=%d\n", ret);
+			goto err_node_put;
+		}
+
+		ret = drm_aux_bridge_register(dev);
+		if (ret) {
+			dev_err(qmp->dev, "aux bridge reg fail ret=%d\n", ret);
+			goto err_node_put;
+		}
+	} else {
+		/* Check for legacy binding with child node. */
+		np = of_get_child_by_name(dev->of_node, "phy");
+		if (np) {
+			ret = qmp_usbc_parse_usb_dt_legacy(qmp, np);
+		} else {
+			np = of_node_get(dev->of_node);
+			ret = qmp_usbc_parse_usb_dt(qmp);
+		}
+		if (ret)
+			goto err_node_put;
 	}
-	if (ret)
-		goto err_node_put;
 
 	pm_runtime_set_active(dev);
 	ret = devm_pm_runtime_enable(dev);
@@ -1724,7 +1981,7 @@ static int qmp_usbc_probe(struct platform_device *pdev)
 	 */
 	pm_runtime_forbid(dev);
 
-	ret = phy_pipe_clk_register(qmp, np);
+	ret = qmp_usbc_register_clocks(qmp, np);
 	if (ret)
 		goto err_node_put;
 
@@ -1737,9 +1994,19 @@ static int qmp_usbc_probe(struct platform_device *pdev)
 
 	phy_set_drvdata(qmp->usb_phy, qmp);
 
+	if (qmp->cfg->type == QMP_PHY_USBC_USB3_DP) {
+		qmp->dp_phy = devm_phy_create(dev, np, &qmp_usbc_dp_phy_ops);
+		if (IS_ERR(qmp->dp_phy)) {
+			ret = PTR_ERR(qmp->dp_phy);
+			dev_err(dev, "failed to create PHY: %d\n", ret);
+			goto err_node_put;
+		}
+		phy_set_drvdata(qmp->dp_phy, qmp);
+	}
+
 	of_node_put(np);
 
-	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+	phy_provider = devm_of_phy_provider_register(dev, qmp_usbc_phy_xlate);
 
 	return PTR_ERR_OR_ZERO(phy_provider);
 

-- 
2.34.1



From xiangxu.yin at oss.qualcomm.com  Wed Aug 20 02:34:54 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Wed, 20 Aug 2025 17:34:54 +0800
Subject: [PATCH v3 12/14] phy: qcom: qmp-usbc: Add QCS615 DP PHY compatible
In-Reply-To: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
Message-ID: <20250820-add-displayport-support-for-qcs615-platform-v3-12-a43bd25ec39c@oss.qualcomm.com>

Introduce qcs615-qmp-usb3-dp-phy compatible string to associate QCS615
platform with its USB/DP switchable PHY configuration. This enables the
driver to apply the correct setup for PHYs that support mode switching
between USB and DisplayPort.

Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
index 74b9f75c8864efe270f394bfbfd748793dada1f5..d56e334d58576d15a9ac047abe40a479e790a324 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
@@ -2022,6 +2022,9 @@ static const struct of_device_id qmp_usbc_of_match_table[] = {
 	}, {
 		.compatible = "qcom,qcm2290-qmp-usb3-phy",
 		.data = &qcm2290_usb3phy_cfg,
+	}, {
+		.compatible = "qcom,qcs615-qmp-usb3-dp-phy",
+		.data =  &qcs615_usb3dp_phy_cfg,
 	}, {
 		.compatible = "qcom,qcs615-qmp-usb3-phy",
 		.data = &qcm2290_usb3phy_cfg,

-- 
2.34.1



From xiangxu.yin at oss.qualcomm.com  Wed Aug 20 02:34:55 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Wed, 20 Aug 2025 17:34:55 +0800
Subject: [PATCH v3 13/14] drm/msm/dp: Add DisplayPort support for sm6150
In-Reply-To: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
Message-ID: <20250820-add-displayport-support-for-qcs615-platform-v3-13-a43bd25ec39c@oss.qualcomm.com>

Add support for SM6150 DisplayPort controller, which shares base offset
and configuration with SC7180. While SM6150 lacks some SC7180 features
(e.g. HBR3), current msm_dp_desc_sc7180 data is sufficient. Listing it
explicitly ensures future compatibility.

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
---
 drivers/gpu/drm/msm/dp/dp_display.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index d87d47cc7ec3eb757ac192c411000bc50b824c59..ddb22b50490035779904d4cab20e2fee7e0f9657 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -196,6 +196,7 @@ static const struct of_device_id msm_dp_dt_match[] = {
 	{ .compatible = "qcom,sc8280xp-dp", .data = &msm_dp_desc_sc8280xp },
 	{ .compatible = "qcom,sc8280xp-edp", .data = &msm_dp_desc_sc8280xp },
 	{ .compatible = "qcom,sdm845-dp", .data = &msm_dp_desc_sdm845 },
+	{ .compatible = "qcom,sm6150-dp", .data = &msm_dp_desc_sc7180 },
 	{ .compatible = "qcom,sm8350-dp", .data = &msm_dp_desc_sc7180 },
 	{ .compatible = "qcom,sm8650-dp", .data = &msm_dp_desc_sm8650 },
 	{ .compatible = "qcom,x1e80100-dp", .data = &msm_dp_desc_x1e80100 },

-- 
2.34.1



From xiangxu.yin at oss.qualcomm.com  Wed Aug 20 02:34:56 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Wed, 20 Aug 2025 17:34:56 +0800
Subject: [PATCH v3 14/14] drm/msm/dp: Add support for lane mapping
 configuration
In-Reply-To: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
Message-ID: <20250820-add-displayport-support-for-qcs615-platform-v3-14-a43bd25ec39c@oss.qualcomm.com>

Since max_dp_lanes and max_dp_link_rate are link-specific parameters,
move their parsing from dp_panel to dp_link for better separation
of concerns.

Add lane mapping configuration for the DisplayPort (DP) controller on
the QCS615 platform.

QCS615 platform requires non-default logical-to-physical lane mapping
due to its unique hardware routing. Unlike the standard mapping sequence
<0 1 2 3>, QCS615 uses <3 2 0 1>, which necessitates explicit
configuration via the data-lanes property in the device tree. This
ensures correct signal routing between the DP controller and PHY.

The DP PHY supports polarity inversion (PN swap) but does not support
lane swapping. Therefore, lane mapping should be handled in the DP
controller domain using REG_DP_LOGICAL2PHYSICAL_LANE_MAPPING.

Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
---
 drivers/gpu/drm/msm/dp/dp_ctrl.c  | 10 ++---
 drivers/gpu/drm/msm/dp/dp_link.c  | 71 +++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/msm/dp/dp_link.h  |  5 +++
 drivers/gpu/drm/msm/dp/dp_panel.c | 78 +++++----------------------------------
 drivers/gpu/drm/msm/dp/dp_panel.h |  3 --
 5 files changed, 90 insertions(+), 77 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c
index c42fd2c17a328f6deae211c9cd57cc7416a9365a..cbcc7c2f0ffc4696749b6c43818d20853ddec069 100644
--- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
+++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
@@ -423,13 +423,13 @@ static void msm_dp_ctrl_config_ctrl(struct msm_dp_ctrl_private *ctrl)
 
 static void msm_dp_ctrl_lane_mapping(struct msm_dp_ctrl_private *ctrl)
 {
-	u32 ln_0 = 0, ln_1 = 1, ln_2 = 2, ln_3 = 3; /* One-to-One mapping */
+	u32 *lane_map = ctrl->link->lane_map;
 	u32 ln_mapping;
 
-	ln_mapping = ln_0 << LANE0_MAPPING_SHIFT;
-	ln_mapping |= ln_1 << LANE1_MAPPING_SHIFT;
-	ln_mapping |= ln_2 << LANE2_MAPPING_SHIFT;
-	ln_mapping |= ln_3 << LANE3_MAPPING_SHIFT;
+	ln_mapping = lane_map[0] << LANE0_MAPPING_SHIFT;
+	ln_mapping |= lane_map[1] << LANE1_MAPPING_SHIFT;
+	ln_mapping |= lane_map[2] << LANE2_MAPPING_SHIFT;
+	ln_mapping |= lane_map[3] << LANE3_MAPPING_SHIFT;
 
 	msm_dp_write_link(ctrl, REG_DP_LOGICAL2PHYSICAL_LANE_MAPPING,
 			ln_mapping);
diff --git a/drivers/gpu/drm/msm/dp/dp_link.c b/drivers/gpu/drm/msm/dp/dp_link.c
index 66e1bbd80db3a28f5f16d083486752007ceaf3f7..7c7a4aa584eb42a0ca7c6ec45de585cde8639cb4 100644
--- a/drivers/gpu/drm/msm/dp/dp_link.c
+++ b/drivers/gpu/drm/msm/dp/dp_link.c
@@ -6,12 +6,14 @@
 #define pr_fmt(fmt)	"[drm-dp] %s: " fmt, __func__
 
 #include <drm/drm_device.h>
+#include <drm/drm_of.h>
 #include <drm/drm_print.h>
 
 #include "dp_reg.h"
 #include "dp_link.h"
 #include "dp_panel.h"
 
+#define DP_LINK_RATE_HBR2      540000 /* kbytes */
 #define DP_TEST_REQUEST_MASK		0x7F
 
 enum audio_sample_rate {
@@ -37,6 +39,7 @@ struct msm_dp_link_request {
 
 struct msm_dp_link_private {
 	u32 prev_sink_count;
+	struct device *dev;
 	struct drm_device *drm_dev;
 	struct drm_dp_aux *aux;
 	struct msm_dp_link msm_dp_link;
@@ -1210,10 +1213,73 @@ u32 msm_dp_link_get_test_bits_depth(struct msm_dp_link *msm_dp_link, u32 bpp)
 	return tbd;
 }
 
+static u32 msm_dp_link_link_frequencies(struct device_node *of_node)
+{
+	struct device_node *endpoint;
+	u64 frequency = 0;
+	int cnt;
+
+	endpoint = of_graph_get_endpoint_by_regs(of_node, 1, 0); /* port at 1 */
+	if (!endpoint)
+		return 0;
+
+	cnt = of_property_count_u64_elems(endpoint, "link-frequencies");
+
+	if (cnt > 0)
+		of_property_read_u64_index(endpoint, "link-frequencies",
+					   cnt - 1, &frequency);
+	of_node_put(endpoint);
+
+	do_div(frequency,
+	       10 * /* from symbol rate to link rate */
+	       1000); /* kbytes */
+
+	return frequency;
+}
+
+static int msm_dp_link_parse_dt(struct msm_dp_link *msm_dp_link)
+{
+	struct msm_dp_link_private *link;
+	struct device_node *of_node;
+	int cnt;
+	u32 lane_map[DP_MAX_NUM_DP_LANES] = {0};
+
+	link = container_of(msm_dp_link, struct msm_dp_link_private, msm_dp_link);
+	of_node = link->dev->of_node;
+
+	/*
+	 * data-lanes is the property of msm_dp_out endpoint
+	 */
+	cnt = drm_of_get_data_lanes_count_ep(of_node, 1, 0, 1, DP_MAX_NUM_DP_LANES);
+	if (cnt < 0) {
+		/* legacy code, data-lanes is the property of mdss_dp node */
+		cnt = drm_of_get_data_lanes_count(of_node, 1, DP_MAX_NUM_DP_LANES);
+	}
+
+	if (cnt > 0) {
+		struct device_node *endpoint;
+
+		msm_dp_link->max_dp_lanes = cnt;
+		endpoint = of_graph_get_endpoint_by_regs(of_node, 1, -1);
+		of_property_read_u32_array(endpoint, "data-lanes", lane_map, cnt);
+	} else {
+		msm_dp_link->max_dp_lanes = DP_MAX_NUM_DP_LANES; /* 4 lanes */
+	}
+
+	memcpy(msm_dp_link->lane_map, lane_map, msm_dp_link->max_dp_lanes * sizeof(u32));
+
+	msm_dp_link->max_dp_link_rate = msm_dp_link_link_frequencies(of_node);
+	if (!msm_dp_link->max_dp_link_rate)
+		msm_dp_link->max_dp_link_rate = DP_LINK_RATE_HBR2;
+
+	return 0;
+}
+
 struct msm_dp_link *msm_dp_link_get(struct device *dev, struct drm_dp_aux *aux)
 {
 	struct msm_dp_link_private *link;
 	struct msm_dp_link *msm_dp_link;
+	int ret;
 
 	if (!dev || !aux) {
 		DRM_ERROR("invalid input\n");
@@ -1225,9 +1291,14 @@ struct msm_dp_link *msm_dp_link_get(struct device *dev, struct drm_dp_aux *aux)
 		return ERR_PTR(-ENOMEM);
 
 	link->aux   = aux;
+	link->dev   = dev;
 
 	mutex_init(&link->psm_mutex);
 	msm_dp_link = &link->msm_dp_link;
 
+	ret = msm_dp_link_parse_dt(msm_dp_link);
+	if (ret)
+		return ERR_PTR(ret);
+
 	return msm_dp_link;
 }
diff --git a/drivers/gpu/drm/msm/dp/dp_link.h b/drivers/gpu/drm/msm/dp/dp_link.h
index ba47c6d19fbfacfc58031263e4a2f5a6d9c2c229..b1eb2de6d2a7693f17aa2f256657110af839533d 100644
--- a/drivers/gpu/drm/msm/dp/dp_link.h
+++ b/drivers/gpu/drm/msm/dp/dp_link.h
@@ -12,6 +12,7 @@
 #define DS_PORT_STATUS_CHANGED 0x200
 #define DP_TEST_BIT_DEPTH_UNKNOWN 0xFFFFFFFF
 #define DP_LINK_CAP_ENHANCED_FRAMING (1 << 0)
+#define DP_MAX_NUM_DP_LANES    4
 
 struct msm_dp_link_info {
 	unsigned char revision;
@@ -72,6 +73,10 @@ struct msm_dp_link {
 	struct msm_dp_link_test_audio test_audio;
 	struct msm_dp_link_phy_params phy_params;
 	struct msm_dp_link_info link_params;
+
+	u32 lane_map[DP_MAX_NUM_DP_LANES];
+	u32 max_dp_lanes;
+	u32 max_dp_link_rate;
 };
 
 /**
diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c b/drivers/gpu/drm/msm/dp/dp_panel.c
index 15b7f6c7146e1176a80b5c9d25896b1c8ede3aed..ad5d55bf009dbe60e61ca4f4c108116333129203 100644
--- a/drivers/gpu/drm/msm/dp/dp_panel.c
+++ b/drivers/gpu/drm/msm/dp/dp_panel.c
@@ -16,9 +16,6 @@
 
 #define DP_INTF_CONFIG_DATABUS_WIDEN     BIT(4)
 
-#define DP_MAX_NUM_DP_LANES	4
-#define DP_LINK_RATE_HBR2	540000 /* kbytes */
-
 struct msm_dp_panel_private {
 	struct device *dev;
 	struct drm_device *drm_dev;
@@ -91,6 +88,7 @@ static int msm_dp_panel_read_dpcd(struct msm_dp_panel *msm_dp_panel)
 	int rc, max_lttpr_lanes, max_lttpr_rate;
 	struct msm_dp_panel_private *panel;
 	struct msm_dp_link_info *link_info;
+	struct msm_dp_link *link;
 	u8 *dpcd, major, minor;
 
 	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
@@ -105,16 +103,20 @@ static int msm_dp_panel_read_dpcd(struct msm_dp_panel *msm_dp_panel)
 	major = (link_info->revision >> 4) & 0x0f;
 	minor = link_info->revision & 0x0f;
 
+	link = panel->link;
+	drm_dbg_dp(panel->drm_dev, "max_lanes=%d max_link_rate=%d\n",
+		   link->max_dp_lanes, link->max_dp_link_rate);
+
 	link_info->rate = drm_dp_max_link_rate(dpcd);
 	link_info->num_lanes = drm_dp_max_lane_count(dpcd);
 
 	/* Limit data lanes from data-lanes of endpoint property of dtsi */
-	if (link_info->num_lanes > msm_dp_panel->max_dp_lanes)
-		link_info->num_lanes = msm_dp_panel->max_dp_lanes;
+	if (link_info->num_lanes > link->max_dp_lanes)
+		link_info->num_lanes = link->max_dp_lanes;
 
 	/* Limit link rate from link-frequencies of endpoint property of dtsi */
-	if (link_info->rate > msm_dp_panel->max_dp_link_rate)
-		link_info->rate = msm_dp_panel->max_dp_link_rate;
+	if (link_info->rate > link->max_dp_link_rate)
+		link_info->rate = link->max_dp_link_rate;
 
 	/* Limit data lanes from LTTPR capabilities, if any */
 	max_lttpr_lanes = drm_dp_lttpr_max_lane_count(panel->link->lttpr_common_caps);
@@ -173,9 +175,6 @@ int msm_dp_panel_read_sink_caps(struct msm_dp_panel *msm_dp_panel,
 
 	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
 
-	drm_dbg_dp(panel->drm_dev, "max_lanes=%d max_link_rate=%d\n",
-		msm_dp_panel->max_dp_lanes, msm_dp_panel->max_dp_link_rate);
-
 	rc = msm_dp_panel_read_dpcd(msm_dp_panel);
 	if (rc) {
 		DRM_ERROR("read dpcd failed %d\n", rc);
@@ -648,60 +647,6 @@ int msm_dp_panel_init_panel_info(struct msm_dp_panel *msm_dp_panel)
 	return 0;
 }
 
-static u32 msm_dp_panel_link_frequencies(struct device_node *of_node)
-{
-	struct device_node *endpoint;
-	u64 frequency = 0;
-	int cnt;
-
-	endpoint = of_graph_get_endpoint_by_regs(of_node, 1, 0); /* port at 1 */
-	if (!endpoint)
-		return 0;
-
-	cnt = of_property_count_u64_elems(endpoint, "link-frequencies");
-
-	if (cnt > 0)
-		of_property_read_u64_index(endpoint, "link-frequencies",
-						cnt - 1, &frequency);
-	of_node_put(endpoint);
-
-	do_div(frequency,
-		10 * /* from symbol rate to link rate */
-		1000); /* kbytes */
-
-	return frequency;
-}
-
-static int msm_dp_panel_parse_dt(struct msm_dp_panel *msm_dp_panel)
-{
-	struct msm_dp_panel_private *panel;
-	struct device_node *of_node;
-	int cnt;
-
-	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
-	of_node = panel->dev->of_node;
-
-	/*
-	 * data-lanes is the property of msm_dp_out endpoint
-	 */
-	cnt = drm_of_get_data_lanes_count_ep(of_node, 1, 0, 1, DP_MAX_NUM_DP_LANES);
-	if (cnt < 0) {
-		/* legacy code, data-lanes is the property of mdss_dp node */
-		cnt = drm_of_get_data_lanes_count(of_node, 1, DP_MAX_NUM_DP_LANES);
-	}
-
-	if (cnt > 0)
-		msm_dp_panel->max_dp_lanes = cnt;
-	else
-		msm_dp_panel->max_dp_lanes = DP_MAX_NUM_DP_LANES; /* 4 lanes */
-
-	msm_dp_panel->max_dp_link_rate = msm_dp_panel_link_frequencies(of_node);
-	if (!msm_dp_panel->max_dp_link_rate)
-		msm_dp_panel->max_dp_link_rate = DP_LINK_RATE_HBR2;
-
-	return 0;
-}
-
 struct msm_dp_panel *msm_dp_panel_get(struct device *dev, struct drm_dp_aux *aux,
 			      struct msm_dp_link *link,
 			      void __iomem *link_base,
@@ -709,7 +654,6 @@ struct msm_dp_panel *msm_dp_panel_get(struct device *dev, struct drm_dp_aux *aux
 {
 	struct msm_dp_panel_private *panel;
 	struct msm_dp_panel *msm_dp_panel;
-	int ret;
 
 	if (!dev || !aux || !link) {
 		DRM_ERROR("invalid input\n");
@@ -729,10 +673,6 @@ struct msm_dp_panel *msm_dp_panel_get(struct device *dev, struct drm_dp_aux *aux
 	msm_dp_panel = &panel->msm_dp_panel;
 	msm_dp_panel->max_bw_code = DP_LINK_BW_8_1;
 
-	ret = msm_dp_panel_parse_dt(msm_dp_panel);
-	if (ret)
-		return ERR_PTR(ret);
-
 	return msm_dp_panel;
 }
 
diff --git a/drivers/gpu/drm/msm/dp/dp_panel.h b/drivers/gpu/drm/msm/dp/dp_panel.h
index d2cf401506dcbaf553192d5e18c87207337664ab..921a296852d4df65f817665d3e1344f2f7c9ece7 100644
--- a/drivers/gpu/drm/msm/dp/dp_panel.h
+++ b/drivers/gpu/drm/msm/dp/dp_panel.h
@@ -41,9 +41,6 @@ struct msm_dp_panel {
 	bool vsc_sdp_supported;
 	u32 hw_revision;
 
-	u32 max_dp_lanes;
-	u32 max_dp_link_rate;
-
 	u32 max_bw_code;
 };
 

-- 
2.34.1



From claudiu.beznea at tuxon.dev  Wed Aug 20 02:40:52 2025
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Wed, 20 Aug 2025 12:40:52 +0300
Subject: [PATCH v5 1/7] dt-bindings: phy: renesas,usb2-phy: Mark resets as
 required for RZ/G3S
In-Reply-To: <20250819133744.GA87211-robh@kernel.org>
References: <20250819054212.486426-1-claudiu.beznea.uj@bp.renesas.com>
 <20250819054212.486426-2-claudiu.beznea.uj@bp.renesas.com>
 <175558495459.3265640.2032619822487575179.robh@kernel.org>
 <20250819133744.GA87211-robh@kernel.org>
Message-ID: <31361b5c-32de-4618-bb89-f550f03b47d1@tuxon.dev>

Hi, Rob,

On 8/19/25 16:37, Rob Herring wrote:
> On Tue, Aug 19, 2025 at 01:29:17AM -0500, Rob Herring (Arm) wrote:
>>
>> On Tue, 19 Aug 2025 08:42:06 +0300, Claudiu wrote:
>>> From: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
>>>
>>> The reset lines are mandatory for the Renesas RZ/G3S platform and must be
>>> explicitly defined in device tree.
>>>
>>> Fixes: f3c849855114 ("dt-bindings: phy: renesas,usb2-phy: Document RZ/G3S phy bindings")
>>> Reviewed-by: Geert Uytterhoeven <geert+renesas at glider.be>
>>> Acked-by: Conor Dooley <conor.dooley at microchip.com>
>>> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
>>> ---
>>>
>>> Changes in v5:
>>> - none
>>>
>>> Changes in v4:
>>> - none
>>>
>>> Changes in v3:
>>> - collected tags
>>> - rebased on top of latest version of renesas,usb2-phy.yaml;
>>>    Conor, Geert: I kept your tags; please let me know if you consider it
>>>    otherwise
>>>
>>> Changes in v2:
>>> - none; this patch is new
>>>
>>>   Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml | 1 +
>>>   1 file changed, 1 insertion(+)
>>>
>>
>> My bot found errors running 'make dt_binding_check' on your patch:
>>
>> yamllint warnings/errors:
>>
>> dtschema/dtc warnings/errors:
>>
>>
>> doc reference errors (make refcheckdocs):
>>
>> See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20250819054212.486426-2-claudiu.beznea.uj at bp.renesas.com
> 
> No issue here. The QCom folks have broken "make dt_binding_check" in
> linux-next...

Is patch 3/7 in this series still good? I can't find any issue with it locally.

Thank you,
Claudiu


From dmitry.baryshkov at oss.qualcomm.com  Wed Aug 20 03:09:35 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Wed, 20 Aug 2025 13:09:35 +0300
Subject: [PATCH v3 02/14] dt-bindings: phy: Add QMP USB3+DP PHY for QCS615
In-Reply-To: <20250820-add-displayport-support-for-qcs615-platform-v3-2-a43bd25ec39c@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-2-a43bd25ec39c@oss.qualcomm.com>
Message-ID: <3lodaz4t72vsxnstfe2msooo3dnwbqy6hxzdshcmyrgb3fbjnv@2afo5atezt24>

On Wed, Aug 20, 2025 at 05:34:44PM +0800, Xiangxu Yin wrote:
> Add device tree binding documentation for the Qualcomm QMP USB3+DP PHY
> on QCS615 Platform. This PHY supports both USB3 and DP functionality
> over USB-C, with PHY mode switching capability. It does not support
> combo mode.
> 
> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
> ---
>  .../bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml   | 108 +++++++++++++++++++++
>  1 file changed, 108 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml
> new file mode 100644
> index 0000000000000000000000000000000000000000..c2b1fbab2930f0653f4ddb95f7b54d8fe994f92d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml
> @@ -0,0 +1,108 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/phy/qcom,qcs615-qmp-usb3dp-phy.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Qualcomm QMP USB3-DP PHY controller (DP, QCS615)
> +
> +maintainers:
> +  - Vinod Koul <vkoul at kernel.org>
> +
> +description:
> +  The QMP PHY controller supports physical layer functionality for both
> +  USB3 and DisplayPort over USB-C. While it enables mode switching
> +  between USB3 and DisplayPort, but does not support combo mode.
> +
> +properties:
> +  compatible:
> +    enum:
> +      - qcom,qcs615-qmp-usb3-dp-phy
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 2
> +
> +  clock-names:
> +    items:
> +      - const: cfg_ahb
> +      - const: ref
> +
> +  resets:
> +    maxItems: 2
> +
> +  reset-names:
> +    items:
> +      - const: phy_phy
> +      - const: dp_phy
> +
> +  vdda-phy-supply: true
> +
> +  vdda-pll-supply: true
> +
> +  "#clock-cells":
> +    const: 1
> +    description:
> +      See include/dt-bindings/phy/phy-qcom-qmp.h
> +
> +  "#phy-cells":
> +    const: 1
> +    description:
> +      See include/dt-bindings/phy/phy-qcom-qmp.h
> +
> +  qcom,tcsr-reg:
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    items:
> +      - items:
> +          - description: phandle to TCSR hardware block
> +          - description: offset of the VLS CLAMP register
> +      - items:
> +          - description: phandle to TCSR hardware block

Why do we need two phandles?

> +          - description: offset of the DP PHY mode register

s/DP PHY/PHY/

> +    description: Clamp and PHY mode register present in the TCSR
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - clock-names
> +  - resets
> +  - reset-names
> +  - vdda-phy-supply
> +  - vdda-pll-supply
> +  - "#clock-cells"
> +  - "#phy-cells"
> +  - qcom,tcsr-reg
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/qcom,qcs615-gcc.h>
> +    #include <dt-bindings/clock/qcom,rpmh.h>
> +
> +    phy at 88e8000 {
> +      compatible = "qcom,qcs615-qmp-usb3-dp-phy";
> +      reg = <0x88e8000 0x2000>;
> +
> +      clocks = <&gcc GCC_AHB2PHY_WEST_CLK>,
> +               <&gcc GCC_USB3_SEC_CLKREF_CLK>;
> +      clock-names = "cfg_ahb",
> +                    "ref";
> +
> +      resets = <&gcc GCC_USB3PHY_PHY_SEC_BCR >,
> +               <&gcc GCC_USB3_DP_PHY_SEC_BCR>;
> +      reset-names = "phy_phy",
> +                    "dp_phy";
> +
> +      vdda-phy-supply = <&vreg_l11a>;
> +      vdda-pll-supply = <&vreg_l5a>;
> +
> +      #clock-cells = <1>;
> +      #phy-cells = <1>;
> +
> +      qcom,tcsr-reg = <&tcsr 0xbff0>,
> +                      <&tcsr 0xb24c>;
> +    };
> 
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry


From dmitry.baryshkov at oss.qualcomm.com  Wed Aug 20 03:18:23 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Wed, 20 Aug 2025 13:18:23 +0300
Subject: [PATCH v3 01/14] dt-bindings: display/msm: dp-controller: Add
 sm6150
In-Reply-To: <20250820-add-displayport-support-for-qcs615-platform-v3-1-a43bd25ec39c@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-1-a43bd25ec39c@oss.qualcomm.com>
Message-ID: <75ra2ofecqu6tid6kr4hnyuztpl6jjaq2ksyquafyajhq2sa4d@4tkggrdqky7y>

On Wed, Aug 20, 2025 at 05:34:43PM +0800, Xiangxu Yin wrote:
> Add DisplayPort controller for Qualcomm SM6150 SoC.
> While SM6150 currently shares the same configuration as SC7180,
> its hardware capabilities differ. Explicitly listing it ensures clarity
> and avoids potential issues if SC7180 support evolves in the future.

I assume, it has no MST support. Am I right?

> 
> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.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 9923b065323bbab99de5079b674a0317f3074373..996d0132e084d401db85014a1a4e445d00d62ed8 100644
> --- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
> +++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
> @@ -27,6 +27,7 @@ properties:
>            - qcom,sc8280xp-dp
>            - qcom,sc8280xp-edp
>            - qcom,sdm845-dp
> +          - qcom,sm6150-dp
>            - qcom,sm8350-dp
>            - qcom,sm8650-dp
>        - items:
> 
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry


From dmitry.baryshkov at oss.qualcomm.com  Wed Aug 20 04:16:37 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Wed, 20 Aug 2025 14:16:37 +0300
Subject: [PATCH v3 08/14] phy: qcom: qmp-usbc: Add DP PHY configuration
 support for QCS615
In-Reply-To: <20250820-add-displayport-support-for-qcs615-platform-v3-8-a43bd25ec39c@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-8-a43bd25ec39c@oss.qualcomm.com>
Message-ID: <su3zkeepxaislh6q5ftqxp6uxsyg7usxmc5hkafw7yn2mgtqeu@wua72odmy7zp>

On Wed, Aug 20, 2025 at 05:34:50PM +0800, Xiangxu Yin wrote:
> Introduce DisplayPort PHY configuration routines for QCS615, including
> aux channel setup, lane control, voltage swing tuning, clock
> programming and calibration. These callbacks are registered via
> qmp_phy_cfg to enable DP mode on USB/DP switchable Type-C PHYs.
> 
> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-dp-phy.h |   1 +
>  drivers/phy/qualcomm/phy-qcom-qmp-usbc.c   | 251 +++++++++++++++++++++++++++++
>  2 files changed, 252 insertions(+)
> 
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy.h b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy.h
> index 0ebd405bcaf0cac8215550bfc9b226f30cc43a59..59885616405f878885d0837838a0bac1899fb69f 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy.h
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy.h
> @@ -25,6 +25,7 @@
>  #define QSERDES_DP_PHY_AUX_CFG7				0x03c
>  #define QSERDES_DP_PHY_AUX_CFG8				0x040
>  #define QSERDES_DP_PHY_AUX_CFG9				0x044
> +#define QSERDES_DP_PHY_VCO_DIV				0x068

This register changes between PHY versions, so you can not declare it here.

Otherwise LGTM.

>  
>  /* QSERDES COM_BIAS_EN_CLKBUFLR_EN bits */
>  # define QSERDES_V3_COM_BIAS_EN				0x0001

-- 
With best wishes
Dmitry


From dmitry.baryshkov at oss.qualcomm.com  Wed Aug 20 04:24:00 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Wed, 20 Aug 2025 14:24:00 +0300
Subject: [PATCH v3 10/14] phy: qcom: qmp-usbc: Add TCSR parsing and
 USB/DP mode mutex handling
In-Reply-To: <20250820-add-displayport-support-for-qcs615-platform-v3-10-a43bd25ec39c@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-10-a43bd25ec39c@oss.qualcomm.com>
Message-ID: <i4rc5siu4q2o4sjk3j4bex7b7qdrs26y6lxsfnike7e7kqdva3@xddrd7vowtlb>

On Wed, Aug 20, 2025 at 05:34:52PM +0800, Xiangxu Yin wrote:
> Parse TCSR registers to support DP mode signaling via dp_phy_mode_reg.
> Introduce mutual exclusion between USB and DP PHY modes to prevent
> simultaneous activation. Also update com_init/com_exit to reflect DP
> mode initialization and cleanup.
> 
> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 60 +++++++++++++++++++++++++-------
>  1 file changed, 47 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> index a1495a2029cf038bb65c36e42d0a4f633e544558..821398653bef23e1915d9d3a3a2950b0bfbefb9a 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> @@ -674,7 +674,7 @@ static const struct qmp_phy_cfg qcs615_usb3dp_phy_cfg = {
>  	.num_vregs		= ARRAY_SIZE(qmp_phy_usbdp_vreg_l),
>  };
>  
> -static int qmp_usbc_com_init(struct phy *phy)
> +static int qmp_usbc_com_init(struct phy *phy, bool is_dp)
>  {
>  	struct qmp_usbc *qmp = phy_get_drvdata(phy);
>  	const struct qmp_phy_cfg *cfg = qmp->cfg;
> @@ -704,15 +704,20 @@ static int qmp_usbc_com_init(struct phy *phy)
>  	if (ret)
>  		goto err_assert_reset;
>  
> -	qphy_setbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], SW_PWRDN);
> +	if (!is_dp) {
> +		qphy_setbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], SW_PWRDN);

Why? Don't we need to program those bits for DP PHY too?

If not, move them to USB init call.

>  
>  #define SW_PORTSELECT_VAL			BIT(0)
>  #define SW_PORTSELECT_MUX			BIT(1)
> -	/* Use software based port select and switch on typec orientation */
> -	val = SW_PORTSELECT_MUX;
> -	if (qmp->orientation == TYPEC_ORIENTATION_REVERSE)
> -		val |= SW_PORTSELECT_VAL;
> -	writel(val, qmp->pcs_misc);
> +		/* Use software based port select and switch on typec orientation */
> +		val = SW_PORTSELECT_MUX;
> +		if (qmp->orientation == TYPEC_ORIENTATION_REVERSE)
> +			val |= SW_PORTSELECT_VAL;
> +		writel(val, qmp->pcs_misc);
> +	}
> +
> +	if (qmp->tcsr_map && qmp->dp_phy_mode_reg)
> +		regmap_write(qmp->tcsr_map, qmp->dp_phy_mode_reg, is_dp);

Write this reg directly from USB / DP init.

>  
>  	return 0;
>  
> @@ -733,6 +738,9 @@ static int qmp_usbc_com_exit(struct phy *phy)
>  
>  	clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks);
>  
> +	if (qmp->tcsr_map && qmp->dp_phy_mode_reg)
> +		regmap_write(qmp->tcsr_map, qmp->dp_phy_mode_reg, 0);

Why?

> +
>  	regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
>  
>  	return 0;
> @@ -1045,6 +1053,17 @@ static int qmp_usbc_usb_power_off(struct phy *phy)
>  	return 0;
>  }
>  
> +static int qmp_check_mutex_phy(struct qmp_usbc *qmp, bool is_dp)
> +{
> +	if ((is_dp && qmp->usb_init_count) ||
> +	    (!is_dp && qmp->dp_init_count)) {
> +		dev_err(qmp->dev, "%s PHY busy\n", is_dp ? "USB" : "DP");

"PHY is configured for %s, can not enable %s\n"

> +		return -EBUSY;
> +	}
> +
> +	return 0;
> +}
> +
>  static int qmp_usbc_usb_enable(struct phy *phy)
>  {
>  	struct qmp_usbc *qmp = phy_get_drvdata(phy);
> @@ -1052,7 +1071,11 @@ static int qmp_usbc_usb_enable(struct phy *phy)
>  
>  	mutex_lock(&qmp->phy_mutex);
>  
> -	ret = qmp_usbc_com_init(phy);
> +	ret = qmp_check_mutex_phy(qmp, false);
> +	if (ret)
> +		goto out_unlock;
> +
> +	ret = qmp_usbc_com_init(phy, false);
>  	if (ret)
>  		goto out_unlock;
>  
> @@ -1103,7 +1126,11 @@ static int qmp_usbc_dp_enable(struct phy *phy)
>  
>  	mutex_lock(&qmp->phy_mutex);
>  
> -	ret = qmp_usbc_com_init(phy);
> +	ret = qmp_check_mutex_phy(qmp, true);
> +	if (ret)
> +		goto dp_init_unlock;
> +
> +	ret = qmp_usbc_com_init(phy, true);
>  	if (ret)
>  		goto dp_init_unlock;
>  
> @@ -1467,7 +1494,7 @@ static int qmp_usbc_typec_switch_set(struct typec_switch_dev *sw,
>  		qmp_usbc_usb_power_off(qmp->usb_phy);
>  		qmp_usbc_com_exit(qmp->usb_phy);
>  
> -		qmp_usbc_com_init(qmp->usb_phy);
> +		qmp_usbc_com_init(qmp->usb_phy, false);
>  		qmp_usbc_usb_power_on(qmp->usb_phy);
>  	}
>  
> @@ -1602,13 +1629,13 @@ static int qmp_usbc_parse_usb_dt(struct qmp_usbc *qmp)
>  	return 0;
>  }
>  
> -static int qmp_usbc_parse_vls_clamp(struct qmp_usbc *qmp)
> +static int qmp_usbc_parse_tcsr(struct qmp_usbc *qmp)
>  {
>  	struct of_phandle_args tcsr_args;
>  	struct device *dev = qmp->dev;
>  	int ret;
>  
> -	/*  for backwards compatibility ignore if there is no property */
> +	/*  for backwards compatibility ignore if there is 1 or no property */
>  	ret = of_parse_phandle_with_fixed_args(dev->of_node, "qcom,tcsr-reg", 1, 0,
>  					       &tcsr_args);
>  	if (ret == -ENOENT)
> @@ -1623,6 +1650,13 @@ static int qmp_usbc_parse_vls_clamp(struct qmp_usbc *qmp)
>  
>  	qmp->vls_clamp_reg = tcsr_args.args[0];
>  
> +	ret = of_parse_phandle_with_fixed_args(dev->of_node, "qcom,tcsr-reg", 1, 1,
> +					       &tcsr_args);
> +	if (ret == -ENOENT)
> +		return 0;
> +
> +	qmp->dp_phy_mode_reg = tcsr_args.args[0];
> +
>  	return 0;
>  }
>  
> @@ -1665,7 +1699,7 @@ static int qmp_usbc_probe(struct platform_device *pdev)
>  	if (ret)
>  		return ret;
>  
> -	ret = qmp_usbc_parse_vls_clamp(qmp);
> +	ret = qmp_usbc_parse_tcsr(qmp);
>  	if (ret)
>  		return ret;
>  
> 
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry


From dmitry.baryshkov at oss.qualcomm.com  Wed Aug 20 04:25:19 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Wed, 20 Aug 2025 14:25:19 +0300
Subject: [PATCH v3 06/14] phy: qcom: qmp-usbc: Add QCS615 DP PHY
 configuration and init data
In-Reply-To: <20250820-add-displayport-support-for-qcs615-platform-v3-6-a43bd25ec39c@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-6-a43bd25ec39c@oss.qualcomm.com>
Message-ID: <bx3cumx7ej7taour6zhqufrzjdxuhvlx23ga3vmvokrlekayem@e5rfjbcwle2r>

On Wed, Aug 20, 2025 at 05:34:48PM +0800, Xiangxu Yin wrote:
> Introduce QCS615 hardware-specific configuration for DP PHY mode,
> including register offsets, initialization tables, voltage swing
> and pre-emphasis settings.

This will trigger unused warnings. Please squash this into the patch
adding compat string to the driver.

> 
> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 139 +++++++++++++++++++++++++++++++
>  1 file changed, 139 insertions(+)
> 
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> index 6b0e86ec43ded3d850f68f248a74c39f74ecb5bb..61128d606238321d1b573655b3b987226aa2d594 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> @@ -284,6 +284,86 @@ static const struct qmp_phy_init_tbl qcm2290_usb3_pcs_tbl[] = {
>  	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x88),
>  };
>  
> +static const struct qmp_phy_init_tbl qcs615_qmp_dp_serdes_tbl[] = {
> +	QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x37),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x00),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x3f),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x0e),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_BG_CTRL, 0x0f),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_BUF_ENABLE, 0x06),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x40),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x08),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x05),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x00),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x00),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x0f),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x02),
> +};
> +
> +static const struct qmp_phy_init_tbl qcs615_qmp_dp_serdes_tbl_rbr[] = {
> +	QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x2c),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x69),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x80),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x07),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xbf),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x21),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0xc6),
> +};
> +
> +static const struct qmp_phy_init_tbl qcs615_qmp_dp_serdes_tbl_hbr[] = {
> +	QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x24),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x69),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x80),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x07),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x3f),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x38),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0xc4),
> +};
> +
> +static const struct qmp_phy_init_tbl qcs615_qmp_dp_serdes_tbl_hbr2[] = {
> +	QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x20),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x8c),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x0a),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x7f),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x70),
> +	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0xc4),
> +};
> +
> +static const struct qmp_phy_init_tbl qcs615_qmp_dp_tx_tbl[] = {
> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_TRANSCEIVER_BIAS_EN, 0x1a),
> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_VMODE_CTRL1, 0x40),
> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_PRE_STALL_LDO_BOOST_EN, 0x30),
> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_INTERFACE_SELECT, 0x3d),
> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_CLKBUF_ENABLE, 0x0f),
> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RESET_TSYNC_EN, 0x03),
> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_TRAN_DRVR_EMP_EN, 0x03),
> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_PARRATE_REC_DETECT_IDLE_EN, 0x00),
> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_INTERFACE_MODE, 0x00),
> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_EMP_POST1_LVL, 0x2b),
> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_DRV_LVL, 0x2f),
> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_BAND, 0x4),
> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x12),
> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x12),
> +};
> +
>  enum qmp_phy_usbc_type {
>  	QMP_PHY_USBC_USB3_ONLY,
>  	QMP_PHY_USBC_USB3_DP,
> @@ -449,6 +529,34 @@ static const struct qmp_usbc_offsets qmp_usbc_offsets_v3_qcm2290 = {
>  	.rx2		= 0x800,
>  };
>  
> +static const struct qmp_usbc_offsets qmp_usbc_usb3dp_offsets_qcs615 = {
> +	.serdes		= 0x0,
> +	.pcs		= 0xc00,
> +	.pcs_misc	= 0xa00,
> +	.tx		= 0x200,
> +	.rx		= 0x400,
> +	.tx2		= 0x600,
> +	.rx2		= 0x800,
> +	.dp_serdes	= 0x1c00,
> +	.dp_txa		= 0x1400,
> +	.dp_txb		= 0x1800,
> +	.dp_dp_phy	= 0x1000,
> +};
> +
> +static const u8 qmp_dp_pre_emphasis_hbr2_rbr[4][4] = {
> +	{0x00, 0x0b, 0x12, 0xff},
> +	{0x00, 0x0a, 0x12, 0xff},
> +	{0x00, 0x0c, 0xff, 0xff},
> +	{0xff, 0xff, 0xff, 0xff}
> +};
> +
> +static const u8 qmp_dp_voltage_swing_hbr2_rbr[4][4] = {
> +	{0x07, 0x0f, 0x14, 0xff},
> +	{0x11, 0x1d, 0x1f, 0xff},
> +	{0x18, 0x1f, 0xff, 0xff},
> +	{0xff, 0xff, 0xff, 0xff}
> +};
> +
>  static const struct qmp_phy_cfg msm8998_usb3phy_cfg = {
>  	.offsets		= &qmp_usbc_offsets_v3_qcm2290,
>  	.type			= QMP_PHY_USBC_USB3_ONLY,
> @@ -500,6 +608,37 @@ static const struct qmp_phy_cfg sdm660_usb3phy_cfg = {
>  	.regs			= qmp_v3_usb3phy_regs_layout_qcm2290,
>  };
>  
> +static const struct qmp_phy_cfg qcs615_usb3dp_phy_cfg = {
> +	.offsets		= &qmp_usbc_usb3dp_offsets_qcs615,
> +	.type			= QMP_PHY_USBC_USB3_DP,
> +
> +	.serdes_tbl		= qcm2290_usb3_serdes_tbl,
> +	.serdes_tbl_num		= ARRAY_SIZE(qcm2290_usb3_serdes_tbl),
> +	.tx_tbl			= qcm2290_usb3_tx_tbl,
> +	.tx_tbl_num		= ARRAY_SIZE(qcm2290_usb3_tx_tbl),
> +	.rx_tbl			= qcm2290_usb3_rx_tbl,
> +	.rx_tbl_num		= ARRAY_SIZE(qcm2290_usb3_rx_tbl),
> +	.pcs_tbl		= qcm2290_usb3_pcs_tbl,
> +	.pcs_tbl_num		= ARRAY_SIZE(qcm2290_usb3_pcs_tbl),
> +
> +	.regs			= qmp_v3_usb3phy_regs_layout_qcm2290,
> +
> +	.dp_serdes_tbl		= qcs615_qmp_dp_serdes_tbl,
> +	.dp_serdes_tbl_num	= ARRAY_SIZE(qcs615_qmp_dp_serdes_tbl),
> +	.dp_tx_tbl		= qcs615_qmp_dp_tx_tbl,
> +	.dp_tx_tbl_num		= ARRAY_SIZE(qcs615_qmp_dp_tx_tbl),
> +
> +	.serdes_tbl_rbr		= qcs615_qmp_dp_serdes_tbl_rbr,
> +	.serdes_tbl_rbr_num	= ARRAY_SIZE(qcs615_qmp_dp_serdes_tbl_rbr),
> +	.serdes_tbl_hbr		= qcs615_qmp_dp_serdes_tbl_hbr,
> +	.serdes_tbl_hbr_num	= ARRAY_SIZE(qcs615_qmp_dp_serdes_tbl_hbr),
> +	.serdes_tbl_hbr2	= qcs615_qmp_dp_serdes_tbl_hbr2,
> +	.serdes_tbl_hbr2_num	= ARRAY_SIZE(qcs615_qmp_dp_serdes_tbl_hbr2),
> +
> +	.swing_tbl		= &qmp_dp_voltage_swing_hbr2_rbr,
> +	.pre_emphasis_tbl	= &qmp_dp_pre_emphasis_hbr2_rbr,
> +};
> +
>  static int qmp_usbc_com_init(struct phy *phy)
>  {
>  	struct qmp_usbc *qmp = phy_get_drvdata(phy);
> 
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry


From dmitry.baryshkov at oss.qualcomm.com  Wed Aug 20 04:30:40 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Wed, 20 Aug 2025 14:30:40 +0300
Subject: [PATCH v3 07/14] phy: qcom: qmp-usbc: Move reset and regulator
 config into PHY cfg
In-Reply-To: <20250820-add-displayport-support-for-qcs615-platform-v3-7-a43bd25ec39c@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-7-a43bd25ec39c@oss.qualcomm.com>
Message-ID: <ofvzduf5xyip7w6yde2xwsrvv3tdh7ew3yyzeya2qzpqty3j7p@bnetyjowhdn5>

On Wed, Aug 20, 2025 at 05:34:49PM +0800, Xiangxu Yin wrote:
> Refactor reset and regulator configuration to be managed via qmp_phy_cfg
> instead of hardcoded lists. This enables per-PHY customization and
> simplifies initialization logic for USB-only and USB/DP switchable PHYs.

Please split into two patches in order to simplify reviewing.

> 
> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 108 +++++++++++++++----------------
>  1 file changed, 53 insertions(+), 55 deletions(-)
> 
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> index 61128d606238321d1b573655b3b987226aa2d594..4e797b7e65da0e3a827efa9a179f1c150c1b8b00 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> @@ -421,8 +421,9 @@ struct qmp_phy_cfg {
>  	int (*configure_dp_phy)(struct qmp_usbc *qmp);
>  	int (*calibrate_dp_phy)(struct qmp_usbc *qmp);
>  
> -	/* regulators to be requested */
> -	const char * const *vreg_list;
> +	const char * const *reset_list;
> +	int num_resets;
> +	const struct regulator_bulk_data *vreg_list;
>  	int num_vregs;
>  
>  	/* array of registers with different offsets */
> @@ -453,7 +454,6 @@ struct qmp_usbc {
>  	struct clk_hw dp_pixel_hw;
>  	struct clk_bulk_data *clks;
>  	int num_clks;
> -	int num_resets;
>  	struct reset_control_bulk_data *resets;
>  	struct regulator_bulk_data *vregs;
>  
> @@ -514,9 +514,18 @@ static const char * const usb3phy_reset_l[] = {
>  	"phy_phy", "phy",
>  };
>  
> -/* list of regulators */
> -static const char * const qmp_phy_vreg_l[] = {
> -	"vdda-phy", "vdda-pll",
> +static const char * const usb3dpphy_reset_l[] = {
> +	"phy_phy", "dp_phy",
> +};
> +
> +static const struct regulator_bulk_data qmp_phy_usb_vreg_l[] = {
> +	{ .supply = "vdda-phy" },
> +	{ .supply = "vdda-pll" },

Please fill in the values for all platforms. It well might be that they
all share the same current requirements.

> +};
> +
> +static const struct regulator_bulk_data qmp_phy_usbdp_vreg_l[] = {
> +	{ .supply = "vdda-phy", .init_load_uA = 21800 },
> +	{ .supply = "vdda-phy", .init_load_uA = 36000 },

Typo

>  };
>  
>  static const struct qmp_usbc_offsets qmp_usbc_offsets_v3_qcm2290 = {
> @@ -569,8 +578,10 @@ static const struct qmp_phy_cfg msm8998_usb3phy_cfg = {
>  	.rx_tbl_num             = ARRAY_SIZE(msm8998_usb3_rx_tbl),
>  	.pcs_tbl                = msm8998_usb3_pcs_tbl,
>  	.pcs_tbl_num            = ARRAY_SIZE(msm8998_usb3_pcs_tbl),
> -	.vreg_list              = qmp_phy_vreg_l,
> -	.num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
> +	.reset_list		= usb3phy_reset_l,
> +	.num_resets		= ARRAY_SIZE(usb3phy_reset_l),
> +	.vreg_list              = qmp_phy_usb_vreg_l,
> +	.num_vregs              = ARRAY_SIZE(qmp_phy_usb_vreg_l),
>  	.regs                   = qmp_v3_usb3phy_regs_layout,
>  };
>  
> @@ -586,8 +597,10 @@ static const struct qmp_phy_cfg qcm2290_usb3phy_cfg = {
>  	.rx_tbl_num		= ARRAY_SIZE(qcm2290_usb3_rx_tbl),
>  	.pcs_tbl		= qcm2290_usb3_pcs_tbl,
>  	.pcs_tbl_num		= ARRAY_SIZE(qcm2290_usb3_pcs_tbl),
> -	.vreg_list		= qmp_phy_vreg_l,
> -	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
> +	.reset_list		= usb3phy_reset_l,
> +	.num_resets		= ARRAY_SIZE(usb3phy_reset_l),
> +	.vreg_list		= qmp_phy_usb_vreg_l,
> +	.num_vregs		= ARRAY_SIZE(qmp_phy_usb_vreg_l),
>  	.regs			= qmp_v3_usb3phy_regs_layout_qcm2290,
>  };
>  
> @@ -603,8 +616,10 @@ static const struct qmp_phy_cfg sdm660_usb3phy_cfg = {
>  	.rx_tbl_num		= ARRAY_SIZE(sdm660_usb3_rx_tbl),
>  	.pcs_tbl		= qcm2290_usb3_pcs_tbl,
>  	.pcs_tbl_num		= ARRAY_SIZE(qcm2290_usb3_pcs_tbl),
> -	.vreg_list		= qmp_phy_vreg_l,
> -	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
> +	.reset_list		= usb3phy_reset_l,
> +	.num_resets		= ARRAY_SIZE(usb3phy_reset_l),
> +	.vreg_list		= qmp_phy_usb_vreg_l,
> +	.num_vregs		= ARRAY_SIZE(qmp_phy_usb_vreg_l),
>  	.regs			= qmp_v3_usb3phy_regs_layout_qcm2290,
>  };
>  
> @@ -637,6 +652,11 @@ static const struct qmp_phy_cfg qcs615_usb3dp_phy_cfg = {
>  
>  	.swing_tbl		= &qmp_dp_voltage_swing_hbr2_rbr,
>  	.pre_emphasis_tbl	= &qmp_dp_pre_emphasis_hbr2_rbr,
> +
> +	.reset_list		= usb3dpphy_reset_l,
> +	.num_resets		= ARRAY_SIZE(usb3dpphy_reset_l),
> +	.vreg_list		= qmp_phy_usbdp_vreg_l,
> +	.num_vregs		= ARRAY_SIZE(qmp_phy_usbdp_vreg_l),
>  };
>  
>  static int qmp_usbc_com_init(struct phy *phy)
> @@ -653,13 +673,13 @@ static int qmp_usbc_com_init(struct phy *phy)
>  		return ret;
>  	}
>  
> -	ret = reset_control_bulk_assert(qmp->num_resets, qmp->resets);
> +	ret = reset_control_bulk_assert(cfg->num_resets, qmp->resets);
>  	if (ret) {
>  		dev_err(qmp->dev, "reset assert failed\n");
>  		goto err_disable_regulators;
>  	}
>  
> -	ret = reset_control_bulk_deassert(qmp->num_resets, qmp->resets);
> +	ret = reset_control_bulk_deassert(cfg->num_resets, qmp->resets);
>  	if (ret) {
>  		dev_err(qmp->dev, "reset deassert failed\n");
>  		goto err_disable_regulators;
> @@ -682,7 +702,7 @@ static int qmp_usbc_com_init(struct phy *phy)
>  	return 0;
>  
>  err_assert_reset:
> -	reset_control_bulk_assert(qmp->num_resets, qmp->resets);
> +	reset_control_bulk_assert(cfg->num_resets, qmp->resets);
>  err_disable_regulators:
>  	regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
>  
> @@ -694,7 +714,7 @@ static int qmp_usbc_com_exit(struct phy *phy)
>  	struct qmp_usbc *qmp = phy_get_drvdata(phy);
>  	const struct qmp_phy_cfg *cfg = qmp->cfg;
>  
> -	reset_control_bulk_assert(qmp->num_resets, qmp->resets);
> +	reset_control_bulk_assert(cfg->num_resets, qmp->resets);
>  
>  	clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks);
>  
> @@ -921,42 +941,22 @@ static const struct dev_pm_ops qmp_usbc_pm_ops = {
>  			   qmp_usbc_runtime_resume, NULL)
>  };
>  
> -static int qmp_usbc_vreg_init(struct qmp_usbc *qmp)
> +static int qmp_usbc_reset_init(struct qmp_usbc *qmp)
>  {
>  	const struct qmp_phy_cfg *cfg = qmp->cfg;
> -	struct device *dev = qmp->dev;
> -	int num = cfg->num_vregs;
> -	int i;
> -
> -	qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL);
> -	if (!qmp->vregs)
> -		return -ENOMEM;
> -
> -	for (i = 0; i < num; i++)
> -		qmp->vregs[i].supply = cfg->vreg_list[i];
> -
> -	return devm_regulator_bulk_get(dev, num, qmp->vregs);
> -}
> -
> -static int qmp_usbc_reset_init(struct qmp_usbc *qmp,
> -			      const char *const *reset_list,
> -			      int num_resets)
> -{
>  	struct device *dev = qmp->dev;
>  	int i;
>  	int ret;
>  
> -	qmp->resets = devm_kcalloc(dev, num_resets,
> +	qmp->resets = devm_kcalloc(dev, cfg->num_resets,
>  				   sizeof(*qmp->resets), GFP_KERNEL);
>  	if (!qmp->resets)
>  		return -ENOMEM;
>  
> -	for (i = 0; i < num_resets; i++)
> -		qmp->resets[i].id = reset_list[i];
> +	for (i = 0; i < cfg->num_resets; i++)
> +		qmp->resets[i].id = cfg->reset_list[i];
>  
> -	qmp->num_resets = num_resets;
> -
> -	ret = devm_reset_control_bulk_get_exclusive(dev, num_resets, qmp->resets);
> +	ret = devm_reset_control_bulk_get_exclusive(dev, cfg->num_resets, qmp->resets);
>  	if (ret)
>  		return dev_err_probe(dev, ret, "failed to get resets\n");
>  
> @@ -1146,11 +1146,6 @@ static int qmp_usbc_parse_usb_dt_legacy(struct qmp_usbc *qmp, struct device_node
>  
>  	qmp->num_clks = ret;
>  
> -	ret = qmp_usbc_reset_init(qmp, usb3phy_legacy_reset_l,
> -				 ARRAY_SIZE(usb3phy_legacy_reset_l));
> -	if (ret)
> -		return ret;
> -
>  	return 0;
>  }
>  
> @@ -1187,14 +1182,9 @@ static int qmp_usbc_parse_usb_dt(struct qmp_usbc *qmp)
>  	qmp->pipe_clk = devm_clk_get(dev, "pipe");
>  	if (IS_ERR(qmp->pipe_clk)) {
>  		return dev_err_probe(dev, PTR_ERR(qmp->pipe_clk),
> -				     "failed to get pipe clock\n");
> +					"failed to get pipe clock\n");

unrelated

>  	}
>  
> -	ret = qmp_usbc_reset_init(qmp, usb3phy_reset_l,
> -				 ARRAY_SIZE(usb3phy_reset_l));
> -	if (ret)
> -		return ret;
> -
>  	return 0;
>  }
>  
> @@ -1228,6 +1218,7 @@ static int qmp_usbc_probe(struct platform_device *pdev)
>  	struct phy_provider *phy_provider;
>  	struct device_node *np;
>  	struct qmp_usbc *qmp;
> +	const struct qmp_phy_cfg *cfg;
>  	int ret;
>  
>  	qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL);
> @@ -1239,13 +1230,20 @@ static int qmp_usbc_probe(struct platform_device *pdev)
>  
>  	qmp->orientation = TYPEC_ORIENTATION_NORMAL;
>  
> -	qmp->cfg = of_device_get_match_data(dev);
> -	if (!qmp->cfg)
> +	cfg = of_device_get_match_data(dev);
> +	if (!cfg)
>  		return -EINVAL;
>  
> +	qmp->cfg = cfg;

Why? This doesn't seem related at all.

> +
>  	mutex_init(&qmp->phy_mutex);
>  
> -	ret = qmp_usbc_vreg_init(qmp);
> +	ret = qmp_usbc_reset_init(qmp);
> +	if (ret)
> +		return ret;
> +
> +	ret = devm_regulator_bulk_get_const(qmp->dev, cfg->num_vregs,
> +					 cfg->vreg_list, &qmp->vregs);
>  	if (ret)
>  		return ret;
>  
> 
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry


From dmitry.baryshkov at oss.qualcomm.com  Wed Aug 20 04:34:03 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Wed, 20 Aug 2025 14:34:03 +0300
Subject: [PATCH v3 04/14] phy: qcom: qmp-usbc: Add USBC PHY type enum
In-Reply-To: <20250820-add-displayport-support-for-qcs615-platform-v3-4-a43bd25ec39c@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-4-a43bd25ec39c@oss.qualcomm.com>
Message-ID: <cueyo7huj2m2yt46sjk3atfktft6y5slhhtslwmi44r7h7lxbn@5zvwxtdmk34t>

On Wed, Aug 20, 2025 at 05:34:46PM +0800, Xiangxu Yin wrote:
> Introduce qmp_phy_usbc_type enum and a 'type' field in qmp_phy_cfg to
> differentiate between USB-only PHYs and USB/DP switchable PHYs.
> 
> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> index e484caec2be20121cfe287c507b17af28fb9f211..5afe090b546977a11265bbffa7c355feb8c72dfa 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> @@ -284,6 +284,11 @@ static const struct qmp_phy_init_tbl qcm2290_usb3_pcs_tbl[] = {
>  	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x88),
>  };
>  
> +enum qmp_phy_usbc_type {
> +	QMP_PHY_USBC_USB3_ONLY,
> +	QMP_PHY_USBC_USB3_DP,

Drop, you can use presense of DP offsets in order to differentiate
between USB3 and USB3+DP.

> +};
> +
>  struct qmp_usbc_offsets {
>  	u16 serdes;
>  	u16 pcs;

-- 
With best wishes
Dmitry


From dmitry.baryshkov at oss.qualcomm.com  Wed Aug 20 04:37:00 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Wed, 20 Aug 2025 14:37:00 +0300
Subject: [PATCH v3 02/14] dt-bindings: phy: Add QMP USB3+DP PHY for QCS615
In-Reply-To: <20250820-add-displayport-support-for-qcs615-platform-v3-2-a43bd25ec39c@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-2-a43bd25ec39c@oss.qualcomm.com>
Message-ID: <tlilctwavwqw6oy46l5fote2pa6f4hdy2im6meo56cjaawba3a@a42bwbbfnsuw>

On Wed, Aug 20, 2025 at 05:34:44PM +0800, Xiangxu Yin wrote:
> Add device tree binding documentation for the Qualcomm QMP USB3+DP PHY
> on QCS615 Platform. This PHY supports both USB3 and DP functionality
> over USB-C, with PHY mode switching capability. It does not support
> combo mode.
> 
> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
> ---
>  .../bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml   | 108 +++++++++++++++++++++
>  1 file changed, 108 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml
> new file mode 100644
> index 0000000000000000000000000000000000000000..c2b1fbab2930f0653f4ddb95f7b54d8fe994f92d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml
> @@ -0,0 +1,108 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/phy/qcom,qcs615-qmp-usb3dp-phy.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Qualcomm QMP USB3-DP PHY controller (DP, QCS615)
> +
> +maintainers:
> +  - Vinod Koul <vkoul at kernel.org>
> +
> +description:
> +  The QMP PHY controller supports physical layer functionality for both
> +  USB3 and DisplayPort over USB-C. While it enables mode switching
> +  between USB3 and DisplayPort, but does not support combo mode.
> +
> +properties:
> +  compatible:
> +    enum:
> +      - qcom,qcs615-qmp-usb3-dp-phy
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 2

Missing GCC_USB2_SEC_PHY_AUX_CLK and GCC_USB2_SEC_PHY_PIPE_CLK

> +
> +  clock-names:
> +    items:
> +      - const: cfg_ahb
> +      - const: ref
> +
> +  resets:
> +    maxItems: 2
> +
> +  reset-names:
> +    items:
> +      - const: phy_phy
> +      - const: dp_phy
> +
> +  vdda-phy-supply: true
> +
> +  vdda-pll-supply: true
> +
> +  "#clock-cells":
> +    const: 1
> +    description:
> +      See include/dt-bindings/phy/phy-qcom-qmp.h
> +
> +  "#phy-cells":
> +    const: 1
> +    description:
> +      See include/dt-bindings/phy/phy-qcom-qmp.h
> +
> +  qcom,tcsr-reg:
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    items:
> +      - items:
> +          - description: phandle to TCSR hardware block
> +          - description: offset of the VLS CLAMP register
> +      - items:
> +          - description: phandle to TCSR hardware block
> +          - description: offset of the DP PHY mode register
> +    description: Clamp and PHY mode register present in the TCSR
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - clock-names
> +  - resets
> +  - reset-names
> +  - vdda-phy-supply
> +  - vdda-pll-supply
> +  - "#clock-cells"
> +  - "#phy-cells"
> +  - qcom,tcsr-reg
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/qcom,qcs615-gcc.h>
> +    #include <dt-bindings/clock/qcom,rpmh.h>
> +
> +    phy at 88e8000 {
> +      compatible = "qcom,qcs615-qmp-usb3-dp-phy";
> +      reg = <0x88e8000 0x2000>;
> +
> +      clocks = <&gcc GCC_AHB2PHY_WEST_CLK>,
> +               <&gcc GCC_USB3_SEC_CLKREF_CLK>;
> +      clock-names = "cfg_ahb",
> +                    "ref";
> +
> +      resets = <&gcc GCC_USB3PHY_PHY_SEC_BCR >,
> +               <&gcc GCC_USB3_DP_PHY_SEC_BCR>;
> +      reset-names = "phy_phy",
> +                    "dp_phy";
> +
> +      vdda-phy-supply = <&vreg_l11a>;
> +      vdda-pll-supply = <&vreg_l5a>;
> +
> +      #clock-cells = <1>;
> +      #phy-cells = <1>;
> +
> +      qcom,tcsr-reg = <&tcsr 0xbff0>,
> +                      <&tcsr 0xb24c>;
> +    };
> 
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry


From dmitry.baryshkov at oss.qualcomm.com  Wed Aug 20 04:42:31 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Wed, 20 Aug 2025 14:42:31 +0300
Subject: [PATCH v3 11/14] phy: qcom: qmp-usbc: Finalize USB/DP switchable
 PHY support
In-Reply-To: <20250820-add-displayport-support-for-qcs615-platform-v3-11-a43bd25ec39c@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-11-a43bd25ec39c@oss.qualcomm.com>
Message-ID: <jjsijdmh4hdbgd2boebtrmzvblvhz2hnl7mtv5ga76ine2fnsb@i72dz3r4lbjp>

On Wed, Aug 20, 2025 at 05:34:53PM +0800, Xiangxu Yin wrote:
> Complete USB/DP switchable PHY integration by adding DP clock
> registration, aux bridge setup, and DT parsing. Implement clock
> provider logic for USB and DP branches, and extend PHY translation
> to support both USB and DP instances.
> 
> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 331 ++++++++++++++++++++++++++++---
>  1 file changed, 299 insertions(+), 32 deletions(-)
> 
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> index 821398653bef23e1915d9d3a3a2950b0bfbefb9a..74b9f75c8864efe270f394bfbfd748793dada1f5 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> @@ -995,6 +995,11 @@ static int qmp_usbc_usb_power_on(struct phy *phy)
>  	qmp_configure(qmp->dev, qmp->serdes, cfg->serdes_tbl,
>  		      cfg->serdes_tbl_num);
>  
> +	if (IS_ERR(qmp->pipe_clk)) {
> +		return dev_err_probe(qmp->dev, PTR_ERR(qmp->pipe_clk),
> +				     "pipe clock not defined\n");
> +	}

No, this should not be allowed.

> +
>  	ret = clk_prepare_enable(qmp->pipe_clk);
>  	if (ret) {
>  		dev_err(qmp->dev, "pipe_clk enable failed err=%d\n", ret);
> @@ -1365,11 +1370,13 @@ static int __maybe_unused qmp_usbc_runtime_resume(struct device *dev)
>  	if (ret)
>  		return ret;
>  
> -	ret = clk_prepare_enable(qmp->pipe_clk);
> -	if (ret) {
> -		dev_err(dev, "pipe_clk enable failed, err=%d\n", ret);
> -		clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks);
> -		return ret;
> +	if (!IS_ERR(qmp->pipe_clk)) {

Similarly.

> +		ret = clk_prepare_enable(qmp->pipe_clk);
> +		if (ret) {
> +			dev_err(dev, "pipe_clk enable failed, err=%d\n", ret);
> +			clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks);
> +			return ret;
> +		}
>  	}
>  
>  	qmp_usbc_disable_autonomous_mode(qmp);
> @@ -1422,9 +1429,23 @@ static int qmp_usbc_clk_init(struct qmp_usbc *qmp)
>  	return devm_clk_bulk_get_optional(dev, num, qmp->clks);
>  }
>  
> -static void phy_clk_release_provider(void *res)
> +static struct clk_hw *qmp_usbc_clks_hw_get(struct of_phandle_args *clkspec, void *data)
>  {
> -	of_clk_del_provider(res);
> +	struct qmp_usbc *qmp = data;
> +
> +	if (clkspec->args_count == 0)
> +		return &qmp->pipe_clk_fixed.hw;
> +
> +	switch (clkspec->args[0]) {
> +	case QMP_USB43DP_USB3_PIPE_CLK:
> +		return &qmp->pipe_clk_fixed.hw;
> +	case QMP_USB43DP_DP_LINK_CLK:
> +		return &qmp->dp_link_hw;
> +	case QMP_USB43DP_DP_VCO_DIV_CLK:
> +		return &qmp->dp_pixel_hw;
> +	}
> +
> +	return ERR_PTR(-EINVAL);
>  }
>  
>  /*
> @@ -1453,8 +1474,11 @@ static int phy_pipe_clk_register(struct qmp_usbc *qmp, struct device_node *np)
>  
>  	ret = of_property_read_string(np, "clock-output-names", &init.name);
>  	if (ret) {
> -		dev_err(qmp->dev, "%pOFn: No clock-output-names\n", np);
> -		return ret;
> +		char name[64];
> +
> +		/* Clock name is not mandatory. */
> +		snprintf(name, sizeof(name), "%s::pipe_clk", dev_name(qmp->dev));
> +		init.name = name;
>  	}
>  
>  	init.ops = &clk_fixed_rate_ops;
> @@ -1463,19 +1487,7 @@ static int phy_pipe_clk_register(struct qmp_usbc *qmp, struct device_node *np)
>  	fixed->fixed_rate = 125000000;
>  	fixed->hw.init = &init;
>  
> -	ret = devm_clk_hw_register(qmp->dev, &fixed->hw);
> -	if (ret)
> -		return ret;
> -
> -	ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &fixed->hw);
> -	if (ret)
> -		return ret;
> -
> -	/*
> -	 * Roll a devm action because the clock provider is the child node, but
> -	 * the child node is not actually a device.
> -	 */
> -	return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
> +	return devm_clk_hw_register(qmp->dev, &fixed->hw);
>  }
>  
>  #if IS_ENABLED(CONFIG_TYPEC)
> @@ -1660,6 +1672,235 @@ static int qmp_usbc_parse_tcsr(struct qmp_usbc *qmp)
>  	return 0;
>  }
>  
> +static int qmp_usbc_parse_usb3dp_dt(struct qmp_usbc *qmp)
> +{
> +	struct platform_device *pdev = to_platform_device(qmp->dev);
> +	const struct qmp_phy_cfg *cfg = qmp->cfg;
> +	const struct qmp_usbc_offsets *offs = cfg->offsets;
> +	struct device *dev = qmp->dev;
> +	void __iomem *base;
> +	int ret;
> +
> +	base = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(base))
> +		return PTR_ERR(base);
> +
> +	qmp->dp_serdes = base + offs->dp_serdes;
> +	qmp->dp_tx = base + offs->dp_txa;
> +	qmp->dp_tx2 = base + offs->dp_txb;
> +	qmp->dp_dp_phy = base + offs->dp_dp_phy;

Squash this into qmp_usbc_parse_dt(). Set these fields if
dp_serdes != 0.

> +	qmp->serdes = base + offs->serdes;
> +	qmp->pcs = base + offs->pcs;
> +	if (offs->pcs_misc)
> +		qmp->pcs_misc = base + offs->pcs_misc;
> +	qmp->tx = base + offs->tx;
> +	qmp->rx = base + offs->rx;
> +
> +	qmp->tx2 = base + offs->tx2;
> +	qmp->rx2 = base + offs->rx2;
> +
> +	ret = qmp_usbc_clk_init(qmp);
> +	if (ret)
> +		return ret;
> +
> +	qmp->pipe_clk = devm_clk_get(dev, "pipe");
> +	if (IS_ERR(qmp->pipe_clk)) {
> +		/* usb3dp allow no pipe clk define */
> +		if (cfg->type == QMP_PHY_USBC_USB3_ONLY)
> +			return dev_err_probe(dev, PTR_ERR(qmp->pipe_clk),
> +						"failed to get pipe clock\n");
> +	}
> +
> +	return 0;
> +}
> +
> +/*
> + * Display Port PLL driver block diagram for branch clocks
> + *
> + *              +------------------------------+
> + *              |         DP_VCO_CLK           |
> + *              |                              |
> + *              |    +-------------------+     |
> + *              |    |   (DP PLL/VCO)    |     |
> + *              |    +---------+---------+     |
> + *              |              v               |
> + *              |   +----------+-----------+   |
> + *              |   | hsclk_divsel_clk_src |   |
> + *              |   +----------+-----------+   |
> + *              +------------------------------+
> + *                              |
> + *          +---------<---------v------------>----------+
> + *          |                                           |
> + * +--------v----------------+                          |
> + * |    dp_phy_pll_link_clk  |                          |
> + * |     link_clk            |                          |
> + * +--------+----------------+                          |
> + *          |                                           |
> + *          |                                           |
> + *          v                                           v
> + * Input to DISPCC block                                |
> + * for link clk, crypto clk                             |
> + * and interface clock                                  |
> + *                                                      |
> + *                                                      |
> + *      +--------<------------+-----------------+---<---+
> + *      |                     |                 |
> + * +----v---------+  +--------v-----+  +--------v------+
> + * | vco_divided  |  | vco_divided  |  | vco_divided   |
> + * |    _clk_src  |  |    _clk_src  |  |    _clk_src   |
> + * |              |  |              |  |               |
> + * |divsel_six    |  |  divsel_two  |  |  divsel_four  |
> + * +-------+------+  +-----+--------+  +--------+------+
> + *         |                 |                  |
> + *         v---->----------v-------------<------v
> + *                         |
> + *              +----------+-----------------+
> + *              |   dp_phy_pll_vco_div_clk   |
> + *              +---------+------------------+
> + *                        |
> + *                        v
> + *              Input to DISPCC block
> + *              for DP pixel clock
> + *
> + */
> +static int qmp_dp_pixel_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
> +{
> +	switch (req->rate) {
> +	case 1620000000UL / 2:
> +	case 2700000000UL / 2:
> +	/* 5.4 and 8.1 GHz are same link rate as 2.7GHz, i.e. div 4 and div 6 */
> +		return 0;
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
> +static unsigned long qmp_dp_pixel_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
> +{
> +	const struct qmp_usbc *qmp;
> +	const struct phy_configure_opts_dp *dp_opts;
> +
> +	qmp = container_of(hw, struct qmp_usbc, dp_pixel_hw);
> +
> +	dp_opts = &qmp->dp_opts;
> +
> +	switch (dp_opts->link_rate) {
> +	case 1620:
> +		return 1620000000UL / 2;
> +	case 2700:
> +		return 2700000000UL / 2;
> +	case 5400:
> +		return 5400000000UL / 4;
> +	default:
> +		return 0;
> +	}
> +}
> +
> +static const struct clk_ops qmp_dp_pixel_clk_ops = {
> +	.determine_rate	= qmp_dp_pixel_clk_determine_rate,
> +	.recalc_rate	= qmp_dp_pixel_clk_recalc_rate,
> +};
> +
> +static int qmp_dp_link_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
> +{
> +	switch (req->rate) {
> +	case 162000000:
> +	case 270000000:
> +	case 540000000:
> +		return 0;
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
> +static unsigned long qmp_dp_link_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
> +{
> +	const struct qmp_usbc *qmp;
> +	const struct phy_configure_opts_dp *dp_opts;
> +
> +	qmp = container_of(hw, struct qmp_usbc, dp_link_hw);
> +	dp_opts = &qmp->dp_opts;
> +
> +	switch (dp_opts->link_rate) {
> +	case 1620:
> +	case 2700:
> +	case 5400:
> +		return dp_opts->link_rate * 100000;
> +	default:
> +		return 0;
> +	}
> +}
> +
> +static const struct clk_ops qmp_dp_link_clk_ops = {
> +	.determine_rate	= qmp_dp_link_clk_determine_rate,
> +	.recalc_rate	= qmp_dp_link_clk_recalc_rate,
> +};
> +
> +static int phy_dp_clks_register(struct qmp_usbc *qmp, struct device_node *np)
> +{
> +	struct clk_init_data init = { };
> +	char name[64];
> +	int ret;
> +
> +	snprintf(name, sizeof(name), "%s::link_clk", dev_name(qmp->dev));
> +	init.ops = &qmp_dp_link_clk_ops;
> +	init.name = name;
> +	qmp->dp_link_hw.init = &init;
> +	ret = devm_clk_hw_register(qmp->dev, &qmp->dp_link_hw);
> +	if (ret < 0) {
> +		dev_err(qmp->dev, "link clk reg fail ret=%d\n", ret);
> +		return ret;
> +	}
> +
> +	snprintf(name, sizeof(name), "%s::vco_div_clk", dev_name(qmp->dev));
> +	init.ops = &qmp_dp_pixel_clk_ops;
> +	init.name = name;
> +	qmp->dp_pixel_hw.init = &init;
> +	ret = devm_clk_hw_register(qmp->dev, &qmp->dp_pixel_hw);
> +	if (ret) {
> +		dev_err(qmp->dev, "pxl clk reg fail ret=%d\n", ret);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int qmp_usbc_register_clocks(struct qmp_usbc *qmp, struct device_node *np)
> +{
> +	int ret;
> +
> +	if (!IS_ERR(qmp->pipe_clk)) {
> +		ret = phy_pipe_clk_register(qmp, np);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	if (qmp->cfg->type == QMP_PHY_USBC_USB3_DP) {

if dp_serdes != 0

> +		ret = phy_dp_clks_register(qmp, np);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return devm_of_clk_add_hw_provider(qmp->dev, qmp_usbc_clks_hw_get, qmp);
> +}
> +
> +static struct phy *qmp_usbc_phy_xlate(struct device *dev, const struct of_phandle_args *args)
> +{
> +	struct qmp_usbc *qmp = dev_get_drvdata(dev);
> +
> +	if (args->args_count == 0)
> +		return qmp->usb_phy;
> +
> +	switch (args->args[0]) {
> +	case QMP_USB43DP_USB3_PHY:
> +		return qmp->usb_phy;
> +	case QMP_USB43DP_DP_PHY:
> +		return qmp->dp_phy;
> +	}
> +
> +	return ERR_PTR(-EINVAL);
> +}
> +
>  static int qmp_usbc_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> @@ -1703,16 +1944,32 @@ static int qmp_usbc_probe(struct platform_device *pdev)
>  	if (ret)
>  		return ret;
>  
> -	/* Check for legacy binding with child node. */
> -	np = of_get_child_by_name(dev->of_node, "phy");
> -	if (np) {
> -		ret = qmp_usbc_parse_usb_dt_legacy(qmp, np);
> -	} else {
> +	if (qmp->cfg->type == QMP_PHY_USBC_USB3_DP) {

Should not be necessary.

>  		np = of_node_get(dev->of_node);
> -		ret = qmp_usbc_parse_usb_dt(qmp);
> +
> +		ret = qmp_usbc_parse_usb3dp_dt(qmp);
> +		if (ret) {
> +			dev_err(qmp->dev, "parse DP dt fail ret=%d\n", ret);
> +			goto err_node_put;
> +		}
> +
> +		ret = drm_aux_bridge_register(dev);
> +		if (ret) {
> +			dev_err(qmp->dev, "aux bridge reg fail ret=%d\n", ret);
> +			goto err_node_put;
> +		}
> +	} else {
> +		/* Check for legacy binding with child node. */
> +		np = of_get_child_by_name(dev->of_node, "phy");
> +		if (np) {
> +			ret = qmp_usbc_parse_usb_dt_legacy(qmp, np);
> +		} else {
> +			np = of_node_get(dev->of_node);
> +			ret = qmp_usbc_parse_usb_dt(qmp);
> +		}
> +		if (ret)
> +			goto err_node_put;
>  	}
> -	if (ret)
> -		goto err_node_put;
>  
>  	pm_runtime_set_active(dev);
>  	ret = devm_pm_runtime_enable(dev);
> @@ -1724,7 +1981,7 @@ static int qmp_usbc_probe(struct platform_device *pdev)
>  	 */
>  	pm_runtime_forbid(dev);
>  
> -	ret = phy_pipe_clk_register(qmp, np);
> +	ret = qmp_usbc_register_clocks(qmp, np);
>  	if (ret)
>  		goto err_node_put;
>  
> @@ -1737,9 +1994,19 @@ static int qmp_usbc_probe(struct platform_device *pdev)
>  
>  	phy_set_drvdata(qmp->usb_phy, qmp);
>  
> +	if (qmp->cfg->type == QMP_PHY_USBC_USB3_DP) {

if dp_serdes != 0

> +		qmp->dp_phy = devm_phy_create(dev, np, &qmp_usbc_dp_phy_ops);
> +		if (IS_ERR(qmp->dp_phy)) {
> +			ret = PTR_ERR(qmp->dp_phy);
> +			dev_err(dev, "failed to create PHY: %d\n", ret);
> +			goto err_node_put;
> +		}
> +		phy_set_drvdata(qmp->dp_phy, qmp);
> +	}
> +
>  	of_node_put(np);
>  
> -	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> +	phy_provider = devm_of_phy_provider_register(dev, qmp_usbc_phy_xlate);
>  
>  	return PTR_ERR_OR_ZERO(phy_provider);
>  
> 
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry


From dmitry.baryshkov at oss.qualcomm.com  Wed Aug 20 04:45:56 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Wed, 20 Aug 2025 14:45:56 +0300
Subject: [PATCH v3 09/14] phy: qcom: qmp-usbc: Add DP PHY ops for USB/DP
 switchable Type-C PHYs
In-Reply-To: <20250820-add-displayport-support-for-qcs615-platform-v3-9-a43bd25ec39c@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-9-a43bd25ec39c@oss.qualcomm.com>
Message-ID: <3pr7ninjxr4pgsz56dr6ojjmx27fzzszmtt6mx4r6qaqt25tnc@nrgx5qiqc7z4>

On Wed, Aug 20, 2025 at 05:34:51PM +0800, Xiangxu Yin wrote:
> Define qmp_usbc_dp_phy_ops struct to support DP mode on USB/DP
> switchable PHYs.
> 
> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 163 +++++++++++++++++++++++++++++++
>  1 file changed, 163 insertions(+)
> 
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> index 1508a4a5f57aff85318485b79528325f28a825a4..a1495a2029cf038bb65c36e42d0a4f633e544558 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> @@ -22,6 +22,8 @@
>  #include <linux/slab.h>
>  #include <linux/usb/typec.h>
>  #include <linux/usb/typec_mux.h>
> +#include <dt-bindings/phy/phy-qcom-qmp.h>
> +#include <drm/bridge/aux-bridge.h>

This one is not necessary yet

>  
>  #include "phy-qcom-qmp-common.h"
>  

[...]

>  static const struct phy_ops qmp_usbc_usb_phy_ops = {
>  	.init		= qmp_usbc_usb_enable,
>  	.exit		= qmp_usbc_usb_disable,
> @@ -1095,6 +1248,16 @@ static const struct phy_ops qmp_usbc_usb_phy_ops = {
>  	.owner		= THIS_MODULE,
>  };
>  
> +static const struct phy_ops qmp_usbc_dp_phy_ops = {

Please try restructuring your patches so that there are no unused
warnings in the middle of the series. You can split the next patch into
'parse' and 'enable' parts, then squash this patch into the 'enable'
one.

> +	.init		= qmp_usbc_dp_enable,
> +	.exit		= qmp_usbc_dp_disable,
> +	.configure	= qmp_usbc_dp_configure,
> +	.calibrate	= qmp_usbc_dp_calibrate,
> +	.power_on	= qmp_usbc_dp_power_on,
> +	.power_off	= qmp_usbc_dp_power_off,
> +	.owner		= THIS_MODULE,
> +};
> +
>  static void qmp_usbc_enable_autonomous_mode(struct qmp_usbc *qmp)
>  {
>  	const struct qmp_phy_cfg *cfg = qmp->cfg;
> 
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry


From dmitry.baryshkov at oss.qualcomm.com  Wed Aug 20 04:46:21 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Wed, 20 Aug 2025 14:46:21 +0300
Subject: [PATCH v3 03/14] phy: qcom: qmp-usbc: Rename USB-specific ops to
 prepare for DP support
In-Reply-To: <20250820-add-displayport-support-for-qcs615-platform-v3-3-a43bd25ec39c@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-3-a43bd25ec39c@oss.qualcomm.com>
Message-ID: <ay4ss7cwpiz6zwiwiav4ts5hwhxjpc6ogc2uirwzfcyhi2crln@3azxsu5hvyhy>

On Wed, Aug 20, 2025 at 05:34:45PM +0800, Xiangxu Yin wrote:
> To support following DisplayPort (DP) mode over the Type-C PHY, rename
> USB-specific functions and ops to clearly separate them from common or
> DP-related logic.
> 
> This is a preparatory cleanup to enable USB + DP dual mode.
> 
> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 50 ++++++++++++++++----------------
>  1 file changed, 25 insertions(+), 25 deletions(-)
> 

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>


-- 
With best wishes
Dmitry


From dmitry.baryshkov at oss.qualcomm.com  Wed Aug 20 04:47:24 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Wed, 20 Aug 2025 14:47:24 +0300
Subject: [PATCH v3 05/14] phy: qcom: qmp-usbc: Add DP-related fields for
 USB/DP switchable PHY
In-Reply-To: <20250820-add-displayport-support-for-qcs615-platform-v3-5-a43bd25ec39c@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-5-a43bd25ec39c@oss.qualcomm.com>
Message-ID: <7b6utbnibia767bp55vhvg6ghdavb66ubdpabyguohuwtmz3mp@unvm36jttota>

On Wed, Aug 20, 2025 at 05:34:47PM +0800, Xiangxu Yin wrote:
> Extend qmp_usbc_offsets and qmp_phy_cfg with DP-specific fields,
> including register offsets, init tables, and callback hooks. Also
> update qmp_usbc struct to track DP-related resources and state.
> This enables support for USB/DP switchable Type-C PHYs that operate
> in either mode.
> 
> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 73 ++++++++++++++++++++++++--------
>  1 file changed, 55 insertions(+), 18 deletions(-)
> 
>  
> +	struct regmap *tcsr_map;
> +	u32 vls_clamp_reg;
> +	u32 dp_phy_mode_reg;
> +
>  	struct mutex phy_mutex;
>  
> +	struct phy *usb_phy;

Should be a part of the previous patch.

>  	enum phy_mode mode;
>  	unsigned int usb_init_count;
>  
> -	struct phy *phy;

Similarly.

> -
> -	struct clk_fixed_rate pipe_clk_fixed;
> +	struct phy *dp_phy;
> +	unsigned int dp_aux_cfg;
> +	struct phy_configure_opts_dp dp_opts;
> +	unsigned int dp_init_count;
>  
>  	struct typec_switch_dev *sw;
>  	enum typec_orientation orientation;
> @@ -874,11 +911,11 @@ static int qmp_usbc_typec_switch_set(struct typec_switch_dev *sw,
>  	qmp->orientation = orientation;
>  
>  	if (qmp->usb_init_count) {
> -		qmp_usbc_usb_power_off(qmp->phy);
> -		qmp_usbc_com_exit(qmp->phy);
> +		qmp_usbc_usb_power_off(qmp->usb_phy);
> +		qmp_usbc_com_exit(qmp->usb_phy);
>  
> -		qmp_usbc_com_init(qmp->phy);
> -		qmp_usbc_usb_power_on(qmp->phy);
> +		qmp_usbc_com_init(qmp->usb_phy);
> +		qmp_usbc_usb_power_on(qmp->usb_phy);

and these.

>  	}
>  
>  	mutex_unlock(&qmp->phy_mutex);
> @@ -1106,14 +1143,14 @@ static int qmp_usbc_probe(struct platform_device *pdev)
>  	if (ret)
>  		goto err_node_put;
>  
> -	qmp->phy = devm_phy_create(dev, np, &qmp_usbc_usb_phy_ops);
> -	if (IS_ERR(qmp->phy)) {
> -		ret = PTR_ERR(qmp->phy);
> +	qmp->usb_phy = devm_phy_create(dev, np, &qmp_usbc_usb_phy_ops);
> +	if (IS_ERR(qmp->usb_phy)) {
> +		ret = PTR_ERR(qmp->usb_phy);
>  		dev_err(dev, "failed to create PHY: %d\n", ret);
>  		goto err_node_put;
>  	}
>  
> -	phy_set_drvdata(qmp->phy, qmp);
> +	phy_set_drvdata(qmp->usb_phy, qmp);
>  
>  	of_node_put(np);
>  
> 
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry


From dmitry.baryshkov at oss.qualcomm.com  Wed Aug 20 04:49:33 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Wed, 20 Aug 2025 14:49:33 +0300
Subject: [PATCH v3 14/14] drm/msm/dp: Add support for lane mapping
 configuration
In-Reply-To: <20250820-add-displayport-support-for-qcs615-platform-v3-14-a43bd25ec39c@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-14-a43bd25ec39c@oss.qualcomm.com>
Message-ID: <wwn24kjpwexl66hd3wufa53lkqojb2bkpdogtxwr3uqotjpf3u@hclfgsv64ajn>

On Wed, Aug 20, 2025 at 05:34:56PM +0800, Xiangxu Yin wrote:
> Since max_dp_lanes and max_dp_link_rate are link-specific parameters,
> move their parsing from dp_panel to dp_link for better separation
> of concerns.
>
> Add lane mapping configuration for the DisplayPort (DP) controller on
> the QCS615 platform.

Separate patch

> 
> QCS615 platform requires non-default logical-to-physical lane mapping
> due to its unique hardware routing. Unlike the standard mapping sequence
> <0 1 2 3>, QCS615 uses <3 2 0 1>, which necessitates explicit
> configuration via the data-lanes property in the device tree. This
> ensures correct signal routing between the DP controller and PHY.
> 
> The DP PHY supports polarity inversion (PN swap) but does not support
> lane swapping. Therefore, lane mapping should be handled in the DP
> controller domain using REG_DP_LOGICAL2PHYSICAL_LANE_MAPPING.
> 
> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
> ---
>  drivers/gpu/drm/msm/dp/dp_ctrl.c  | 10 ++---
>  drivers/gpu/drm/msm/dp/dp_link.c  | 71 +++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/msm/dp/dp_link.h  |  5 +++
>  drivers/gpu/drm/msm/dp/dp_panel.c | 78 +++++----------------------------------
>  drivers/gpu/drm/msm/dp/dp_panel.h |  3 --
>  5 files changed, 90 insertions(+), 77 deletions(-)
> 

-- 
With best wishes
Dmitry


From dmitry.baryshkov at oss.qualcomm.com  Wed Aug 20 04:54:34 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Wed, 20 Aug 2025 14:54:34 +0300
Subject: [PATCH V3 2/2] phy: qcom-qmp-ufs: Add regulator loads for SM8650
 and SM8750
In-Reply-To: <b453b8ff-a460-4ccd-9019-aed746a7d52d@quicinc.com>
References: <20250819222832.8471-1-quic_nitirawa@quicinc.com>
 <20250819222832.8471-3-quic_nitirawa@quicinc.com>
 <ger4kizeltjwalfuwu4dpfjiskrv2okgo5c7d6n3pb24yaxgfo@nkcndblyx3il>
 <b453b8ff-a460-4ccd-9019-aed746a7d52d@quicinc.com>
Message-ID: <ukxv7donvkulgci2dwrokuflzxzeyh4kohoyja2vywropntxnb@qepcssbe4wpc>

On Wed, Aug 20, 2025 at 12:07:57PM +0530, Nitin Rawat wrote:
> 
> 
> On 8/20/2025 6:19 AM, Dmitry Baryshkov wrote:
> > On Wed, Aug 20, 2025 at 03:58:26AM +0530, Nitin Rawat wrote:
> > > Add regulator load voting support for SM8650 and SM8750 platforms by
> > > introducing dedicated regulator bulk data arrays with their load
> > > values.
> > > 
> > > The load requirements are:
> > > - SM8650: vdda-phy (205mA), vdda-pll (17.5mA)
> > > - SM8750: vdda-phy (213mA), vdda-pll (18.3mA)
> > > 
> > > This ensures stable operation and proper power management for these
> > > platforms where regulators are shared between the QMP USB PHY and
> > > other IP blocks by setting appropriate regulator load currents during PHY
> > > operations.
> > > 
> > > Configurations without specific load requirements will continue to work
> > > unchanged, as init_load_uA remains zero-initialized when .init_load_uA
> > > is not provided.
> > 
> > Can we please get configuration for the rest of the platforms?
> 
> Hi Dmitry,
> 
> If you're okay with it, can I merge the configuration for the remaining
> platforms in the next patch series after I complete testing on all remaining
> platforms.

You don't need to test, finding MSM8996 or 98 might be troublesome. Just
fill in the values from the hardware documentation.

-- 
With best wishes
Dmitry


From Frank.li at nxp.com  Wed Aug 20 07:39:23 2025
From: Frank.li at nxp.com (Frank Li)
Date: Wed, 20 Aug 2025 10:39:23 -0400
Subject: [PATCH v2 00/32] media: add imx93 mipi/controller csi support
In-Reply-To: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
Message-ID: <aKXeG0+QxcgZYiUE@lizhi-Precision-Tower-5810>

On Fri, Aug 08, 2025 at 06:39:03PM -0400, Frank Li wrote:
> Totally rewrite CSI part driver compared to V1.

Laurent Pinchart:

	Not sure if you have chance to look this patches, which is big
changeset.

	Please check first 3 patches firstly, which help reduce many
hardcode in current code base.

	media: v4l2-common: Add helper function v4l_get_required_align_by_bpp()
	media: v4l2-common: Add helper function media_bus_fmt_to_csi2_bpp()
	media: v4l2-common: Add helper function media_bus_fmt_to_csi2_dt()

	The other patchset https://lore.kernel.org/imx/20250820-csi2_imx8mq-v5-0-e04a6fc593bd at nxp.com/T/#t
depend on this first 3 patches.

Frank
>
> This only includes CSI related patches.
>
> DTS part: see https://lore.kernel.org/imx/20250701-95_cam-v1-6-c5172bab387b at nxp.com/
> PHY part: see https://lore.kernel.org/imx/20250701-95_cam-v1-4-c5172bab387b at nxp.com/
> AP1302 part: see https://lore.kernel.org/imx/20250701-95_cam-v1-7-c5172bab387b at nxp.com/
> 	upstream: https://lore.kernel.org/imx/20250623-ap1302-v3-0-c9ca5b791494 at nxp.com/
>
> First 3 patches add some common helper function to simple code and remove
> duplicated code in difference CSI2 drivers.
>
> Clean up stage imx6 old version csi2 driver, and prepare create common
> dw csi2 library for difference IP version.
>
> Move stage driver under driver/media/synosis.
>
> Create simple platform driver for common dw csi2 use case.
>
> TODO:
> 	1. create bus, to probe phy driver under "test_if" interface for
> specific phys under CSI2.
> 	2. support to combine phy, (which connect to both dw CSI and DSI's
> test_if). Need use DSI's test_if to config combo phy to switch to RX mode.
> and also need config RX part's phy register by use CSI's testif.
> 	3. move other vendor's csi driver to use this common DWC CSI
> library.
>
> Signed-off-by: Frank Li <Frank.Li at nxp.com>
> ---
> Changes in v2:
> - totally rewrite, see above section
> - Link to v1: https://lore.kernel.org/r/20250701-95_cam-v1-0-c5172bab387b at nxp.com
>
> ---
> Eugen Hristev (1):
>       dt-bindings: media: add DW MIPI CSI-2 Host support
>
> Frank Li (31):
>       media: v4l2-common: Add helper function v4l_get_required_align_by_bpp()
>       media: v4l2-common: Add helper function media_bus_fmt_to_csi2_bpp()
>       media: v4l2-common: Add helper function media_bus_fmt_to_csi2_dt()
>       media: staging: media: imx6-mipi-csi2: replace space with tab for alignment
>       media: staging: media: imx6-mipi-csi2: use devm_add_action_or_reset() to simplify code
>       media: staging: media: imx6-mipi-csi2: use devm_clk_bulk_get_all() to fetch clocks
>       media: staging: media: imx6-mipi-csi2: use devm_mutex_init() to simplify code
>       media: staging: media: imx6-mipi-csi2: use guard() to simplify code
>       media: staging: media: imx6-mipi-csi2: use register structure to match hardware
>       media: staging: media: imx6-mipi-csi2: use devm_platform_ioremap_resource() simplify code
>       media: staging: media: imx6-mipi-csi2: move probe part to imx6-csi2.c
>       media: staging: media: imx6-mipi-csi2: move sd imx6's specific initialization into imx6-sci2.c
>       media: staging: media: imx6-mipi-csi2: move csi2ipu_gasket_init() to imx6-csi2.c
>       media: staging: media: imx6-mipi-csi2: move number pad macro define into imx6-csi2.c
>       media: staging: media: imx6-mipi-csi2: move dphy init part to imx6-csi2.c
>       media: staging: media: imx6-mipi-csi2: use runtime_pm frame to control clks
>       media: synopsys: move imx6-mipi-csi2.c to synopsys/mipi-csi2.c
>       media: synopsys: csi2: Remove deprecated s_stream and use v4l2_subdev_pad_ops
>       media: synopsys: csi2: Add phy interface support
>       media: synopsys: csi2: Add basic v150* version register
>       media: synopsys: csi2: Add irq support to record error count
>       media: synopsys: csi2: Handle alignment requirement for width
>       media: synopsys: csi2: Add register prefix to register field definitions
>       media: synopsys: csi2: Add need_dphy_reset in config
>       media: synopsys: csi2: Add default simple dw_csi2_subdev_init_state
>       media: synopsys: csi2: Add v150 lane stop state register bit define
>       media: synopsys: csi2: use standard v4l2_subdev_get_fmt() function
>       media: synopsys: csi2: Add customize get_frame_desc() callback
>       media: synopsys: csi2: Add Image Pixel Interface (IPI) support for v150
>       media: synopsys: csi2: Remove source pad connected check at dw_csi2_enable_streams()
>       media: synopsys: csi2: Add simple synopsys platform driver
>
>  .../bindings/media/snps,dw-mipi-csi2-v150.yaml     |  158 +++
>  MAINTAINERS                                        |    1 +
>  drivers/media/platform/synopsys/Kconfig            |   20 +
>  drivers/media/platform/synopsys/Makefile           |    3 +
>  drivers/media/platform/synopsys/mipi-csi2-simple.c |   75 ++
>  drivers/media/platform/synopsys/mipi-csi2.c        | 1258 ++++++++++++++++++++
>  drivers/media/v4l2-core/v4l2-common.c              |  220 ++++
>  drivers/staging/media/imx/Kconfig                  |    1 +
>  drivers/staging/media/imx/Makefile                 |    2 +-
>  drivers/staging/media/imx/imx6-csi2.c              |  181 +++
>  drivers/staging/media/imx/imx6-mipi-csi2.c         |  846 -------------
>  include/media/dw-mipi-csi2.h                       |  120 ++
>  include/media/mipi-csi2.h                          |    5 +
>  include/media/v4l2-common.h                        |   30 +
>  14 files changed, 2073 insertions(+), 847 deletions(-)
> ---
> base-commit: 33652d58b64e92d2598205fd992989bd93cd61f4
> change-id: 20250606-95_cam-b74c094ad1fb
>
> Best regards,
> --
> Frank Li <Frank.Li at nxp.com>
>


From vkoul at kernel.org  Wed Aug 20 09:07:36 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 20 Aug 2025 21:37:36 +0530
Subject: [PATCH v2 3/3] phy: eswin: Create eswin directory and add
 EIC7700 SATA PHY driver
In-Reply-To: <20250819140043.1862-1-luyulin@eswincomputing.com>
References: <20250819134722.220-1-luyulin@eswincomputing.com>
 <20250819140043.1862-1-luyulin@eswincomputing.com>
Message-ID: <aKXyyAT-xRPhoYDx@vaman>

On 19-08-25, 22:00, Yulin Lu wrote:
> From: luyulin <luyulin at eswincomputing.com>
> 
> Created the eswin phy driver directory and added support for
> the SATA phy driver on the EIC7700 SoC platform.
> 
> Signed-off-by: luyulin <luyulin at eswincomputing.com>

Please use full name as you have used in the copyright notices


> +#define SATA_P0_PHY_TX_PREEMPH_GEN2	(0x05 << 8)
> +#define SATA_P0_PHY_TX_PREEMPH_GEN3	(0x08 << 16)
> +#define SATA_MPLL_MULTIPLIER		(0x3c << 16)

Use GENMASK for these

> +static int eic7700_sata_phy_init(struct phy *phy)
> +{
> +	struct eic7700_sata_phy *sata_phy = phy_get_drvdata(phy);
> +	u32 val = 0;
> +	int ret = 0;

both initializations are superfluous

> +static int eic7700_sata_phy_exit(struct phy *phy)
> +{
> +	struct eic7700_sata_phy *sata_phy = phy_get_drvdata(phy);
> +	u32 val = 0;

here and other places

> +static struct platform_driver eic7700_sata_phy_driver = {
> +	.probe	= eic7700_sata_phy_probe,
> +	.driver = {
> +		.of_match_table	= eic7700_sata_phy_of_match,
> +		.name  = "eswin,sata-phy",
> +		.suppress_bind_attrs = true,

why?

-- 
~Vinod


From vkoul at kernel.org  Wed Aug 20 09:17:15 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 20 Aug 2025 21:47:15 +0530
Subject: [PATCH] phy: mediatek: Modify mipi clk upper bound to 2.5Gbps
In-Reply-To: <20250814125406.4161220-1-payne.lin@mediatek.com>
References: <20250814125406.4161220-1-payne.lin@mediatek.com>
Message-ID: <aKX1CxD_2mlOwYn-@vaman>

On 14-08-25, 20:54, payne.lin wrote:
> From: Bincai Liu <bincai.liu at mediatek.com>
> 
> Mipi dphy can support up to 4k30 without dsc.

Good, how does that translate to below value change, can you please
explain?

> 
> Signed-off-by: Bincai Liu <bincai.liu at mediatek.com>
> Signed-off-by: Payne Lin <payne.lin at mediatek.com>
> ---
>  drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
> index 553725e1269c..b8233c496070 100644
> --- a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
> +++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
> @@ -100,7 +100,7 @@ static void mtk_mipi_tx_pll_disable(struct clk_hw *hw)
>  static long mtk_mipi_tx_pll_round_rate(struct clk_hw *hw, unsigned long rate,
>  				       unsigned long *prate)
>  {
> -	return clamp_val(rate, 125000000, 1600000000);
> +	return clamp_val(rate, 125000000, 2500000000);
>  }
>  
>  static const struct clk_ops mtk_mipi_tx_pll_ops = {
> -- 
> 2.45.2

-- 
~Vinod


From vkoul at kernel.org  Wed Aug 20 09:29:25 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 20 Aug 2025 21:59:25 +0530
Subject: [PATCH v2 2/9] phy: mediatek: phy-mtk-hdmi-mt2701: convert from
 round_rate() to determine_rate()
In-Reply-To: <20250810-phy-clk-round-rate-v2-2-9162470bb9f2@redhat.com>
References: <20250810-phy-clk-round-rate-v2-0-9162470bb9f2@redhat.com>
 <20250810-phy-clk-round-rate-v2-2-9162470bb9f2@redhat.com>
Message-ID: <aKX35U4jX55W3W61@vaman>

On 10-08-25, 18:45, Brian Masney wrote:
> The round_rate() clk ops is deprecated, so migrate this driver from
> round_rate() to determine_rate() using the Coccinelle semantic patch
> on the cover letter of this series.
> 
> Signed-off-by: Brian Masney <bmasney at redhat.com>
> ---
>  drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c b/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c
> index e51b2d13eab473dddace48c75c2a8d73c8c65635..b0b6497e7eedcb6867541b573d22156ded29a4d5 100644
> --- a/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c
> +++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c
> @@ -90,10 +90,10 @@ static void mtk_hdmi_pll_unprepare(struct clk_hw *hw)
>  	usleep_range(80, 100);
>  }
>  
> -static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
> -				    unsigned long *parent_rate)
> +static int mtk_hdmi_pll_determine_rate(struct clk_hw *hw,
> +				       struct clk_rate_request *req)
>  {
> -	return rate;
> +	return 0;

This does not sound correct to me? should this not check the requested
rate?

>  }
>  
>  static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
> @@ -170,7 +170,7 @@ static const struct clk_ops mtk_hdmi_phy_pll_ops = {
>  	.prepare = mtk_hdmi_pll_prepare,
>  	.unprepare = mtk_hdmi_pll_unprepare,
>  	.set_rate = mtk_hdmi_pll_set_rate,
> -	.round_rate = mtk_hdmi_pll_round_rate,
> +	.determine_rate = mtk_hdmi_pll_determine_rate,
>  	.recalc_rate = mtk_hdmi_pll_recalc_rate,
>  };
>  
> 
> -- 
> 2.50.1

-- 
~Vinod


From vkoul at kernel.org  Wed Aug 20 09:34:19 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 20 Aug 2025 22:04:19 +0530
Subject: [PATCH v3 1/2] phy: add new phy_notify_state() api
In-Reply-To: <20250813-phy-notify-pmstate-v3-1-3bda59055dd3@linaro.org>
References: <20250813-phy-notify-pmstate-v3-0-3bda59055dd3@linaro.org>
 <20250813-phy-notify-pmstate-v3-1-3bda59055dd3@linaro.org>
Message-ID: <aKX5C9Xlx2CSJraY@vaman>

On 13-08-25, 16:00, Peter Griffin wrote:
> Add a new phy_notify_state() api that notifies and configures a phy for a
> given state transition.
> 
> This is intended to be by phy drivers which need to do some runtime
                    ^^^^^^^^^^
Missing 'used' possibly? 

> configuration of parameters that can't be handled by phy_calibrate() or
> phy_power_{on|off}().
> 
> The first usage of this API is in the Samsung UFS phy that needs to issue
> some register writes when entering and exiting the hibernate link state.
> 
> Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> ---
>  drivers/phy/phy-core.c  | 25 +++++++++++++++++++++++++
>  include/linux/phy/phy.h | 19 +++++++++++++++++++
>  2 files changed, 44 insertions(+)
> 
> diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
> index 04a5a34e7a950ae94fae915673c25d476fc071c1..60be8af984bf06649ef00e695d0ed4ced597cdb9 100644
> --- a/drivers/phy/phy-core.c
> +++ b/drivers/phy/phy-core.c
> @@ -520,6 +520,31 @@ int phy_notify_disconnect(struct phy *phy, int port)
>  }
>  EXPORT_SYMBOL_GPL(phy_notify_disconnect);
>  
> +/**
> + * phy_notify_state() - phy state notification
> + * @phy: the PHY returned by phy_get()
> + * @state: the PHY state
> + *
> + * Notify the PHY of a state transition. Used to notify and
> + * configure the PHY accordingly.
> + *
> + * Returns: %0 if successful, a negative error code otherwise
> + */
> +int phy_notify_state(struct phy *phy, union phy_notify state)
> +{
> +	int ret;
> +
> +	if (!phy || !phy->ops->notify_phystate)
> +		return 0;
> +
> +	mutex_lock(&phy->mutex);
> +	ret = phy->ops->notify_phystate(phy, state);
> +	mutex_unlock(&phy->mutex);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(phy_notify_state);
> +
>  /**
>   * phy_configure() - Changes the phy parameters
>   * @phy: the phy returned by phy_get()
> diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
> index 13add0c2c40721fe9ca3f0350d13c035cd25af45..664d0864c3a5042949cb121e982368fe0a97827f 100644
> --- a/include/linux/phy/phy.h
> +++ b/include/linux/phy/phy.h
> @@ -53,6 +53,15 @@ enum phy_media {
>  	PHY_MEDIA_DAC,
>  };
>  
> +enum phy_ufs_state {
> +	PHY_UFS_HIBERN8_ENTER,
> +	PHY_UFS_HIBERN8_EXIT,
> +};
> +
> +union phy_notify {
> +	enum phy_ufs_state ufs_state;
> +};
> +
>  /**
>   * union phy_configure_opts - Opaque generic phy configuration
>   *
> @@ -83,6 +92,7 @@ union phy_configure_opts {
>   * @set_speed: set the speed of the phy (optional)
>   * @reset: resetting the phy
>   * @calibrate: calibrate the phy
> + * @notify_phystate: notify and configure the phy for a particular state
>   * @release: ops to be performed while the consumer relinquishes the PHY
>   * @owner: the module owner containing the ops
>   */
> @@ -132,6 +142,7 @@ struct phy_ops {
>  	int	(*connect)(struct phy *phy, int port);
>  	int	(*disconnect)(struct phy *phy, int port);
>  
> +	int	(*notify_phystate)(struct phy *phy, union phy_notify state);
>  	void	(*release)(struct phy *phy);
>  	struct module *owner;
>  };
> @@ -255,6 +266,7 @@ int phy_reset(struct phy *phy);
>  int phy_calibrate(struct phy *phy);
>  int phy_notify_connect(struct phy *phy, int port);
>  int phy_notify_disconnect(struct phy *phy, int port);
> +int phy_notify_state(struct phy *phy, union phy_notify state);
>  static inline int phy_get_bus_width(struct phy *phy)
>  {
>  	return phy->attrs.bus_width;
> @@ -412,6 +424,13 @@ static inline int phy_notify_disconnect(struct phy *phy, int index)
>  	return -ENOSYS;
>  }
>  
> +static inline int phy_notify_phystate(struct phy *phy, union phy_notify state)
> +{
> +	if (!phy)
> +		return 0;
> +	return -ENOSYS;

Should be -ENOSYS either way, right?

-- 
~Vinod


From vkoul at kernel.org  Wed Aug 20 10:02:13 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 20 Aug 2025 22:32:13 +0530
Subject: (subset) [PATCH 0/4] arm64: dts: qcom: Add PCIe Support for
 sm8750
In-Reply-To: <20250809-pakala-v1-0-abf1c416dbaa@oss.qualcomm.com>
References: <20250809-pakala-v1-0-abf1c416dbaa@oss.qualcomm.com>
Message-ID: <175570933399.66459.8492859060215712340.b4-ty@kernel.org>


On Sat, 09 Aug 2025 15:29:15 +0530, Krishna Chaitanya Chundru wrote:
> Describe PCIe controller and PHY. Also add required system resources like
> regulators, clocks, interrupts and registers configuration for PCIe.
> 
> 

Applied, thanks!

[1/4] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Document the SM8750 QMP PCIe PHY Gen3 x2
      commit: edafd4f3fd52a614c5cee2684559367eac2286dc
[2/4] phy: qcom-qmp-pcie: add dual lane PHY support for SM8750
      commit: 0f051749c804b5a4f485013c0e3c932e1dd9f70b

Best regards,
-- 
~Vinod




From vkoul at kernel.org  Wed Aug 20 10:02:20 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 20 Aug 2025 22:32:20 +0530
Subject: [PATCH] phy: sun4i-usb: drop num_phys assumption
In-Reply-To: <20250819001522.13011-1-andre.przywara@arm.com>
References: <20250819001522.13011-1-andre.przywara@arm.com>
Message-ID: <175570934053.66459.17487502489276312055.b4-ty@kernel.org>


On Tue, 19 Aug 2025 01:15:22 +0100, Andre Przywara wrote:
> So far we set a number of expected Allwinner USB PHY instances for any
> given compatible string, and would fail if we do not find every PHY
> described properly in the DT (missing reset/PMU/clocks).
> This is somewhat redundant, as the DT only describes the resources for
> the implemented PHYs, but goes in line with being strict about firmware
> descriptions, and rather fixing things in the driver code, based on the
> compatible string.
> However this causes issues when we make a mistake, like we did recently
> on the A523: there are actually three USB PHYs, not two, as we assumed.
> Changing the number in the driver and the compatible string would cause
> all kinds of compatibility issues, both with older and newer DTs.
> 
> [...]

Applied, thanks!

[1/1] phy: sun4i-usb: drop num_phys assumption
      commit: 75c21418beb92382dda164fdc2554610b49ed441

Best regards,
-- 
~Vinod




From vkoul at kernel.org  Wed Aug 20 10:02:59 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 20 Aug 2025 22:32:59 +0530
Subject: (subset) [PATCH] phy: rockchip: naneng-combphy: Convert comma
 to semicolon
In-Reply-To: <20250814013943.2905307-1-nichen@iscas.ac.cn>
References: <20250814013943.2905307-1-nichen@iscas.ac.cn>
Message-ID: <175570937971.66459.9785527061700801116.b4-ty@kernel.org>


On Thu, 14 Aug 2025 09:39:43 +0800, Chen Ni wrote:
> Replace comma between expressions with semicolons.
> 
> Using a ',' in place of a ';' can have unintended side effects.
> Although that is not the case here, it is seems best to use ';'
> unless ',' is intended.
> 
> Found by inspection.
> No functional change intended.
> Compile tested only.
> 
> [...]

Applied, thanks!

[1/1] phy: rockchip: naneng-combphy: Convert comma to semicolon
      commit: a8f9de937dbf7bdabda72bd0c51e201e550129c2

Best regards,
-- 
~Vinod




From vkoul at kernel.org  Wed Aug 20 10:03:03 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 20 Aug 2025 22:33:03 +0530
Subject: (subset) [PATCH v4 0/6] arm64: qcom: allow up to 4 lanes for
 the Type-C DisplayPort Altmode
In-Reply-To: <20250807-topic-4ln_dp_respin-v4-0-43272d6eca92@oss.qualcomm.com>
References: <20250807-topic-4ln_dp_respin-v4-0-43272d6eca92@oss.qualcomm.com>
Message-ID: <175570938300.66459.13600812398405419297.b4-ty@kernel.org>


On Thu, 07 Aug 2025 18:33:18 +0200, Konrad Dybcio wrote:
> Register a typec mux in order to change the PHY mode on the Type-C
> mux events depending on the mode and the svid when in Altmode setup.
> 
> The DisplayPort phy should be left enabled if is still powered on
> by the DRM DisplayPort controller, so bail out until the DisplayPort
> PHY is not powered off.
> 
> [...]

Applied, thanks!

[1/6] dt-bindings: phy: qcom,sc8280xp-qmp-usb43dp: Reference usb-switch.yaml to allow mode-switch
      commit: 3bad7fe22796a420c6e16b591c37ed1bd6cc2a30
[2/6] phy: qcom: qmp-combo: Rename 'mode' to 'phy_mode'
      commit: 5daf1bbc73e249075373e030e7221f46c175e04b
[3/6] phy: qcom: qmp-combo: store DP phy power state
      commit: 86390472554b2e8fb4cba16a139cade94be58f72
[4/6] phy: qcom: qmp-combo: introduce QMPPHY_MODE
      commit: dd331112c0adaebbc8fc767fc805da4a641576db
[5/6] phy: qcom: qmp-combo: register a typec mux to change the QMPPHY_MODE
      commit: 896277138c1344cf9f5c415298f048ee29da274d

Best regards,
-- 
~Vinod




From vkoul at kernel.org  Wed Aug 20 10:03:08 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 20 Aug 2025 22:33:08 +0530
Subject: [PATCH v2 0/5] Add USB2 PHY support for RZ/T2H and RZ/N2H SoCs
In-Reply-To: <20250808215209.3692744-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20250808215209.3692744-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <175570938875.66459.17504688667907589630.b4-ty@kernel.org>


On Fri, 08 Aug 2025 22:52:04 +0100, Prabhakar wrote:
> This patch series adds support for the USB2 PHY on the Renesas RZ/T2H
> and RZ/N2H SoCs. The USB2 PHY driver has been updated to handle
> differences in clocking, reset handling, and register configurations
> specific to these SoCs.
> 
> v1->v2:
> - Added Acked-by from Conor for the DT bindings.
> - Renamed drvdata to phy_data.
> - Updated commit message to clarify the change.
> - Dropped local phy_data variable in probe, using channel->phy_data
>   directly.
> - Included the necessary header files.
> - Simplified device/host detection in rcar_gen3_check_id() as suggested
>   by Geert.
> - Added Reviewed-by from Neil.
> 
> [...]

Applied, thanks!

[1/5] dt-bindings: phy: renesas,usb2-phy: Add RZ/T2H and RZ/N2H support
      commit: ab9c8aeb2d208381a7c948ea2f753cbe8a451502
[2/5] phy: renesas: rcar-gen3-usb2: store drvdata pointer in channel
      commit: f75806d26318c08ddb79652cce89086e4da17257
[3/5] phy: renesas: rcar-gen3-usb2: Allow SoC-specific OBINT bits via phy_data
      commit: 4b7aa47e4c2c921b9511389bf42a4e30d64373e6
[4/5] phy: renesas: rcar-gen3-usb2: Add support for RZ/T2H SoC
      commit: b725741f1c21e8507a58ae86c5a80ca383f96852
[5/5] phy: renesas: rcar-gen3-usb2: Move debug print after register value is updated
      commit: 5f54134428b48261151c725c64b40be54e373345

Best regards,
-- 
~Vinod




From vkoul at kernel.org  Wed Aug 20 10:03:14 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 20 Aug 2025 22:33:14 +0530
Subject: [PATCH RESEND] dt-bindings: phy: Add eDP PHY compatible for
 QCS8300
In-Reply-To: <20250730072725.1433360-1-quic_yongmou@quicinc.com>
References: <20250730072725.1433360-1-quic_yongmou@quicinc.com>
Message-ID: <175570939464.66459.14512137933312026042.b4-ty@kernel.org>


On Wed, 30 Jul 2025 15:27:25 +0800, Yongxing Mou wrote:
> Add compatible string for the supported eDP PHY on QCS8300 platform.
> QCS8300 have the same eDP PHY with SA8775P.
> 
> 

Applied, thanks!

[1/1] dt-bindings: phy: Add eDP PHY compatible for QCS8300
      commit: ce489635960a6a3fcb0abe0918994f2d8deb02ed

Best regards,
-- 
~Vinod




From vkoul at kernel.org  Wed Aug 20 10:03:18 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 20 Aug 2025 22:33:18 +0530
Subject: [PATCH] phy: ingenic: use core driver model helper to handle
 probe errors
In-Reply-To: <aIIMW971BYsIk4As@bhairav-test.ee.iitb.ac.in>
References: <aIIMW971BYsIk4As@bhairav-test.ee.iitb.ac.in>
Message-ID: <175570939883.66459.13384631190910835404.b4-ty@kernel.org>


On Thu, 24 Jul 2025 16:05:07 +0530, Akhilesh Patil wrote:
> Use core driver model helper dev_err_probe() defined at
> drivers/base/core.c in driver probe path to propagate errors.
> standardize and improve the code of deferred probe error handling
> using this helper for ingenic usb phy driver.
> Inspired by,
> commit a787e5400a1ce ("driver core: add device probe log helper")
> 
> [...]

Applied, thanks!

[1/1] phy: ingenic: use core driver model helper to handle probe errors
      commit: 38404274bbee1f0001a490c0dc98aac32a4d7c9d

Best regards,
-- 
~Vinod




From biju.das.au at gmail.com  Wed Aug 20 10:17:47 2025
From: biju.das.au at gmail.com (Biju)
Date: Wed, 20 Aug 2025 18:17:47 +0100
Subject: [PATCH 00/11] Add RZ/G3E USB3.2 Gen1 Host Controller support
Message-ID: <20250820171812.402519-1-biju.das.jz@bp.renesas.com>

From: Biju Das <biju.das.jz at bp.renesas.com>

Add RZ/G3E USB3.2 Gen1 Host Controller and PHY support. The USB3HOST
is compliant with the Universal Serial Bus 3.2 Specification Revision 1.0.
 - Supports 1 downstream USB receptacles
     - Number of SSP Gen2 or SS ports: 1
     - Number of HS or FS or LS ports: 1
 - Supports Super Speed Plus Gen2x1 (10 Gbps), Super Speed (5 Gbps),
   High Speed (480 Mbps), Full Speed (12Mbps), and Low Speed (1.5 Mbps).
 - Supports all transfer-types: Control, Bulk, Interrupt, Isochronous, and
   these split-transactions.
 - Supports Power Control and Over Current Detection.

Biju Das (11):
  dt-bindings: clock: renesas,r9a09g047-cpg: Add USB3.0 core clocks
  clk: renesas: r9a09g047: Add USB3.0 clocks/resets
  dt-bindings: phy: renesas: Document Renesas RZ/G3E USB3.0 PHY
  phy: renesas: Add Renesas RZ/G3E USB3.0 PHY driver
  usb: host: xhci-rcar: Move R-Car reg definitions
  dt-bindings: usb: Document Renesas RZ/G3E USB3HOST
  usb: host: xhci-plat: Add .post_resume_quirk for struct xhci_plat_priv
  usb: host: xhci-rcar: Add Renesas RZ/G3E USB3 Host driver support
  arm64: dts: renesas: r9a09g047: Add USB3 PHY/Host nodes
  arm64: dts: renesas: r9a09g047e57-smarc: Enable USB3HOST
  arm64: defconfig: Enable RZ/G3E USB3 PHY driver

 .../bindings/phy/renesas,rzg3e-usb3-phy.yaml  |  63 +++++
 .../bindings/usb/renesas,rzg3e-xhci.yaml      |  84 ++++++
 arch/arm64/boot/dts/renesas/r9a09g047.dtsi    |  30 +++
 .../boot/dts/renesas/r9a09g047e57-smarc.dts   |  10 +
 .../boot/dts/renesas/renesas-smarc2.dtsi      |   8 +
 arch/arm64/configs/defconfig                  |   1 +
 drivers/clk/renesas/r9a09g047-cpg.c           |   9 +-
 drivers/phy/renesas/Kconfig                   |   7 +
 drivers/phy/renesas/Makefile                  |   1 +
 drivers/phy/renesas/phy-rzg3e-usb3.c          | 249 ++++++++++++++++++
 drivers/usb/host/Kconfig                      |   2 +-
 drivers/usb/host/xhci-plat.c                  |  14 +
 drivers/usb/host/xhci-plat.h                  |   1 +
 drivers/usb/host/xhci-rcar-regs.h             |  49 ++++
 drivers/usb/host/xhci-rcar.c                  | 100 +++----
 drivers/usb/host/xhci-rzg3e-regs.h            |  12 +
 .../dt-bindings/clock/renesas,r9a09g047-cpg.h |   2 +
 17 files changed, 596 insertions(+), 46 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/phy/renesas,rzg3e-usb3-phy.yaml
 create mode 100644 Documentation/devicetree/bindings/usb/renesas,rzg3e-xhci.yaml
 create mode 100644 drivers/phy/renesas/phy-rzg3e-usb3.c
 create mode 100644 drivers/usb/host/xhci-rcar-regs.h
 create mode 100644 drivers/usb/host/xhci-rzg3e-regs.h

-- 
2.43.0



From biju.das.au at gmail.com  Wed Aug 20 10:17:50 2025
From: biju.das.au at gmail.com (Biju)
Date: Wed, 20 Aug 2025 18:17:50 +0100
Subject: [PATCH 03/11] dt-bindings: phy: renesas: Document Renesas RZ/G3E USB3.0 PHY
In-Reply-To: <20250820171812.402519-1-biju.das.jz@bp.renesas.com>
References: <20250820171812.402519-1-biju.das.jz@bp.renesas.com>
Message-ID: <20250820171812.402519-4-biju.das.jz@bp.renesas.com>

From: Biju Das <biju.das.jz at bp.renesas.com>

Document Renesas RZ/G3E USB3.0 PHY. This IP is connected between
USB3HOST and PHY module. The main functions of the module are
as follows:
 - Reset control
 - Control of PHY input pins
 - Monitoring of PHY output pins

Signed-off-by: Biju Das <biju.das.jz at bp.renesas.com>
---
 .../bindings/phy/renesas,rzg3e-usb3-phy.yaml  | 63 +++++++++++++++++++
 1 file changed, 63 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/renesas,rzg3e-usb3-phy.yaml

diff --git a/Documentation/devicetree/bindings/phy/renesas,rzg3e-usb3-phy.yaml b/Documentation/devicetree/bindings/phy/renesas,rzg3e-usb3-phy.yaml
new file mode 100644
index 000000000000..b86dc7a291a4
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/renesas,rzg3e-usb3-phy.yaml
@@ -0,0 +1,63 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/renesas,rzg3e-usb3-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas RZ/G3E USB 3.0 PHY
+
+maintainers:
+  - Biju Das <biju.das.jz at bp.renesas.com>
+
+properties:
+  compatible:
+    const: renesas,r9a09g047-usb3-phy
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: APB bus clock
+      - description: USB 2.0 PHY reference clock
+      - description: USB 3.0 PHY reference clock
+
+  clock-names:
+    items:
+      - const: pclk
+      - const: core
+      - const: ref_alt_clk_p
+
+  power-domains:
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+
+  '#phy-cells':
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - power-domains
+  - resets
+  - '#phy-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/renesas,r9a09g047-cpg.h>
+
+    usb-phy at 15870000 {
+        compatible = "renesas,r9a09g047-usb3-phy";
+        reg = <0x15870000 0x10000>;
+        clocks = <&cpg CPG_MOD 0xb0>, <&cpg CPG_CORE 13>, <&cpg CPG_CORE 12>;
+        clock-names = "pclk", "core", "ref_alt_clk_p";
+        power-domains = <&cpg>;
+        resets = <&cpg 0xaa>;
+        #phy-cells = <0>;
+    };
-- 
2.43.0



From biju.das.au at gmail.com  Wed Aug 20 10:17:51 2025
From: biju.das.au at gmail.com (Biju)
Date: Wed, 20 Aug 2025 18:17:51 +0100
Subject: [PATCH 04/11] phy: renesas: Add Renesas RZ/G3E USB3.0 PHY driver
In-Reply-To: <20250820171812.402519-1-biju.das.jz@bp.renesas.com>
References: <20250820171812.402519-1-biju.das.jz@bp.renesas.com>
Message-ID: <20250820171812.402519-5-biju.das.jz@bp.renesas.com>

From: Biju Das <biju.das.jz at bp.renesas.com>

Add Renesas RZ/G3E USB3.0 PHY driver. This module is connected
between USB3 Host and PHY module. The main functions of this
module are:
 1) Reset control
 2) Control of PHY input pins
 3) Monitoring of PHY output pins

Signed-off-by: Biju Das <biju.das.jz at bp.renesas.com>
---
 drivers/phy/renesas/Kconfig          |   7 +
 drivers/phy/renesas/Makefile         |   1 +
 drivers/phy/renesas/phy-rzg3e-usb3.c | 249 +++++++++++++++++++++++++++
 3 files changed, 257 insertions(+)
 create mode 100644 drivers/phy/renesas/phy-rzg3e-usb3.c

diff --git a/drivers/phy/renesas/Kconfig b/drivers/phy/renesas/Kconfig
index e342eef0640b..16211072098e 100644
--- a/drivers/phy/renesas/Kconfig
+++ b/drivers/phy/renesas/Kconfig
@@ -40,3 +40,10 @@ config PHY_RCAR_GEN3_USB3
 	select GENERIC_PHY
 	help
 	  Support for USB 3.0 PHY found on Renesas R-Car generation 3 SoCs.
+
+config PHY_RZ_G3E_USB3
+	tristate "Renesas RZ/G3E USB 3.0 PHY driver"
+	depends on ARCH_RENESAS || COMPILE_TEST
+	select GENERIC_PHY
+	help
+	  Support for USB 3.0 PHY found on Renesas RZ/G3E SoCs.
diff --git a/drivers/phy/renesas/Makefile b/drivers/phy/renesas/Makefile
index 8896d1919faa..0e98083f2f0c 100644
--- a/drivers/phy/renesas/Makefile
+++ b/drivers/phy/renesas/Makefile
@@ -4,3 +4,4 @@ obj-$(CONFIG_PHY_RCAR_GEN2)		+= phy-rcar-gen2.o
 obj-$(CONFIG_PHY_RCAR_GEN3_PCIE)	+= phy-rcar-gen3-pcie.o
 obj-$(CONFIG_PHY_RCAR_GEN3_USB2)	+= phy-rcar-gen3-usb2.o
 obj-$(CONFIG_PHY_RCAR_GEN3_USB3)	+= phy-rcar-gen3-usb3.o
+obj-$(CONFIG_PHY_RZ_G3E_USB3)		+= phy-rzg3e-usb3.o
diff --git a/drivers/phy/renesas/phy-rzg3e-usb3.c b/drivers/phy/renesas/phy-rzg3e-usb3.c
new file mode 100644
index 000000000000..3ea521ed8f48
--- /dev/null
+++ b/drivers/phy/renesas/phy-rzg3e-usb3.c
@@ -0,0 +1,249 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas RZ/G3E USB3.0 PHY driver
+ *
+ * Copyright (C) 2025 Renesas Electronics Corporation
+ */
+
+#include <linux/bitfield.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+
+#define USB3_TEST_RESET				0x0000
+#define USB3_TEST_UTMICTRL2			0x0b04
+#define USB3_TEST_PRMCTRL5_R			0x0c10
+#define USB3_TEST_PRMCTRL6_R			0x0c14
+
+#define USB3_TEST_RSTCTRL			0x1000
+#define USB3_TEST_CLKCTRL			0x1004
+#define USB3_TEST_RAMCTRL			0x100c
+#define USB3_TEST_CREGCTRL			0x1010
+#define USB3_TEST_LANECONFIG0			0x1030
+
+#define USB3_TEST_RESET_PORTRESET0_CTRL		BIT(9)
+#define USB3_TEST_RESET_SIDDQ			BIT(3)
+#define USB3_TEST_RESET_PHY_RESET		BIT(2)
+#define USB3_TEST_RESET_PORTRESET0		BIT(1)
+
+#define USB3_TEST_UTMICTRL2_CTRL_MASK		GENMASK(9, 8)
+#define USB3_TEST_UTMICTRL2_MODE_MASK		GENMASK(1, 0)
+
+#define USB3_TEST_PRMCTRL5_R_TXPREEMPAMPTUNE0_MASK	GENMASK(2, 1)
+
+#define USB3_TEST_PRMCTRL6_R_OTGTUNE0_MASK	GENMASK(2, 0)
+
+#define USB3_TEST_RAMCTRL_SRAM_INIT_DONE	BIT(2)
+
+struct rz_usb3 {
+	void __iomem *base;
+	struct reset_control *rstc;
+	bool skip_reinit;
+};
+
+static void rzg3e_phy_usb2test_phy_init(void __iomem *base)
+{
+	u32 val;
+
+	val = readl(base + USB3_TEST_UTMICTRL2);
+	val |= USB3_TEST_UTMICTRL2_CTRL_MASK | USB3_TEST_UTMICTRL2_MODE_MASK;
+	writel(val, base + USB3_TEST_UTMICTRL2);
+
+	val = readl(base + USB3_TEST_PRMCTRL5_R);
+	val &= ~USB3_TEST_PRMCTRL5_R_TXPREEMPAMPTUNE0_MASK;
+	val |= FIELD_PREP(USB3_TEST_PRMCTRL5_R_TXPREEMPAMPTUNE0_MASK, 2);
+	writel(val, base + USB3_TEST_PRMCTRL5_R);
+
+	val = readl(base + USB3_TEST_PRMCTRL6_R);
+	val &= ~USB3_TEST_PRMCTRL6_R_OTGTUNE0_MASK;
+	val |= FIELD_PREP(USB3_TEST_PRMCTRL6_R_OTGTUNE0_MASK, 7);
+	writel(val, base + USB3_TEST_PRMCTRL6_R);
+
+	val = readl(base + USB3_TEST_RESET);
+	val &= ~USB3_TEST_RESET_SIDDQ;
+	val |= USB3_TEST_RESET_PORTRESET0_CTRL | USB3_TEST_RESET_PHY_RESET |
+	       USB3_TEST_RESET_PORTRESET0;
+	writel(val, base + USB3_TEST_RESET);
+	fsleep(10);
+
+	val &= ~(USB3_TEST_RESET_PHY_RESET | USB3_TEST_RESET_PORTRESET0);
+	writel(val, base + USB3_TEST_RESET);
+	fsleep(10);
+
+	val = readl(base + USB3_TEST_UTMICTRL2);
+	val &= ~USB3_TEST_UTMICTRL2_CTRL_MASK;
+	writel(val, base + USB3_TEST_UTMICTRL2);
+
+	writel(0, base + USB3_TEST_RESET);
+}
+
+static int rzg3e_phy_usb3test_phy_init(void __iomem *base)
+{
+	int ret;
+	u32 val;
+
+	writel(0x00000100, base + USB3_TEST_CREGCTRL);
+	writel(0x00000303, base + USB3_TEST_RSTCTRL);
+	fsleep(20);
+
+	writel(0x00000004, base + USB3_TEST_CLKCTRL);
+	writel(0x0000000d, base + USB3_TEST_LANECONFIG0);
+	writel(0x00000301, base + USB3_TEST_RSTCTRL);
+
+	ret = readl_poll_timeout_atomic(base + USB3_TEST_RAMCTRL, val,
+					val & USB3_TEST_RAMCTRL_SRAM_INIT_DONE, 1, 10000);
+	if (ret)
+		return ret;
+
+	writel(0x00000300, base + USB3_TEST_RSTCTRL);
+	writel(0x00000001, base + USB3_TEST_RAMCTRL);
+	writel(0x00000000, base + USB3_TEST_RSTCTRL);
+
+	return 0;
+}
+
+static int rzg3e_phy_usb3_init_helper(void __iomem *base)
+{
+	rzg3e_phy_usb2test_phy_init(base);
+
+	return rzg3e_phy_usb3test_phy_init(base);
+}
+
+static int rzg3e_phy_usb3_init(struct phy *p)
+{
+	struct rz_usb3 *r = phy_get_drvdata(p);
+	int ret = 0;
+
+	if (!r->skip_reinit)
+		ret = rzg3e_phy_usb3_init_helper(r->base);
+
+	return ret;
+}
+
+static const struct phy_ops rzg3e_phy_usb3_ops = {
+	.init = rzg3e_phy_usb3_init,
+	.owner = THIS_MODULE,
+};
+
+static int rzg3e_phy_usb3_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct phy_provider *provider;
+	struct rz_usb3 *r;
+	struct phy *phy;
+	int ret;
+
+	r = devm_kzalloc(dev, sizeof(*r), GFP_KERNEL);
+	if (!r)
+		return -ENOMEM;
+
+	r->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(r->base))
+		return PTR_ERR(r->base);
+
+	r->rstc = devm_reset_control_get_shared(dev, NULL);
+	if (IS_ERR(r->rstc))
+		return dev_err_probe(dev, PTR_ERR(r->rstc), "failed to get reset\n");
+
+	ret = reset_control_deassert(r->rstc);
+	if (ret)
+		return ret;
+
+	/*
+	 * devm_phy_create() will call pm_runtime_enable(&phy->dev);
+	 * And then, phy-core will manage runtime pm for this device.
+	 */
+	ret = devm_pm_runtime_enable(dev);
+	if (ret < 0)
+		return ret;
+
+	phy = devm_phy_create(dev, NULL, &rzg3e_phy_usb3_ops);
+	if (IS_ERR(phy))
+		return dev_err_probe(dev, PTR_ERR(phy), "failed to create USB3 PHY\n");
+
+	platform_set_drvdata(pdev, r);
+	phy_set_drvdata(phy, r);
+
+	provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+	if (IS_ERR(provider))
+		return dev_err_probe(dev, PTR_ERR(provider), "failed to register PHY provider\n");
+
+	return 0;
+}
+
+static void rzg3e_phy_usb3_remove(struct platform_device *pdev)
+{
+	struct rz_usb3 *r = dev_get_drvdata(&pdev->dev);
+
+	reset_control_assert(r->rstc);
+};
+
+static int rzg3e_phy_usb3_suspend(struct device *dev)
+{
+	struct rz_usb3 *r = dev_get_drvdata(dev);
+
+	pm_runtime_put(dev);
+	reset_control_assert(r->rstc);
+	r->skip_reinit = false;
+
+	return 0;
+}
+
+static int rzg3e_phy_usb3_resume(struct device *dev)
+{
+	struct rz_usb3 *r = dev_get_drvdata(dev);
+	int ret;
+
+	ret = reset_control_deassert(r->rstc);
+	if (ret)
+		return ret;
+
+	ret = pm_runtime_resume_and_get(dev);
+	if (ret)
+		goto reset_assert;
+
+	ret = rzg3e_phy_usb3_init_helper(r->base);
+	if (ret)
+		goto pm_put;
+
+	r->skip_reinit = true;
+
+	return 0;
+
+pm_put:
+	pm_runtime_put(dev);
+reset_assert:
+	reset_control_assert(r->rstc);
+	return ret;
+}
+
+static const struct dev_pm_ops rzg3e_phy_usb3_pm = {
+	NOIRQ_SYSTEM_SLEEP_PM_OPS(rzg3e_phy_usb3_suspend, rzg3e_phy_usb3_resume)
+};
+
+static const struct of_device_id rzg3e_phy_usb3_match_table[] = {
+	{ .compatible = "renesas,r9a09g047-usb3-phy" },
+	{ /* Sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, rzg3e_phy_usb3_match_table);
+static struct platform_driver rzg3e_phy_usb3_driver = {
+	.driver = {
+		.name = "phy_rzg3e_usb3",
+		.of_match_table = rzg3e_phy_usb3_match_table,
+		.pm = pm_sleep_ptr(&rzg3e_phy_usb3_pm),
+	},
+	.probe	= rzg3e_phy_usb3_probe,
+	.remove	= rzg3e_phy_usb3_remove,
+};
+module_platform_driver(rzg3e_phy_usb3_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Renesas RZ/G3E USB3.0 PHY Driver");
+MODULE_AUTHOR("biju.das.jz at bp.renesas.com>");
-- 
2.43.0



From bmasney at redhat.com  Wed Aug 20 10:27:35 2025
From: bmasney at redhat.com (Brian Masney)
Date: Wed, 20 Aug 2025 13:27:35 -0400
Subject: [PATCH v2 2/9] phy: mediatek: phy-mtk-hdmi-mt2701: convert from
 round_rate() to determine_rate()
In-Reply-To: <aKX35U4jX55W3W61@vaman>
References: <20250810-phy-clk-round-rate-v2-0-9162470bb9f2@redhat.com>
 <20250810-phy-clk-round-rate-v2-2-9162470bb9f2@redhat.com>
 <aKX35U4jX55W3W61@vaman>
Message-ID: <aKYFh5YI9j-MHKH4@x1>

Hi Vinod,

On Wed, Aug 20, 2025 at 09:59:25PM +0530, Vinod Koul wrote:
> On 10-08-25, 18:45, Brian Masney wrote:
> > The round_rate() clk ops is deprecated, so migrate this driver from
> > round_rate() to determine_rate() using the Coccinelle semantic patch
> > on the cover letter of this series.
> > 
> > Signed-off-by: Brian Masney <bmasney at redhat.com>
> > ---
> >  drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c | 8 ++++----
> >  1 file changed, 4 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c b/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c
> > index e51b2d13eab473dddace48c75c2a8d73c8c65635..b0b6497e7eedcb6867541b573d22156ded29a4d5 100644
> > --- a/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c
> > +++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c
> > @@ -90,10 +90,10 @@ static void mtk_hdmi_pll_unprepare(struct clk_hw *hw)
> >  	usleep_range(80, 100);
> >  }
> >  
> > -static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
> > -				    unsigned long *parent_rate)
> > +static int mtk_hdmi_pll_determine_rate(struct clk_hw *hw,
> > +				       struct clk_rate_request *req)
> >  {
> > -	return rate;
> > +	return 0;
> 
> This does not sound correct to me? should this not check the requested
> rate?

I can't speak as to whether or not this specific driver should have a
rate check here. I've seen in some other drivers where the specific
frequencies are managed in firmware, and Linux just passes on the rate
request as is.

Some other phy drivers (most notably drivers/gpu/drm/msm/dsi/phy/) only
makes sure that the requested rate is within a min/max range. Assuming
I read this driver's set_rate() correctly, it looks like the min/max
range may be 64-192 MHz. I'm not sure to be honest.

This change keeps the existing behavior of the driver as it is today,
and just migrates off an old API.

Brian



From laurent.pinchart at ideasonboard.com  Wed Aug 20 12:16:51 2025
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Wed, 20 Aug 2025 22:16:51 +0300
Subject: [PATCH v2 04/32] media: v4l2-common: Add helper function
 media_bus_fmt_to_csi2_dt()
In-Reply-To: <20250808-95_cam-v2-4-4b29fa6919a7@nxp.com>
References: <20250808-95_cam-v2-0-4b29fa6919a7@nxp.com>
 <20250808-95_cam-v2-4-4b29fa6919a7@nxp.com>
Message-ID: <20250820191651.GB1722@pendragon.ideasonboard.com>

Hi Frank,

Thank you for the patch.

On Fri, Aug 08, 2025 at 06:39:07PM -0400, Frank Li wrote:
> CSI2 data type is defined by MIPI Camera Serial Interface 2 Spec Ver4.1.
> See section 9.4.
> 
> Add helper function media_bus_fmt_to_csi2_dt() to convert media bus fmt to
> MIPI defined data type and avoid below duplicated static array in each CSI2
> drivers.
> 
> 	{
> 		.code = MEDIA_BUS_FMT_UYVY8_1X16,
> 		.data_type = MIPI_CSI2_DT_YUV422_8B,
> 	}
> 
> Signed-off-by: Frank Li <Frank.Li at nxp.com>
> ---
>  drivers/media/v4l2-core/v4l2-common.c | 44 +++++++++++++++++++++++++++++++++++
>  include/media/mipi-csi2.h             |  3 +++
>  2 files changed, 47 insertions(+)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
> index 3a48b6a55c6e322696b910dd519def4f0b4a58fb..fcc01030beb347499da2a3c8539793d20f6f512c 100644
> --- a/drivers/media/v4l2-core/v4l2-common.c
> +++ b/drivers/media/v4l2-core/v4l2-common.c
> @@ -701,6 +701,50 @@ int v4l2_link_freq_to_bitmap(struct device *dev, const u64 *fw_link_freqs,
>  }
>  EXPORT_SYMBOL_GPL(v4l2_link_freq_to_bitmap);
>  
> +int media_bus_fmt_to_csi2_dt(int bus_fmt)
> +{
> +	switch (bus_fmt) {
> +	case MEDIA_BUS_FMT_UYVY8_1X16:
> +		return MIPI_CSI2_DT_YUV422_8B;
> +	case MEDIA_BUS_FMT_RGB565_1X16:
> +		return MIPI_CSI2_DT_RGB565;
> +	case MEDIA_BUS_FMT_BGR888_1X24:
> +		return MIPI_CSI2_DT_RGB888;
> +	case MEDIA_BUS_FMT_SBGGR8_1X8:
> +	case MEDIA_BUS_FMT_SGBRG8_1X8:
> +	case MEDIA_BUS_FMT_SGRBG8_1X8:
> +	case MEDIA_BUS_FMT_SRGGB8_1X8:
> +	case MEDIA_BUS_FMT_Y8_1X8:
> +		return MIPI_CSI2_DT_RAW8;
> +	case MEDIA_BUS_FMT_SBGGR10_1X10:
> +	case MEDIA_BUS_FMT_SGBRG10_1X10:
> +	case MEDIA_BUS_FMT_SGRBG10_1X10:
> +	case MEDIA_BUS_FMT_SRGGB10_1X10:
> +	case MEDIA_BUS_FMT_Y10_1X10:
> +		return MIPI_CSI2_DT_RAW10;
> +	case MEDIA_BUS_FMT_SBGGR12_1X12:
> +	case MEDIA_BUS_FMT_SGBRG12_1X12:
> +	case MEDIA_BUS_FMT_SGRBG12_1X12:
> +	case MEDIA_BUS_FMT_SRGGB12_1X12:
> +	case MEDIA_BUS_FMT_Y12_1X12:
> +		return MIPI_CSI2_DT_RAW12;
> +	case MEDIA_BUS_FMT_SBGGR14_1X14:
> +	case MEDIA_BUS_FMT_SGBRG14_1X14:
> +	case MEDIA_BUS_FMT_SGRBG14_1X14:
> +	case MEDIA_BUS_FMT_SRGGB14_1X14:
> +		return MIPI_CSI2_DT_RAW14;
> +	case MEDIA_BUS_FMT_SBGGR16_1X16:
> +	case MEDIA_BUS_FMT_SGBRG16_1X16:
> +	case MEDIA_BUS_FMT_SGRBG16_1X16:
> +	case MEDIA_BUS_FMT_SRGGB16_1X16:
> +		return MIPI_CSI2_DT_RAW16;
> +
> +	default:
> +		return MIPI_CSI2_DT_NULL;

I would use 0 here. MIPI_CSI2_DT_NULL is equal to 0x10, and I'm
concerned about driver comparing the return value of the function to 0.

> +	}
> +}
> +EXPORT_SYMBOL_GPL(media_bus_fmt_to_csi2_dt);
> +

We have something similar for pixel formats, with the v4l2_format_info
structure and the v4l2_format_info() lookup function. Adding information
about media bus formats to the V4L2 core seems to be a good idea.

Regarding the implementation, I think you should mimick what we do for
the pixel formats, and add the data to an info structure with a lookup
function.

>  int media_bus_fmt_to_csi2_bpp(int bus_fmt)
>  {
>  	switch (bus_fmt) {
> diff --git a/include/media/mipi-csi2.h b/include/media/mipi-csi2.h
> index c5b4e8e1ca93803568b1eee85f7f99c3a45a0b6e..35de536b9b65b49ad9e2914437d26d0e4240cf38 100644
> --- a/include/media/mipi-csi2.h
> +++ b/include/media/mipi-csi2.h
> @@ -8,6 +8,8 @@
>  #ifndef _MEDIA_MIPI_CSI2_H
>  #define _MEDIA_MIPI_CSI2_H
>  
> +/* DT value ref to MIPI Camera Serial Interface 2 Spec Ver4.1 section 9.4 */
> +
>  /* Short packet data types */
>  #define MIPI_CSI2_DT_FS			0x00
>  #define MIPI_CSI2_DT_FE			0x01
> @@ -44,6 +46,7 @@
>  #define MIPI_CSI2_DT_RAW20		0x2f
>  #define MIPI_CSI2_DT_USER_DEFINED(n)	(0x30 + (n))	/* 0..7 */
>  
> +int media_bus_fmt_to_csi2_dt(int buf_fmt);
>  int media_bus_fmt_to_csi2_bpp(int bus_fmt);
>  
>  #endif /* _MEDIA_MIPI_CSI2_H */
> 
> 

-- 
Regards,

Laurent Pinchart


From conor at kernel.org  Wed Aug 20 13:10:07 2025
From: conor at kernel.org (Conor Dooley)
Date: Wed, 20 Aug 2025 21:10:07 +0100
Subject: [PATCH 03/11] dt-bindings: phy: renesas: Document Renesas RZ/G3E
 USB3.0 PHY
In-Reply-To: <20250820171812.402519-4-biju.das.jz@bp.renesas.com>
References: <20250820171812.402519-1-biju.das.jz@bp.renesas.com>
 <20250820171812.402519-4-biju.das.jz@bp.renesas.com>
Message-ID: <20250820-primer-shaded-66da9fa4bcae@spud>

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/20250820/f88750b9/attachment.sig>

From conor at kernel.org  Wed Aug 20 13:12:31 2025
From: conor at kernel.org (Conor Dooley)
Date: Wed, 20 Aug 2025 21:12:31 +0100
Subject: [PATCH 03/11] dt-bindings: phy: renesas: Document Renesas RZ/G3E
 USB3.0 PHY
In-Reply-To: <20250820-primer-shaded-66da9fa4bcae@spud>
References: <20250820171812.402519-1-biju.das.jz@bp.renesas.com>
 <20250820171812.402519-4-biju.das.jz@bp.renesas.com>
 <20250820-primer-shaded-66da9fa4bcae@spud>
Message-ID: <20250820-commodity-curator-1f580789885b@spud>

On Wed, Aug 20, 2025 at 09:10:07PM +0100, Conor Dooley wrote:
> Acked-by: Conor Dooley <conor.dooley at microchip.com>

Now that I look again, same applies here with the different filename and
compatible. Copypaste mistake? Or why does the compatible not match the
filename?


-------------- 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/20250820/b38c8d4a/attachment.sig>

From biju.das.jz at bp.renesas.com  Thu Aug 21 00:18:59 2025
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Thu, 21 Aug 2025 07:18:59 +0000
Subject: [PATCH 03/11] dt-bindings: phy: renesas: Document Renesas RZ/G3E
 USB3.0 PHY
In-Reply-To: <20250820-commodity-curator-1f580789885b@spud>
References: <20250820171812.402519-1-biju.das.jz@bp.renesas.com>
 <20250820171812.402519-4-biju.das.jz@bp.renesas.com>
 <20250820-primer-shaded-66da9fa4bcae@spud>
 <20250820-commodity-curator-1f580789885b@spud>
Message-ID: <TY3PR01MB113467039A598C0EDC284AE198632A@TY3PR01MB11346.jpnprd01.prod.outlook.com>

Hi Conor,

Thanks for the feedback.

> -----Original Message-----
> From: Conor Dooley <conor at kernel.org>
> Sent: 20 August 2025 21:13
> Subject: Re: [PATCH 03/11] dt-bindings: phy: renesas: Document Renesas RZ/G3E USB3.0 PHY
> 
> On Wed, Aug 20, 2025 at 09:10:07PM +0100, Conor Dooley wrote:
> > Acked-by: Conor Dooley <conor.dooley at microchip.com>
> 
> Now that I look again, same applies here with the different filename and compatible. Copypaste mistake?
> Or why does the compatible not match the filename?
> 

r9a09g047 is SoC part number which also known as RZ/G3E SoC.

I just followed the convention used in [1] and [2].
Please let me know, should I change rzg3e-usb3-phy.yaml.yaml-> r9a09g047-usb3-phy.yaml ?

[1]
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/Documentation/devicetree/bindings?h=next-20250820&id=44b91d61c505863b8ae90b7094aee5ca0dce808f

[2]
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/Documentation/devicetree/bindings?h=next-20250820&id=b2d25905366b4e6791f60e6bc76a636d1b88e6f8

Cheers,
Biju



From pritam.sutar at samsung.com  Thu Aug 21 00:36:58 2025
From: pritam.sutar at samsung.com (Pritam Manohar Sutar)
Date: Thu, 21 Aug 2025 13:06:58 +0530
Subject: [PATCH v6 1/6] dt-bindings: phy: samsung,usb3-drd-phy: add
 ExynosAutov920 HS phy compatible
In-Reply-To: <20250821073703.2498302-1-pritam.sutar@samsung.com>
References: <20250821073703.2498302-1-pritam.sutar@samsung.com>
	<CGME20250821072804epcas5p20256917f2a714f4946139174f8fc20f5@epcas5p2.samsung.com>
Message-ID: <20250821073703.2498302-2-pritam.sutar@samsung.com>

This SoC has USB2.0 phy and supports only UTMI+ interface. This phy
requires two clocks, named as "phy" and "ref". The required supplies for
this phy are vdd075_usb20(0.75v), vdd18_usb20(1.8v), vdd33_usb20(3.3v).

Add a dedicated compatible string for USB HS phy found in this SoC.

Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
---
 .../bindings/phy/samsung,usb3-drd-phy.yaml    | 24 +++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
index e906403208c0..e238fd0c9f6c 100644
--- a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
@@ -34,6 +34,7 @@ properties:
       - samsung,exynos7870-usbdrd-phy
       - samsung,exynos850-usbdrd-phy
       - samsung,exynos990-usbdrd-phy
+      - samsung,exynosautov920-usbdrd-phy
 
   clocks:
     minItems: 1
@@ -110,6 +111,12 @@ properties:
   vddh-usbdp-supply:
     description: VDDh power supply for the USB DP phy.
 
+  dvdd075-usb20-supply:
+    description: 0.75V power supply for the USB 2.0 phy.
+
+  vdd18-usb20-supply:
+    description: 1.8V power supply for the USB 2.0 phy.
+
 required:
   - compatible
   - clocks
@@ -219,6 +226,7 @@ allOf:
               - samsung,exynos7870-usbdrd-phy
               - samsung,exynos850-usbdrd-phy
               - samsung,exynos990-usbdrd-phy
+              - samsung,exynosautov920-usbdrd-phy
     then:
       properties:
         clocks:
@@ -235,6 +243,22 @@ allOf:
 
         reg-names:
           maxItems: 1
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - samsung,exynosautov920-usbdrd-phy
+    then:
+      required:
+        - dvdd075-usb20-supply
+        - vdd18-usb20-supply
+        - vdd33-usb20-supply
+
+    else:
+      properties:
+        dvdd075-usb20-supply: false
+        vdd18-usb20-supply: false
 
 unevaluatedProperties: false
 
-- 
2.34.1



From pritam.sutar at samsung.com  Thu Aug 21 00:36:59 2025
From: pritam.sutar at samsung.com (Pritam Manohar Sutar)
Date: Thu, 21 Aug 2025 13:06:59 +0530
Subject: [PATCH v6 2/6] phy: exynos5-usbdrd: support HS phy for
 ExynosAutov920
In-Reply-To: <20250821073703.2498302-1-pritam.sutar@samsung.com>
References: <20250821073703.2498302-1-pritam.sutar@samsung.com>
	<CGME20250821072807epcas5p2d8e2e2508cf2318b640a45cc54ee3afa@epcas5p2.samsung.com>
Message-ID: <20250821073703.2498302-3-pritam.sutar@samsung.com>

Enable UTMI+ phy support for this SoC which is very similar to what
the existing Exynos850 supports.

Add required change in phy driver to support HS phy for this SoC.

Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
---
 drivers/phy/samsung/phy-exynos5-usbdrd.c    | 123 ++++++++++++++++++++
 include/linux/soc/samsung/exynos-regs-pmu.h |   2 +
 2 files changed, 125 insertions(+)

diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
index a88ba95bdc8f..b238d14e2f4a 100644
--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
+++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
@@ -2054,6 +2054,126 @@ static const struct exynos5_usbdrd_phy_drvdata exynos990_usbdrd_phy = {
 	.n_regulators		= ARRAY_SIZE(exynos5_regulator_names),
 };
 
+static int exynosautov920_usbdrd_phy_init(struct phy *phy)
+{
+	struct phy_usb_instance *inst = phy_get_drvdata(phy);
+	struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
+	int ret;
+
+	ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks);
+	if (ret)
+		return ret;
+
+	/* Bypass PHY isol */
+	inst->phy_cfg->phy_isol(inst, false);
+
+	/* UTMI or PIPE3 specific init */
+	inst->phy_cfg->phy_init(phy_drd);
+
+	clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks);
+
+	return 0;
+}
+
+static int exynosautov920_usbdrd_phy_exit(struct phy *phy)
+{
+	struct phy_usb_instance *inst = phy_get_drvdata(phy);
+	struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
+	int ret;
+
+	ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks);
+	if (ret)
+		return ret;
+
+	exynos850_usbdrd_phy_exit(phy);
+
+	/* enable PHY isol */
+	inst->phy_cfg->phy_isol(inst, true);
+
+	clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks);
+
+	return 0;
+}
+
+static int exynosautov920_usbdrd_phy_power_on(struct phy *phy)
+{
+	struct phy_usb_instance *inst = phy_get_drvdata(phy);
+	struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
+	int ret;
+
+	dev_dbg(phy_drd->dev, "Request to power_on usbdrd_phy phy\n");
+
+	ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_core_clks,
+				      phy_drd->core_clks);
+	if (ret)
+		return ret;
+
+	/* Enable supply */
+	ret = regulator_bulk_enable(phy_drd->drv_data->n_regulators,
+				    phy_drd->regulators);
+	if (ret) {
+		dev_err(phy_drd->dev, "Failed to enable PHY regulator(s)\n");
+		goto fail_supply;
+	}
+
+	return 0;
+
+fail_supply:
+	clk_bulk_disable_unprepare(phy_drd->drv_data->n_core_clks,
+				   phy_drd->core_clks);
+
+	return ret;
+}
+
+static int exynosautov920_usbdrd_phy_power_off(struct phy *phy)
+{
+	struct phy_usb_instance *inst = phy_get_drvdata(phy);
+	struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
+
+	dev_dbg(phy_drd->dev, "Request to power_off usbdrd_phy phy\n");
+
+	/* Disable supply */
+	regulator_bulk_disable(phy_drd->drv_data->n_regulators,
+			       phy_drd->regulators);
+
+	clk_bulk_disable_unprepare(phy_drd->drv_data->n_core_clks,
+				   phy_drd->core_clks);
+
+	return 0;
+}
+
+static const char * const exynosautov920_usb20_regulators[] = {
+	"dvdd075-usb20", "vdd18-usb20", "vdd33-usb20",
+};
+
+static const struct phy_ops exynosautov920_usbdrd_phy_ops = {
+	.init		= exynosautov920_usbdrd_phy_init,
+	.exit		= exynosautov920_usbdrd_phy_exit,
+	.power_on       = exynosautov920_usbdrd_phy_power_on,
+	.power_off      = exynosautov920_usbdrd_phy_power_off,
+	.owner		= THIS_MODULE,
+};
+
+static const struct exynos5_usbdrd_phy_config phy_cfg_exynosautov920[] = {
+	{
+		.id		= EXYNOS5_DRDPHY_UTMI,
+		.phy_isol	= exynos5_usbdrd_phy_isol,
+		.phy_init	= exynos850_usbdrd_utmi_init,
+	},
+};
+
+static const struct exynos5_usbdrd_phy_drvdata exynosautov920_usbdrd_phy = {
+	.phy_cfg		= phy_cfg_exynosautov920,
+	.phy_ops		= &exynosautov920_usbdrd_phy_ops,
+	.pmu_offset_usbdrd0_phy	= EXYNOSAUTOV920_PHY_CTRL_USB20,
+	.clk_names		= exynos5_clk_names,
+	.n_clks			= ARRAY_SIZE(exynos5_clk_names),
+	.core_clk_names		= exynos5_core_clk_names,
+	.n_core_clks		= ARRAY_SIZE(exynos5_core_clk_names),
+	.regulator_names	= exynosautov920_usb20_regulators,
+	.n_regulators		= ARRAY_SIZE(exynosautov920_usb20_regulators),
+};
+
 static const struct exynos5_usbdrd_phy_config phy_cfg_gs101[] = {
 	{
 		.id		= EXYNOS5_DRDPHY_UTMI,
@@ -2260,6 +2380,9 @@ static const struct of_device_id exynos5_usbdrd_phy_of_match[] = {
 	}, {
 		.compatible = "samsung,exynos990-usbdrd-phy",
 		.data = &exynos990_usbdrd_phy
+	}, {
+		.compatible = "samsung,exynosautov920-usbdrd-phy",
+		.data = &exynosautov920_usbdrd_phy
 	},
 	{ },
 };
diff --git a/include/linux/soc/samsung/exynos-regs-pmu.h b/include/linux/soc/samsung/exynos-regs-pmu.h
index 71e0c09a49eb..4923f9be3d1f 100644
--- a/include/linux/soc/samsung/exynos-regs-pmu.h
+++ b/include/linux/soc/samsung/exynos-regs-pmu.h
@@ -688,4 +688,6 @@
 #define GS101_GRP2_INTR_BID_UPEND				(0x0208)
 #define GS101_GRP2_INTR_BID_CLEAR				(0x020c)
 
+/* exynosautov920 */
+#define EXYNOSAUTOV920_PHY_CTRL_USB20				(0x0710)
 #endif /* __LINUX_SOC_EXYNOS_REGS_PMU_H */
-- 
2.34.1



From pritam.sutar at samsung.com  Thu Aug 21 00:37:00 2025
From: pritam.sutar at samsung.com (Pritam Manohar Sutar)
Date: Thu, 21 Aug 2025 13:07:00 +0530
Subject: [PATCH v6 3/6] dt-bindings: phy: samsung,usb3-drd-phy: add
 ExynosAutov920 combo hsphy
In-Reply-To: <20250821073703.2498302-1-pritam.sutar@samsung.com>
References: <20250821073703.2498302-1-pritam.sutar@samsung.com>
	<CGME20250821072811epcas5p39b60f480203e26e99dec09321951d4ea@epcas5p3.samsung.com>
Message-ID: <20250821073703.2498302-4-pritam.sutar@samsung.com>

This phy only supports USB2.0 HS(480Mbps), FS(12Mbps) and
LS(1.5Mbps) data rates. It requires two clocks, named as "phy" and "ref".
The required supplies for this phy, named as vdd075_usb20(0.75v),
vdd18_usb20(1.8v), vdd33_usb20(3.3v).

Add schema for combo hsphy found on this SoC.

Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
---
 .../devicetree/bindings/phy/samsung,usb3-drd-phy.yaml          | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
index e238fd0c9f6c..f0cfca5736b8 100644
--- a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
@@ -34,6 +34,7 @@ properties:
       - samsung,exynos7870-usbdrd-phy
       - samsung,exynos850-usbdrd-phy
       - samsung,exynos990-usbdrd-phy
+      - samsung,exynosautov920-usbdrd-combo-hsphy
       - samsung,exynosautov920-usbdrd-phy
 
   clocks:
@@ -226,6 +227,7 @@ allOf:
               - samsung,exynos7870-usbdrd-phy
               - samsung,exynos850-usbdrd-phy
               - samsung,exynos990-usbdrd-phy
+              - samsung,exynosautov920-usbdrd-combo-hsphy
               - samsung,exynosautov920-usbdrd-phy
     then:
       properties:
@@ -248,6 +250,7 @@ allOf:
         compatible:
           contains:
             enum:
+              - samsung,exynosautov920-usbdrd-combo-hsphy
               - samsung,exynosautov920-usbdrd-phy
     then:
       required:
-- 
2.34.1



From pritam.sutar at samsung.com  Thu Aug 21 00:36:57 2025
From: pritam.sutar at samsung.com (Pritam Manohar Sutar)
Date: Thu, 21 Aug 2025 13:06:57 +0530
Subject: [PATCH v6 0/6] initial usbdrd phy support for Exynosautov920 soc
References: <CGME20250821072800epcas5p4fb5ee3058bd9da196616f59a0db14899@epcas5p4.samsung.com>
Message-ID: <20250821073703.2498302-1-pritam.sutar@samsung.com>

This SoC has a single USB 3.1 DRD combo phy and three USB2.0 only
DRD phy controllers as mentined below

  * Combo phy supports USB3.1 SSP+(10Gbps) protocol and is backwards
    compatible to the USB3.0 SS(5Gbps). 'Add-on USB2.0' phy is added
    to support USB2.0 HS(480Mbps), FS(12Mbps) and LS(1.5Mbps) data rates.
    These two phys are combined to form a combo phy as mentioned below.


   USB30DRD_0 port

 +------------------------------------------------------------+
 |                                                            |
 |                (combo) USB phy controller                  |
 |      +----------------------------------------------+      |
 |      |                  USB HSPHY                   |      |
 |      |  (samsung,exynosautov920-usbdrd-combo-hsphy) |      |
 |      +----------------------------------------------+      |
 |                                                            |
 |    +--------------------------------------------------+    |
 |    |                   USB SSPHY                      |    |
 |    |   (samsung,exynosautov920-usb31drd-combo-ssphy)  |    |
 |    +--------------------------------------------------+-   |
 |                                                            |
 +------------------------------------------------------------+
 |                                                            |
 |                     USBDRD30 Link                          |
 |                       Controller                           |
 +------------------------------------------------------------+

  * USB2.0 phy supports only UTMI+ interface. USB2.0DRD phy
    is very similar to the existing Exynos850 support in this driver.

    USB20DRD_0/1/2 ports

      +---------------------------------------------------+
      |                                                   |
      |                USB PHY controller                 |
      |    +-----------------------------------------+    |
      |    |              USB HSPHY                  |    |
      |    |  (samsung,exynosautov920-usbdrd-phy)    |    |
      |    +-----------------------------------------+    |
      |                                                   |
      +---------------------------------------------------+
      |                                                   |
      |             USBDRD20_* Link                       |
      |                Controller                         |
      |                                                   |
      +---------------------------------------------------+

The "USB20 phy output isolation" is shared across the USB20 phys.
We have to bypass isolation when any one of the USBs is configured
and enable it when all are turned off. The "USB31 phy isolation"
is seperate for USB31 phy.

This patchset only supports device mode and same is verified with
as NCM device

changelog
----------
Changes in v6:
- added else part for new supplies in schemas those are only
  supported for exynosautov920.
- addressed comments for driver given in v5.
  link for v5: https://lore.kernel.org/linux-phy/20250805115216.3798121-1-pritam.sutar at samsung.com/

Changes in v5:
- significant changes were added in v4, removed "Reviewed-by" tag.
- addressed comments from v4 patchset.
  - patch (1/6)
    - DTS style is corrected and added required supplies in code/schema.
    - schema block added to resolve below failure during 'dtbs_check'.
      Unevaluated properties are not allowed ('dvdd075-usb-supply', 'vdd18-usb20-supply', 'vdd33-usb20-supply' were unexpected.
  - patch (2/6)
    - removed usage_counter(take this later in subsequent patch-sets)
  - patch (3/6)
    - There are 3 types of the phys in this SoC.
      - one is simmilar with exynos850 as mentioned in patch no.1.
      - second supports only USB3.1 SSP+ and denoted in patch no 5
      - third supports only USB2.0 HS as in patch3.
    - hs phy in combo phy is "NOT" same as phy. (in patch no. 1)
    - These three phys(usbdrd-phy, combo-hsphy, combo-ssphy) are totally
      deferent, "NOT" same, hence added three compatible for three phys.
  - patch (5/6)
    - Since there are two phys in combo phy, explaination is given
      in each patch.
  link for v4: https://lore.kernel.org/linux-phy/20250701120706.2219355-1-pritam.sutar at samsung.com/

Changes in v4:
- addressed comments from v3 patchset
  - removed dts related patches, to be posted in new patchset.
  - added regulator, pmu and power sequences.
  - phy isol is shared across USBs, added usage counter to bypass or
    enable phy isolation.
  - modified schemas with hs and combo phy compatible names
    (used "combo" to denote combo phy) and regulators
- modified code to work with binding and unbinding devices/drivers
- added "Reviewed-by" tag.
  link for v3: https://lore.kernel.org/linux-phy/20250613055613.866909-1-pritam.sutar at samsung.com/

Changes in v3:
- Updated dt-bindings for USB2.0 only.
- Added dt-bindings for combo phy.
- Added implementation for combo phy (SS and HS phy).
- Added added DTS nodes for all the phys
  link for v2: https://lore.kernel.org/linux-phy/20250516102650.2144487-1-pritam.sutar at samsung.com/

Changes in v2:
- Used standard GENMASK() and FIELD_GET() to get the major version
  from controller version register.
  link for v1: https://lore.kernel.org/linux-phy/20250514134813.380807-1-pritam.sutar at samsung.com/

Pritam Manohar Sutar (6):
  dt-bindings: phy: samsung,usb3-drd-phy: add ExynosAutov920 HS phy
    compatible
  phy: exynos5-usbdrd: support HS phy for ExynosAutov920
  dt-bindings: phy: samsung,usb3-drd-phy: add ExynosAutov920 combo hsphy
  phy: exynos5-usbdrd: support HS combo phy for ExynosAutov920
  dt-bindings: phy: samsung,usb3-drd-phy: add ExynosAutov920 combo ssphy
  phy: exynos5-usbdrd: support SS combo phy for ExynosAutov920

 .../bindings/phy/samsung,usb3-drd-phy.yaml    |  50 ++
 drivers/phy/samsung/phy-exynos5-usbdrd.c      | 651 ++++++++++++++++++
 include/linux/soc/samsung/exynos-regs-pmu.h   |   3 +
 3 files changed, 704 insertions(+)

-- 
2.34.1



From pritam.sutar at samsung.com  Thu Aug 21 00:37:02 2025
From: pritam.sutar at samsung.com (Pritam Manohar Sutar)
Date: Thu, 21 Aug 2025 13:07:02 +0530
Subject: [PATCH v6 5/6] dt-bindings: phy: samsung,usb3-drd-phy: add
 ExynosAutov920 combo ssphy
In-Reply-To: <20250821073703.2498302-1-pritam.sutar@samsung.com>
References: <20250821073703.2498302-1-pritam.sutar@samsung.com>
	<CGME20250821072818epcas5p1763afdfb7f0b4cf48a98d9c4e6eca055@epcas5p1.samsung.com>
Message-ID: <20250821073703.2498302-6-pritam.sutar@samsung.com>

This phy supports USB3.1 SSP+(10Gbps) protocol and is backwards
compatible to the USB3.0 SS(5Gbps). It requires two clocks, named
"phy" and "ref". The required supplies for USB3.1 are named as
vdd075_usb30(0.75v), vdd18_usb30(1.8v).

Add schemas for combo ssphy found on this SoC.

Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
---
 .../bindings/phy/samsung,usb3-drd-phy.yaml    | 23 +++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
index f0cfca5736b8..96e5bbb2e42c 100644
--- a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
@@ -34,6 +34,7 @@ properties:
       - samsung,exynos7870-usbdrd-phy
       - samsung,exynos850-usbdrd-phy
       - samsung,exynos990-usbdrd-phy
+      - samsung,exynosautov920-usb31drd-combo-ssphy
       - samsung,exynosautov920-usbdrd-combo-hsphy
       - samsung,exynosautov920-usbdrd-phy
 
@@ -118,6 +119,12 @@ properties:
   vdd18-usb20-supply:
     description: 1.8V power supply for the USB 2.0 phy.
 
+  dvdd075-usb30-supply:
+    description: 0.75V power supply for the USB 3.0 phy.
+
+  vdd18-usb30-supply:
+    description: 1.8V power supply for the USB 3.0 phy.
+
 required:
   - compatible
   - clocks
@@ -227,6 +234,7 @@ allOf:
               - samsung,exynos7870-usbdrd-phy
               - samsung,exynos850-usbdrd-phy
               - samsung,exynos990-usbdrd-phy
+              - samsung,exynosautov920-usb31drd-combo-ssphy
               - samsung,exynosautov920-usbdrd-combo-hsphy
               - samsung,exynosautov920-usbdrd-phy
     then:
@@ -262,6 +270,21 @@ allOf:
       properties:
         dvdd075-usb20-supply: false
         vdd18-usb20-supply: false
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - samsung,exynosautov920-usb31drd-combo-ssphy
+    then:
+      required:
+        - dvdd075-usb30-supply
+        - vdd18-usb30-supply
+
+    else:
+      properties:
+        dvdd075-usb30-supply: false
+        vdd18-usb30-supply: false
 
 unevaluatedProperties: false
 
-- 
2.34.1



From pritam.sutar at samsung.com  Thu Aug 21 00:37:03 2025
From: pritam.sutar at samsung.com (Pritam Manohar Sutar)
Date: Thu, 21 Aug 2025 13:07:03 +0530
Subject: [PATCH v6 6/6] phy: exynos5-usbdrd: support SS combo phy for
 ExynosAutov920
In-Reply-To: <20250821073703.2498302-1-pritam.sutar@samsung.com>
References: <20250821073703.2498302-1-pritam.sutar@samsung.com>
	<CGME20250821072821epcas5p10ab75c76b70687d7b13b6593b771fdad@epcas5p1.samsung.com>
Message-ID: <20250821073703.2498302-7-pritam.sutar@samsung.com>

Add required change in phy driver to support combo SS phy for this SoC.

Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
---
 drivers/phy/samsung/phy-exynos5-usbdrd.c    | 325 +++++++++++++++++++-
 include/linux/soc/samsung/exynos-regs-pmu.h |   1 +
 2 files changed, 322 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
index 32178c5c120d..e0e90f614121 100644
--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
+++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
@@ -273,6 +273,36 @@
 #define EXYNOSAUTOV920_DRD_HSPPLLTUNE		0x110
 #define HSPPLLTUNE_FSEL				GENMASK(18, 16)
 
+/* ExynosAutov920 phy usb31drd port reg */
+#define EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL	0x000
+#define PHY_RST_CTRL_PIPE_LANE0_RESET_N_OVRD_EN	BIT(5)
+#define PHY_RST_CTRL_PIPE_LANE0_RESET_N		BIT(4)
+#define PHY_RST_CTRL_PHY_RESET_OVRD_EN		BIT(1)
+#define PHY_RST_CTRL_PHY_RESET			BIT(0)
+
+#define EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0	0x0004
+#define PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR		GENMASK(31, 16)
+#define PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK		BIT(8)
+#define PHY_CR_PARA_CON0_PHY0_CR_PARA_ACK		BIT(4)
+#define PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL		BIT(0)
+
+#define EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON1	0x0008
+
+#define EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2	0x000c
+#define PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_EN		BIT(0)
+#define PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_DATA		GENMASK(31, 16)
+
+#define EXYNOSAUTOV920_USB31DRD_PHY_CONFIG0	0x100
+#define PHY_CONFIG0_PHY0_PMA_PWR_STABLE		BIT(14)
+#define PHY_CONFIG0_PHY0_PCS_PWR_STABLE		BIT(13)
+#define PHY_CONFIG0_PHY0_ANA_PWR_EN		BIT(1)
+
+#define EXYNOSAUTOV920_USB31DRD_PHY_CONFIG7	0x11c
+#define PHY_CONFIG7_PHY_TEST_POWERDOWN		BIT(24)
+
+#define EXYNOSAUTOV920_USB31DRD_PHY_CONFIG4	0x110
+#define PHY_CONFIG4_PIPE_RX0_SRIS_MODE_EN	BIT(2)
+
 /* Exynos9 - GS101 */
 #define EXYNOS850_DRD_SECPMACTL			0x48
 #define SECPMACTL_PMA_ROPLL_REF_CLK_SEL		GENMASK(13, 12)
@@ -2077,6 +2107,251 @@ static const struct exynos5_usbdrd_phy_drvdata exynos990_usbdrd_phy = {
 	.n_regulators		= ARRAY_SIZE(exynos5_regulator_names),
 };
 
+static void
+exynosautov920_usb31drd_cr_clk(struct exynos5_usbdrd_phy *phy_drd, bool high)
+{
+	void __iomem *reg_phy = phy_drd->reg_phy;
+	u32 reg;
+
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
+	if (high)
+		reg |= PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK;
+	else
+		reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK;
+
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
+	fsleep(1);
+}
+
+static void
+exynosautov920_usb31drd_port_phy_ready(struct exynos5_usbdrd_phy *phy_drd)
+{
+	struct device *dev = phy_drd->dev;
+	void __iomem *reg_phy = phy_drd->reg_phy;
+	static const unsigned int timeout_us = 20000;
+	static const unsigned int sleep_us = 40;
+	u32 reg;
+	int err;
+
+	/* Clear cr_para_con */
+	reg &= ~(PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK |
+			PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR);
+	reg |= PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
+	writel(0x0, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON1);
+	writel(0x0, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2);
+
+	exynosautov920_usb31drd_cr_clk(phy_drd, true);
+	exynosautov920_usb31drd_cr_clk(phy_drd, false);
+
+	/*
+	 * The maximum time from phy reset de-assertion to de-assertion of
+	 * tx/rx_ack can be as high as 5ms in fast simulation mode.
+	 * Time to phy ready is < 20ms
+	 */
+	err = readl_poll_timeout(reg_phy +
+				EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0,
+			reg, !(reg & PHY_CR_PARA_CON0_PHY0_CR_PARA_ACK),
+			sleep_us, timeout_us);
+	if (err)
+		dev_err(dev, "timed out waiting for rx/tx_ack: %#.8x\n", reg);
+
+	reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
+}
+
+static void
+exynosautov920_usb31drd_cr_write(struct exynos5_usbdrd_phy *phy_drd,
+				 u16 addr, u16 data)
+{
+	struct device *dev = phy_drd->dev;
+	void __iomem *reg_phy = phy_drd->reg_phy;
+	u32 cnt = 0;
+	u32 reg;
+
+	/* Pre Clocking */
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
+	reg |= PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
+
+	/*
+	 * tx clks must be available prior to assertion of tx req.
+	 * tx pstate p2 to p0 transition directly is not permitted.
+	 * tx clk ready must be asserted synchronously on tx clk prior
+	 * to internal transmit clk alignment sequence in the phy
+	 * when entering from p2 to p1 to p0.
+	 */
+	do {
+		exynosautov920_usb31drd_cr_clk(phy_drd, true);
+		exynosautov920_usb31drd_cr_clk(phy_drd, false);
+		cnt++;
+	} while (cnt < 15);
+
+	reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
+
+	/*
+	 * tx data path is active when tx lane is in p0 state
+	 * and tx data en asserted. enable cr_para_wr_en.
+	 */
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2);
+	reg &= ~PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_DATA;
+	reg |= FIELD_PREP(PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_DATA, data) |
+		PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_EN;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2);
+
+	/* write addr */
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
+	reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR;
+	reg |= FIELD_PREP(PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR, addr) |
+		PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK |
+		PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
+
+	/* check cr_para_ack*/
+	cnt = 0;
+	do {
+		/*
+		 * data symbols are captured by phy on rising edge of the
+		 * tx_clk when tx data enabled.
+		 * completion of the write cycle is acknowledged by assertion
+		 * of the cr_para_ack.
+		 */
+		exynosautov920_usb31drd_cr_clk(phy_drd, true);
+		reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
+		if ((reg & PHY_CR_PARA_CON0_PHY0_CR_PARA_ACK))
+			break;
+
+		exynosautov920_usb31drd_cr_clk(phy_drd, false);
+
+		/*
+		 * wait for minimum of 10 cr_para_clk cycles after phy reset
+		 * is negated, before accessing control regs to allow for
+		 * internal resets.
+		 */
+		cnt++;
+	} while (cnt < 10);
+
+	if (cnt < 10)
+		exynosautov920_usb31drd_cr_clk(phy_drd, false);
+}
+
+static void
+exynosautov920_usb31drd_phy_reset(struct exynos5_usbdrd_phy *phy_drd, int val)
+{
+	void __iomem *reg_phy = phy_drd->reg_phy;
+	u32 reg;
+
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL);
+	reg &= ~PHY_RST_CTRL_PHY_RESET_OVRD_EN;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL);
+
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL);
+	if (val)
+		reg |= PHY_RST_CTRL_PHY_RESET;
+	else
+		reg &= ~PHY_RST_CTRL_PHY_RESET;
+
+	reg |= PHY_RST_CTRL_PHY_RESET_OVRD_EN;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL);
+}
+
+static void
+exynosautov920_usb31drd_lane0_reset(struct exynos5_usbdrd_phy *phy_drd, int val)
+{
+	void __iomem *reg_phy = phy_drd->reg_phy;
+	u32 reg;
+
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL);
+	reg |= PHY_RST_CTRL_PIPE_LANE0_RESET_N_OVRD_EN;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL);
+
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL);
+	if (val)
+		reg &= ~PHY_RST_CTRL_PIPE_LANE0_RESET_N;
+	else
+		reg |= PHY_RST_CTRL_PIPE_LANE0_RESET_N;
+
+	reg &= ~PHY_RST_CTRL_PIPE_LANE0_RESET_N_OVRD_EN;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL);
+}
+
+static void
+exynosautov920_usb31drd_pipe3_init(struct exynos5_usbdrd_phy *phy_drd)
+{
+	void __iomem *reg_phy = phy_drd->reg_phy;
+	u32 reg;
+
+	/*
+	 * Phy and Pipe Lane reset assert.
+	 * assert reset (phy_reset = 1).
+	 * The lane-ack outputs are asserted during reset (tx_ack = rx_ack = 1)
+	 */
+	exynosautov920_usb31drd_phy_reset(phy_drd, 1);
+	exynosautov920_usb31drd_lane0_reset(phy_drd, 1);
+
+	/*
+	 * ANA Power En, PCS & PMA PWR Stable Set
+	 * ramp-up power suppiles
+	 */
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG0);
+	reg |= PHY_CONFIG0_PHY0_ANA_PWR_EN | PHY_CONFIG0_PHY0_PCS_PWR_STABLE |
+		PHY_CONFIG0_PHY0_PMA_PWR_STABLE;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG0);
+
+	fsleep(10);
+
+	/*
+	 * phy is not functional in test_powerdown mode, test_powerdown to be
+	 * de-asserted for normal operation
+	 */
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG7);
+	reg &= ~PHY_CONFIG7_PHY_TEST_POWERDOWN;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG7);
+
+	/*
+	 * phy reset signal be asserted for minimum 10us after power
+	 * supplies are ramped-up
+	 */
+	fsleep(10);
+
+	/*
+	 * Phy and Pipe Lane reset assert de-assert
+	 */
+	exynosautov920_usb31drd_phy_reset(phy_drd, 0);
+	exynosautov920_usb31drd_lane0_reset(phy_drd, 0);
+
+	/* Pipe_rx0_sris_mode_en  = 1 */
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG4);
+	reg |= PHY_CONFIG4_PIPE_RX0_SRIS_MODE_EN;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG4);
+
+	/*
+	 * wait for lane ack outputs to de-assert (tx_ack = rx_ack = 0)
+	 * Exit from the reset state is indicated by de-assertion of *_ack
+	 */
+	exynosautov920_usb31drd_port_phy_ready(phy_drd);
+
+	/* override values for level settings */
+	exynosautov920_usb31drd_cr_write(phy_drd, 0x22, 0x00F5);
+}
+
+static void
+exynosautov920_usb31drd_ssphy_disable(struct exynos5_usbdrd_phy *phy_drd)
+{
+	void __iomem *reg_phy = phy_drd->reg_phy;
+	u32 reg;
+
+	/* 1. Assert reset (phy_reset = 1) */
+	exynosautov920_usb31drd_lane0_reset(phy_drd, 1);
+	exynosautov920_usb31drd_phy_reset(phy_drd, 1);
+
+	/* phy test power down */
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG7);
+	reg |= PHY_CONFIG7_PHY_TEST_POWERDOWN;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG7);
+}
+
 static void
 exynosautov920_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd)
 {
@@ -2172,12 +2447,15 @@ exynosautov920_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd)
 	/* after POR low and delay 75us, PHYCLOCK is guaranteed. */
 	fsleep(75);
 
-	/* force pipe3 signal for link */
+	/* Disable forcing pipe interface */
 	reg = readl(reg_phy + EXYNOS850_DRD_LINKCTRL);
-	reg |= LINKCTRL_FORCE_PIPE_EN;
-	reg &= ~LINKCTRL_FORCE_PHYSTATUS;
-	reg |= LINKCTRL_FORCE_RXELECIDLE;
+	reg &= ~LINKCTRL_FORCE_PIPE_EN;
 	writel(reg, reg_phy + EXYNOS850_DRD_LINKCTRL);
+
+	/* Pclk to pipe_clk */
+	reg = readl(reg_phy + EXYNOS2200_DRD_CLKRST);
+	reg |= EXYNOS2200_CLKRST_LINK_PCLK_SEL;
+	writel(reg, reg_phy + EXYNOS2200_DRD_CLKRST);
 }
 
 static void
@@ -2264,6 +2542,8 @@ static int exynosautov920_usbdrd_combo_phy_exit(struct phy *phy)
 
 	if (inst->phy_cfg->id == EXYNOS5_DRDPHY_UTMI)
 		exynosautov920_usbdrd_hsphy_disable(phy_drd);
+	else if (inst->phy_cfg->id == EXYNOS5_DRDPHY_PIPE3)
+		exynosautov920_usb31drd_ssphy_disable(phy_drd);
 
 	/* enable PHY isol */
 	inst->phy_cfg->phy_isol(inst, true);
@@ -2320,10 +2600,44 @@ static int exynosautov920_usbdrd_phy_power_off(struct phy *phy)
 	return 0;
 }
 
+static const char * const exynosautov920_usb30_regulators[] = {
+	"dvdd075-usb30", "vdd18-usb30",
+};
+
 static const char * const exynosautov920_usb20_regulators[] = {
 	"dvdd075-usb20", "vdd18-usb20", "vdd33-usb20",
 };
 
+static const struct
+exynos5_usbdrd_phy_config usb31drd_phy_cfg_exynosautov920[] = {
+	{
+		.id		= EXYNOS5_DRDPHY_PIPE3,
+		.phy_isol	= exynos5_usbdrd_phy_isol,
+		.phy_init	= exynosautov920_usb31drd_pipe3_init,
+	},
+};
+
+static const struct phy_ops exynosautov920_usb31drd_combo_ssphy_ops = {
+	.init		= exynosautov920_usbdrd_phy_init,
+	.exit		= exynosautov920_usbdrd_combo_phy_exit,
+	.power_on	= exynosautov920_usbdrd_phy_power_on,
+	.power_off	= exynosautov920_usbdrd_phy_power_off,
+	.owner		= THIS_MODULE,
+};
+
+static const
+struct exynos5_usbdrd_phy_drvdata exynosautov920_usb31drd_combo_ssphy = {
+	.phy_cfg		= usb31drd_phy_cfg_exynosautov920,
+	.phy_ops		= &exynosautov920_usb31drd_combo_ssphy_ops,
+	.pmu_offset_usbdrd0_phy	= EXYNOSAUTOV920_PHY_CTRL_USB31,
+	.clk_names		= exynos5_clk_names,
+	.n_clks			= ARRAY_SIZE(exynos5_clk_names),
+	.core_clk_names		= exynos5_core_clk_names,
+	.n_core_clks		= ARRAY_SIZE(exynos5_core_clk_names),
+	.regulator_names	= exynosautov920_usb30_regulators,
+	.n_regulators		= ARRAY_SIZE(exynosautov920_usb30_regulators),
+};
+
 static const struct phy_ops exynosautov920_usbdrd_combo_hsphy_ops = {
 	.init		= exynosautov920_usbdrd_phy_init,
 	.exit		= exynosautov920_usbdrd_combo_phy_exit,
@@ -2588,6 +2902,9 @@ static const struct of_device_id exynos5_usbdrd_phy_of_match[] = {
 	}, {
 		.compatible = "samsung,exynos990-usbdrd-phy",
 		.data = &exynos990_usbdrd_phy
+	}, {
+		.compatible = "samsung,exynosautov920-usb31drd-combo-ssphy",
+		.data = &exynosautov920_usb31drd_combo_ssphy
 	}, {
 		.compatible = "samsung,exynosautov920-usbdrd-combo-hsphy",
 		.data = &exynosautov920_usbdrd_combo_hsphy
diff --git a/include/linux/soc/samsung/exynos-regs-pmu.h b/include/linux/soc/samsung/exynos-regs-pmu.h
index 4923f9be3d1f..f96c773b85c9 100644
--- a/include/linux/soc/samsung/exynos-regs-pmu.h
+++ b/include/linux/soc/samsung/exynos-regs-pmu.h
@@ -690,4 +690,5 @@
 
 /* exynosautov920 */
 #define EXYNOSAUTOV920_PHY_CTRL_USB20				(0x0710)
+#define EXYNOSAUTOV920_PHY_CTRL_USB31				(0x0714)
 #endif /* __LINUX_SOC_EXYNOS_REGS_PMU_H */
-- 
2.34.1



From pritam.sutar at samsung.com  Thu Aug 21 00:37:01 2025
From: pritam.sutar at samsung.com (Pritam Manohar Sutar)
Date: Thu, 21 Aug 2025 13:07:01 +0530
Subject: [PATCH v6 4/6] phy: exynos5-usbdrd: support HS combo phy for
 ExynosAutov920
In-Reply-To: <20250821073703.2498302-1-pritam.sutar@samsung.com>
References: <20250821073703.2498302-1-pritam.sutar@samsung.com>
	<CGME20250821072814epcas5p2814d441d6ed81acc86f6c5b449bd0b4d@epcas5p2.samsung.com>
Message-ID: <20250821073703.2498302-5-pritam.sutar@samsung.com>

Support UTMI+ combo phy for this SoC which is somewhat simmilar to
what the existing Exynos850 support does. The difference is that
some register offsets and bit fields are defferent from Exynos850.

Add required change in phy driver to support combo HS phy for this SoC.

Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
---
 drivers/phy/samsung/phy-exynos5-usbdrd.c | 211 +++++++++++++++++++++++
 1 file changed, 211 insertions(+)

diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
index b238d14e2f4a..32178c5c120d 100644
--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
+++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
@@ -41,6 +41,13 @@
 #define EXYNOS2200_CLKRST_LINK_PCLK_SEL		BIT(1)
 
 #define EXYNOS2200_DRD_UTMI			0x10
+
+/* ExynosAutov920 bits */
+#define UTMICTL_FORCE_UTMI_SUSPEND		BIT(13)
+#define UTMICTL_FORCE_UTMI_SLEEP		BIT(12)
+#define UTMICTL_FORCE_DPPULLDOWN		BIT(9)
+#define UTMICTL_FORCE_DMPULLDOWN		BIT(8)
+
 #define EXYNOS2200_UTMI_FORCE_VBUSVALID		BIT(1)
 #define EXYNOS2200_UTMI_FORCE_BVALID		BIT(0)
 
@@ -250,6 +257,22 @@
 #define EXYNOS850_DRD_HSP_TEST			0x5c
 #define HSP_TEST_SIDDQ				BIT(24)
 
+#define EXYNOSAUTOV920_DRD_HSP_CLKRST		0x100
+#define HSPCLKRST_PHY20_SW_PORTRESET		BIT(3)
+#define HSPCLKRST_PHY20_SW_POR			BIT(1)
+#define HSPCLKRST_PHY20_SW_POR_SEL		BIT(0)
+
+#define EXYNOSAUTOV920_DRD_HSPCTL		0x104
+#define HSPCTRL_VBUSVLDEXTSEL			BIT(13)
+#define HSPCTRL_VBUSVLDEXT			BIT(12)
+#define HSPCTRL_EN_UTMISUSPEND			BIT(9)
+#define HSPCTRL_COMMONONN			BIT(8)
+
+#define EXYNOSAUTOV920_DRD_HSP_TEST		0x10c
+
+#define EXYNOSAUTOV920_DRD_HSPPLLTUNE		0x110
+#define HSPPLLTUNE_FSEL				GENMASK(18, 16)
+
 /* Exynos9 - GS101 */
 #define EXYNOS850_DRD_SECPMACTL			0x48
 #define SECPMACTL_PMA_ROPLL_REF_CLK_SEL		GENMASK(13, 12)
@@ -2054,6 +2077,140 @@ static const struct exynos5_usbdrd_phy_drvdata exynos990_usbdrd_phy = {
 	.n_regulators		= ARRAY_SIZE(exynos5_regulator_names),
 };
 
+static void
+exynosautov920_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd)
+{
+	void __iomem *reg_phy = phy_drd->reg_phy;
+	u32 reg;
+
+	/*
+	 * Disable HWACG (hardware auto clock gating control). This
+	 * forces QACTIVE signal in Q-Channel interface to HIGH level,
+	 * to make sure the PHY clock is not gated by the hardware.
+	 */
+	reg = readl(reg_phy + EXYNOS850_DRD_LINKCTRL);
+	reg |= LINKCTRL_FORCE_QACT;
+	writel(reg, reg_phy + EXYNOS850_DRD_LINKCTRL);
+
+	/* De-assert link reset */
+	reg = readl(reg_phy + EXYNOS2200_DRD_CLKRST);
+	reg &= ~CLKRST_LINK_SW_RST;
+	writel(reg, reg_phy + EXYNOS2200_DRD_CLKRST);
+
+	/* Set PHY POR High */
+	reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSP_CLKRST);
+	reg |= HSPCLKRST_PHY20_SW_POR | HSPCLKRST_PHY20_SW_POR_SEL;
+	writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSP_CLKRST);
+
+	/* Enable UTMI+ */
+	reg = readl(reg_phy + EXYNOS2200_DRD_UTMI);
+	reg &= ~(UTMICTL_FORCE_UTMI_SUSPEND | UTMICTL_FORCE_UTMI_SLEEP |
+		UTMICTL_FORCE_DPPULLDOWN | UTMICTL_FORCE_DMPULLDOWN);
+	writel(reg, reg_phy + EXYNOS2200_DRD_UTMI);
+
+	/* set phy clock & control HS phy */
+	reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSPCTL);
+	reg |= HSPCTRL_EN_UTMISUSPEND | HSPCTRL_COMMONONN;
+	writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSPCTL);
+
+	fsleep(100);
+
+	/* Set VBUS Valid and DP-Pull up control by VBUS pad usage */
+	reg = readl(reg_phy + EXYNOS850_DRD_LINKCTRL);
+	reg |= FIELD_PREP_CONST(LINKCTRL_BUS_FILTER_BYPASS, 0xf);
+	writel(reg, reg_phy + EXYNOS850_DRD_LINKCTRL);
+
+	reg = readl(reg_phy + EXYNOS2200_DRD_UTMI);
+	reg |= EXYNOS2200_UTMI_FORCE_VBUSVALID | EXYNOS2200_UTMI_FORCE_BVALID;
+	writel(reg, reg_phy + EXYNOS2200_DRD_UTMI);
+
+	reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSPCTL);
+	reg |= HSPCTRL_VBUSVLDEXTSEL | HSPCTRL_VBUSVLDEXT;
+	writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSPCTL);
+
+	/* Setting FSEL for refference clock */
+	reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSPPLLTUNE);
+	reg &= ~HSPPLLTUNE_FSEL;
+
+	switch (phy_drd->extrefclk) {
+	case EXYNOS5_FSEL_50MHZ:
+		reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 7);
+		break;
+	case EXYNOS5_FSEL_26MHZ:
+		reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 6);
+		break;
+	case EXYNOS5_FSEL_24MHZ:
+		reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 2);
+		break;
+	case EXYNOS5_FSEL_20MHZ:
+		reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 1);
+		break;
+	case EXYNOS5_FSEL_19MHZ2:
+		reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 0);
+		break;
+	default:
+		dev_warn(phy_drd->dev, "unsupported ref clk: %#.2x\n",
+			 phy_drd->extrefclk);
+		break;
+	}
+	writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSPPLLTUNE);
+
+	/* Enable PHY Power Mode */
+	reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSP_TEST);
+	reg &= ~HSP_TEST_SIDDQ;
+	writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSP_TEST);
+
+	/* before POR low, 10us delay is needed to Finish PHY reset */
+	fsleep(10);
+
+	/* Set PHY POR Low */
+	reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSP_CLKRST);
+	reg |= HSPCLKRST_PHY20_SW_POR_SEL;
+	reg &= ~(HSPCLKRST_PHY20_SW_POR | HSPCLKRST_PHY20_SW_PORTRESET);
+	writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSP_CLKRST);
+
+	/* after POR low and delay 75us, PHYCLOCK is guaranteed. */
+	fsleep(75);
+
+	/* force pipe3 signal for link */
+	reg = readl(reg_phy + EXYNOS850_DRD_LINKCTRL);
+	reg |= LINKCTRL_FORCE_PIPE_EN;
+	reg &= ~LINKCTRL_FORCE_PHYSTATUS;
+	reg |= LINKCTRL_FORCE_RXELECIDLE;
+	writel(reg, reg_phy + EXYNOS850_DRD_LINKCTRL);
+}
+
+static void
+exynosautov920_usbdrd_hsphy_disable(struct exynos5_usbdrd_phy *phy_drd)
+{
+	u32 reg;
+	void __iomem *reg_phy = phy_drd->reg_phy;
+
+	/* set phy clock & control HS phy */
+	reg = readl(reg_phy + EXYNOS2200_DRD_UTMI);
+	reg |= UTMICTL_FORCE_UTMI_SUSPEND | UTMICTL_FORCE_UTMI_SLEEP;
+	reg &= ~(UTMICTL_FORCE_DPPULLDOWN | UTMICTL_FORCE_DMPULLDOWN);
+	writel(reg, reg_phy + EXYNOS2200_DRD_UTMI);
+
+	/* Disable PHY Power Mode */
+	reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSP_TEST);
+	reg |= HSP_TEST_SIDDQ;
+	writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSP_TEST);
+
+	/* clear force q-channel */
+	reg = readl(reg_phy + EXYNOS850_DRD_LINKCTRL);
+	reg &= ~LINKCTRL_FORCE_QACT;
+	writel(reg, reg_phy + EXYNOS850_DRD_LINKCTRL);
+
+	/* link sw reset is need for USB_DP/DM high-z in host mode */
+	reg = readl(reg_phy + EXYNOS2200_DRD_CLKRST);
+	reg |= CLKRST_LINK_SW_RST;
+	writel(reg, reg_phy + EXYNOS2200_DRD_CLKRST);
+	fsleep(10);
+	reg &= ~CLKRST_LINK_SW_RST;
+	writel(reg, reg_phy + EXYNOS2200_DRD_CLKRST);
+}
+
 static int exynosautov920_usbdrd_phy_init(struct phy *phy)
 {
 	struct phy_usb_instance *inst = phy_get_drvdata(phy);
@@ -2095,6 +2252,27 @@ static int exynosautov920_usbdrd_phy_exit(struct phy *phy)
 	return 0;
 }
 
+static int exynosautov920_usbdrd_combo_phy_exit(struct phy *phy)
+{
+	struct phy_usb_instance *inst = phy_get_drvdata(phy);
+	struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
+	int ret = 0;
+
+	ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks);
+	if (ret)
+		return ret;
+
+	if (inst->phy_cfg->id == EXYNOS5_DRDPHY_UTMI)
+		exynosautov920_usbdrd_hsphy_disable(phy_drd);
+
+	/* enable PHY isol */
+	inst->phy_cfg->phy_isol(inst, true);
+
+	clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks);
+
+	return 0;
+}
+
 static int exynosautov920_usbdrd_phy_power_on(struct phy *phy)
 {
 	struct phy_usb_instance *inst = phy_get_drvdata(phy);
@@ -2146,6 +2324,36 @@ static const char * const exynosautov920_usb20_regulators[] = {
 	"dvdd075-usb20", "vdd18-usb20", "vdd33-usb20",
 };
 
+static const struct phy_ops exynosautov920_usbdrd_combo_hsphy_ops = {
+	.init		= exynosautov920_usbdrd_phy_init,
+	.exit		= exynosautov920_usbdrd_combo_phy_exit,
+	.power_on	= exynosautov920_usbdrd_phy_power_on,
+	.power_off	= exynosautov920_usbdrd_phy_power_off,
+	.owner		= THIS_MODULE,
+};
+
+static const struct
+exynos5_usbdrd_phy_config usbdrd_hsphy_cfg_exynosautov920[] = {
+	{
+		.id		= EXYNOS5_DRDPHY_UTMI,
+		.phy_isol	= exynos5_usbdrd_phy_isol,
+		.phy_init	= exynosautov920_usbdrd_utmi_init,
+	},
+};
+
+static const
+struct exynos5_usbdrd_phy_drvdata exynosautov920_usbdrd_combo_hsphy = {
+	.phy_cfg		= usbdrd_hsphy_cfg_exynosautov920,
+	.phy_ops		= &exynosautov920_usbdrd_combo_hsphy_ops,
+	.pmu_offset_usbdrd0_phy	= EXYNOSAUTOV920_PHY_CTRL_USB20,
+	.clk_names		= exynos5_clk_names,
+	.n_clks			= ARRAY_SIZE(exynos5_clk_names),
+	.core_clk_names		= exynos5_core_clk_names,
+	.n_core_clks		= ARRAY_SIZE(exynos5_core_clk_names),
+	.regulator_names	= exynosautov920_usb20_regulators,
+	.n_regulators		= ARRAY_SIZE(exynosautov920_usb20_regulators),
+};
+
 static const struct phy_ops exynosautov920_usbdrd_phy_ops = {
 	.init		= exynosautov920_usbdrd_phy_init,
 	.exit		= exynosautov920_usbdrd_phy_exit,
@@ -2380,6 +2588,9 @@ static const struct of_device_id exynos5_usbdrd_phy_of_match[] = {
 	}, {
 		.compatible = "samsung,exynos990-usbdrd-phy",
 		.data = &exynos990_usbdrd_phy
+	}, {
+		.compatible = "samsung,exynosautov920-usbdrd-combo-hsphy",
+		.data = &exynosautov920_usbdrd_combo_hsphy
 	}, {
 		.compatible = "samsung,exynosautov920-usbdrd-phy",
 		.data = &exynosautov920_usbdrd_phy
-- 
2.34.1



From krzk at kernel.org  Thu Aug 21 00:55:23 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 21 Aug 2025 09:55:23 +0200
Subject: [PATCH v2 2/3] dt-bindings: phy: eswin: Document for EIC7700 SoC
 SATA PHY
In-Reply-To: <20250820092758.803-1-luyulin@eswincomputing.com>
References: <20250819134722.220-1-luyulin@eswincomputing.com>
 <20250820092758.803-1-luyulin@eswincomputing.com>
Message-ID: <20250821-precise-delightful-lyrebird-6b4275@kuoka>

On Wed, Aug 20, 2025 at 05:27:58PM +0800, Yulin Lu wrote:
> Add document for the SATA phy on the EIC7700 SoC platform,
> describing its usage.
> 
> Signed-off-by: Yulin Lu <luyulin at eswincomputing.com>

You already sent this patch separately (!!!) and received review.

Best regards,
Krzysztof



From stephan.gerhold at linaro.org  Thu Aug 21 01:01:47 2025
From: stephan.gerhold at linaro.org (Stephan Gerhold)
Date: Thu, 21 Aug 2025 10:01:47 +0200
Subject: [PATCH v3] phy: qcom: qmp-pcie: Fix PHY initialization when
 powered down by firmware
Message-ID: <20250821-phy-qcom-qmp-pcie-nocsr-fix-v3-1-4898db0cc07c@linaro.org>

Commit 0cc22f5a861c ("phy: qcom: qmp-pcie: Add PHY register retention
support") added support for using the "no_csr" reset to skip configuration
of the PHY if the init sequence was already applied by the boot firmware.
The expectation is that the PHY is only turned on/off by using the "no_csr"
reset, instead of powering it down and re-programming it after a full
reset.

The boot firmware on X1E does not fully conform to this expectation: If the
PCIe3 link fails to come up (e.g. because no PCIe card is inserted), the
firmware powers down the PHY using the QPHY_PCS_POWER_DOWN_CONTROL
register. The QPHY_START_CTRL register is kept as-is, so the driver assumes
the PHY is already initialized and skips the configuration/power up
sequence. The PHY won't come up again without clearing the
QPHY_PCS_POWER_DOWN_CONTROL, so eventually initialization fails:

  qcom-qmp-pcie-phy 1be0000.phy: phy initialization timed-out
  phy phy-1be0000.phy.0: phy poweron failed --> -110
  qcom-pcie 1bd0000.pcie: cannot initialize host
  qcom-pcie 1bd0000.pcie: probe with driver qcom-pcie failed with error -110

This can be reliably reproduced on the X1E CRD, QCP and Devkit when no card
is inserted for PCIe3.

Fix this by checking the QPHY_PCS_POWER_DOWN_CONTROL register in addition
to QPHY_START_CTRL. If the PHY is powered down with the register, it
doesn't conform to the expectations for using the "no_csr" reset, so we
fully re-initialize with the normal reset sequence.

Also check the register more carefully to ensure all of the bits we expect
are actually set. A simple !!(readl()) is not enough, because the PHY might
be only partially set up with some of the expected bits set.

Cc: stable at vger.kernel.org
Fixes: 0cc22f5a861c ("phy: qcom: qmp-pcie: Add PHY register retention support")
Signed-off-by: Stephan Gerhold <stephan.gerhold at linaro.org>
---
Changes in v3:
- Move up existing comment block and clarify it, so that it is more obvious
  what the additional checks really do (Bjorn)
- Link to v2: https://lore.kernel.org/r/20250814-phy-qcom-qmp-pcie-nocsr-fix-v2-1-fe562b5d02a1 at linaro.org

Changes in v2:
- Ensure that all expected bits are set (Konrad)
- Link to v1: https://lore.kernel.org/r/20250812-phy-qcom-qmp-pcie-nocsr-fix-v1-1-9a7d0a5d2b46 at linaro.org
---
 drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 25 +++++++++++++++++++------
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index 95830dcfdec9b1f68fd55d1cc3c102985cfafcc1..0fa63b734b67b8f44580b56555950bb5d74ef94c 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -3067,6 +3067,14 @@ struct qmp_pcie {
 	struct clk_fixed_rate aux_clk_fixed;
 };
 
+static bool qphy_checkbits(const void __iomem *base, u32 offset, u32 val)
+{
+	u32 reg;
+
+	reg = readl(base + offset);
+	return (reg & val) == val;
+}
+
 static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
 {
 	u32 reg;
@@ -4339,16 +4347,21 @@ static int qmp_pcie_init(struct phy *phy)
 	struct qmp_pcie *qmp = phy_get_drvdata(phy);
 	const struct qmp_phy_cfg *cfg = qmp->cfg;
 	void __iomem *pcs = qmp->pcs;
-	bool phy_initialized = !!(readl(pcs + cfg->regs[QPHY_START_CTRL]));
 	int ret;
 
-	qmp->skip_init = qmp->nocsr_reset && phy_initialized;
 	/*
-	 * We need to check the existence of init sequences in two cases:
-	 * 1. The PHY doesn't support no_csr reset.
-	 * 2. The PHY supports no_csr reset but isn't initialized by bootloader.
-	 * As we can't skip init in these two cases.
+	 * We can skip PHY initialization if all of the following conditions
+	 * are met:
+	 *  1. The PHY supports the nocsr_reset that preserves the PHY config.
+	 *  2. The PHY was started (and not powered down again) by the
+	 *     bootloader, with all of the expected bits set correctly.
+	 * In this case, we can continue without having the init sequence
+	 * defined in the driver.
 	 */
+	qmp->skip_init = qmp->nocsr_reset &&
+		qphy_checkbits(pcs, cfg->regs[QPHY_START_CTRL], SERDES_START | PCS_START) &&
+		qphy_checkbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], cfg->pwrdn_ctrl);
+
 	if (!qmp->skip_init && !cfg->tbls.serdes_num) {
 		dev_err(qmp->dev, "Init sequence not available\n");
 		return -ENODATA;

---
base-commit: aac1256a41cfbbaca12d6c0a5753d1e3b8d2d8bf
change-id: 20250812-phy-qcom-qmp-pcie-nocsr-fix-1603106294cd

Best regards,
-- 
Stephan Gerhold <stephan.gerhold at linaro.org>



From lkp at intel.com  Thu Aug 21 01:41:05 2025
From: lkp at intel.com (kernel test robot)
Date: Thu, 21 Aug 2025 16:41:05 +0800
Subject: [PATCH v2 3/3] phy: eswin: Create eswin directory and add
 EIC7700 SATA PHY driver
In-Reply-To: <20250819140043.1862-1-luyulin@eswincomputing.com>
References: <20250819140043.1862-1-luyulin@eswincomputing.com>
Message-ID: <202508211623.d8Spdqn7-lkp@intel.com>

Hi Yulin,

kernel test robot noticed the following build errors:

[auto build test ERROR on robh/for-next]
[also build test ERROR on linus/master v6.17-rc2 next-20250820]
[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/Yulin-Lu/dt-bindings-ata-eswin-Document-for-EIC7700-SoC-ahci/20250820-213411
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
patch link:    https://lore.kernel.org/r/20250819140043.1862-1-luyulin%40eswincomputing.com
patch subject: [PATCH v2 3/3] phy: eswin: Create eswin directory and add EIC7700 SATA PHY driver
config: s390-allmodconfig (https://download.01.org/0day-ci/archive/20250821/202508211623.d8Spdqn7-lkp at intel.com/config)
compiler: clang version 18.1.8 (https://github.com/llvm/llvm-project 3b5b5c1ec4a3095ab096dd780e84d7ab81f3d7ff)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250821/202508211623.d8Spdqn7-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/202508211623.d8Spdqn7-lkp at intel.com/

All errors (new ones prefixed by >>):

>> drivers/phy/eswin/phy-eic7700-sata.c:60:8: error: call to undeclared function 'readl'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
      60 |                 if ((readl(base + reg) & checkbit) == status)
         |                      ^
   drivers/phy/eswin/phy-eic7700-sata.c:79:8: error: call to undeclared function 'readl'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
      79 |         val = readl(sata_phy->regs + SATA_CLK_CTRL);
         |               ^
>> drivers/phy/eswin/phy-eic7700-sata.c:81:2: error: call to undeclared function 'writel'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
      81 |         writel(val, sata_phy->regs + SATA_CLK_CTRL);
         |         ^
   drivers/phy/eswin/phy-eic7700-sata.c:119:8: error: call to undeclared function 'readl'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
     119 |         val = readl(sata_phy->regs + SATA_RESET_CTRL);
         |               ^
   drivers/phy/eswin/phy-eic7700-sata.c:121:2: error: call to undeclared function 'writel'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
     121 |         writel(val, sata_phy->regs + SATA_RESET_CTRL);
         |         ^
   drivers/phy/eswin/phy-eic7700-sata.c:172:8: error: call to undeclared function 'readl'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
     172 |         val = readl(sata_phy->regs + SATA_CLK_CTRL);
         |               ^
   drivers/phy/eswin/phy-eic7700-sata.c:174:2: error: call to undeclared function 'writel'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
     174 |         writel(val, sata_phy->regs + SATA_CLK_CTRL);
         |         ^
   7 errors generated.


vim +/readl +60 drivers/phy/eswin/phy-eic7700-sata.c

    52	
    53	static int wait_for_phy_ready(void __iomem *base, u32 reg, u32 checkbit,
    54				      u32 status)
    55	{
    56		unsigned long start = jiffies;
    57		unsigned long timeout = start + PHY_READY_TIMEOUT;
    58	
    59		while (time_before(start, timeout)) {
  > 60			if ((readl(base + reg) & checkbit) == status)
    61				return 0;
    62			usleep_range(50, 70);
    63		}
    64	
    65		return -EFAULT;
    66	}
    67	
    68	static int eic7700_sata_phy_init(struct phy *phy)
    69	{
    70		struct eic7700_sata_phy *sata_phy = phy_get_drvdata(phy);
    71		u32 val = 0;
    72		int ret = 0;
    73	
    74		/*
    75		 * The SATA_CLK_CTRL register offset controls the pmalive, rxoob,
    76		 * and rbc clocks gate provided by the PHY through the HSP bus,
    77		 * and it is not registered in the clock tree.
    78		 */
    79		val = readl(sata_phy->regs + SATA_CLK_CTRL);
    80		val |= SATA_SYS_CLK_EN;
  > 81		writel(val, sata_phy->regs + SATA_CLK_CTRL);
    82	
    83		writel(SATA_CLK_RST_SOURCE_PHY, sata_phy->regs + SATA_REF_CTRL1);
    84		writel(SATA_P0_AMPLITUDE_GEN1 | SATA_P0_AMPLITUDE_GEN2 |
    85		       SATA_P0_AMPLITUDE_GEN3, sata_phy->regs + SATA_PHY_CTRL0);
    86		writel(SATA_P0_PHY_TX_PREEMPH_GEN1 | SATA_P0_PHY_TX_PREEMPH_GEN2 |
    87		       SATA_P0_PHY_TX_PREEMPH_GEN3, sata_phy->regs + SATA_PHY_CTRL1);
    88		writel(SATA_LOS_LEVEL | SATA_LOS_BIAS,
    89		       sata_phy->regs + SATA_LOS_IDEN);
    90		writel(SATA_M_CSYSREQ | SATA_S_CSYSREQ,
    91		       sata_phy->regs + SATA_AXI_LP_CTRL);
    92		writel(SATA_REF_REPEATCLK_EN | SATA_REF_USE_PAD,
    93		       sata_phy->regs + SATA_REG_CTRL);
    94		writel(SATA_MPLL_MULTIPLIER, sata_phy->regs + SATA_MPLL_CTRL);
    95		usleep_range(15, 20);
    96	
    97		/*
    98		 * The SATA_RESET_CTRL register offset controls reset/deassert
    99		 * for both the port and the PHY through the HSP bus,
   100		 * and it is not registered in the reset tree.
   101		 */
   102		val = readl(sata_phy->regs + SATA_RESET_CTRL);
   103		val &= ~(SATA_PHY_RESET | SATA_PORT_RESET);
   104		writel(val, sata_phy->regs + SATA_RESET_CTRL);
   105	
   106		ret = wait_for_phy_ready(sata_phy->regs, SATA_P0_PHY_STAT,
   107					 SATA_P0_PHY_READY, 1);
   108		if (ret < 0)
   109			dev_err(&sata_phy->phy->dev,
   110				"PHY READY check failed\n");
   111		return ret;
   112	}
   113	

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


From wenbin.yao at oss.qualcomm.com  Thu Aug 21 02:44:28 2025
From: wenbin.yao at oss.qualcomm.com (Wenbin Yao)
Date: Thu, 21 Aug 2025 02:44:28 -0700
Subject: [PATCH v2 1/4] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy:
 Document the Glymur QMP PCIe PHY
In-Reply-To: <20250821-glymur_pcie5-v2-0-cd516784ef20@oss.qualcomm.com>
References: <20250821-glymur_pcie5-v2-0-cd516784ef20@oss.qualcomm.com>
Message-ID: <20250821-glymur_pcie5-v2-1-cd516784ef20@oss.qualcomm.com>

From: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>

The fifth PCIe instance on Glymur has a Gen5 4-lane PHY. Document it as a
separate compatible.

Signed-off-by: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
Signed-off-by: Wenbin Yao <wenbin.yao at oss.qualcomm.com>
---
 Documentation/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 b6f140bf5b3b2f79b5c96e591ec0edb76cd45fa5..61e0e2f7ec7f9cb08447e4cd9503698c0a2d383a 100644
--- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
@@ -16,6 +16,7 @@ description:
 properties:
   compatible:
     enum:
+      - qcom,glymur-qmp-gen5x4-pcie-phy
       - qcom,qcs615-qmp-gen3x1-pcie-phy
       - qcom,qcs8300-qmp-gen4x2-pcie-phy
       - qcom,sa8775p-qmp-gen4x2-pcie-phy
@@ -176,6 +177,7 @@ allOf:
         compatible:
           contains:
             enum:
+              - qcom,glymur-qmp-gen5x4-pcie-phy
               - qcom,sa8775p-qmp-gen4x2-pcie-phy
               - qcom,sa8775p-qmp-gen4x4-pcie-phy
               - qcom,sc8280xp-qmp-gen3x1-pcie-phy
@@ -211,6 +213,7 @@ allOf:
         compatible:
           contains:
             enum:
+              - qcom,glymur-qmp-gen5x4-pcie-phy
               - qcom,sm8550-qmp-gen4x2-pcie-phy
               - qcom,sm8650-qmp-gen4x2-pcie-phy
               - qcom,x1e80100-qmp-gen4x2-pcie-phy

-- 
2.34.1



From wenbin.yao at oss.qualcomm.com  Thu Aug 21 02:44:27 2025
From: wenbin.yao at oss.qualcomm.com (Wenbin Yao)
Date: Thu, 21 Aug 2025 02:44:27 -0700
Subject: [PATCH v2 0/4] PCI: qcom: Add support for Glymur PCIe Gen5x4
Message-ID: <20250821-glymur_pcie5-v2-0-cd516784ef20@oss.qualcomm.com>

Glymur is the next generation compute SoC of Qualcomm. This patch series
aims to add support for the fifth PCIe instance on it. The fifth PCIe
instance on Glymur has a Gen5 4-lane PHY. Patch [1/4] documents PHY as a
separate compatible and Patch [2/4] documents controller as a separate
compatible. Patch [3/4] describles the new PCS offsets in a dedicated
header file. Patch [4/4] adds configuration and compatible for PHY.

The device tree changes and whatever driver patches that are not part of
this patch series will be posted separately after official announcement of
the SOC.

Signed-off-by: Wenbin Yao <wenbin.yao at oss.qualcomm.com>
---
Changes in v2:
- Add offsets of PLL and TXRXZ register blocks for v8.50 PHY in Patch[4/4].
- Link to v1: https://lore.kernel.org/r/20250819-glymur_pcie5-v1-0-2ea09f83cbb0 at oss.qualcomm.com

---
Prudhvi Yarlagadda (4):
      dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Document the Glymur QMP PCIe PHY
      dt-bindings: PCI: qcom: Document the Glymur PCIe Controller
      phy: qcom-qmp: pcs: Add v8.50 register offsets
      phy: qcom: qmp-pcie: Add support for Glymur PCIe Gen5x4 PHY

 .../bindings/pci/qcom,pcie-x1e80100.yaml           |  7 ++++-
 .../bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml   |  3 ++
 drivers/phy/qualcomm/phy-qcom-qmp-pcie.c           | 32 ++++++++++++++++++++++
 drivers/phy/qualcomm/phy-qcom-qmp-pcs-v8_50.h      | 13 +++++++++
 drivers/phy/qualcomm/phy-qcom-qmp.h                |  2 ++
 5 files changed, 56 insertions(+), 1 deletion(-)
---
base-commit: 886e5e7b0432360842303d587bb4a65d10741ae8
change-id: 20250818-glymur_pcie5-db4ef032e233

Best regards,
-- 
Wenbin Yao <wenbin.yao at oss.qualcomm.com>



From wenbin.yao at oss.qualcomm.com  Thu Aug 21 02:44:29 2025
From: wenbin.yao at oss.qualcomm.com (Wenbin Yao)
Date: Thu, 21 Aug 2025 02:44:29 -0700
Subject: [PATCH v2 2/4] dt-bindings: PCI: qcom: Document the Glymur PCIe
 Controller
In-Reply-To: <20250821-glymur_pcie5-v2-0-cd516784ef20@oss.qualcomm.com>
References: <20250821-glymur_pcie5-v2-0-cd516784ef20@oss.qualcomm.com>
Message-ID: <20250821-glymur_pcie5-v2-2-cd516784ef20@oss.qualcomm.com>

From: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>

On the Qualcomm Glymur platform the PCIe host is compatible with the DWC
controller present on the X1E80100 platform. So document the PCIe
controllers found on Glymur and use the X1E80100 compatible string as a
fallback in the schema.

Signed-off-by: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
Signed-off-by: Wenbin Yao <wenbin.yao at oss.qualcomm.com>
---
 Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml
index 257068a1826492a7071600d03ca0c99babb75bd9..8600f2c74cb81bcb924fa2035d992c3bd147db31 100644
--- a/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml
+++ b/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml
@@ -16,7 +16,12 @@ description:
 
 properties:
   compatible:
-    const: qcom,pcie-x1e80100
+    oneOf:
+      - const: qcom,pcie-x1e80100
+      - items:
+          - enum:
+              - qcom,glymur-pcie
+          - const: qcom,pcie-x1e80100
 
   reg:
     minItems: 6

-- 
2.34.1



From wenbin.yao at oss.qualcomm.com  Thu Aug 21 02:44:30 2025
From: wenbin.yao at oss.qualcomm.com (Wenbin Yao)
Date: Thu, 21 Aug 2025 02:44:30 -0700
Subject: [PATCH v2 3/4] phy: qcom-qmp: pcs: Add v8.50 register offsets
In-Reply-To: <20250821-glymur_pcie5-v2-0-cd516784ef20@oss.qualcomm.com>
References: <20250821-glymur_pcie5-v2-0-cd516784ef20@oss.qualcomm.com>
Message-ID: <20250821-glymur_pcie5-v2-3-cd516784ef20@oss.qualcomm.com>

From: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>

The new Glymur SoC bumps up the HW version of QMP phy to v8.50 for PCIE
g5x4. Add the new PCS offsets in a dedicated header file.

Signed-off-by: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
Signed-off-by: Wenbin Yao <wenbin.yao at oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-pcs-v8_50.h | 13 +++++++++++++
 drivers/phy/qualcomm/phy-qcom-qmp.h           |  2 ++
 2 files changed, 15 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v8_50.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v8_50.h
new file mode 100644
index 0000000000000000000000000000000000000000..325c127e8eb7ad842018dce51d09a6ee54ed86ff
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v8_50.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#ifndef QCOM_PHY_QMP_PCS_V8_50_H_
+#define QCOM_PHY_QMP_PCS_V8_50_H_
+
+#define QPHY_V8_50_PCS_STATUS1			0x010
+#define QPHY_V8_50_PCS_START_CONTROL			0x05c
+#define QPHY_V8_50_PCS_POWER_DOWN_CONTROL			0x64
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.h b/drivers/phy/qualcomm/phy-qcom-qmp.h
index f58c82b2dd23e1bda616d67ab7993794b997063b..da2a7ad2cdccef1308a2b7aa71a2e5cf8bd7c1d7 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.h
@@ -58,6 +58,8 @@
 
 #include "phy-qcom-qmp-pcs-v8.h"
 
+#include "phy-qcom-qmp-pcs-v8_50.h"
+
 /* QPHY_SW_RESET bit */
 #define SW_RESET				BIT(0)
 /* QPHY_POWER_DOWN_CONTROL */

-- 
2.34.1



From wenbin.yao at oss.qualcomm.com  Thu Aug 21 02:44:31 2025
From: wenbin.yao at oss.qualcomm.com (Wenbin Yao)
Date: Thu, 21 Aug 2025 02:44:31 -0700
Subject: [PATCH v2 4/4] phy: qcom: qmp-pcie: Add support for Glymur PCIe
 Gen5x4 PHY
In-Reply-To: <20250821-glymur_pcie5-v2-0-cd516784ef20@oss.qualcomm.com>
References: <20250821-glymur_pcie5-v2-0-cd516784ef20@oss.qualcomm.com>
Message-ID: <20250821-glymur_pcie5-v2-4-cd516784ef20@oss.qualcomm.com>

From: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>

Add support for Gen5 x4 PCIe QMP PHY found on Glymur platform.

Signed-off-by: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
Signed-off-by: Wenbin Yao <wenbin.yao at oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index 95830dcfdec9b1f68fd55d1cc3c102985cfafcc1..fc67ee1e4a3c0c6f2ec23f51c09c3cc16df9aaf4 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -93,6 +93,12 @@ static const unsigned int pciephy_v6_regs_layout[QPHY_LAYOUT_SIZE] = {
 	[QPHY_PCS_POWER_DOWN_CONTROL]	= QPHY_V6_PCS_POWER_DOWN_CONTROL,
 };
 
+static const unsigned int pciephy_v8_50_regs_layout[QPHY_LAYOUT_SIZE] = {
+	[QPHY_START_CTRL]		= QPHY_V8_50_PCS_START_CONTROL,
+	[QPHY_PCS_STATUS]		= QPHY_V8_50_PCS_STATUS1,
+	[QPHY_PCS_POWER_DOWN_CONTROL]   = QPHY_V8_50_PCS_POWER_DOWN_CONTROL,
+};
+
 static const struct qmp_phy_init_tbl msm8998_pcie_serdes_tbl[] = {
 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
@@ -2963,6 +2969,7 @@ struct qmp_pcie_offsets {
 	u16 rx2;
 	u16 txz;
 	u16 rxz;
+	u16 txrxz;
 	u16 ln_shrd;
 };
 
@@ -3229,6 +3236,12 @@ static const struct qmp_pcie_offsets qmp_pcie_offsets_v6_30 = {
 	.ln_shrd	= 0x8000,
 };
 
+static const struct qmp_pcie_offsets qmp_pcie_offsets_v8_50 = {
+	.serdes     = 0x8000,
+	.pcs        = 0x9000,
+	.txrxz      = 0xd000,
+};
+
 static const struct qmp_phy_cfg ipq8074_pciephy_cfg = {
 	.lanes			= 1,
 
@@ -4258,6 +4271,22 @@ static const struct qmp_phy_cfg qmp_v6_gen4x4_pciephy_cfg = {
 	.phy_status             = PHYSTATUS_4_20,
 };
 
+static const struct qmp_phy_cfg glymur_qmp_gen5x4_pciephy_cfg = {
+	.lanes = 4,
+
+	.offsets        = &qmp_pcie_offsets_v8_50,
+
+	.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_v8_50_regs_layout,
+
+	.pwrdn_ctrl     = SW_PWRDN | REFCLK_DRV_DSBL,
+	.phy_status     = PHYSTATUS_4_20,
+};
+
 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;
@@ -5114,6 +5143,9 @@ static const struct of_device_id qmp_pcie_of_match_table[] = {
 	}, {
 		.compatible = "qcom,x1p42100-qmp-gen4x4-pcie-phy",
 		.data = &qmp_v6_gen4x4_pciephy_cfg,
+	}, {
+		.compatible = "qcom,glymur-qmp-gen5x4-pcie-phy",
+		.data = &glymur_qmp_gen5x4_pciephy_cfg,
 	},
 	{ },
 };

-- 
2.34.1



From dmitry.baryshkov at oss.qualcomm.com  Thu Aug 21 02:57:09 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Thu, 21 Aug 2025 12:57:09 +0300
Subject: [PATCH v2 4/4] phy: qcom: qmp-pcie: Add support for Glymur PCIe
 Gen5x4 PHY
In-Reply-To: <20250821-glymur_pcie5-v2-4-cd516784ef20@oss.qualcomm.com>
References: <20250821-glymur_pcie5-v2-0-cd516784ef20@oss.qualcomm.com>
 <20250821-glymur_pcie5-v2-4-cd516784ef20@oss.qualcomm.com>
Message-ID: <bm3cp2vyw4rpllkwoxoxwrvsjxrtolcroqwx76bkpwmcdvx7ag@b6hvybyouq7m>

On Thu, Aug 21, 2025 at 02:44:31AM -0700, Wenbin Yao wrote:
> From: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
> 
> Add support for Gen5 x4 PCIe QMP PHY found on Glymur platform.
> 
> Signed-off-by: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
> Signed-off-by: Wenbin Yao <wenbin.yao at oss.qualcomm.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 32 ++++++++++++++++++++++++++++++++
>  1 file changed, 32 insertions(+)
> @@ -5114,6 +5143,9 @@ static const struct of_device_id qmp_pcie_of_match_table[] = {
>  	}, {
>  		.compatible = "qcom,x1p42100-qmp-gen4x4-pcie-phy",
>  		.data = &qmp_v6_gen4x4_pciephy_cfg,
> +	}, {
> +		.compatible = "qcom,glymur-qmp-gen5x4-pcie-phy",
> +		.data = &glymur_qmp_gen5x4_pciephy_cfg,

Please keep the array sorted. LGTM otherwise.

>  	},
>  	{ },
>  };
> 
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry


From dmitry.baryshkov at oss.qualcomm.com  Thu Aug 21 02:57:25 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Thu, 21 Aug 2025 12:57:25 +0300
Subject: [PATCH v2 3/4] phy: qcom-qmp: pcs: Add v8.50 register offsets
In-Reply-To: <20250821-glymur_pcie5-v2-3-cd516784ef20@oss.qualcomm.com>
References: <20250821-glymur_pcie5-v2-0-cd516784ef20@oss.qualcomm.com>
 <20250821-glymur_pcie5-v2-3-cd516784ef20@oss.qualcomm.com>
Message-ID: <utakatkrxgfggm2fo3rtg3w3t43vibqaomnwfsp5wi6okuxv62@sdsx74667hgz>

On Thu, Aug 21, 2025 at 02:44:30AM -0700, Wenbin Yao wrote:
> From: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
> 
> The new Glymur SoC bumps up the HW version of QMP phy to v8.50 for PCIE
> g5x4. Add the new PCS offsets in a dedicated header file.
> 
> Signed-off-by: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
> Signed-off-by: Wenbin Yao <wenbin.yao at oss.qualcomm.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-pcs-v8_50.h | 13 +++++++++++++
>  drivers/phy/qualcomm/phy-qcom-qmp.h           |  2 ++
>  2 files changed, 15 insertions(+)
> 

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>


-- 
With best wishes
Dmitry


From dmitry.baryshkov at oss.qualcomm.com  Thu Aug 21 03:00:22 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Thu, 21 Aug 2025 13:00:22 +0300
Subject: [PATCH v3] phy: qcom: qmp-pcie: Fix PHY initialization when
 powered down by firmware
In-Reply-To: <20250821-phy-qcom-qmp-pcie-nocsr-fix-v3-1-4898db0cc07c@linaro.org>
References: <20250821-phy-qcom-qmp-pcie-nocsr-fix-v3-1-4898db0cc07c@linaro.org>
Message-ID: <opdbvesy3gomk7k7fmtd5dqwycfc2wjdwhjrjedsud7zrxwnsz@zlmx5sdjdk6b>

On Thu, Aug 21, 2025 at 10:01:47AM +0200, Stephan Gerhold wrote:
> Commit 0cc22f5a861c ("phy: qcom: qmp-pcie: Add PHY register retention
> support") added support for using the "no_csr" reset to skip configuration
> of the PHY if the init sequence was already applied by the boot firmware.
> The expectation is that the PHY is only turned on/off by using the "no_csr"
> reset, instead of powering it down and re-programming it after a full
> reset.
> 
> The boot firmware on X1E does not fully conform to this expectation: If the
> PCIe3 link fails to come up (e.g. because no PCIe card is inserted), the
> firmware powers down the PHY using the QPHY_PCS_POWER_DOWN_CONTROL
> register. The QPHY_START_CTRL register is kept as-is, so the driver assumes
> the PHY is already initialized and skips the configuration/power up
> sequence. The PHY won't come up again without clearing the
> QPHY_PCS_POWER_DOWN_CONTROL, so eventually initialization fails:
> 
>   qcom-qmp-pcie-phy 1be0000.phy: phy initialization timed-out
>   phy phy-1be0000.phy.0: phy poweron failed --> -110
>   qcom-pcie 1bd0000.pcie: cannot initialize host
>   qcom-pcie 1bd0000.pcie: probe with driver qcom-pcie failed with error -110
> 
> This can be reliably reproduced on the X1E CRD, QCP and Devkit when no card
> is inserted for PCIe3.
> 
> Fix this by checking the QPHY_PCS_POWER_DOWN_CONTROL register in addition
> to QPHY_START_CTRL. If the PHY is powered down with the register, it
> doesn't conform to the expectations for using the "no_csr" reset, so we
> fully re-initialize with the normal reset sequence.
> 
> Also check the register more carefully to ensure all of the bits we expect
> are actually set. A simple !!(readl()) is not enough, because the PHY might
> be only partially set up with some of the expected bits set.
> 
> Cc: stable at vger.kernel.org
> Fixes: 0cc22f5a861c ("phy: qcom: qmp-pcie: Add PHY register retention support")
> Signed-off-by: Stephan Gerhold <stephan.gerhold at linaro.org>
> ---
> Changes in v3:
> - Move up existing comment block and clarify it, so that it is more obvious
>   what the additional checks really do (Bjorn)
> - Link to v2: https://lore.kernel.org/r/20250814-phy-qcom-qmp-pcie-nocsr-fix-v2-1-fe562b5d02a1 at linaro.org
> 
> Changes in v2:
> - Ensure that all expected bits are set (Konrad)
> - Link to v1: https://lore.kernel.org/r/20250812-phy-qcom-qmp-pcie-nocsr-fix-v1-1-9a7d0a5d2b46 at linaro.org
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 25 +++++++++++++++++++------
>  1 file changed, 19 insertions(+), 6 deletions(-)
> 

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>


-- 
With best wishes
Dmitry


From neil.armstrong at linaro.org  Thu Aug 21 06:53:25 2025
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Thu, 21 Aug 2025 15:53:25 +0200
Subject: [PATCH RFC 0/3] phy: qcom: qmp-combo: set default qmpphy_mode from
 DT for Thinkpad HDMI support
Message-ID: <20250821-topic-x1e80100-hdmi-v1-0-f14ad9430e88@linaro.org>

The Thinkpad T14s embeds a transparent 4lanes DP->HDMI transceiver
connected to the third QMP Combo PHY 4 lanes.

The QMP USB3/DP Combo PHY hosts an USB3 phy and a DP PHY on top
of a combo glue to route either lanes to the 4 shared physical lanes.

The routing of the lanes can be:
- 2 DP + 2 USB3
- 4 DP
- 2 USB3

And the layout of the lanes can be swpped depending of an
eventual USB-C connector orientation.

Nevertheless those QMP Comby PHY can be statically used to
drive a DisplayPort connector, DP->HDMI bridge, USB3 A Connector...

But if a 4lanes DP->HDMI bridge is directly connected to the
QMP Comby PHY lanes, in the default routing 2 or the 4 lanes would
probbaly be USB3, making the DP->HDMI bridge non functional.

Support the property set set in which layout mode the QMP Comby PHY
should be as startup.

Finally Add all the data routing in DT, disable mode switching and specify
the QMP Combo PHY should be in DP-Only mode to route the 4 lanes to
the underlying DP phy.

Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
Neil Armstrong (3):
      dt-bindings: phy: qcom,sc8280xp-qmp-usb43dp-phy: Document default phy mode
      phy: qcom: qmp-combo: get default qmpphy_mode from DT
      arm64: dts: qcom: x1e78100-lenovo-thinkpad-t14s: add HDMI nodes

 .../phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml         | 13 +++++++
 .../dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi    | 44 ++++++++++++++++++++++
 drivers/phy/qualcomm/phy-qcom-qmp-combo.c          | 20 +++++++++-
 3 files changed, 76 insertions(+), 1 deletion(-)
---
base-commit: 7fa4d8dc380fbd81a9d702a855c50690c9c6442c
change-id: 20250821-topic-x1e80100-hdmi-3bd5b5bd2d96

Best regards,
-- 
Neil Armstrong <neil.armstrong at linaro.org>



From neil.armstrong at linaro.org  Thu Aug 21 06:53:26 2025
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Thu, 21 Aug 2025 15:53:26 +0200
Subject: [PATCH RFC 1/3] dt-bindings: phy: qcom,sc8280xp-qmp-usb43dp-phy:
 Document default phy mode
In-Reply-To: <20250821-topic-x1e80100-hdmi-v1-0-f14ad9430e88@linaro.org>
References: <20250821-topic-x1e80100-hdmi-v1-0-f14ad9430e88@linaro.org>
Message-ID: <20250821-topic-x1e80100-hdmi-v1-1-f14ad9430e88@linaro.org>

The QMP USB3/DP Combo PHY hosts an USB3 phy and a DP PHY on top
of a combo glue to route either lanes to the 4 shared physical lanes.

The routing of the lanes can be:
- 2 DP + 2 USB3
- 4 DP
- 2 USB3

And the layout of the lanes can be swpped depending of an
eventual USB-C connector orientation.

Nevertheless those QMP Comby PHY can be statically used to
drive a DisplayPort connector, DP->HDMI bridge, USB3 A Connector...

But if a 4lanes DP->HDMI bridge is directly connected to the
QMP Comby PHY lanes, in the default routing 2 or the 4 lanes would
probbaly be USB3, making the DP->HDMI bridge non functional.

Add a property to hint in which layout mode the QMP Comby PHY
should be as startup.

Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 .../bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml         | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml
index c8bc512df08b5694c8599f475de78679a4438449..129475a1d9527733e43ded5a38aad766f9810fe7 100644
--- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml
@@ -76,6 +76,19 @@ properties:
   mode-switch: true
   orientation-switch: true
 
+  qcom,combo-initial-mode:
+    description:
+      Describe the initial mode of the Combo PHY configuration.
+      The Combo PHY is a wrapper on top of a DP PHY and an USB3 PHY,
+      sharing the same SuperSpeed lanes with either DisplayPort over
+      the 4 lanes (dp), USB3 on a pair of lanes (usb3) or both
+      technologies in a 2+2 configuration (usb3+dp) as default.
+    default: usb3+dp
+    enum:
+      - usb3+dp
+      - usb3
+      - dp
+
   ports:
     $ref: /schemas/graph.yaml#/properties/ports
     properties:

-- 
2.34.1



From neil.armstrong at linaro.org  Thu Aug 21 06:53:27 2025
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Thu, 21 Aug 2025 15:53:27 +0200
Subject: [PATCH RFC 2/3] phy: qcom: qmp-combo: get default qmpphy_mode from
 DT
In-Reply-To: <20250821-topic-x1e80100-hdmi-v1-0-f14ad9430e88@linaro.org>
References: <20250821-topic-x1e80100-hdmi-v1-0-f14ad9430e88@linaro.org>
Message-ID: <20250821-topic-x1e80100-hdmi-v1-2-f14ad9430e88@linaro.org>

The QMP USB3/DP Combo PHY hosts an USB3 phy and a DP PHY on top
of a combo glue to route either lanes to the 4 shared physical lanes.

The routing of the lanes can be:
- 2 DP + 2 USB3
- 4 DP
- 2 USB3

And the layout of the lanes can be swpped depending of an
eventual USB-C connector orientation.

Nevertheless those QMP Comby PHY can be statically used to
drive a DisplayPort connector, DP->HDMI bridge, USB3 A Connector...

But if a 4lanes DP->HDMI bridge is directly connected to the
QMP Comby PHY lanes, in the default routing 2 or the 4 lanes would
probbaly be USB3, making the DP->HDMI bridge non functional.

Support the property to set in which layout mode the QMP Comby PHY
should be as startup.

Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
index 7b5af30f1d028c592500e723ecd27b54ed554709..622db8a204d3c7c95f110e59cab96b07eadabade 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
@@ -4117,13 +4117,19 @@ static struct phy *qmp_combo_phy_xlate(struct device *dev, const struct of_phand
 	return ERR_PTR(-EINVAL);
 }
 
+static const char * const qmpphy_mode_str[] = {
+	[QMPPHY_MODE_USB3DP] = "usb3+dp",
+	[QMPPHY_MODE_DP_ONLY] = "dp",
+	[QMPPHY_MODE_USB3_ONLY] = "usb3",
+};
+
 static int qmp_combo_probe(struct platform_device *pdev)
 {
 	struct qmp_combo *qmp;
 	struct device *dev = &pdev->dev;
 	struct device_node *dp_np, *usb_np;
 	struct phy_provider *phy_provider;
-	int ret;
+	int ret, i;
 
 	qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL);
 	if (!qmp)
@@ -4195,6 +4201,18 @@ static int qmp_combo_probe(struct platform_device *pdev)
 	 */
 	qmp->qmpphy_mode = QMPPHY_MODE_USB3DP;
 
+	/* Replace with DT provided mode */
+	if (of_find_property(dev->of_node, "qcom,combo-initial-mode", NULL)) {
+		for (i = 0; i < ARRAY_SIZE(qmpphy_mode_str); ++i) {
+			ret = of_property_match_string(dev->of_node, "qcom,combo-initial-mode",
+						       qmpphy_mode_str[i]);
+			if (!ret) {
+				qmp->qmpphy_mode = i;
+				break;
+			}
+		}
+	}
+
 	qmp->usb_phy = devm_phy_create(dev, usb_np, &qmp_combo_usb_phy_ops);
 	if (IS_ERR(qmp->usb_phy)) {
 		ret = PTR_ERR(qmp->usb_phy);

-- 
2.34.1



From neil.armstrong at linaro.org  Thu Aug 21 06:53:28 2025
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Thu, 21 Aug 2025 15:53:28 +0200
Subject: [PATCH RFC 3/3] arm64: dts: qcom: x1e78100-lenovo-thinkpad-t14s:
 add HDMI nodes
In-Reply-To: <20250821-topic-x1e80100-hdmi-v1-0-f14ad9430e88@linaro.org>
References: <20250821-topic-x1e80100-hdmi-v1-0-f14ad9430e88@linaro.org>
Message-ID: <20250821-topic-x1e80100-hdmi-v1-3-f14ad9430e88@linaro.org>

The Thinkpad T14s embeds a transparent 4lanes DP->HDMI transceiver
connected to the third QMP Combo PHY 4 lanes.

Add all the data routing, disable mode switching and specify the
QMP Combo PHY should be in DP-Only mode to route the 4 lanes to
the underlying DP phy.

Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 .../dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi    | 44 ++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi
index 4cf61c2a34e31233b1adc93332bcabef22de3f86..5b62b8c3123633360f249e3ecdc8ea23f44e8e09 100644
--- a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi
+++ b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi
@@ -62,6 +62,20 @@ switch-lid {
 		};
 	};
 
+
+	hdmi-connector {
+		compatible = "hdmi-connector";
+		type = "a";
+		pinctrl-0 = <&hdmi_hpd_default>;
+		pinctrl-names = "default";
+
+		port {
+			hdmi_con: endpoint {
+				remote-endpoint = <&usb_1_ss2_qmpphy_out>;
+			};
+		};
+	};
+
 	pmic-glink {
 		compatible = "qcom,x1e80100-pmic-glink",
 			     "qcom,sm8550-pmic-glink",
@@ -1007,6 +1021,14 @@ &mdss_dp1_out {
 	link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>;
 };
 
+&mdss_dp2 {
+	status = "okay";
+};
+
+&mdss_dp2_out {
+	data-lanes = <0 1 2 3>;
+};
+
 &mdss_dp3 {
 	/delete-property/ #sound-dai-cells;
 
@@ -1263,6 +1285,12 @@ &tlmm {
 			       <72 2>, /* Secure EC I2C connection (?) */
 			       <238 1>; /* UFS Reset */
 
+	hdmi_hpd_default: hdmi-hpd-default-state {
+		pins = "gpio126";
+		function = "usb2_dp";
+		bias-disable;
+	};
+
 	eusb3_reset_n: eusb3-reset-n-state {
 		pins = "gpio6";
 		function = "gpio";
@@ -1486,6 +1514,22 @@ &usb_1_ss0_qmpphy_out {
 	remote-endpoint = <&retimer_ss0_ss_in>;
 };
 
+&usb_1_ss2_qmpphy {
+	vdda-phy-supply = <&vreg_l2j_1p2>;
+	vdda-pll-supply = <&vreg_l2d_0p9>;
+
+	qcom,combo-initial-mode = "dp";
+
+	/delete-property/ mode-switch;
+	/delete-property/ orientation-switch;
+
+	status = "okay";
+};
+
+&usb_1_ss2_qmpphy_out {
+	remote-endpoint = <&hdmi_con>;
+};
+
 &usb_1_ss1_hsphy {
 	vdd-supply = <&vreg_l3j_0p8>;
 	vdda12-supply = <&vreg_l2j_1p2>;

-- 
2.34.1



From sven at kernel.org  Thu Aug 21 08:38:58 2025
From: sven at kernel.org (Sven Peter)
Date: Thu, 21 Aug 2025 15:38:58 +0000
Subject: [PATCH RFC 06/22] usb: dwc3: apple: Use synchronous role switch
 for apple
In-Reply-To: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
Message-ID: <20250821-atcphy-6-17-v1-6-172beda182b8@kernel.org>

From: Hector Martin <marcan at marcan.st>

Apple's dwc3 is connected to a Type-C PHY which supports multiple
protocols (USB2, 3, DisplayPort, Thunderbolt) and has to act as a Type-C
protocol mux driven by the PD prot driver (tipd). The mode and mux
transitions have to be tightly synchronized with dwc3 bringup and
shutdown.

To avoid racing PHY (re-)configuration during hotplug or role switch
events run the role switching inside dwc3 synchronously instead of
relying on a work queue on these controllers.

Signed-off-by: Hector Martin <marcan at marcan.st>
[sven: added commit description]
Signed-off-by: Sven Peter <sven at kernel.org>
---
 drivers/usb/dwc3/core.c | 6 +++++-
 drivers/usb/dwc3/core.h | 3 +++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 8d2dc7fa18114102cc8893c4ca0e745e16f30754..f8013ba2bdc22fa5e719df0841b12b84d9465b62 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -317,7 +317,10 @@ void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
 	dwc->desired_dr_role = mode;
 	spin_unlock_irqrestore(&dwc->lock, flags);
 
-	queue_work(system_freezable_wq, &dwc->drd_work);
+	if (dwc->synchronous_drd_switch)
+		__dwc3_set_mode(&dwc->drd_work);
+	else
+		queue_work(system_freezable_wq, &dwc->drd_work);
 }
 
 u32 dwc3_core_fifo_space(struct dwc3_ep *dep, u8 type)
@@ -2274,6 +2277,7 @@ int dwc3_core_probe(const struct dwc3_probe_data *data)
 			dwc->dr_mode = USB_DR_MODE_OTG;
 			dwc->role_switch_reset_quirk = true;
 			dwc->no_early_roothub_poweroff = true;
+			dwc->synchronous_drd_switch = true;
 		}
 	}
 
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 3c3a36ec37345b2f9e71444ba3b90b52dbd24443..98e748cc348dfd9de1962c93fcf9f6a6690c2388 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -1156,6 +1156,8 @@ struct dwc3_scratchpad_array {
  *		  before PM suspend.
  * @role_switch_reset_quirk: set to force reinitialization after any role switch
  * @no_early_roothub_poweroff: set to skip early root hub port power off
+ * @synchronous_drd_switch: set to perform role switches synchronously instead
+ *			    of using a workqueue
  * @imod_interval: set the interrupt moderation interval in 250ns
  *			increments or 0 to disable.
  * @max_cfg_eps: current max number of IN eps used across all USB configs.
@@ -1396,6 +1398,7 @@ struct dwc3 {
 
 	unsigned		role_switch_reset_quirk:1;
 	unsigned		no_early_roothub_poweroff:1;
+	unsigned		synchronous_drd_switch:1;
 
 	u16			imod_interval;
 

-- 
2.34.1




From sven at kernel.org  Thu Aug 21 08:38:52 2025
From: sven at kernel.org (Sven Peter)
Date: Thu, 21 Aug 2025 15:38:52 +0000
Subject: [PATCH RFC 00/22] Apple Silicon USB3 support
Message-ID: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>

Hi,

This series includes changes to dwc3, tipd and a new phy driver to enable
USB3 on these machines. There's also some preparations to eventually enable
DisplayPort AltMode and Thunderbolt but those need future work.
Overall, this entire setup is quite a mess and we've tried to make it work
for quite a while now and finally came up with this solution here.

The USB3 controller is a very special kind of broken: It never sees any port
plug/unplug events that should normally arrive directly at dwc3.
Additionally, it needs to go through a full hard reset for every new connection
and most mode change. Details on why this is required are in the commit
description.

On top of that we need to keep the Type-C PHY bringup and dwc3 bringup tightly
synchronized. If there's a race between the two systems at best the port stops
working until a system reboot and at worst there's a watchdog somewhere that 
forcefully resets the entire SoC after ~5 seconds. I've only seen the latter
when bringing up thunderbolt so far but wouldn't be surprised if it happens
with just usb3 as well.

The entire bringup/bringup is orchestrated by a TIPD variant called CD321x
found on these machines. Unlike the original chips we however get no control
over which mode is negotiated or are even able to see the PDOs or VDOs. We only
get to know once the mode has been negotiated and have to act accordingly. I
even went as far as dumping the firmware from the chip to confirm this [1][2].

Hector wrote another summary of this early in January as well [3] and this
series is the only way we've been able to bring these ports up reliably.
It's not pretty in some places but I have no other idea how to implement this,
hence the RFC tag. Happy to discuss other approaches as well.

Both the PHY and the TIPD driver already include changes for DisplayPort
AltMode and USB4/Thunderbolt. These need additional work though but
since we can't control the mode devices end up in we can already merge
them now.

I used phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml as a template for the dt-binding
for atcphy (especially the ports). That was the most recent binding I found for
a PHY with similar features.

In order to test this you need to run the latest m1n1 master [4] because the
1.5.0 release does not include the code that lifts the tunables from Apple's
device tree. A kernel tree for testing is also tagged as apple-usb3-v1 at [5].

If the overall approach here is fine and no one can think of a better way to
support this SoC I'll drop the RFC and include the dts changes for the other
M1 and M2 machines as well.

Best,

Sven

[1] https://social.treehouse.systems/@sven/111092587315536174
[2] https://social.treehouse.systems/@sven/111096589846468888
[3] https://lore.kernel.org/all/fda8b831-1ffc-4087-8e7b-d97779b3ecc5 at marcan.st/
[4] https://github.com/AsahiLinux/m1n1
[5] https://git.kernel.org/pub/scm/linux/kernel/git/sven/linux.git

Signed-off-by: Sven Peter <sven at kernel.org>
---
Hector Martin (7):
      usb: dwc3: apple: Use synchronous role switch for apple
      usb: dwc3: apple: Adjust vendor-specific registers during init
      usb: typec: tipd: Update partner identity when power status was updated
      usb: typec: tipd: Use read_power_status function in probe
      usb: typec: tipd: Read data status in probe and cache its value
      usb: typec: mux: Introduce data_role to mux state
      usb: typec: tipd: Handle mode transitions for CD321x

Janne Grunau (1):
      usb: dwc3: apple: Do not use host-vbus-glitches workaround

Sven Peter (14):
      dt-bindings: usb: snps,dwc3: Allow multiple iommus
      dt-bindings: usb: Add Apple dwc3
      dt-bindings: phy: Add Apple Type-C PHY
      usb: dwc3: apple: Reset dwc3 during role switches
      usb: typec: tipd: Clear interrupts first
      usb: typec: tipd: Move initial irq mask to tipd_data
      usb: typec: tipd: Move switch_power_state to tipd_data
      usb: typec: tipd: Trace data status for CD321x correctly
      usb: typec: tipd: Add cd321x struct with separate size
      usb: typec: tipd: Read USB4, Thunderbolt and DisplayPort status for cd321x
      usb: typec: tipd: Register DisplayPort and Thunderbolt altmodes for cd321x
      soc: apple: Add hardware tunable support
      phy: apple: Add Apple Type-C PHY
      arm64: dts: apple: t8103: Add Apple Type-C PHY and dwc3 nodes

 .../devicetree/bindings/phy/apple,atcphy.yaml      |  210 ++
 .../devicetree/bindings/usb/apple,dwc3.yaml        |   82 +
 .../devicetree/bindings/usb/snps,dwc3.yaml         |    2 +-
 MAINTAINERS                                        |    3 +
 arch/arm64/boot/dts/apple/t8103-j274.dts           |   12 +
 arch/arm64/boot/dts/apple/t8103-j293.dts           |   12 +
 arch/arm64/boot/dts/apple/t8103-j313.dts           |   12 +
 arch/arm64/boot/dts/apple/t8103-j456.dts           |   12 +
 arch/arm64/boot/dts/apple/t8103-j457.dts           |   12 +
 arch/arm64/boot/dts/apple/t8103-jxxx.dtsi          |  137 ++
 arch/arm64/boot/dts/apple/t8103.dtsi               |  105 +
 drivers/phy/Kconfig                                |    1 +
 drivers/phy/Makefile                               |    1 +
 drivers/phy/apple/Kconfig                          |   14 +
 drivers/phy/apple/Makefile                         |    4 +
 drivers/phy/apple/atc.c                            | 2537 ++++++++++++++++++++
 drivers/soc/apple/Kconfig                          |    4 +
 drivers/soc/apple/Makefile                         |    3 +
 drivers/soc/apple/tunable.c                        |   77 +
 drivers/usb/dwc3/core.c                            |   85 +-
 drivers/usb/dwc3/core.h                            |   26 +
 drivers/usb/dwc3/drd.c                             |   11 +-
 drivers/usb/dwc3/host.c                            |    8 +-
 drivers/usb/typec/tipd/core.c                      |  569 ++++-
 drivers/usb/typec/tipd/tps6598x.h                  |    5 +
 drivers/usb/typec/tipd/trace.h                     |   39 +
 include/linux/soc/apple/tunable.h                  |   64 +
 include/linux/usb/typec_mux.h                      |    1 +
 28 files changed, 3987 insertions(+), 61 deletions(-)
---
base-commit: 8f5ae30d69d7543eee0d70083daf4de8fe15d585
change-id: 20250820-atcphy-6-17-b7eaf23be17c

Best regards,
-- 
Sven Peter <sven at kernel.org>




From sven at kernel.org  Thu Aug 21 08:39:03 2025
From: sven at kernel.org (Sven Peter)
Date: Thu, 21 Aug 2025 15:39:03 +0000
Subject: [PATCH RFC 11/22] usb: typec: tipd: Trace data status for CD321x
 correctly
In-Reply-To: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
Message-ID: <20250821-atcphy-6-17-v1-11-172beda182b8@kernel.org>

Some bits inside the CD321x TPS_DATA_STATUS register have a different
function compared to the original tipd chip. Add these and introduce a
separate trace function to show them correctly.

Signed-off-by: Sven Peter <sven at kernel.org>
---
 drivers/usb/typec/tipd/core.c     |  8 +++++++-
 drivers/usb/typec/tipd/tps6598x.h |  5 +++++
 drivers/usb/typec/tipd/trace.h    | 39 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c
index 4815c5c462837865a5f9d37bbc139249c82c2f75..19d713937870304e68325a441b0de63eb5db3b80 100644
--- a/drivers/usb/typec/tipd/core.c
+++ b/drivers/usb/typec/tipd/core.c
@@ -114,6 +114,7 @@ struct tipd_data {
 	irq_handler_t irq_handler;
 	u64 irq_mask1;
 	int (*register_port)(struct tps6598x *tps, struct fwnode_handle *node);
+	void (*trace_data_status)(u32 status);
 	void (*trace_power_status)(u16 status);
 	void (*trace_status)(u32 status);
 	int (*apply_patch)(struct tps6598x *tps);
@@ -492,7 +493,9 @@ static bool tps6598x_read_data_status(struct tps6598x *tps)
 		dev_err(tps->dev, "failed to read data status: %d\n", ret);
 		return false;
 	}
-	trace_tps6598x_data_status(data_status);
+
+	if (tps->data->trace_data_status)
+		tps->data->trace_data_status(data_status);
 
 	return true;
 }
@@ -1519,6 +1522,7 @@ static const struct tipd_data cd321x_data = {
 		     APPLE_CD_REG_INT_DATA_STATUS_UPDATE |
 		     APPLE_CD_REG_INT_PLUG_EVENT,
 	.register_port = tps6598x_register_port,
+	.trace_data_status = trace_cd321x_data_status,
 	.trace_power_status = trace_tps6598x_power_status,
 	.trace_status = trace_tps6598x_status,
 	.init = cd321x_init,
@@ -1532,6 +1536,7 @@ static const struct tipd_data tps6598x_data = {
 		     TPS_REG_INT_DATA_STATUS_UPDATE |
 		     TPS_REG_INT_PLUG_EVENT,
 	.register_port = tps6598x_register_port,
+	.trace_data_status = trace_tps6598x_data_status,
 	.trace_power_status = trace_tps6598x_power_status,
 	.trace_status = trace_tps6598x_status,
 	.apply_patch = tps6598x_apply_patch,
@@ -1545,6 +1550,7 @@ static const struct tipd_data tps25750_data = {
 		     TPS_REG_INT_DATA_STATUS_UPDATE |
 		     TPS_REG_INT_PLUG_EVENT,
 	.register_port = tps25750_register_port,
+	.trace_data_status = trace_tps6598x_data_status,
 	.trace_power_status = trace_tps25750_power_status,
 	.trace_status = trace_tps25750_status,
 	.apply_patch = tps25750_apply_patch,
diff --git a/drivers/usb/typec/tipd/tps6598x.h b/drivers/usb/typec/tipd/tps6598x.h
index cecb8d11d23972dab0d8c15458b4052af7510b03..03edbb77bbd6d8093b2560db83e5913e25d06154 100644
--- a/drivers/usb/typec/tipd/tps6598x.h
+++ b/drivers/usb/typec/tipd/tps6598x.h
@@ -197,6 +197,11 @@
 #define TPS_DATA_STATUS_FORCE_LSX	     BIT(23)
 #define TPS_DATA_STATUS_POWER_MISMATCH	     BIT(24)
 
+/* modified TPS_REG_DATA_STATUS bits for CD321x (and likely also TPS65987DDK) */
+#define CD321X_DATA_STATUS_HPD_IRQ	     BIT(14)
+#define CD321X_DATA_STATUS_HPD_LEVEL	     BIT(15)
+#define CD321X_DATA_STATUS_USB4_CONNECTION   BIT(23)
+
 #define TPS_DATA_STATUS_DP_PIN_ASSIGNMENT_MASK GENMASK(11, 10)
 #define TPS_DATA_STATUS_DP_PIN_ASSIGNMENT(x) \
 	TPS_FIELD_GET(TPS_DATA_STATUS_DP_PIN_ASSIGNMENT_MASK, (x))
diff --git a/drivers/usb/typec/tipd/trace.h b/drivers/usb/typec/tipd/trace.h
index bea383f2db9de5bbf1804fbad9ee6b134407b932..e9e40425138a01f15e35867f38f62e13623dbcec 100644
--- a/drivers/usb/typec/tipd/trace.h
+++ b/drivers/usb/typec/tipd/trace.h
@@ -217,6 +217,26 @@
 		{ TPS_DATA_STATUS_FORCE_LSX,		"FORCE_LSX" }, \
 		{ TPS_DATA_STATUS_POWER_MISMATCH,	"POWER_MISMATCH" })
 
+#define show_cd321x_data_status_flags(data_status) \
+	__print_flags(data_status & TPS_DATA_STATUS_FLAGS_MASK, "|", \
+		{ TPS_DATA_STATUS_DATA_CONNECTION,	"DATA_CONNECTION" }, \
+		{ TPS_DATA_STATUS_UPSIDE_DOWN,		"DATA_UPSIDE_DOWN" }, \
+		{ TPS_DATA_STATUS_ACTIVE_CABLE,		"ACTIVE_CABLE" }, \
+		{ TPS_DATA_STATUS_USB2_CONNECTION,	"USB2_CONNECTION" }, \
+		{ TPS_DATA_STATUS_USB3_CONNECTION,	"USB3_CONNECTION" }, \
+		{ TPS_DATA_STATUS_USB3_GEN2,		"USB3_GEN2" }, \
+		{ TPS_DATA_STATUS_USB_DATA_ROLE,	"USB_DATA_ROLE" }, \
+		{ TPS_DATA_STATUS_DP_CONNECTION,	"DP_CONNECTION" }, \
+		{ TPS_DATA_STATUS_DP_SINK,		"DP_SINK" }, \
+		{ CD321X_DATA_STATUS_HPD_IRQ,		"HPD_IRQ" }, \
+		{ CD321X_DATA_STATUS_HPD_LEVEL,		"HPD_LEVEL" }, \
+		{ TPS_DATA_STATUS_TBT_CONNECTION,	"TBT_CONNECTION" }, \
+		{ TPS_DATA_STATUS_TBT_TYPE,		"TBT_TYPE" }, \
+		{ TPS_DATA_STATUS_OPTICAL_CABLE,	"OPTICAL_CABLE" }, \
+		{ TPS_DATA_STATUS_ACTIVE_LINK_TRAIN,	"ACTIVE_LINK_TRAIN" }, \
+		{ CD321X_DATA_STATUS_USB4_CONNECTION,	"USB4" }, \
+		{ TPS_DATA_STATUS_POWER_MISMATCH,	"POWER_MISMATCH" })
+
 #define show_data_status_dp_pin_assignment(data_status) \
 	__print_symbolic(TPS_DATA_STATUS_DP_SPEC_PIN_ASSIGNMENT(data_status), \
 		{ TPS_DATA_STATUS_DP_SPEC_PIN_ASSIGNMENT_E, "E" }, \
@@ -388,6 +408,25 @@ TRACE_EVENT(tps6598x_data_status,
 		    )
 );
 
+TRACE_EVENT(cd321x_data_status,
+	TP_PROTO(u32 data_status),
+	TP_ARGS(data_status),
+
+	TP_STRUCT__entry(
+			 __field(u32, data_status)
+			 ),
+
+	TP_fast_assign(
+		       __entry->data_status = data_status;
+		       ),
+
+	TP_printk("%s%s%s",
+		  show_cd321x_data_status_flags(__entry->data_status),
+		  __entry->data_status & TPS_DATA_STATUS_DP_CONNECTION ? ", DP pinout " : "",
+		  maybe_show_data_status_dp_pin_assignment(__entry->data_status)
+		)
+);
+
 #endif /* _TPS6598X_TRACE_H_ */
 
 /* This part must be outside protection */

-- 
2.34.1




From sven at kernel.org  Thu Aug 21 08:39:05 2025
From: sven at kernel.org (Sven Peter)
Date: Thu, 21 Aug 2025 15:39:05 +0000
Subject: [PATCH RFC 13/22] usb: typec: tipd: Read USB4, Thunderbolt and
 DisplayPort status for cd321x
In-Reply-To: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
Message-ID: <20250821-atcphy-6-17-v1-13-172beda182b8@kernel.org>

CD321x supports various alternate modes and stores information once
these are entered into separate status registers. Read those when they
are active when reading TPS_DATA_STATUS to prepare supporting these.

Signed-off-by: Sven Peter <sven at kernel.org>
---
 drivers/usb/typec/tipd/core.c | 81 ++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 77 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c
index 51b0f3be8b66a743ddc3ea96c1b25f597a1e8f6c..59d270eb50ea3dc49ad32ff71f8354e23c1083c9 100644
--- a/drivers/usb/typec/tipd/core.c
+++ b/drivers/usb/typec/tipd/core.c
@@ -35,14 +35,19 @@
 #define TPS_REG_INT_MASK2		0x17
 #define TPS_REG_INT_CLEAR1		0x18
 #define TPS_REG_INT_CLEAR2		0x19
-#define TPS_REG_SYSTEM_POWER_STATE	0x20
 #define TPS_REG_STATUS			0x1a
+#define TPS_REG_SYSTEM_POWER_STATE	0x20
+#define TPS_REG_USB4_STATUS		0x24
+#define TPS_REG_DP_SID_STATUS		0x58
 #define TPS_REG_SYSTEM_CONF		0x28
 #define TPS_REG_CTRL_CONF		0x29
 #define TPS_REG_BOOT_STATUS		0x2D
 #define TPS_REG_POWER_STATUS		0x3f
 #define TPS_REG_PD_STATUS		0x40
 #define TPS_REG_RX_IDENTITY_SOP		0x48
+#define TPS_REG_CF_VID_STATUS		0x5e
+#define TPS_REG_DP_SID_STATUS		0x58
+#define TPS_REG_INTEL_VID_STATUS	0x59
 #define TPS_REG_DATA_STATUS		0x5f
 #define TPS_REG_SLEEP_CONF		0x70
 
@@ -85,6 +90,31 @@ struct tps6598x_rx_identity_reg {
 	struct usb_pd_identity identity;
 } __packed;
 
+/* TPS_REG_USB4_STATUS */
+struct tps6598x_usb4_status_reg {
+	u8 mode_status;
+	__le32 eudo;
+	__le32 unknown;
+} __packed;
+
+/* TPS_REG_DP_SID_STATUS */
+struct tps6598x_dp_sid_status_reg {
+	u8 mode_status;
+	__le32 status_tx;
+	__le32 status_rx;
+	__le32 configure;
+	__le32 mode_data;
+} __packed;
+
+/* TPS_REG_INTEL_VID_STATUS */
+struct tps6598x_intel_vid_status_reg {
+	u8 mode_status;
+	__le32 attention_vdo;
+	__le16 enter_vdo;
+	__le16 device_mode;
+	__le16 cable_mode;
+} __packed;
+
 /* Standard Task return codes */
 #define TPS_TASK_TIMEOUT		1
 #define TPS_TASK_REJECTED		3
@@ -121,6 +151,7 @@ struct tipd_data {
 	int (*apply_patch)(struct tps6598x *tps);
 	int (*init)(struct tps6598x *tps);
 	int (*switch_power_state)(struct tps6598x *tps, u8 target_state);
+	bool (*read_data_status)(struct tps6598x *tps);
 	int (*reset)(struct tps6598x *tps);
 };
 
@@ -151,6 +182,10 @@ struct tps6598x {
 
 struct cd321x {
 	struct tps6598x tps;
+
+	struct tps6598x_dp_sid_status_reg dp_sid_status;
+	struct tps6598x_intel_vid_status_reg intel_vid_status;
+	struct tps6598x_usb4_status_reg usb4_status;
 };
 
 static enum power_supply_property tps6598x_psy_props[] = {
@@ -505,6 +540,41 @@ static bool tps6598x_read_data_status(struct tps6598x *tps)
 	return true;
 }
 
+static bool cd321x_read_data_status(struct tps6598x *tps)
+{
+	struct cd321x *cd321x = container_of(tps, struct cd321x, tps);
+	int ret;
+
+	ret = tps6598x_read_data_status(tps);
+	if (ret < 0)
+		return false;
+
+	if (tps->data_status & TPS_DATA_STATUS_DP_CONNECTION) {
+		ret = tps6598x_block_read(tps, TPS_REG_DP_SID_STATUS,
+				&cd321x->dp_sid_status, sizeof(cd321x->dp_sid_status));
+		if (ret)
+			dev_err(tps->dev, "Failed to read DP SID Status: %d\n",
+				ret);
+	}
+
+	if (tps->data_status & TPS_DATA_STATUS_TBT_CONNECTION) {
+		ret = tps6598x_block_read(tps, TPS_REG_INTEL_VID_STATUS,
+				&cd321x->intel_vid_status, sizeof(cd321x->intel_vid_status));
+		if (ret)
+			dev_err(tps->dev, "Failed to read Intel VID Status: %d\n", ret);
+	}
+
+	if (tps->data_status & CD321X_DATA_STATUS_USB4_CONNECTION) {
+		ret = tps6598x_block_read(tps, TPS_REG_USB4_STATUS,
+				&cd321x->usb4_status, sizeof(cd321x->usb4_status));
+		if (ret)
+			dev_err(tps->dev,
+				"Failed to read USB4 Status: %d\n", ret);
+	}
+
+	return true;
+}
+
 static bool tps6598x_read_power_status(struct tps6598x *tps)
 {
 	u16 pwr_status;
@@ -565,7 +635,7 @@ static irqreturn_t cd321x_interrupt(int irq, void *data)
 			goto err_unlock;
 
 	if (event & APPLE_CD_REG_INT_DATA_STATUS_UPDATE)
-		if (!tps6598x_read_data_status(tps))
+		if (!tps->data->read_data_status(tps))
 			goto err_unlock;
 
 	/* Handle plug insert or removal */
@@ -614,7 +684,7 @@ static irqreturn_t tps25750_interrupt(int irq, void *data)
 			goto err_clear_ints;
 
 	if (event[0] & TPS_REG_INT_DATA_STATUS_UPDATE)
-		if (!tps6598x_read_data_status(tps))
+		if (!tps->data->read_data_status(tps))
 			goto err_clear_ints;
 
 	/*
@@ -688,7 +758,7 @@ static irqreturn_t tps6598x_interrupt(int irq, void *data)
 			goto err_unlock;
 
 	if ((event1[0] | event2[0]) & TPS_REG_INT_DATA_STATUS_UPDATE)
-		if (!tps6598x_read_data_status(tps))
+		if (!tps->data->read_data_status(tps))
 			goto err_unlock;
 
 	/* Handle plug insert or removal */
@@ -1534,6 +1604,7 @@ static const struct tipd_data cd321x_data = {
 	.trace_power_status = trace_tps6598x_power_status,
 	.trace_status = trace_tps6598x_status,
 	.init = cd321x_init,
+	.read_data_status = cd321x_read_data_status,
 	.reset = cd321x_reset,
 	.switch_power_state = cd321x_switch_power_state,
 };
@@ -1550,6 +1621,7 @@ static const struct tipd_data tps6598x_data = {
 	.trace_status = trace_tps6598x_status,
 	.apply_patch = tps6598x_apply_patch,
 	.init = tps6598x_init,
+	.read_data_status = tps6598x_read_data_status,
 	.reset = tps6598x_reset,
 };
 
@@ -1565,6 +1637,7 @@ static const struct tipd_data tps25750_data = {
 	.trace_status = trace_tps25750_status,
 	.apply_patch = tps25750_apply_patch,
 	.init = tps25750_init,
+	.read_data_status = tps6598x_read_data_status,
 	.reset = tps25750_reset,
 };
 

-- 
2.34.1




From sven at kernel.org  Thu Aug 21 08:38:53 2025
From: sven at kernel.org (Sven Peter)
Date: Thu, 21 Aug 2025 15:38:53 +0000
Subject: [PATCH RFC 01/22] dt-bindings: usb: snps,dwc3: Allow multiple
 iommus
In-Reply-To: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
Message-ID: <20250821-atcphy-6-17-v1-1-172beda182b8@kernel.org>

Apple's dwc3 variant requires two iommus.

Signed-off-by: Sven Peter <sven at kernel.org>
---
 Documentation/devicetree/bindings/usb/snps,dwc3.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
index 4380bb6fa2f08a475b557e80467abc2861f622e2..6d35dcc605c01977f4fc6fdb6f12976f1cef2b9e 100644
--- a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
+++ b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
@@ -60,7 +60,7 @@ properties:
   dma-coherent: true
 
   iommus:
-    maxItems: 1
+    maxItems: 2
 
   power-domains:
     description:

-- 
2.34.1




From sven at kernel.org  Thu Aug 21 08:39:00 2025
From: sven at kernel.org (Sven Peter)
Date: Thu, 21 Aug 2025 15:39:00 +0000
Subject: [PATCH RFC 08/22] usb: typec: tipd: Clear interrupts first
In-Reply-To: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
Message-ID: <20250821-atcphy-6-17-v1-8-172beda182b8@kernel.org>

Right now the interrupt handler first reads all updated status registers
and only then clears the interrupts. It's possible that a duplicate
interrupt for a changed register or plug state comes in after the
interrupts have been processed but before they have been cleared:

* plug is inserted, TPS_REG_INT_PLUG_EVENT is set
* TPS_REG_INT_EVENT1 is read
* tps6598x_handle_plug_event() has run and registered the plug
* plug is removed again, TPS_REG_INT_PLUG_EVENT is set (again)
* TPS_REG_INT_CLEAR1 is written, TPS_REG_INT_PLUG_EVENT is cleared

We then have no plug connected and no pending interrupt but the tipd
core still thinks there is a plug. It's possible to trigger this with
e.g. a slightly broken Type-C to USB A converter.

Fix this by first clearing the interrupts and only then reading the
updated registers.

Fixes: 45188f27b3d0 ("usb: typec: tipd: Add support for Apple CD321X")
Fixes: 0a4c005bd171 ("usb: typec: driver for TI TPS6598x USB Power Delivery controllers")
Cc: stable at kernel.org
Signed-off-by: Sven Peter <sven at kernel.org>
---
 drivers/usb/typec/tipd/core.c | 24 +++++++++++-------------
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c
index dcf141ada07812295a6f07e41d77f95f98116010..1c80296c3b273e24ceacb3feff432c4f6e6835cc 100644
--- a/drivers/usb/typec/tipd/core.c
+++ b/drivers/usb/typec/tipd/core.c
@@ -545,24 +545,23 @@ static irqreturn_t cd321x_interrupt(int irq, void *data)
 	if (!event)
 		goto err_unlock;
 
+	tps6598x_write64(tps, TPS_REG_INT_CLEAR1, event);
+
 	if (!tps6598x_read_status(tps, &status))
-		goto err_clear_ints;
+		goto err_unlock;
 
 	if (event & APPLE_CD_REG_INT_POWER_STATUS_UPDATE)
 		if (!tps6598x_read_power_status(tps))
-			goto err_clear_ints;
+			goto err_unlock;
 
 	if (event & APPLE_CD_REG_INT_DATA_STATUS_UPDATE)
 		if (!tps6598x_read_data_status(tps))
-			goto err_clear_ints;
+			goto err_unlock;
 
 	/* Handle plug insert or removal */
 	if (event & APPLE_CD_REG_INT_PLUG_EVENT)
 		tps6598x_handle_plug_event(tps, status);
 
-err_clear_ints:
-	tps6598x_write64(tps, TPS_REG_INT_CLEAR1, event);
-
 err_unlock:
 	mutex_unlock(&tps->lock);
 
@@ -668,25 +667,24 @@ static irqreturn_t tps6598x_interrupt(int irq, void *data)
 	if (!(event1[0] | event1[1] | event2[0] | event2[1]))
 		goto err_unlock;
 
+	tps6598x_block_write(tps, TPS_REG_INT_CLEAR1, event1, intev_len);
+	tps6598x_block_write(tps, TPS_REG_INT_CLEAR2, event2, intev_len);
+
 	if (!tps6598x_read_status(tps, &status))
-		goto err_clear_ints;
+		goto err_unlock;
 
 	if ((event1[0] | event2[0]) & TPS_REG_INT_POWER_STATUS_UPDATE)
 		if (!tps6598x_read_power_status(tps))
-			goto err_clear_ints;
+			goto err_unlock;
 
 	if ((event1[0] | event2[0]) & TPS_REG_INT_DATA_STATUS_UPDATE)
 		if (!tps6598x_read_data_status(tps))
-			goto err_clear_ints;
+			goto err_unlock;
 
 	/* Handle plug insert or removal */
 	if ((event1[0] | event2[0]) & TPS_REG_INT_PLUG_EVENT)
 		tps6598x_handle_plug_event(tps, status);
 
-err_clear_ints:
-	tps6598x_block_write(tps, TPS_REG_INT_CLEAR1, event1, intev_len);
-	tps6598x_block_write(tps, TPS_REG_INT_CLEAR2, event2, intev_len);
-
 err_unlock:
 	mutex_unlock(&tps->lock);
 

-- 
2.34.1




From sven at kernel.org  Thu Aug 21 08:38:56 2025
From: sven at kernel.org (Sven Peter)
Date: Thu, 21 Aug 2025 15:38:56 +0000
Subject: [PATCH RFC 04/22] usb: dwc3: apple: Reset dwc3 during role
 switches
In-Reply-To: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
Message-ID: <20250821-atcphy-6-17-v1-4-172beda182b8@kernel.org>

As mad as it sounds, the dwc3 controller present on the Apple M1 must be
reset and reinitialized whenever a device is unplugged from the root
port or when the PHY mode is changed.

This is required for at least the following reasons:

  - The USB2 D+/D- lines are connected through a stateful eUSB2 repeater
    which in turn is controlled by a variant of the TI TPS6598x USB PD
    chip. When the USB PD controller detects a hotplug event it resets
    the eUSB2 repeater. Afterwards, no new device is recognized before
    the DWC3 core and PHY are reset as well because the eUSB2 repeater
    and the PHY/dwc3 block disagree about the current state.

  - It's possible to completely break the dwc3 controller by switching
    it to device mode and unplugging the cable at just the wrong time.
    If this happens dwc3 behaves as if no device is connected.
    CORESOFTRESET will also never clear after it has been set. The only
    workaround is to trigger a hard reset of the entire dwc3 core with
    its external reset line.

  - Whenever the PHY mode is changed (to e.g. transition to DisplayPort
    alternate mode or USB4) dwc3 has to be shutdown and reinitialized.
    Otherwise the Type-C port will not be usable until the entire SoC
    has been reset.

All of this can be easily worked around by respecting transitions to
USB_ROLE_NONE and making sure the external reset line is asserted when
switching roles. We additionally have to ensure that the PHY is
suspended during init.

Signed-off-by: Sven Peter <sven at kernel.org>
---
 drivers/usb/dwc3/core.c | 61 +++++++++++++++++++++++++++++++++++++++++++++----
 drivers/usb/dwc3/core.h |  3 +++
 drivers/usb/dwc3/drd.c  | 11 ++++++++-
 drivers/usb/dwc3/host.c |  3 ++-
 4 files changed, 72 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 8002c23a5a02acb8f3e87b2662a53998a4cf4f5c..26aa507a738f001409a97ef563c6561433a1cac5 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -158,6 +158,9 @@ void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode, bool ignore_susphy)
 	dwc->current_dr_role = mode;
 }
 
+static void dwc3_core_exit(struct dwc3 *dwc);
+static int dwc3_core_init_for_resume(struct dwc3 *dwc);
+
 static void __dwc3_set_mode(struct work_struct *work)
 {
 	struct dwc3 *dwc = work_to_dwc(work);
@@ -177,7 +180,7 @@ static void __dwc3_set_mode(struct work_struct *work)
 	if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_OTG)
 		dwc3_otg_update(dwc, 0);
 
-	if (!desired_dr_role)
+	if (!desired_dr_role && !dwc->role_switch_reset_quirk)
 		goto out;
 
 	if (desired_dr_role == dwc->current_dr_role)
@@ -205,13 +208,32 @@ static void __dwc3_set_mode(struct work_struct *work)
 		break;
 	}
 
+	if (dwc->role_switch_reset_quirk) {
+		if (dwc->current_dr_role) {
+			dwc->current_dr_role = 0;
+			dwc3_core_exit(dwc);
+		}
+
+		if (desired_dr_role) {
+			ret = dwc3_core_init_for_resume(dwc);
+			if (ret) {
+				dev_err(dwc->dev,
+				    "failed to reinitialize core\n");
+				goto out;
+			}
+		} else {
+			goto out;
+		}
+	}
+
 	/*
 	 * When current_dr_role is not set, there's no role switching.
 	 * Only perform GCTL.CoreSoftReset when there's DRD role switching.
 	 */
-	if (dwc->current_dr_role && ((DWC3_IP_IS(DWC3) ||
+	if (dwc->role_switch_reset_quirk ||
+		(dwc->current_dr_role && ((DWC3_IP_IS(DWC3) ||
 			DWC3_VER_IS_PRIOR(DWC31, 190A)) &&
-			desired_dr_role != DWC3_GCTL_PRTCAP_OTG)) {
+			desired_dr_role != DWC3_GCTL_PRTCAP_OTG))) {
 		reg = dwc3_readl(dwc->regs, DWC3_GCTL);
 		reg |= DWC3_GCTL_CORESOFTRESET;
 		dwc3_writel(dwc->regs, DWC3_GCTL, reg);
@@ -1372,6 +1394,9 @@ static int dwc3_core_init(struct dwc3 *dwc)
 	if (ret)
 		goto err_exit_phy;
 
+	if (dwc->role_switch_reset_quirk)
+		dwc3_enable_susphy(dwc, true);
+
 	dwc3_core_setup_global_control(dwc);
 	dwc3_core_num_eps(dwc);
 
@@ -1635,6 +1660,18 @@ static int dwc3_core_init_mode(struct dwc3 *dwc)
 		ret = dwc3_drd_init(dwc);
 		if (ret)
 			return dev_err_probe(dev, ret, "failed to initialize dual-role\n");
+
+		/*
+		 * If the role switch reset quirk is required the first role
+		 * switch notification will initialize the core such that we
+		 * have to shut it down here. Make sure that the __dwc3_set_mode
+		 * queued by dwc3_drd_init has completed before since it
+		 * may still try to access MMIO.
+		 */
+		if (dwc->role_switch_reset_quirk) {
+			flush_work(&dwc->drd_work);
+			dwc3_core_exit(dwc);
+		}
 		break;
 	default:
 		dev_err(dev, "Unsupported mode of operation %d\n", dwc->dr_mode);
@@ -2223,6 +2260,22 @@ int dwc3_core_probe(const struct dwc3_probe_data *data)
 			goto err_put_psy;
 	}
 
+	if (dev->of_node) {
+		if (of_device_is_compatible(dev->of_node, "apple,t8103-dwc3")) {
+			if (!IS_ENABLED(CONFIG_USB_ROLE_SWITCH) ||
+			    !IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)) {
+				dev_err(dev,
+				    "Apple DWC3 requires role switch support.\n"
+				    );
+				ret = -EINVAL;
+				goto err_put_psy;
+			}
+
+			dwc->dr_mode = USB_DR_MODE_OTG;
+			dwc->role_switch_reset_quirk = true;
+		}
+	}
+
 	ret = reset_control_deassert(dwc->reset);
 	if (ret)
 		goto err_put_psy;
@@ -2391,7 +2444,6 @@ static void dwc3_remove(struct platform_device *pdev)
 	dwc3_core_remove(platform_get_drvdata(pdev));
 }
 
-#ifdef CONFIG_PM
 static int dwc3_core_init_for_resume(struct dwc3 *dwc)
 {
 	int ret;
@@ -2418,6 +2470,7 @@ static int dwc3_core_init_for_resume(struct dwc3 *dwc)
 	return ret;
 }
 
+#ifdef CONFIG_PM
 static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
 {
 	u32 reg;
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index d5b985fa12f4d9ee3f318ea5cce7c1b225cd3623..38f32f2a6193c1b2662ab4f38f4d20cf4b0e198d 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -1154,6 +1154,7 @@ struct dwc3_scratchpad_array {
  * @suspended: set to track suspend event due to U3/L2.
  * @susphy_state: state of DWC3_GUSB2PHYCFG_SUSPHY + DWC3_GUSB3PIPECTL_SUSPHY
  *		  before PM suspend.
+ * @role_switch_reset_quirk: set to force reinitialization after any role switch
  * @imod_interval: set the interrupt moderation interval in 250ns
  *			increments or 0 to disable.
  * @max_cfg_eps: current max number of IN eps used across all USB configs.
@@ -1392,6 +1393,8 @@ struct dwc3 {
 	unsigned		suspended:1;
 	unsigned		susphy_state:1;
 
+	unsigned		role_switch_reset_quirk:1;
+
 	u16			imod_interval;
 
 	int			max_cfg_eps;
diff --git a/drivers/usb/dwc3/drd.c b/drivers/usb/dwc3/drd.c
index 7977860932b142924edd19f859f7c4041d11eda6..65450db91bdea00bb30bfb368f5195ad2fd58da4 100644
--- a/drivers/usb/dwc3/drd.c
+++ b/drivers/usb/dwc3/drd.c
@@ -464,6 +464,9 @@ static int dwc3_usb_role_switch_set(struct usb_role_switch *sw,
 		break;
 	}
 
+	if (dwc->role_switch_reset_quirk && role == USB_ROLE_NONE)
+		mode = 0;
+
 	dwc3_set_mode(dwc, mode);
 	return 0;
 }
@@ -492,6 +495,10 @@ static enum usb_role dwc3_usb_role_switch_get(struct usb_role_switch *sw)
 			role = USB_ROLE_DEVICE;
 		break;
 	}
+
+	if (dwc->role_switch_reset_quirk && !dwc->current_dr_role)
+		role = USB_ROLE_NONE;
+
 	spin_unlock_irqrestore(&dwc->lock, flags);
 	return role;
 }
@@ -502,7 +509,9 @@ static int dwc3_setup_role_switch(struct dwc3 *dwc)
 	u32 mode;
 
 	dwc->role_switch_default_mode = usb_get_role_switch_default_mode(dwc->dev);
-	if (dwc->role_switch_default_mode == USB_DR_MODE_HOST) {
+	if (dwc->role_switch_reset_quirk) {
+		mode = 0;
+	} else if (dwc->role_switch_default_mode == USB_DR_MODE_HOST) {
 		mode = DWC3_GCTL_PRTCAP_HOST;
 	} else {
 		dwc->role_switch_default_mode = USB_DR_MODE_PERIPHERAL;
diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c
index 1c513bf8002ec9ec91b41bfd096cbd0da1dd2d2e..f7a71e6f9d80aca632f1f970d900a3de8a76f0a7 100644
--- a/drivers/usb/dwc3/host.c
+++ b/drivers/usb/dwc3/host.c
@@ -223,7 +223,8 @@ void dwc3_host_exit(struct dwc3 *dwc)
 	if (dwc->sys_wakeup)
 		device_init_wakeup(&dwc->xhci->dev, false);
 
-	dwc3_enable_susphy(dwc, false);
+	if (!dwc->role_switch_reset_quirk)
+		dwc3_enable_susphy(dwc, false);
 	platform_device_unregister(dwc->xhci);
 	dwc->xhci = NULL;
 }

-- 
2.34.1




From sven at kernel.org  Thu Aug 21 08:38:54 2025
From: sven at kernel.org (Sven Peter)
Date: Thu, 21 Aug 2025 15:38:54 +0000
Subject: [PATCH RFC 02/22] dt-bindings: usb: Add Apple dwc3
In-Reply-To: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
Message-ID: <20250821-atcphy-6-17-v1-2-172beda182b8@kernel.org>

Apple Silicon uses Synopsys DesignWare dwc3 based USB controllers for
their Type-C ports.

Signed-off-by: Sven Peter <sven at kernel.org>
---
 .../devicetree/bindings/usb/apple,dwc3.yaml        | 82 ++++++++++++++++++++++
 MAINTAINERS                                        |  1 +
 2 files changed, 83 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/apple,dwc3.yaml b/Documentation/devicetree/bindings/usb/apple,dwc3.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..dfea726a6c053ad0c8f3d973a95b45bbf1724234
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/apple,dwc3.yaml
@@ -0,0 +1,82 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/usb/apple,dwc3.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple Silicon DWC3 USB controller
+
+maintainers:
+  - Sven Peter <sven at svenpeter.dev>
+
+description:
+  Apple Silicon SoCs use a Synopsys DesignWare DWC3 based controller for each of
+  their Type-C ports.
+
+  The common content of the node is defined in snps,dwc3.yaml.
+
+allOf:
+  - $ref: snps,dwc3.yaml#
+
+select:
+  properties:
+    compatible:
+      contains:
+        const: apple,t8103-dwc3
+  required:
+    - compatible
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+        - enum:
+            - apple,t6000-dwc3
+            - apple,t6020-dwc3
+            - apple,t8112-dwc3
+        - const: apple,t8103-dwc3
+        - const: snps,dwc3
+      - items:
+        - const: apple,t8103-dwc3
+        - const: snps,dwc3
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  iommus:
+    maxItems: 2
+
+  resets:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+unevaluatedProperties: false
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - iommus
+  - resets
+  - power-domains
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/apple-aic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    usb at 82280000 {
+      compatible = "apple,t8103-dwc3", "snps,dwc3";
+      reg = <0x82280000 0x10000>;
+      interrupts = <AIC_IRQ 777 IRQ_TYPE_LEVEL_HIGH>;
+      iommus = <&dwc3_0_dart_0 0>, <&dwc3_0_dart_1 1>;
+
+      dr_mode = "otg";
+      usb-role-switch;
+      role-switch-default-mode = "host";
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index fe168477caa45799dfe07de2f54de6d6a1ce0615..0e085cb0762f765958d67be61ae0d3d773503431 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2399,6 +2399,7 @@ F:	Documentation/devicetree/bindings/power/reset/apple,smc-reboot.yaml
 F:	Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
 F:	Documentation/devicetree/bindings/spi/apple,spi.yaml
 F:	Documentation/devicetree/bindings/spmi/apple,spmi.yaml
+F:	Documentation/devicetree/bindings/usb/apple,dwc3.yaml
 F:	Documentation/devicetree/bindings/watchdog/apple,wdt.yaml
 F:	arch/arm64/boot/dts/apple/
 F:	drivers/bluetooth/hci_bcm4377.c

-- 
2.34.1




From sven at kernel.org  Thu Aug 21 08:38:57 2025
From: sven at kernel.org (Sven Peter)
Date: Thu, 21 Aug 2025 15:38:57 +0000
Subject: [PATCH RFC 05/22] usb: dwc3: apple: Do not use host-vbus-glitches
 workaround
In-Reply-To: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
Message-ID: <20250821-atcphy-6-17-v1-5-172beda182b8@kernel.org>

From: Janne Grunau <j at jannau.net>

It results in SErrors during init presumedly because MMIO accesses fail
while certain parts are shutdown.

Signed-off-by: Janne Grunau <j at jannau.net>
Signed-off-by: Sven Peter <sven at kernel.org>
---
 drivers/usb/dwc3/core.c | 1 +
 drivers/usb/dwc3/core.h | 2 ++
 drivers/usb/dwc3/host.c | 5 ++++-
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 26aa507a738f001409a97ef563c6561433a1cac5..8d2dc7fa18114102cc8893c4ca0e745e16f30754 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -2273,6 +2273,7 @@ int dwc3_core_probe(const struct dwc3_probe_data *data)
 
 			dwc->dr_mode = USB_DR_MODE_OTG;
 			dwc->role_switch_reset_quirk = true;
+			dwc->no_early_roothub_poweroff = true;
 		}
 	}
 
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 38f32f2a6193c1b2662ab4f38f4d20cf4b0e198d..3c3a36ec37345b2f9e71444ba3b90b52dbd24443 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -1155,6 +1155,7 @@ struct dwc3_scratchpad_array {
  * @susphy_state: state of DWC3_GUSB2PHYCFG_SUSPHY + DWC3_GUSB3PIPECTL_SUSPHY
  *		  before PM suspend.
  * @role_switch_reset_quirk: set to force reinitialization after any role switch
+ * @no_early_roothub_poweroff: set to skip early root hub port power off
  * @imod_interval: set the interrupt moderation interval in 250ns
  *			increments or 0 to disable.
  * @max_cfg_eps: current max number of IN eps used across all USB configs.
@@ -1394,6 +1395,7 @@ struct dwc3 {
 	unsigned		susphy_state:1;
 
 	unsigned		role_switch_reset_quirk:1;
+	unsigned		no_early_roothub_poweroff:1;
 
 	u16			imod_interval;
 
diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c
index f7a71e6f9d80aca632f1f970d900a3de8a76f0a7..f7c3a0fc5fe258705311f89c1ba11ff599c01afe 100644
--- a/drivers/usb/dwc3/host.c
+++ b/drivers/usb/dwc3/host.c
@@ -134,8 +134,11 @@ int dwc3_host_init(struct dwc3 *dwc)
 	/*
 	 * Some platforms need to power off all Root hub ports immediately after DWC3 set to host
 	 * mode to avoid VBUS glitch happen when xhci get reset later.
+	 * On Apple platforms we must not touch any MMIO yet because dwc3
+	 * will not work correctly before its PHY has been initialized.
 	 */
-	dwc3_power_off_all_roothub_ports(dwc);
+	if (!dwc->no_early_roothub_poweroff)
+		dwc3_power_off_all_roothub_ports(dwc);
 
 	irq = dwc3_host_get_irq(dwc);
 	if (irq < 0)

-- 
2.34.1




From sven at kernel.org  Thu Aug 21 08:38:59 2025
From: sven at kernel.org (Sven Peter)
Date: Thu, 21 Aug 2025 15:38:59 +0000
Subject: [PATCH RFC 07/22] usb: dwc3: apple: Adjust vendor-specific
 registers during init
In-Reply-To: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
Message-ID: <20250821-atcphy-6-17-v1-7-172beda182b8@kernel.org>

From: Hector Martin <marcan at marcan.st>

When tracing Apple's dwc3 driver under our hypervisor and comparing its
MMIO access with their kernel debug output these vendor-specific
registers have been identified. We don't know exactly what these do
or why they are required but without changing these parameters sometimes
USB3 devices don't work or take an additional 5 seconds to be recognized.

Signed-off-by: Hector Martin <marcan at marcan.st>
Co-developed-by: Sven Peter <sven at kernel.org>
Signed-off-by: Sven Peter <sven at kernel.org>
---
 drivers/usb/dwc3/core.c | 17 +++++++++++++++++
 drivers/usb/dwc3/core.h | 18 ++++++++++++++++++
 2 files changed, 35 insertions(+)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index f8013ba2bdc22fa5e719df0841b12b84d9465b62..e018e80778cf39a9981d438c7e54534b26cddf63 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -1366,6 +1366,23 @@ static int dwc3_core_init(struct dwc3 *dwc)
 	 */
 	dwc3_writel(dwc->regs, DWC3_GUID, LINUX_VERSION_CODE);
 
+	/* Apply Apple quirks */
+	if (of_device_is_compatible(dwc->dev->of_node, "apple,t8103-dwc3")) {
+		dwc3_writel(dwc->regs,
+			    APPLE_DWC3_CIO_LFPS_OFFSET,
+			    APPLE_DWC3_CIO_LFPS_OFFSET_VALUE);
+		dwc3_writel(dwc->regs,
+			    APPLE_DWC3_CIO_BW_NGT_OFFSET,
+			    APPLE_DWC3_CIO_BW_NGT_OFFSET_VALUE);
+
+		u32 link_timer = dwc3_readl(dwc->regs, APPLE_DWC3_CIO_LINK_TIMER);
+
+		link_timer &= ~APPLE_DWC3_CIO_PENDING_HP_TIMER;
+		link_timer |= FIELD_PREP(APPLE_DWC3_CIO_PENDING_HP_TIMER,
+					 APPLE_DWC3_CIO_PENDING_HP_TIMER_VALUE);
+		dwc3_writel(dwc->regs, APPLE_DWC3_CIO_LINK_TIMER, link_timer);
+	}
+
 	ret = dwc3_phy_setup(dwc);
 	if (ret)
 		return ret;
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 98e748cc348dfd9de1962c93fcf9f6a6690c2388..1caa46ca8b2ffb74dd3e58b174122e8f8216dd48 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -181,6 +181,24 @@
 
 #define DWC3_LLUCTL(n)		(0xd024 + ((n) * 0x80))
 
+/*
+ * Apple Silicon dwc3 vendor-specific registers
+ *
+ * These registers were identified by tracing XNU's memory access patterns
+ * and correlating them with debug output over serial to determine their names.
+ * We don't exactly know what these do but without these USB3 devices sometimes
+ * don't work.
+ */
+#define APPLE_DWC3_CIO_LFPS_OFFSET 0xcd38
+#define APPLE_DWC3_CIO_LFPS_OFFSET_VALUE 0xf800f80
+
+#define APPLE_DWC3_CIO_BW_NGT_OFFSET 0xcd3c
+#define APPLE_DWC3_CIO_BW_NGT_OFFSET_VALUE 0xfc00fc0
+
+#define APPLE_DWC3_CIO_LINK_TIMER 0xcd40
+#define APPLE_DWC3_CIO_PENDING_HP_TIMER GENMASK(23, 16)
+#define APPLE_DWC3_CIO_PENDING_HP_TIMER_VALUE 0x14
+
 /* Bit fields */
 
 /* Global SoC Bus Configuration INCRx Register 0 */

-- 
2.34.1




From sven at kernel.org  Thu Aug 21 08:38:55 2025
From: sven at kernel.org (Sven Peter)
Date: Thu, 21 Aug 2025 15:38:55 +0000
Subject: [PATCH RFC 03/22] dt-bindings: phy: Add Apple Type-C PHY
In-Reply-To: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
Message-ID: <20250821-atcphy-6-17-v1-3-172beda182b8@kernel.org>

Apple's Type-C PHY (ATCPHY) is a PHY for USB 2.0, USB 3.x,
USB4/Thunderbolt, and DisplayPort connectivity found in Apple Silicon
SoCs.

The PHY handles muxing between these different protocols and also provides
the reset controller for the attached dwc3 USB controller.

Signed-off-by: Sven Peter <sven at kernel.org>
---
 .../devicetree/bindings/phy/apple,atcphy.yaml      | 210 +++++++++++++++++++++
 MAINTAINERS                                        |   1 +
 2 files changed, 211 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/apple,atcphy.yaml b/Documentation/devicetree/bindings/phy/apple,atcphy.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..eb14010557c94f313b54b528e2d4039fe540062a
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/apple,atcphy.yaml
@@ -0,0 +1,210 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/apple,atcphy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple Type-C PHY (ATCPHY)
+
+maintainers:
+  - Sven Peter <sven at kernel.org>
+
+description:
+  The Apple Type-C PHY (ATCPHY) is a PHY for USB 2.0, USB 3.x,
+  USB4/Thunderbolt, and DisplayPort connectivity found in Apple Silicon SoCs.
+
+  The PHY handles muxing between these different protocols and also provides the
+  reset controller for the attached dwc3 USB controller.
+
+  The PHY is designed for USB4 operation and does not handle individual
+  differential pairs as distinct DisplayPort lanes. Any reference to lane in
+  this binding hence refers to two differential pairs (RX and TX) as used in USB
+  terminology.
+
+properties:
+  compatible:
+    enum:
+      - apple,t6000-atcphy
+      - apple,t6000-atcphy-dp-only # PHY hardwired to DP-to-HDMI converter on M2 Pro MacBook
+      - apple,t6020-atcphy
+      - apple,t8103-atcphy
+      - apple,t8112-atcphy
+
+  reg:
+    minItems: 5
+    maxItems: 5
+
+  reg-names:
+    items:
+      - const: core
+      - const: lpdptx
+      - const: axi2af
+      - const: usb2phy
+      - const: pipehandler
+
+  "#phy-cells":
+    const: 1
+
+  "#reset-cells":
+    const: 0
+
+  orientation-switch:
+    type: boolean
+    description:
+      The PHY handles swapping lanes if the Type-C connector is flipped.
+
+  mode-switch:
+    type: boolean
+    description:
+      The PHY handles muxing between USB 2.0, USB 3.x, USB4/Thunderbolt, and DisplayPort.
+
+  power-domains:
+    minItems: 1
+    maxItems: 1
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+    properties:
+      port at 0:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: Output endpoint of the PHY to the Type-C connector
+
+      port at 1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: Incoming endpoint from the USB3 controller
+
+      port at 2:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: Incoming endpoint from the DisplayPort controller
+
+      port at 3:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: Incoming endpoint from the USB4/Thunderbolt controller
+
+  apple,tunable-axi2af:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    description:
+      AXI2AF tunables.
+
+      This array is filled with 3-tuples each containing three 32-bit values
+      <register offset>, <mask>, and <value> by the bootloader.
+      The driver will use these to configure the PHY by reading from each
+      register, ANDing it with <mask>, ORing it with <value>, and storing the
+      result back to the register.
+      These values slightly differ even between different chips of the same
+      generation and are likely calibration values determined by Apple at
+      manufacturing time.
+
+  apple,tunable-common:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    description:
+      Common tunables required for all modes, see apple,tunable-axi2af for details.
+
+  apple,tunable-fuses:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    description:
+      Fuse based tunables required for all modes, see apple,tunable-axi2af for details.
+
+  apple,tunable-lane0-usb:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    description:
+      USB tunables on lane 0, see apple,tunable-axi2af for details.
+
+  apple,tunable-lane1-usb:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    description:
+      USB tunables on lane 1, see apple,tunable-axi2af for details.
+
+  apple,tunable-lane0-cio:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    description:
+      USB4/Thunderbolt ("converged IO") tunables on lane 0, see apple,tunable-axi2af for details.
+
+  apple,tunable-lane1-cio:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    description:
+      USB4/Thunderbolt ("converged IO") tunables on lane 1, see apple,tunable-axi2af for details.
+
+  apple,tunable-lane0-dp:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    description:
+      DisplayPort tunables on lane 0, see apple,tunable-axi2af for details.
+
+      Note that lane here refers to a USB RX and TX pair re-used for DisplayPort
+      and not to an individual DisplayPort differential lane.
+
+  apple,tunable-lane1-dp:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    description:
+      DisplayPort tunables on lane 1, see apple,tunable-axi2af for details.
+
+      Note that lane here refers to a USB RX and TX pair re-used for DisplayPort
+      and not to an individual DisplayPort differential lane.
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - "#phy-cells"
+  - "#reset-cells"
+  - orientation-switch
+  - mode-switch
+
+additionalProperties: false
+
+examples:
+  - |
+    phy at 383000000 {
+      compatible = "apple,t8103-atcphy";
+      reg = <0x3 0x83000000 0x0 0x4c000>,
+            <0x3 0x83050000 0x0 0x8000>,
+            <0x3 0x80000000 0x0 0x4000>,
+            <0x3 0x82a90000 0x0 0x4000>,
+            <0x3 0x82a84000 0x0 0x4000>;
+      reg-names = "core", "lpdptx", "axi2af", "usb2phy",
+                  "pipehandler";
+
+      #phy-cells = <1>;
+      #reset-cells = <0>;
+
+      orientation-switch;
+      mode-switch;
+      power-domains = <&ps_atc0_usb>;
+
+      ports {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        port at 0 {
+          reg = <0>;
+
+          endpoint {
+            remote-endpoint = <&typec_connector_ss>;
+          };
+        };
+
+        port at 1 {
+          reg = <1>;
+
+          endpoint {
+            remote-endpoint = <&dwc3_ss_out>;
+          };
+        };
+
+        port at 2 {
+          reg = <2>;
+
+          endpoint {
+            remote-endpoint = <&dcp_dp_out>;
+          };
+        };
+
+        port at 3 {
+          reg = <3>;
+
+          endpoint {
+            remote-endpoint = <&acio_tbt_out>;
+          };
+        };
+      };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 0e085cb0762f765958d67be61ae0d3d773503431..11a9b084a2e51d7b9b2e4c1777a2439df4a6858b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2393,6 +2393,7 @@ F:	Documentation/devicetree/bindings/nvme/apple,nvme-ans.yaml
 F:	Documentation/devicetree/bindings/nvmem/apple,efuses.yaml
 F:	Documentation/devicetree/bindings/nvmem/apple,spmi-nvmem.yaml
 F:	Documentation/devicetree/bindings/pci/apple,pcie.yaml
+F:	Documentation/devicetree/bindings/phy/apple,atcphy.yaml
 F:	Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml
 F:	Documentation/devicetree/bindings/power/apple*
 F:	Documentation/devicetree/bindings/power/reset/apple,smc-reboot.yaml

-- 
2.34.1




From sven at kernel.org  Thu Aug 21 08:39:01 2025
From: sven at kernel.org (Sven Peter)
Date: Thu, 21 Aug 2025 15:39:01 +0000
Subject: [PATCH RFC 09/22] usb: typec: tipd: Move initial irq mask to
 tipd_data
In-Reply-To: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
Message-ID: <20250821-atcphy-6-17-v1-9-172beda182b8@kernel.org>

Since the irq mask was originally added more tipd variants have been
introduced and there's now struct tipd_data. Move the initial mask in
there.

Signed-off-by: Sven Peter <sven at kernel.org>
---
 drivers/usb/typec/tipd/core.c | 23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c
index 1c80296c3b273e24ceacb3feff432c4f6e6835cc..6d8bcbc9cad8a1394e066504d4c5ca570edd4e4f 100644
--- a/drivers/usb/typec/tipd/core.c
+++ b/drivers/usb/typec/tipd/core.c
@@ -112,6 +112,7 @@ struct tps6598x;
 
 struct tipd_data {
 	irq_handler_t irq_handler;
+	u64 irq_mask1;
 	int (*register_port)(struct tps6598x *tps, struct fwnode_handle *node);
 	void (*trace_power_status)(u16 status);
 	void (*trace_status)(u32 status);
@@ -1298,7 +1299,6 @@ static int tps6598x_probe(struct i2c_client *client)
 	u32 status;
 	u32 vid;
 	int ret;
-	u64 mask1;
 
 	tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
 	if (!tps)
@@ -1337,16 +1337,6 @@ static int tps6598x_probe(struct i2c_client *client)
 		if (ret)
 			return ret;
 
-		/* CD321X chips have all interrupts masked initially */
-		mask1 = APPLE_CD_REG_INT_POWER_STATUS_UPDATE |
-			APPLE_CD_REG_INT_DATA_STATUS_UPDATE |
-			APPLE_CD_REG_INT_PLUG_EVENT;
-
-	} else {
-		/* Enable power status, data status and plug event interrupts */
-		mask1 = TPS_REG_INT_POWER_STATUS_UPDATE |
-			TPS_REG_INT_DATA_STATUS_UPDATE |
-			TPS_REG_INT_PLUG_EVENT;
 	}
 
 	tps->data = i2c_get_match_data(client);
@@ -1364,7 +1354,7 @@ static int tps6598x_probe(struct i2c_client *client)
 			return ret;
 	}
 
-	ret = tps6598x_write64(tps, TPS_REG_INT_MASK1, mask1);
+	ret = tps6598x_write64(tps, TPS_REG_INT_MASK1, tps->data->irq_mask1);
 	if (ret)
 		goto err_reset_controller;
 
@@ -1527,6 +1517,9 @@ static const struct dev_pm_ops tps6598x_pm_ops = {
 
 static const struct tipd_data cd321x_data = {
 	.irq_handler = cd321x_interrupt,
+	.irq_mask1 = APPLE_CD_REG_INT_POWER_STATUS_UPDATE |
+		     APPLE_CD_REG_INT_DATA_STATUS_UPDATE |
+		     APPLE_CD_REG_INT_PLUG_EVENT,
 	.register_port = tps6598x_register_port,
 	.trace_power_status = trace_tps6598x_power_status,
 	.trace_status = trace_tps6598x_status,
@@ -1536,6 +1529,9 @@ static const struct tipd_data cd321x_data = {
 
 static const struct tipd_data tps6598x_data = {
 	.irq_handler = tps6598x_interrupt,
+	.irq_mask1 = TPS_REG_INT_POWER_STATUS_UPDATE |
+		     TPS_REG_INT_DATA_STATUS_UPDATE |
+		     TPS_REG_INT_PLUG_EVENT,
 	.register_port = tps6598x_register_port,
 	.trace_power_status = trace_tps6598x_power_status,
 	.trace_status = trace_tps6598x_status,
@@ -1546,6 +1542,9 @@ static const struct tipd_data tps6598x_data = {
 
 static const struct tipd_data tps25750_data = {
 	.irq_handler = tps25750_interrupt,
+	.irq_mask1 = TPS_REG_INT_POWER_STATUS_UPDATE |
+		     TPS_REG_INT_DATA_STATUS_UPDATE |
+		     TPS_REG_INT_PLUG_EVENT,
 	.register_port = tps25750_register_port,
 	.trace_power_status = trace_tps25750_power_status,
 	.trace_status = trace_tps25750_status,

-- 
2.34.1




From sven at kernel.org  Thu Aug 21 08:39:02 2025
From: sven at kernel.org (Sven Peter)
Date: Thu, 21 Aug 2025 15:39:02 +0000
Subject: [PATCH RFC 10/22] usb: typec: tipd: Move switch_power_state to
 tipd_data
In-Reply-To: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
Message-ID: <20250821-atcphy-6-17-v1-10-172beda182b8@kernel.org>

When support for CD321x was originally added no other hardware variant
was supported and there was no need for struct tipd_data. Now that it
exists move the special case in there so that we can drop the
of_device_is_compatible_check entirely.

Signed-off-by: Sven Peter <sven at kernel.org>
---
 drivers/usb/typec/tipd/core.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c
index 6d8bcbc9cad8a1394e066504d4c5ca570edd4e4f..4815c5c462837865a5f9d37bbc139249c82c2f75 100644
--- a/drivers/usb/typec/tipd/core.c
+++ b/drivers/usb/typec/tipd/core.c
@@ -118,6 +118,7 @@ struct tipd_data {
 	void (*trace_status)(u32 status);
 	int (*apply_patch)(struct tps6598x *tps);
 	int (*init)(struct tps6598x *tps);
+	int (*switch_power_state)(struct tps6598x *tps, u8 target_state);
 	int (*reset)(struct tps6598x *tps);
 };
 
@@ -1293,7 +1294,6 @@ tps25750_register_port(struct tps6598x *tps, struct fwnode_handle *fwnode)
 
 static int tps6598x_probe(struct i2c_client *client)
 {
-	struct device_node *np = client->dev.of_node;
 	struct tps6598x *tps;
 	struct fwnode_handle *fwnode;
 	u32 status;
@@ -1331,18 +1331,16 @@ static int tps6598x_probe(struct i2c_client *client)
 	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
 		tps->i2c_protocol = true;
 
-	if (np && of_device_is_compatible(np, "apple,cd321x")) {
-		/* Switch CD321X chips to the correct system power state */
-		ret = cd321x_switch_power_state(tps, TPS_SYSTEM_POWER_STATE_S0);
-		if (ret)
-			return ret;
-
-	}
-
 	tps->data = i2c_get_match_data(client);
 	if (!tps->data)
 		return -EINVAL;
 
+	if (tps->data->switch_power_state) {
+		ret = tps->data->switch_power_state(tps, TPS_SYSTEM_POWER_STATE_S0);
+		if (ret)
+			return ret;
+	}
+
 	/* Make sure the controller has application firmware running */
 	ret = tps6598x_check_mode(tps);
 	if (ret < 0)
@@ -1525,6 +1523,7 @@ static const struct tipd_data cd321x_data = {
 	.trace_status = trace_tps6598x_status,
 	.init = cd321x_init,
 	.reset = cd321x_reset,
+	.switch_power_state = cd321x_switch_power_state,
 };
 
 static const struct tipd_data tps6598x_data = {

-- 
2.34.1




From sven at kernel.org  Thu Aug 21 08:39:04 2025
From: sven at kernel.org (Sven Peter)
Date: Thu, 21 Aug 2025 15:39:04 +0000
Subject: [PATCH RFC 12/22] usb: typec: tipd: Add cd321x struct with
 separate size
In-Reply-To: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
Message-ID: <20250821-atcphy-6-17-v1-12-172beda182b8@kernel.org>

We're about to add more fields to struct tps6598x which are only relevant
for Apple's CD321x and to ensure that we don't waste memory everywhere for
those add a separate struct for cd321x and prepare to allocate more space
inside probe.

Signed-off-by: Sven Peter <sven at kernel.org>
---
 drivers/usb/typec/tipd/core.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c
index 19d713937870304e68325a441b0de63eb5db3b80..51b0f3be8b66a743ddc3ea96c1b25f597a1e8f6c 100644
--- a/drivers/usb/typec/tipd/core.c
+++ b/drivers/usb/typec/tipd/core.c
@@ -113,6 +113,7 @@ struct tps6598x;
 struct tipd_data {
 	irq_handler_t irq_handler;
 	u64 irq_mask1;
+	size_t tps_struct_size;
 	int (*register_port)(struct tps6598x *tps, struct fwnode_handle *node);
 	void (*trace_data_status)(u32 status);
 	void (*trace_power_status)(u16 status);
@@ -148,6 +149,10 @@ struct tps6598x {
 	const struct tipd_data *data;
 };
 
+struct cd321x {
+	struct tps6598x tps;
+};
+
 static enum power_supply_property tps6598x_psy_props[] = {
 	POWER_SUPPLY_PROP_USB_TYPE,
 	POWER_SUPPLY_PROP_ONLINE,
@@ -1297,18 +1302,24 @@ tps25750_register_port(struct tps6598x *tps, struct fwnode_handle *fwnode)
 
 static int tps6598x_probe(struct i2c_client *client)
 {
+	const struct tipd_data *data;
 	struct tps6598x *tps;
 	struct fwnode_handle *fwnode;
 	u32 status;
 	u32 vid;
 	int ret;
 
-	tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
+	data = i2c_get_match_data(client);
+	if (!data)
+		return -EINVAL;
+
+	tps = devm_kzalloc(&client->dev, data->tps_struct_size, GFP_KERNEL);
 	if (!tps)
 		return -ENOMEM;
 
 	mutex_init(&tps->lock);
 	tps->dev = &client->dev;
+	tps->data = data;
 
 	tps->reset = devm_gpiod_get_optional(tps->dev, "reset", GPIOD_OUT_LOW);
 	if (IS_ERR(tps->reset))
@@ -1334,10 +1345,6 @@ static int tps6598x_probe(struct i2c_client *client)
 	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
 		tps->i2c_protocol = true;
 
-	tps->data = i2c_get_match_data(client);
-	if (!tps->data)
-		return -EINVAL;
-
 	if (tps->data->switch_power_state) {
 		ret = tps->data->switch_power_state(tps, TPS_SYSTEM_POWER_STATE_S0);
 		if (ret)
@@ -1521,6 +1528,7 @@ static const struct tipd_data cd321x_data = {
 	.irq_mask1 = APPLE_CD_REG_INT_POWER_STATUS_UPDATE |
 		     APPLE_CD_REG_INT_DATA_STATUS_UPDATE |
 		     APPLE_CD_REG_INT_PLUG_EVENT,
+	.tps_struct_size = sizeof(struct cd321x),
 	.register_port = tps6598x_register_port,
 	.trace_data_status = trace_cd321x_data_status,
 	.trace_power_status = trace_tps6598x_power_status,
@@ -1535,6 +1543,7 @@ static const struct tipd_data tps6598x_data = {
 	.irq_mask1 = TPS_REG_INT_POWER_STATUS_UPDATE |
 		     TPS_REG_INT_DATA_STATUS_UPDATE |
 		     TPS_REG_INT_PLUG_EVENT,
+	.tps_struct_size = sizeof(struct tps6598x),
 	.register_port = tps6598x_register_port,
 	.trace_data_status = trace_tps6598x_data_status,
 	.trace_power_status = trace_tps6598x_power_status,
@@ -1549,6 +1558,7 @@ static const struct tipd_data tps25750_data = {
 	.irq_mask1 = TPS_REG_INT_POWER_STATUS_UPDATE |
 		     TPS_REG_INT_DATA_STATUS_UPDATE |
 		     TPS_REG_INT_PLUG_EVENT,
+	.tps_struct_size = sizeof(struct tps6598x),
 	.register_port = tps25750_register_port,
 	.trace_data_status = trace_tps6598x_data_status,
 	.trace_power_status = trace_tps25750_power_status,

-- 
2.34.1




From sven at kernel.org  Thu Aug 21 08:39:08 2025
From: sven at kernel.org (Sven Peter)
Date: Thu, 21 Aug 2025 15:39:08 +0000
Subject: [PATCH RFC 16/22] usb: typec: tipd: Use read_power_status function
 in probe
In-Reply-To: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
Message-ID: <20250821-atcphy-6-17-v1-16-172beda182b8@kernel.org>

From: Hector Martin <marcan at marcan.st>

We need the initial power status to be able to reliably detect connector
changes once we introduce de-bouncing for CD321x next. read_power_status
takes care of this and also forwards the status to the trace subsystem
so let's use that instead of open-coding it inside probe.

Signed-off-by: Hector Martin <marcan at marcan.st>
Signed-off-by: Sven Peter <sven at kernel.org>
---
 drivers/usb/typec/tipd/core.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c
index b0fdd4dddd3a490dbc2a8ced21ea0803658f36a7..2b7c5017a347d153b50383b34123a2ecc424eb68 100644
--- a/drivers/usb/typec/tipd/core.c
+++ b/drivers/usb/typec/tipd/core.c
@@ -1552,11 +1552,8 @@ static int tps6598x_probe(struct i2c_client *client)
 		goto err_role_put;
 
 	if (status & TPS_STATUS_PLUG_PRESENT) {
-		ret = tps6598x_read16(tps, TPS_REG_POWER_STATUS, &tps->pwr_status);
-		if (ret < 0) {
-			dev_err(tps->dev, "failed to read power status: %d\n", ret);
+		if (!tps6598x_read_power_status(tps))
 			goto err_unregister_port;
-		}
 		ret = tps6598x_connect(tps, status);
 		if (ret)
 			dev_err(&client->dev, "failed to register partner\n");

-- 
2.34.1




From sven at kernel.org  Thu Aug 21 08:39:10 2025
From: sven at kernel.org (Sven Peter)
Date: Thu, 21 Aug 2025 15:39:10 +0000
Subject: [PATCH RFC 18/22] usb: typec: mux: Introduce data_role to mux
 state
In-Reply-To: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
Message-ID: <20250821-atcphy-6-17-v1-18-172beda182b8@kernel.org>

From: Hector Martin <marcan at marcan.st>

Some muxes may need to know the data role that is being switched to,
such as to direct the data pins to separate host/device controllers or
configure a unified PHY correctly.

Signed-off-by: Hector Martin <marcan at marcan.st>
Signed-off-by: Sven Peter <sven at kernel.org>
---
 include/linux/usb/typec_mux.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/usb/typec_mux.h b/include/linux/usb/typec_mux.h
index 2489a7857d8e10a73450a66ee85b5068f401f047..89b64ed081aecaa70529aaa717579c0dc7a5f961 100644
--- a/include/linux/usb/typec_mux.h
+++ b/include/linux/usb/typec_mux.h
@@ -45,6 +45,7 @@ void *typec_switch_get_drvdata(struct typec_switch_dev *sw);
 struct typec_mux_state {
 	struct typec_altmode *alt;
 	unsigned long mode;
+	enum typec_data_role data_role;
 	void *data;
 };
 

-- 
2.34.1




From sven at kernel.org  Thu Aug 21 08:39:14 2025
From: sven at kernel.org (Sven Peter)
Date: Thu, 21 Aug 2025 15:39:14 +0000
Subject: [PATCH RFC 22/22] arm64: dts: apple: t8103: Add Apple Type-C PHY
 and dwc3 nodes
In-Reply-To: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
Message-ID: <20250821-atcphy-6-17-v1-22-172beda182b8@kernel.org>

Add all nodes and connections required to make USB3 work on M1-based
Apple machines.

Co-developed-by: Hector Martin <marcan at marcan.st>
Signed-off-by: Hector Martin <marcan at marcan.st>
Signed-off-by: Sven Peter <sven at kernel.org>
---
 arch/arm64/boot/dts/apple/t8103-j274.dts  |  12 +++
 arch/arm64/boot/dts/apple/t8103-j293.dts  |  12 +++
 arch/arm64/boot/dts/apple/t8103-j313.dts  |  12 +++
 arch/arm64/boot/dts/apple/t8103-j456.dts  |  12 +++
 arch/arm64/boot/dts/apple/t8103-j457.dts  |  12 +++
 arch/arm64/boot/dts/apple/t8103-jxxx.dtsi | 137 ++++++++++++++++++++++++++++++
 arch/arm64/boot/dts/apple/t8103.dtsi      | 105 +++++++++++++++++++++++
 7 files changed, 302 insertions(+)

diff --git a/arch/arm64/boot/dts/apple/t8103-j274.dts b/arch/arm64/boot/dts/apple/t8103-j274.dts
index 1c3e37f86d46d7b5d733717b47c4b57dc55e1201..968fe22163d4431fe5e7049854687e61e0ec50f1 100644
--- a/arch/arm64/boot/dts/apple/t8103-j274.dts
+++ b/arch/arm64/boot/dts/apple/t8103-j274.dts
@@ -29,6 +29,18 @@ &wifi0 {
 	brcm,board-type = "apple,atlantisb";
 };
 
+/*
+ * Provide labels for the USB type C ports.
+ */
+
+&typec0 {
+	label = "USB-C Back-left";
+};
+
+&typec1 {
+	label = "USB-C Back-right";
+};
+
 /*
  * Force the bus number assignments so that we can declare some of the
  * on-board devices and properties that are populated by the bootloader
diff --git a/arch/arm64/boot/dts/apple/t8103-j293.dts b/arch/arm64/boot/dts/apple/t8103-j293.dts
index 5b3c42e9f0e6776241bf746d3458766e44e3639a..678f89c3d47fbf2d0705b46bb8feba3fa018ca7a 100644
--- a/arch/arm64/boot/dts/apple/t8103-j293.dts
+++ b/arch/arm64/boot/dts/apple/t8103-j293.dts
@@ -46,6 +46,18 @@ &wifi0 {
 	brcm,board-type = "apple,honshu";
 };
 
+/*
+ * Provide labels for the USB type C ports.
+ */
+
+&typec0 {
+	label = "USB-C Left-back";
+};
+
+&typec1 {
+	label = "USB-C Left-front";
+};
+
 &i2c2 {
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/apple/t8103-j313.dts b/arch/arm64/boot/dts/apple/t8103-j313.dts
index 97a4344d8dca685708aff136af92a1b316f3c3dd..bce9b911009e2b0caa9d8b2222cd1e8c3215f3b9 100644
--- a/arch/arm64/boot/dts/apple/t8103-j313.dts
+++ b/arch/arm64/boot/dts/apple/t8103-j313.dts
@@ -41,3 +41,15 @@ &wifi0 {
 &fpwm1 {
 	status = "okay";
 };
+
+/*
+ * Provide labels for the USB type C ports.
+ */
+
+&typec0 {
+	label = "USB-C Left-back";
+};
+
+&typec1 {
+	label = "USB-C Left-front";
+};
diff --git a/arch/arm64/boot/dts/apple/t8103-j456.dts b/arch/arm64/boot/dts/apple/t8103-j456.dts
index 58c8e43789b4861544e20c717124ede3327be010..9983e11cacdf19d0a92ede108ceac21b7a02d5da 100644
--- a/arch/arm64/boot/dts/apple/t8103-j456.dts
+++ b/arch/arm64/boot/dts/apple/t8103-j456.dts
@@ -47,6 +47,18 @@ hpm3: usb-pd at 3c {
 	};
 };
 
+/*
+ * Provide labels for the USB type C ports.
+ */
+
+&typec0 {
+	label = "USB-C Back-right";
+};
+
+&typec1 {
+	label = "USB-C Back-right-middle";
+};
+
 /*
  * Force the bus number assignments so that we can declare some of the
  * on-board devices and properties that are populated by the bootloader
diff --git a/arch/arm64/boot/dts/apple/t8103-j457.dts b/arch/arm64/boot/dts/apple/t8103-j457.dts
index 152f95fd49a2118093396838fbd8b6bd1b518f81..a622ff607d407519000d1526b7244419a59644a3 100644
--- a/arch/arm64/boot/dts/apple/t8103-j457.dts
+++ b/arch/arm64/boot/dts/apple/t8103-j457.dts
@@ -29,6 +29,18 @@ &wifi0 {
 	brcm,board-type = "apple,santorini";
 };
 
+/*
+ * Provide labels for the USB type C ports.
+ */
+
+&typec0 {
+	label = "USB-C Back-right";
+};
+
+&typec1 {
+	label = "USB-C Back-left";
+};
+
 /*
  * Force the bus number assignments so that we can declare some of the
  * on-board devices and properties that are populated by the bootloader
diff --git a/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi b/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi
index 0c8206156bfefda8a32c869787b2e0c8e67a9d17..758b2196954bc139c201d25298444f59c7832ea5 100644
--- a/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi
+++ b/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi
@@ -15,6 +15,8 @@ aliases {
 		serial0 = &serial0;
 		serial2 = &serial2;
 		wifi0 = &wifi0;
+		atcphy0 = &atcphy0;
+		atcphy1 = &atcphy1;
 	};
 
 	chosen {
@@ -53,6 +55,30 @@ hpm0: usb-pd at 38 {
 		interrupt-parent = <&pinctrl_ap>;
 		interrupts = <106 IRQ_TYPE_LEVEL_LOW>;
 		interrupt-names = "irq";
+
+		typec0: connector {
+			compatible = "usb-c-connector";
+			power-role = "dual";
+			data-role = "dual";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					reg = <0>;
+					typec0_connector_hs: endpoint {
+						remote-endpoint = <&dwc3_0_hs>;
+					};
+				};
+				port at 1 {
+					reg = <1>;
+					typec0_connector_ss: endpoint {
+						remote-endpoint = <&atcphy0_typec_lanes>;
+					};
+				};
+			};
+		};
 	};
 
 	hpm1: usb-pd at 3f {
@@ -61,6 +87,117 @@ hpm1: usb-pd at 3f {
 		interrupt-parent = <&pinctrl_ap>;
 		interrupts = <106 IRQ_TYPE_LEVEL_LOW>;
 		interrupt-names = "irq";
+
+		typec1: connector {
+			compatible = "usb-c-connector";
+			power-role = "dual";
+			data-role = "dual";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					reg = <0>;
+					typec1_connector_hs: endpoint {
+						remote-endpoint = <&dwc3_1_hs>;
+					};
+				};
+
+				port at 1 {
+					reg = <1>;
+					typec1_connector_ss: endpoint {
+						remote-endpoint = <&atcphy1_typec_lanes>;
+					};
+				};
+			};
+		};
+	};
+};
+
+/* USB controllers */
+&dwc3_0 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port at 0 {
+			reg = <0>;
+			dwc3_0_hs: endpoint {
+				remote-endpoint = <&typec0_connector_hs>;
+			};
+		};
+
+		port at 1 {
+			reg = <1>;
+			dwc3_0_ss: endpoint {
+				remote-endpoint = <&atcphy0_usb3>;
+			};
+		};
+	};
+};
+
+&dwc3_1 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port at 0 {
+			reg = <0>;
+			dwc3_1_hs: endpoint {
+				remote-endpoint = <&typec1_connector_hs>;
+			};
+		};
+
+		port at 1 {
+			reg = <1>;
+			dwc3_1_ss: endpoint {
+				remote-endpoint = <&atcphy1_usb3>;
+			};
+		};
+	};
+};
+
+/* Type-C PHYs */
+&atcphy0 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port at 0 {
+			reg = <0>;
+			atcphy0_typec_lanes: endpoint {
+				remote-endpoint = <&typec0_connector_ss>;
+			};
+		};
+
+		port at 1 {
+			reg = <1>;
+			atcphy0_usb3: endpoint {
+				remote-endpoint = <&dwc3_0_ss>;
+			};
+		};
+	};
+};
+
+&atcphy1 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port at 0 {
+			reg = <0>;
+			atcphy1_typec_lanes: endpoint {
+				remote-endpoint = <&typec1_connector_ss>;
+			};
+		};
+
+		port at 1 {
+			reg = <1>;
+			atcphy1_usb3: endpoint {
+				remote-endpoint = <&dwc3_1_ss>;
+			};
+		};
 	};
 };
 
diff --git a/arch/arm64/boot/dts/apple/t8103.dtsi b/arch/arm64/boot/dts/apple/t8103.dtsi
index 589ddc0397995ecf6fc11b135164229ab1ee7cf8..659a73fafccb04c1b944f6b7afeb0e372d4bb748 100644
--- a/arch/arm64/boot/dts/apple/t8103.dtsi
+++ b/arch/arm64/boot/dts/apple/t8103.dtsi
@@ -10,6 +10,7 @@
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/interrupt-controller/apple-aic.h>
 #include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/phy/phy.h>
 #include <dt-bindings/pinctrl/apple.h>
 #include <dt-bindings/spmi/spmi.h>
 
@@ -972,6 +973,110 @@ nvme at 27bcc0000 {
 			resets = <&ps_ans2>;
 		};
 
+		dwc3_0: usb at 382280000 {
+			compatible = "apple,t8103-dwc3", "snps,dwc3";
+			reg = <0x3 0x82280000 0x0 0x100000>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 777 IRQ_TYPE_LEVEL_HIGH>;
+			dr_mode = "otg";
+			usb-role-switch;
+			role-switch-default-mode = "host";
+			iommus = <&dwc3_0_dart_0 0>, <&dwc3_0_dart_1 1>;
+			power-domains = <&ps_atc0_usb>;
+			resets = <&atcphy0>;
+			phys = <&atcphy0 PHY_TYPE_USB2>, <&atcphy0 PHY_TYPE_USB3>;
+			phy-names = "usb2-phy", "usb3-phy";
+		};
+
+		dwc3_0_dart_0: iommu at 382f00000 {
+			compatible = "apple,t8103-dart";
+			reg = <0x3 0x82f00000 0x0 0x4000>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 781 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			power-domains = <&ps_atc0_usb>;
+		};
+
+		dwc3_0_dart_1: iommu at 382f80000 {
+			compatible = "apple,t8103-dart";
+			reg = <0x3 0x82f80000 0x0 0x4000>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 781 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			power-domains = <&ps_atc0_usb>;
+		};
+
+		atcphy0: phy at 383000000 {
+			compatible = "apple,t8103-atcphy";
+			reg = <0x3 0x83000000 0x0 0x4c000>,
+				<0x3 0x83050000 0x0 0x8000>,
+				<0x3 0x80000000 0x0 0x4000>,
+				<0x3 0x82a90000 0x0 0x4000>,
+				<0x3 0x82a84000 0x0 0x4000>;
+			reg-names = "core", "lpdptx", "axi2af", "usb2phy",
+				"pipehandler";
+
+			#phy-cells = <1>;
+			#reset-cells = <0>;
+
+			orientation-switch;
+			mode-switch;
+			power-domains = <&ps_atc0_usb>;
+			//power-domains = <&ps_atc0_usb_aon>, <&ps_atc0_common>;
+		};
+
+		dwc3_1: usb at 502280000 {
+			compatible = "apple,t8103-dwc3", "snps,dwc3";
+			reg = <0x5 0x02280000 0x0 0x100000>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 857 IRQ_TYPE_LEVEL_HIGH>;
+			dr_mode = "otg";
+			usb-role-switch;
+			role-switch-default-mode = "host";
+			iommus = <&dwc3_1_dart_0 0>, <&dwc3_1_dart_1 1>;
+			power-domains = <&ps_atc1_usb>;
+			resets = <&atcphy1>;
+			phys = <&atcphy1 PHY_TYPE_USB2>, <&atcphy1 PHY_TYPE_USB3>;
+			phy-names = "usb2-phy", "usb3-phy";
+		};
+
+		dwc3_1_dart_0: iommu at 502f00000 {
+			compatible = "apple,t8103-dart";
+			reg = <0x5 0x02f00000 0x0 0x4000>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 861 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			power-domains = <&ps_atc1_usb>;
+		};
+
+		dwc3_1_dart_1: iommu at 502f80000 {
+			compatible = "apple,t8103-dart";
+			reg = <0x5 0x02f80000 0x0 0x4000>;
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 861 IRQ_TYPE_LEVEL_HIGH>;
+			#iommu-cells = <1>;
+			power-domains = <&ps_atc1_usb>;
+		};
+
+		atcphy1: phy at 503000000 {
+			compatible = "apple,t8103-atcphy";
+			reg = <0x5 0x03000000 0x0 0x4c000>,
+				<0x5 0x03050000 0x0 0x8000>,
+				<0x5 0x0 0x0 0x4000>,
+				<0x5 0x02a90000 0x0 0x4000>,
+				<0x5 0x02a84000 0x0 0x4000>;
+			reg-names = "core", "lpdptx", "axi2af", "usb2phy",
+				"pipehandler";
+
+			#phy-cells = <1>;
+			#reset-cells = <0>;
+
+			orientation-switch;
+			mode-switch;
+			power-domains = <&ps_atc1_usb>;
+			//power-domains = <&ps_atc1_usb_aon>, <&ps_atc1_common>;
+		};
+
 		pcie0_dart_0: iommu at 681008000 {
 			compatible = "apple,t8103-dart";
 			reg = <0x6 0x81008000 0x0 0x4000>;

-- 
2.34.1




From sven at kernel.org  Thu Aug 21 08:39:09 2025
From: sven at kernel.org (Sven Peter)
Date: Thu, 21 Aug 2025 15:39:09 +0000
Subject: [PATCH RFC 17/22] usb: typec: tipd: Read data status in probe and
 cache its value
In-Reply-To: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
Message-ID: <20250821-atcphy-6-17-v1-17-172beda182b8@kernel.org>

From: Hector Martin <marcan at marcan.st>

Just like for power status we also need to keep track of data status to
be able to detect mode changes once we introduce de-bouncing for CD321x.
Read it during probe and keep a cached copy of its value.

Signed-off-by: Hector Martin <marcan at marcan.st>
Signed-off-by: Sven Peter <sven at kernel.org>
---
 drivers/usb/typec/tipd/core.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c
index 2b7c5017a347d153b50383b34123a2ecc424eb68..bada42fbe59b29a9e864e17644da41908a445102 100644
--- a/drivers/usb/typec/tipd/core.c
+++ b/drivers/usb/typec/tipd/core.c
@@ -177,6 +177,7 @@ struct tps6598x {
 
 	int wakeup;
 	u32 status; /* status reg */
+	u32 data_status;
 	u16 pwr_status;
 	struct delayed_work	wq_poll;
 
@@ -539,6 +540,7 @@ static bool tps6598x_read_data_status(struct tps6598x *tps)
 		dev_err(tps->dev, "failed to read data status: %d\n", ret);
 		return false;
 	}
+	tps->data_status = data_status;
 
 	if (tps->data->trace_data_status)
 		tps->data->trace_data_status(data_status);
@@ -1554,6 +1556,8 @@ static int tps6598x_probe(struct i2c_client *client)
 	if (status & TPS_STATUS_PLUG_PRESENT) {
 		if (!tps6598x_read_power_status(tps))
 			goto err_unregister_port;
+		if (!tps->data->read_data_status(tps))
+			goto err_unregister_port;
 		ret = tps6598x_connect(tps, status);
 		if (ret)
 			dev_err(&client->dev, "failed to register partner\n");

-- 
2.34.1




From sven at kernel.org  Thu Aug 21 08:39:13 2025
From: sven at kernel.org (Sven Peter)
Date: Thu, 21 Aug 2025 15:39:13 +0000
Subject: [PATCH RFC 21/22] phy: apple: Add Apple Type-C PHY
In-Reply-To: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
Message-ID: <20250821-atcphy-6-17-v1-21-172beda182b8@kernel.org>

The Apple Type-C PHY (ATCPHY) is a PHY for USB 2.0, USB 3.x,
USB4/Thunderbolt, and DisplayPort connectivity found in Apple Silicon SoCs.
The PHY handles muxing between these different protocols and also provides
the reset controller for the attached dwc3 USB controller.

There is no documentation available for this PHY and the entire sequence
of MMIO pokes has been figured out by tracing all MMIO access of Apple's
driver under a thin hypervisor and correlating the register reads/writes
to their kernel's debug output to find their names. Deviations from this
sequence generally results in the port not working or, especially when
the mode is switched to USB4 or Thunderbolt, to some watchdog resetting
the entire SoC.

This initial commit already introduces support for Display Port and
USB4/Thunderbolt but the drivers for these are not ready. We cannot
control the alternate mode negotiation and are stuck with whatever Apple's
firmware decides such that any DisplayPort or USB4/Thunderbolt device will
result in a correctly setup PHY but not be usable until the other drivers
are upstreamed as well.

Co-developed-by: Janne Grunau <j at jannau.net>
Signed-off-by: Janne Grunau <j at jannau.net>
Co-developed-by: Hector Martin <marcan at marcan.st>
Signed-off-by: Hector Martin <marcan at marcan.st>
Signed-off-by: Sven Peter <sven at kernel.org>
---
 MAINTAINERS                |    1 +
 drivers/phy/Kconfig        |    1 +
 drivers/phy/Makefile       |    1 +
 drivers/phy/apple/Kconfig  |   14 +
 drivers/phy/apple/Makefile |    4 +
 drivers/phy/apple/atc.c    | 2537 ++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 2558 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 11a9b084a2e51d7b9b2e4c1777a2439df4a6858b..f17dc2140ef3aab88a51b710eaf5d8251df972d8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2419,6 +2419,7 @@ F:	drivers/mfd/macsmc.c
 F:	drivers/nvme/host/apple.c
 F:	drivers/nvmem/apple-efuses.c
 F:	drivers/nvmem/apple-spmi-nvmem.c
+F:	drivers/phy/apple/
 F:	drivers/pinctrl/pinctrl-apple-gpio.c
 F:	drivers/power/reset/macsmc-reboot.c
 F:	drivers/pwm/pwm-apple.c
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 58c911e1b2d20a0398f02550e938ce62633230d4..602339a1f14e35f1941880c71c4442b5fa73c9f9 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -103,6 +103,7 @@ config PHY_NXP_PTN3222
 
 source "drivers/phy/allwinner/Kconfig"
 source "drivers/phy/amlogic/Kconfig"
+source "drivers/phy/apple/Kconfig"
 source "drivers/phy/broadcom/Kconfig"
 source "drivers/phy/cadence/Kconfig"
 source "drivers/phy/freescale/Kconfig"
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index c670a8dac46807863c9ef990beb149082238ad16..e5933f7c38337e0745ec0e32bed0c544e4af383a 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_PHY_AIROHA_PCIE)		+= phy-airoha-pcie.o
 obj-$(CONFIG_PHY_NXP_PTN3222)		+= phy-nxp-ptn3222.o
 obj-y					+= allwinner/	\
 					   amlogic/	\
+					   apple/	\
 					   broadcom/	\
 					   cadence/	\
 					   freescale/	\
diff --git a/drivers/phy/apple/Kconfig b/drivers/phy/apple/Kconfig
new file mode 100644
index 0000000000000000000000000000000000000000..67f460512592602ae60b2245b1562f5f667488c9
--- /dev/null
+++ b/drivers/phy/apple/Kconfig
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+config PHY_APPLE_ATC
+	tristate "Apple Type-C PHY"
+	depends on (ARM64 && ARCH_APPLE) || (COMPILE_TEST && !GENERIC_ATOMIC64)
+	depends on TYPEC
+	select GENERIC_PHY
+	select APPLE_TUNABLE
+	help
+	  Enable this to add support for the Apple Type-C PHY found in
+	  Apple Silicon M-series SoCs. This PHY supports USB2,
+	  USB3, USB4, Thunderbolt, and DisplayPort.
+
+	  If M is selected the module will be called 'phy-apple-atc'.
+
diff --git a/drivers/phy/apple/Makefile b/drivers/phy/apple/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..e02836a63df3b5324c5ac102b379b12a24494301
--- /dev/null
+++ b/drivers/phy/apple/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+
+obj-$(CONFIG_PHY_APPLE_ATC)		+= phy-apple-atc.o
+phy-apple-atc-y			:= atc.o
diff --git a/drivers/phy/apple/atc.c b/drivers/phy/apple/atc.c
new file mode 100644
index 0000000000000000000000000000000000000000..51c5d7880d9bb36089e286c159ccc3505c62ecff
--- /dev/null
+++ b/drivers/phy/apple/atc.c
@@ -0,0 +1,2537 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * Apple Type-C PHY driver
+ *
+ * Copyright (C) The Asahi Linux Contributors
+ * Author: Sven Peter <sven at kernel.org>
+ */
+
+#include <dt-bindings/phy/phy.h>
+#include <linux/bitfield.h>
+#include <linux/cleanup.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/iopoll.h>
+#include <linux/lockdep.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/reset-controller.h>
+#include <linux/soc/apple/tunable.h>
+#include <linux/types.h>
+#include <linux/usb/pd.h>
+#include <linux/usb/typec.h>
+#include <linux/usb/typec_altmode.h>
+#include <linux/usb/typec_dp.h>
+#include <linux/usb/typec_mux.h>
+#include <linux/usb/typec_tbt.h>
+#include <linux/workqueue.h>
+
+#define AUSPLL_FSM_CTRL 0x1014
+
+#define AUSPLL_APB_CMD_OVERRIDE 0x2000
+#define AUSPLL_APB_CMD_OVERRIDE_REQ BIT(0)
+#define AUSPLL_APB_CMD_OVERRIDE_ACK BIT(1)
+#define AUSPLL_APB_CMD_OVERRIDE_UNK28 BIT(28)
+#define AUSPLL_APB_CMD_OVERRIDE_CMD GENMASK(27, 3)
+
+#define AUSPLL_FREQ_DESC_A 0x2080
+#define AUSPLL_FD_FREQ_COUNT_TARGET GENMASK(9, 0)
+#define AUSPLL_FD_FBDIVN_HALF BIT(10)
+#define AUSPLL_FD_REV_DIVN GENMASK(13, 11)
+#define AUSPLL_FD_KI_MAN GENMASK(17, 14)
+#define AUSPLL_FD_KI_EXP GENMASK(21, 18)
+#define AUSPLL_FD_KP_MAN GENMASK(25, 22)
+#define AUSPLL_FD_KP_EXP GENMASK(29, 26)
+#define AUSPLL_FD_KPKI_SCALE_HBW GENMASK(31, 30)
+
+#define AUSPLL_FREQ_DESC_B 0x2084
+#define AUSPLL_FD_FBDIVN_FRAC_DEN GENMASK(13, 0)
+#define AUSPLL_FD_FBDIVN_FRAC_NUM GENMASK(27, 14)
+
+#define AUSPLL_FREQ_DESC_C 0x2088
+#define AUSPLL_FD_SDM_SSC_STEP GENMASK(7, 0)
+#define AUSPLL_FD_SDM_SSC_EN BIT(8)
+#define AUSPLL_FD_PCLK_DIV_SEL GENMASK(13, 9)
+#define AUSPLL_FD_LFSDM_DIV GENMASK(15, 14)
+#define AUSPLL_FD_LFCLK_CTRL GENMASK(19, 16)
+#define AUSPLL_FD_VCLK_OP_DIVN GENMASK(21, 20)
+#define AUSPLL_FD_VCLK_PRE_DIVN BIT(22)
+
+#define AUSPLL_DCO_EFUSE_SPARE 0x222c
+#define AUSPLL_RODCO_ENCAP_EFUSE GENMASK(10, 9)
+#define AUSPLL_RODCO_BIAS_ADJUST_EFUSE GENMASK(14, 12)
+
+#define AUSPLL_FRACN_CAN 0x22a4
+#define AUSPLL_DLL_START_CAPCODE GENMASK(18, 17)
+
+#define AUSPLL_CLKOUT_MASTER 0x2200
+#define AUSPLL_CLKOUT_MASTER_PCLK_DRVR_EN BIT(2)
+#define AUSPLL_CLKOUT_MASTER_PCLK2_DRVR_EN BIT(4)
+#define AUSPLL_CLKOUT_MASTER_REFBUFCLK_DRVR_EN BIT(6)
+
+#define AUSPLL_CLKOUT_DIV 0x2208
+#define AUSPLL_CLKOUT_PLLA_REFBUFCLK_DI GENMASK(20, 16)
+
+#define AUSPLL_BGR 0x2214
+#define AUSPLL_BGR_CTRL_AVAIL BIT(0)
+
+#define AUSPLL_CLKOUT_DTC_VREG 0x2220
+#define AUSPLL_DTC_VREG_ADJUST GENMASK(16, 14)
+#define AUSPLL_DTC_VREG_BYPASS BIT(7)
+
+#define AUSPLL_FREQ_CFG 0x2224
+#define AUSPLL_FREQ_REFCLK GENMASK(1, 0)
+
+#define AUS_COMMON_SHIM_BLK_VREG 0x0a04
+#define AUS_VREG_TRIM GENMASK(6, 2)
+
+#define AUS_UNK_A20 0x0a20
+#define AUS_UNK_A20_TX_CAL_CODE GENMASK(23, 20)
+
+#define ACIOPHY_CMN_SHM_STS_REG0 0x0a74
+#define ACIOPHY_CMN_SHM_STS_REG0_CMD_READY BIT(0)
+
+#define CIO3PLL_CLK_CTRL 0x2a00
+#define CIO3PLL_CLK_PCLK_EN BIT(1)
+#define CIO3PLL_CLK_REFCLK_EN BIT(5)
+
+#define CIO3PLL_DCO_NCTRL 0x2a38
+#define CIO3PLL_DCO_COARSEBIN_EFUSE0 GENMASK(6, 0)
+#define CIO3PLL_DCO_COARSEBIN_EFUSE1 GENMASK(23, 17)
+
+#define CIO3PLL_FRACN_CAN 0x2aa4
+#define CIO3PLL_DLL_CAL_START_CAPCODE GENMASK(18, 17)
+
+#define CIO3PLL_DTC_VREG 0x2a20
+#define CIO3PLL_DTC_VREG_ADJUST GENMASK(16, 14)
+
+#define ACIOPHY_CFG0 0x08
+#define ACIOPHY_CFG0_COMMON_BIG_OV BIT(1)
+#define ACIOPHY_CFG0_COMMON_SMALL_OV BIT(3)
+#define ACIOPHY_CFG0_COMMON_CLAMP_OV BIT(5)
+#define ACIOPHY_CFG0_RX_SMALL_OV GENMASK(9, 8)
+#define ACIOPHY_CFG0_RX_BIG_OV GENMASK(13, 12)
+#define ACIOPHY_CFG0_RX_CLAMP_OV GENMASK(17, 16)
+
+#define ACIOPHY_CROSSBAR 0x4c
+#define ACIOPHY_CROSSBAR_PROTOCOL GENMASK(4, 0)
+#define ACIOPHY_CROSSBAR_PROTOCOL_USB4 0x0
+#define ACIOPHY_CROSSBAR_PROTOCOL_USB4_SWAPPED 0x1
+#define ACIOPHY_CROSSBAR_PROTOCOL_USB3 0xa
+#define ACIOPHY_CROSSBAR_PROTOCOL_USB3_SWAPPED 0xb
+#define ACIOPHY_CROSSBAR_PROTOCOL_USB3_DP 0x10
+#define ACIOPHY_CROSSBAR_PROTOCOL_USB3_DP_SWAPPED 0x11
+#define ACIOPHY_CROSSBAR_PROTOCOL_DP 0x14
+#define ACIOPHY_CROSSBAR_DP_SINGLE_PMA GENMASK(16, 5)
+#define ACIOPHY_CROSSBAR_DP_SINGLE_PMA_NONE 0x0000
+#define ACIOPHY_CROSSBAR_DP_SINGLE_PMA_UNK100 0x100
+#define ACIOPHY_CROSSBAR_DP_SINGLE_PMA_UNK008 0x008
+#define ACIOPHY_CROSSBAR_DP_BOTH_PMA BIT(17)
+
+#define ACIOPHY_LANE_MODE 0x48
+#define ACIOPHY_LANE_MODE_RX0 GENMASK(2, 0)
+#define ACIOPHY_LANE_MODE_TX0 GENMASK(5, 3)
+#define ACIOPHY_LANE_MODE_RX1 GENMASK(8, 6)
+#define ACIOPHY_LANE_MODE_TX1 GENMASK(11, 9)
+#define ACIOPHY_LANE_MODE_USB4 0
+#define ACIOPHY_LANE_MODE_USB3 1
+#define ACIOPHY_LANE_MODE_DP 2
+#define ACIOPHY_LANE_MODE_OFF 3
+
+#define ACIOPHY_TOP_BIST_CIOPHY_CFG1 0x84
+#define ACIOPHY_TOP_BIST_CIOPHY_CFG1_CLK_EN BIT(27)
+#define ACIOPHY_TOP_BIST_CIOPHY_CFG1_BIST_EN BIT(28)
+
+#define ACIOPHY_TOP_BIST_OV_CFG 0x8c
+#define ACIOPHY_TOP_BIST_OV_CFG_LN0_RESET_N_OV BIT(13)
+#define ACIOPHY_TOP_BIST_OV_CFG_LN0_PWR_DOWN_OV BIT(25)
+
+#define ACIOPHY_TOP_BIST_READ_CTRL 0x90
+#define ACIOPHY_TOP_BIST_READ_CTRL_LN0_PHY_STATUS_RE BIT(2)
+
+#define ACIOPHY_TOP_PHY_STAT 0x9c
+#define ACIOPHY_TOP_PHY_STAT_LN0_UNK0 BIT(0)
+#define ACIOPHY_TOP_PHY_STAT_LN0_UNK23 BIT(23)
+
+#define ACIOPHY_TOP_BIST_PHY_CFG0 0xa8
+#define ACIOPHY_TOP_BIST_PHY_CFG0_LN0_RESET_N BIT(0)
+
+#define ACIOPHY_TOP_BIST_PHY_CFG1 0xac
+#define ACIOPHY_TOP_BIST_PHY_CFG1_LN0_PWR_DOWN GENMASK(13, 10)
+
+#define ACIOPHY_SLEEP_CTRL 0x1b0
+#define ACIOPHY_SLEEP_CTRL_TX_BIG_OV GENMASK(3, 2)
+#define ACIOPHY_SLEEP_CTRL_TX_SMALL_OV GENMASK(7, 6)
+#define ACIOPHY_SLEEP_CTRL_TX_CLAMP_OV GENMASK(11, 10)
+
+#define ACIOPHY_PLL_PCTL_FSM_CTRL1 0x1014
+#define ACIOPHY_PLL_APB_REQ_OV_SEL GENMASK(21, 13)
+#define ACIOPHY_PLL_COMMON_CTRL 0x1028
+#define ACIOPHY_PLL_WAIT_FOR_CMN_READY_BEFORE_RESET_EXIT BIT(24)
+
+#define ATCPHY_POWER_CTRL 0x20000
+#define ATCPHY_POWER_STAT 0x20004
+#define ATCPHY_POWER_SLEEP_SMALL BIT(0)
+#define ATCPHY_POWER_SLEEP_BIG BIT(1)
+#define ATCPHY_POWER_CLAMP_EN BIT(2)
+#define ATCPHY_POWER_APB_RESET_N BIT(3)
+#define ATCPHY_POWER_PHY_RESET_N BIT(4)
+
+#define ATCPHY_MISC 0x20008
+#define ATCPHY_MISC_RESET_N BIT(0)
+#define ATCPHY_MISC_LANE_SWAP BIT(2)
+
+#define ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0 0x7000
+#define DP_PMA_BYTECLK_RESET BIT(0)
+#define DP_MAC_DIV20_CLK_SEL BIT(1)
+#define DPTXPHY_PMA_LANE_RESET_N BIT(2)
+#define DPTXPHY_PMA_LANE_RESET_N_OV BIT(3)
+#define DPTX_PCLK1_SELECT GENMASK(6, 4)
+#define DPTX_PCLK2_SELECT GENMASK(9, 7)
+#define DPRX_PCLK_SELECT GENMASK(12, 10)
+#define DPTX_PCLK1_ENABLE BIT(13)
+#define DPTX_PCLK2_ENABLE BIT(14)
+#define DPRX_PCLK_ENABLE BIT(15)
+
+#define ACIOPHY_DP_PCLK_STAT 0x7044
+#define ACIOPHY_AUSPLL_LOCK BIT(3)
+
+#define LN0_AUSPMA_RX_TOP 0x9000
+#define LN0_AUSPMA_RX_EQ 0xA000
+#define LN0_AUSPMA_RX_SHM 0xB000
+#define LN0_AUSPMA_TX_TOP 0xC000
+#define LN0_AUSPMA_TX_SHM 0xD000
+
+#define LN1_AUSPMA_RX_TOP 0x10000
+#define LN1_AUSPMA_RX_EQ 0x11000
+#define LN1_AUSPMA_RX_SHM 0x12000
+#define LN1_AUSPMA_TX_TOP 0x13000
+#define LN1_AUSPMA_TX_SHM 0x14000
+
+#define LN_AUSPMA_RX_TOP_PMAFSM 0x0010
+#define LN_AUSPMA_RX_TOP_PMAFSM_PCS_OV BIT(0)
+#define LN_AUSPMA_RX_TOP_PMAFSM_PCS_REQ BIT(9)
+
+#define LN_AUSPMA_RX_TOP_TJ_CFG_RX_TXMODE 0x00F0
+#define LN_RX_TXMODE BIT(0)
+
+#define LN_AUSPMA_RX_SHM_TJ_RXA_CTLE_CTRL0 0x00
+#define LN_TX_CLK_EN BIT(20)
+#define LN_TX_CLK_EN_OV BIT(21)
+
+#define LN_AUSPMA_RX_SHM_TJ_RXA_AFE_CTRL1 0x04
+#define LN_RX_DIV20_RESET_N_OV BIT(29)
+#define LN_RX_DIV20_RESET_N BIT(30)
+
+#define LN_AUSPMA_RX_SHM_TJ_RXA_UNK_CTRL2 0x08
+#define LN_AUSPMA_RX_SHM_TJ_RXA_UNK_CTRL3 0x0C
+#define LN_AUSPMA_RX_SHM_TJ_RXA_UNK_CTRL4 0x10
+#define LN_AUSPMA_RX_SHM_TJ_RXA_UNK_CTRL5 0x14
+#define LN_AUSPMA_RX_SHM_TJ_RXA_UNK_CTRL6 0x18
+#define LN_AUSPMA_RX_SHM_TJ_RXA_UNK_CTRL7 0x1C
+#define LN_AUSPMA_RX_SHM_TJ_RXA_UNK_CTRL8 0x20
+#define LN_AUSPMA_RX_SHM_TJ_RXA_UNK_CTRL9 0x24
+#define LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL10 0x28
+#define LN_DTVREG_ADJUST GENMASK(31, 27)
+
+#define LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL11 0x2C
+#define LN_DTVREG_BIG_EN BIT(23)
+#define LN_DTVREG_BIG_EN_OV BIT(24)
+#define LN_DTVREG_SML_EN BIT(25)
+#define LN_DTVREG_SML_EN_OV BIT(26)
+
+#define LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL12 0x30
+#define LN_TX_BYTECLK_RESET_SYNC_CLR BIT(22)
+#define LN_TX_BYTECLK_RESET_SYNC_CLR_OV BIT(23)
+#define LN_TX_BYTECLK_RESET_SYNC_EN BIT(24)
+#define LN_TX_BYTECLK_RESET_SYNC_EN_OV BIT(25)
+#define LN_TX_HRCLK_SEL BIT(28)
+#define LN_TX_HRCLK_SEL_OV BIT(29)
+#define LN_TX_PBIAS_EN BIT(30)
+#define LN_TX_PBIAS_EN_OV BIT(31)
+
+#define LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL13 0x34
+#define LN_TX_PRE_EN BIT(0)
+#define LN_TX_PRE_EN_OV BIT(1)
+#define LN_TX_PST1_EN BIT(2)
+#define LN_TX_PST1_EN_OV BIT(3)
+#define LN_DTVREG_ADJUST_OV BIT(15)
+
+#define LN_AUSPMA_RX_SHM_TJ_UNK_CTRL14A 0x38
+#define LN_AUSPMA_RX_SHM_TJ_UNK_CTRL14B 0x3C
+#define LN_AUSPMA_RX_SHM_TJ_UNK_CTRL15A 0x40
+#define LN_AUSPMA_RX_SHM_TJ_UNK_CTRL15B 0x44
+#define LN_AUSPMA_RX_SHM_TJ_RXA_SAVOS_CTRL16 0x48
+#define LN_RXTERM_EN BIT(21)
+#define LN_RXTERM_EN_OV BIT(22)
+#define LN_RXTERM_PULLUP_LEAK_EN BIT(23)
+#define LN_RXTERM_PULLUP_LEAK_EN_OV BIT(24)
+#define LN_TX_CAL_CODE GENMASK(29, 25)
+#define LN_TX_CAL_CODE_OV BIT(30)
+
+#define LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL17 0x4C
+#define LN_TX_MARGIN GENMASK(19, 15)
+#define LN_TX_MARGIN_OV BIT(20)
+#define LN_TX_MARGIN_LSB BIT(21)
+#define LN_TX_MARGIN_LSB_OV BIT(22)
+#define LN_TX_MARGIN_P1 GENMASK(26, 23)
+#define LN_TX_MARGIN_P1_OV BIT(27)
+#define LN_TX_MARGIN_P1_LSB GENMASK(29, 28)
+#define LN_TX_MARGIN_P1_LSB_OV BIT(30)
+
+#define LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18 0x50
+#define LN_TX_P1_CODE GENMASK(3, 0)
+#define LN_TX_P1_CODE_OV BIT(4)
+#define LN_TX_P1_LSB_CODE GENMASK(6, 5)
+#define LN_TX_P1_LSB_CODE_OV BIT(7)
+#define LN_TX_MARGIN_PRE GENMASK(10, 8)
+#define LN_TX_MARGIN_PRE_OV BIT(11)
+#define LN_TX_MARGIN_PRE_LSB GENMASK(13, 12)
+#define LN_TX_MARGIN_PRE_LSB_OV BIT(14)
+#define LN_TX_PRE_LSB_CODE GENMASK(16, 15)
+#define LN_TX_PRE_LSB_CODE_OV BIT(17)
+#define LN_TX_PRE_CODE GENMASK(21, 18)
+#define LN_TX_PRE_CODE_OV BIT(22)
+
+#define LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19 0x54
+#define LN_TX_TEST_EN BIT(21)
+#define LN_TX_TEST_EN_OV BIT(22)
+#define LN_TX_EN BIT(23)
+#define LN_TX_EN_OV BIT(24)
+#define LN_TX_CLK_DLY_CTRL_TAPGEN GENMASK(27, 25)
+#define LN_TX_CLK_DIV2_EN BIT(28)
+#define LN_TX_CLK_DIV2_EN_OV BIT(29)
+#define LN_TX_CLK_DIV2_RST BIT(30)
+#define LN_TX_CLK_DIV2_RST_OV BIT(31)
+
+#define LN_AUSPMA_RX_SHM_TJ_RXA_UNK_CTRL20 0x58
+#define LN_AUSPMA_RX_SHM_TJ_RXA_UNK_CTRL21 0x5C
+#define LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22 0x60
+#define LN_VREF_ADJUST_GRAY GENMASK(11, 7)
+#define LN_VREF_ADJUST_GRAY_OV BIT(12)
+#define LN_VREF_BIAS_SEL GENMASK(14, 13)
+#define LN_VREF_BIAS_SEL_OV BIT(15)
+#define LN_VREF_BOOST_EN BIT(16)
+#define LN_VREF_BOOST_EN_OV BIT(17)
+#define LN_VREF_EN BIT(18)
+#define LN_VREF_EN_OV BIT(19)
+#define LN_VREF_LPBKIN_DATA GENMASK(29, 28)
+#define LN_VREF_TEST_RXLPBKDT_EN BIT(30)
+#define LN_VREF_TEST_RXLPBKDT_EN_OV BIT(31)
+
+#define LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG0 0x00
+#define LN_BYTECLK_RESET_SYNC_EN_OV BIT(2)
+#define LN_BYTECLK_RESET_SYNC_EN BIT(3)
+#define LN_BYTECLK_RESET_SYNC_CLR_OV BIT(4)
+#define LN_BYTECLK_RESET_SYNC_CLR BIT(5)
+#define LN_BYTECLK_RESET_SYNC_SEL_OV BIT(6)
+
+#define LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG1 0x04
+#define LN_TXA_DIV2_EN_OV BIT(8)
+#define LN_TXA_DIV2_EN BIT(9)
+#define LN_TXA_DIV2_RESET_OV BIT(10)
+#define LN_TXA_DIV2_RESET BIT(11)
+#define LN_TXA_CLK_EN_OV BIT(22)
+#define LN_TXA_CLK_EN BIT(23)
+
+#define LN_AUSPMA_TX_SHM_TXA_IMP_REG0 0x08
+#define LN_TXA_CAL_CTRL_OV BIT(0)
+#define LN_TXA_CAL_CTRL GENMASK(18, 1)
+#define LN_TXA_CAL_CTRL_BASE_OV BIT(19)
+#define LN_TXA_CAL_CTRL_BASE GENMASK(23, 20)
+#define LN_TXA_HIZ_OV BIT(29)
+#define LN_TXA_HIZ BIT(30)
+
+#define LN_AUSPMA_TX_SHM_TXA_IMP_REG1 0x0C
+#define LN_AUSPMA_TX_SHM_TXA_IMP_REG2 0x10
+#define LN_TXA_MARGIN_OV BIT(0)
+#define LN_TXA_MARGIN GENMASK(18, 1)
+#define LN_TXA_MARGIN_2R_OV BIT(19)
+#define LN_TXA_MARGIN_2R BIT(20)
+
+#define LN_AUSPMA_TX_SHM_TXA_IMP_REG3 0x14
+#define LN_TXA_MARGIN_POST_OV BIT(0)
+#define LN_TXA_MARGIN_POST GENMASK(10, 1)
+#define LN_TXA_MARGIN_POST_2R_OV BIT(11)
+#define LN_TXA_MARGIN_POST_2R BIT(12)
+#define LN_TXA_MARGIN_POST_4R_OV BIT(13)
+#define LN_TXA_MARGIN_POST_4R BIT(14)
+#define LN_TXA_MARGIN_PRE_OV BIT(15)
+#define LN_TXA_MARGIN_PRE GENMASK(21, 16)
+#define LN_TXA_MARGIN_PRE_2R_OV BIT(22)
+#define LN_TXA_MARGIN_PRE_2R BIT(23)
+#define LN_TXA_MARGIN_PRE_4R_OV BIT(24)
+#define LN_TXA_MARGIN_PRE_4R BIT(25)
+
+#define LN_AUSPMA_TX_SHM_TXA_UNK_REG0 0x18
+#define LN_AUSPMA_TX_SHM_TXA_UNK_REG1 0x1C
+#define LN_AUSPMA_TX_SHM_TXA_UNK_REG2 0x20
+
+#define LN_AUSPMA_TX_SHM_TXA_LDOCLK 0x24
+#define LN_LDOCLK_BYPASS_SML_OV BIT(8)
+#define LN_LDOCLK_BYPASS_SML BIT(9)
+#define LN_LDOCLK_BYPASS_BIG_OV BIT(10)
+#define LN_LDOCLK_BYPASS_BIG BIT(11)
+#define LN_LDOCLK_EN_SML_OV BIT(12)
+#define LN_LDOCLK_EN_SML BIT(13)
+#define LN_LDOCLK_EN_BIG_OV BIT(14)
+#define LN_LDOCLK_EN_BIG BIT(15)
+
+/* LPDPTX registers */
+#define LPDPTX_AUX_CFG_BLK_AUX_CTRL 0x0000
+#define LPDPTX_BLK_AUX_CTRL_PWRDN BIT(4)
+#define LPDPTX_BLK_AUX_RXOFFSET GENMASK(25, 22)
+
+#define LPDPTX_AUX_CFG_BLK_AUX_LDO_CTRL 0x0008
+
+#define LPDPTX_AUX_CFG_BLK_AUX_MARGIN 0x000c
+#define LPDPTX_MARGIN_RCAL_RXOFFSET_EN BIT(5)
+#define LPDPTX_AUX_MARGIN_RCAL_TXSWING GENMASK(10, 6)
+
+#define LPDPTX_AUX_SHM_CFG_BLK_AUX_CTRL_REG0 0x0204
+#define LPDPTX_CFG_PMA_AUX_SEL_LF_DATA BIT(15)
+
+#define LPDPTX_AUX_SHM_CFG_BLK_AUX_CTRL_REG1 0x0208
+#define LPDPTX_CFG_PMA_PHYS_ADJ GENMASK(22, 20)
+#define LPDPTX_CFG_PMA_PHYS_ADJ_OV BIT(19)
+
+#define LPDPTX_AUX_CONTROL 0x4000
+#define LPDPTX_AUX_PWN_DOWN 0x10
+#define LPDPTX_AUX_CLAMP_EN 0x04
+#define LPDPTX_SLEEP_B_BIG_IN 0x02
+#define LPDPTX_SLEEP_B_SML_IN 0x01
+#define LPDPTX_TXTERM_CODEMSB 0x400
+#define LPDPTX_TXTERM_CODE GENMASK(9, 5)
+
+/* pipehandler registers */
+#define PIPEHANDLER_OVERRIDE 0x00
+#define PIPEHANDLER_OVERRIDE_RXVALID BIT(0)
+#define PIPEHANDLER_OVERRIDE_RXDETECT BIT(2)
+
+#define PIPEHANDLER_OVERRIDE_VALUES 0x04
+#define PIPEHANDLER_OVERRIDE_VAL_RXDETECT0 BIT(1)
+#define PIPEHANDLER_OVERRIDE_VAL_RXDETECT1 BIT(2)
+#define PIPEHANDLER_OVERRIDE_VAL_PHY_STATUS BIT(4)
+
+#define PIPEHANDLER_MUX_CTRL 0x0c
+#define PIPEHANDLED_MUX_CTRL_CLK GENMASK(5, 3)
+#define PIPEHANDLED_MUX_CTRL_DATA GENMASK(2, 0)
+#define PIPEHANDLED_MUX_CTRL_CLK_OFF 0
+#define PIPEHANDLED_MUX_CTRL_CLK_USB3 1
+#define PIPEHANDLED_MUX_CTRL_CLK_USB4 2
+#define PIPEHANDLED_MUX_CTRL_CLK_DUMMY 4
+
+#define PIPEHANDLED_MUX_CTRL_DATA_USB3 0
+#define PIPEHANDLED_MUX_CTRL_DATA_USB4 1
+#define PIPEHANDLED_MUX_CTRL_DATA_DUMMY 2
+
+#define PIPEHANDLER_LOCK_REQ 0x10
+#define PIPEHANDLER_LOCK_ACK 0x14
+#define PIPEHANDLER_LOCK_EN BIT(0)
+
+#define PIPEHANDLER_AON_GEN 0x1C
+#define PIPEHANDLER_AON_GEN_DWC3_FORCE_CLAMP_EN BIT(4)
+#define PIPEHANDLER_AON_GEN_DWC3_RESET_N BIT(0)
+
+#define PIPEHANDLER_NONSELECTED_OVERRIDE 0x20
+#define PIPEHANDLER_NATIVE_RESET BIT(12)
+#define PIPEHANDLER_DUMMY_PHY_EN BIT(15)
+#define PIPEHANDLER_NATIVE_POWER_DOWN GENMASK(3, 0)
+
+#define PIPEHANDLER_UNK_2C 0x2c
+
+/* USB2 PHY regs */
+#define USB2PHY_USBCTL 0x00
+#define USB2PHY_USBCTL_RUN 2
+#define USB2PHY_USBCTL_ISOLATION 4
+
+#define USB2PHY_CTL 0x04
+#define USB2PHY_CTL_RESET BIT(0)
+#define USB2PHY_CTL_PORT_RESET BIT(1)
+#define USB2PHY_CTL_APB_RESET_N BIT(2)
+#define USB2PHY_CTL_SIDDQ BIT(3)
+
+#define USB2PHY_SIG 0x08
+#define USB2PHY_SIG_VBUSDET_FORCE_VAL BIT(0)
+#define USB2PHY_SIG_VBUSDET_FORCE_EN BIT(1)
+#define USB2PHY_SIG_VBUSVLDEXT_FORCE_VAL BIT(2)
+#define USB2PHY_SIG_VBUSVLDEXT_FORCE_EN BIT(3)
+#define USB2PHY_SIG_HOST (7 << 12)
+
+#define USB2PHY_MISCTUNE 0x1c
+#define USB2PHY_MISCTUNE_APBCLK_GATE_OFF BIT(29)
+#define USB2PHY_MISCTUNE_REFCLK_GATE_OFF BIT(30)
+
+enum atcphy_dp_link_rate {
+	ATCPHY_DP_LINK_RATE_RBR,
+	ATCPHY_DP_LINK_RATE_HBR,
+	ATCPHY_DP_LINK_RATE_HBR2,
+	ATCPHY_DP_LINK_RATE_HBR3,
+};
+
+enum atcphy_pipehandler_state {
+	ATCPHY_PIPEHANDLER_STATE_INVALID,
+	ATCPHY_PIPEHANDLER_STATE_DUMMY,
+	ATCPHY_PIPEHANDLER_STATE_USB3,
+	ATCPHY_PIPEHANDLER_STATE_USB4,
+};
+
+enum atcphy_mode {
+	APPLE_ATCPHY_MODE_OFF,
+	APPLE_ATCPHY_MODE_USB2,
+	APPLE_ATCPHY_MODE_USB3,
+	APPLE_ATCPHY_MODE_USB3_DP,
+	APPLE_ATCPHY_MODE_TBT,
+	APPLE_ATCPHY_MODE_USB4,
+	APPLE_ATCPHY_MODE_DP,
+};
+
+enum atcphy_lane {
+	APPLE_ATCPHY_LANE_0,
+	APPLE_ATCPHY_LANE_1,
+};
+
+struct atcphy_dp_link_rate_configuration {
+	u16 freqinit_count_target;
+	u16 fbdivn_frac_den;
+	u16 fbdivn_frac_num;
+	u16 pclk_div_sel;
+	u8 lfclk_ctrl;
+	u8 vclk_op_divn;
+	bool plla_clkout_vreg_bypass;
+	bool txa_ldoclk_bypass;
+	bool txa_div2_en;
+};
+
+struct atcphy_mode_configuration {
+	u32 crossbar;
+	u32 crossbar_dp_single_pma;
+	bool crossbar_dp_both_pma;
+	u32 lane_mode[2];
+	bool dp_lane[2];
+	bool set_swap;
+};
+
+struct apple_atcphy_hw {
+	unsigned int dp_only : 1; /* hard-wired to internal DP->HDMI converter */
+};
+
+struct apple_atcphy {
+	struct device_node *np;
+	struct device *dev;
+	const struct apple_atcphy_hw *hw;
+
+	/* tunables provided by firmware through the device tree */
+	struct {
+		struct apple_tunable fuses;
+		struct apple_tunable axi2af;
+		struct apple_tunable common;
+		struct apple_tunable lane_usb3[2];
+		struct apple_tunable lane_displayport[2];
+		struct apple_tunable lane_usb4[2];
+	} tunables;
+
+	enum atcphy_mode mode;
+	enum atcphy_mode target_mode;
+	enum atcphy_pipehandler_state pipehandler_state;
+	bool swap_lanes;
+	int dp_link_rate;
+	bool pipehandler_up;
+	bool is_host_mode;
+	bool dwc3_running;
+
+	struct {
+		void __iomem *core;
+		void __iomem *axi2af;
+		void __iomem *usb2phy;
+		void __iomem *pipehandler;
+		void __iomem *lpdptx;
+	} regs;
+
+	struct device **pd_dev;
+	struct device_link **pd_link;
+	int pd_count;
+
+	struct phy *phy_usb2;
+	struct phy *phy_usb3;
+	struct phy *phy_dp;
+	struct phy_provider *phy_provider;
+	struct reset_controller_dev rcdev;
+	struct typec_switch *sw;
+	struct typec_mux *mux;
+
+	struct mutex lock;
+};
+
+static const struct {
+	const struct atcphy_mode_configuration normal;
+	const struct atcphy_mode_configuration swapped;
+	bool enable_dp_aux;
+	enum atcphy_pipehandler_state pipehandler_state;
+} atcphy_modes[] = {
+	[APPLE_ATCPHY_MODE_OFF] = {
+		.normal = {
+			.crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB3,
+			.crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_NONE,
+			.crossbar_dp_both_pma = false,
+			.lane_mode = {ACIOPHY_LANE_MODE_OFF, ACIOPHY_LANE_MODE_OFF},
+			.dp_lane = {false, false},
+			.set_swap = false,
+		},
+		.swapped = {
+			.crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB3_SWAPPED,
+			.crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_NONE,
+			.crossbar_dp_both_pma = false,
+			.lane_mode = {ACIOPHY_LANE_MODE_OFF, ACIOPHY_LANE_MODE_OFF},
+			.dp_lane = {false, false},
+			.set_swap = false, /* doesn't matter since the SS lanes are off */
+		},
+		.enable_dp_aux = false,
+		.pipehandler_state = ATCPHY_PIPEHANDLER_STATE_DUMMY,
+	},
+	[APPLE_ATCPHY_MODE_USB2] = {
+		.normal = {
+			.crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB3,
+			.crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_NONE,
+			.crossbar_dp_both_pma = false,
+			.lane_mode = {ACIOPHY_LANE_MODE_OFF, ACIOPHY_LANE_MODE_OFF},
+			.dp_lane = {false, false},
+			.set_swap = false,
+		},
+		.swapped = {
+			.crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB3_SWAPPED,
+			.crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_NONE,
+			.crossbar_dp_both_pma = false,
+			.lane_mode = {ACIOPHY_LANE_MODE_OFF, ACIOPHY_LANE_MODE_OFF},
+			.dp_lane = {false, false},
+			.set_swap = false, /* doesn't matter since the SS lanes are off */
+		},
+		.enable_dp_aux = false,
+		.pipehandler_state = ATCPHY_PIPEHANDLER_STATE_DUMMY,
+	},
+	[APPLE_ATCPHY_MODE_USB3] = {
+		.normal = {
+			.crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB3,
+			.crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_NONE,
+			.crossbar_dp_both_pma = false,
+			.lane_mode = {ACIOPHY_LANE_MODE_USB3, ACIOPHY_LANE_MODE_OFF},
+			.dp_lane = {false, false},
+			.set_swap = false,
+		},
+		.swapped = {
+			.crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB3_SWAPPED,
+			.crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_NONE,
+			.crossbar_dp_both_pma = false,
+			.lane_mode = {ACIOPHY_LANE_MODE_OFF, ACIOPHY_LANE_MODE_USB3},
+			.dp_lane = {false, false},
+			.set_swap = true,
+		},
+		.enable_dp_aux = false,
+		.pipehandler_state = ATCPHY_PIPEHANDLER_STATE_USB3,
+	},
+	[APPLE_ATCPHY_MODE_USB3_DP] = {
+		.normal = {
+			.crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB3_DP,
+			.crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_UNK008,
+			.crossbar_dp_both_pma = false,
+			.lane_mode = {ACIOPHY_LANE_MODE_USB3, ACIOPHY_LANE_MODE_DP},
+			.dp_lane = {false, true},
+			.set_swap = false,
+		},
+		.swapped = {
+			.crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB3_DP_SWAPPED,
+			.crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_UNK008,
+			.crossbar_dp_both_pma = false,
+			.lane_mode = {ACIOPHY_LANE_MODE_DP, ACIOPHY_LANE_MODE_USB3},
+			.dp_lane = {true, false},
+			.set_swap = true,
+		},
+		.enable_dp_aux = true,
+		.pipehandler_state = ATCPHY_PIPEHANDLER_STATE_USB3,
+	},
+	[APPLE_ATCPHY_MODE_TBT] = {
+		.normal = {
+			.crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB4,
+			.crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_NONE,
+			.crossbar_dp_both_pma = false,
+			.lane_mode = {ACIOPHY_LANE_MODE_USB4, ACIOPHY_LANE_MODE_USB4},
+			.dp_lane = {false, false},
+			.set_swap = false,
+		},
+		.swapped = {
+			.crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB4_SWAPPED,
+			.crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_NONE,
+			.crossbar_dp_both_pma = false,
+			.lane_mode = {ACIOPHY_LANE_MODE_USB4, ACIOPHY_LANE_MODE_USB4},
+			.dp_lane = {false, false},
+			.set_swap = false, /* intentionally false */
+		},
+		.enable_dp_aux = false,
+		.pipehandler_state = ATCPHY_PIPEHANDLER_STATE_DUMMY,
+	},
+	[APPLE_ATCPHY_MODE_USB4] = {
+		.normal = {
+			.crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB4,
+			.crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_NONE,
+			.crossbar_dp_both_pma = false,
+			.lane_mode = {ACIOPHY_LANE_MODE_USB4, ACIOPHY_LANE_MODE_USB4},
+			.dp_lane = {false, false},
+			.set_swap = false,
+		},
+		.swapped = {
+			.crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB4_SWAPPED,
+			.crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_NONE,
+			.crossbar_dp_both_pma = false,
+			.lane_mode = {ACIOPHY_LANE_MODE_USB4, ACIOPHY_LANE_MODE_USB4},
+			.dp_lane = {false, false},
+			.set_swap = false, /* intentionally false */
+		},
+		.enable_dp_aux = false,
+		.pipehandler_state = ATCPHY_PIPEHANDLER_STATE_USB4,
+	},
+	[APPLE_ATCPHY_MODE_DP] = {
+		.normal = {
+			.crossbar = ACIOPHY_CROSSBAR_PROTOCOL_DP,
+			.crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_UNK100,
+			.crossbar_dp_both_pma = true,
+			.lane_mode = {ACIOPHY_LANE_MODE_DP, ACIOPHY_LANE_MODE_DP},
+			.dp_lane = {true, true},
+			.set_swap = false,
+		},
+		.swapped = {
+			.crossbar = ACIOPHY_CROSSBAR_PROTOCOL_DP,
+			.crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_UNK008,
+			.crossbar_dp_both_pma = false, /* intentionally false */
+			.lane_mode = {ACIOPHY_LANE_MODE_DP, ACIOPHY_LANE_MODE_DP},
+			.dp_lane = {true, true},
+			.set_swap = false, /* intentionally false */
+		},
+		.enable_dp_aux = true,
+		.pipehandler_state = ATCPHY_PIPEHANDLER_STATE_DUMMY,
+	},
+};
+
+static const struct atcphy_dp_link_rate_configuration dp_lr_config[] = {
+	[ATCPHY_DP_LINK_RATE_RBR] = {
+		.freqinit_count_target = 0x21c,
+		.fbdivn_frac_den = 0x0,
+		.fbdivn_frac_num = 0x0,
+		.pclk_div_sel = 0x13,
+		.lfclk_ctrl = 0x5,
+		.vclk_op_divn = 0x2,
+		.plla_clkout_vreg_bypass = true,
+		.txa_ldoclk_bypass = true,
+		.txa_div2_en = true,
+	},
+	[ATCPHY_DP_LINK_RATE_HBR] = {
+		.freqinit_count_target = 0x1c2,
+		.fbdivn_frac_den = 0x3ffe,
+		.fbdivn_frac_num = 0x1fff,
+		.pclk_div_sel = 0x9,
+		.lfclk_ctrl = 0x5,
+		.vclk_op_divn = 0x2,
+		.plla_clkout_vreg_bypass = true,
+		.txa_ldoclk_bypass = true,
+		.txa_div2_en = false,
+	},
+	[ATCPHY_DP_LINK_RATE_HBR2] = {
+		.freqinit_count_target = 0x1c2,
+		.fbdivn_frac_den = 0x3ffe,
+		.fbdivn_frac_num = 0x1fff,
+		.pclk_div_sel = 0x4,
+		.lfclk_ctrl = 0x5,
+		.vclk_op_divn = 0x0,
+		.plla_clkout_vreg_bypass = true,
+		.txa_ldoclk_bypass = true,
+		.txa_div2_en = false,
+	},
+	[ATCPHY_DP_LINK_RATE_HBR3] = {
+		.freqinit_count_target = 0x2a3,
+		.fbdivn_frac_den = 0x3ffc,
+		.fbdivn_frac_num = 0x2ffd,
+		.pclk_div_sel = 0x4,
+		.lfclk_ctrl = 0x6,
+		.vclk_op_divn = 0x0,
+		.plla_clkout_vreg_bypass = false,
+		.txa_ldoclk_bypass = false,
+		.txa_div2_en = false,
+	},
+};
+
+static void atcphy_configure_pipehandler_dummy(struct apple_atcphy *atcphy);
+static void atcphy_configure_pipehandler(struct apple_atcphy *atcphy);
+static void atcphy_usb2_power_on(struct apple_atcphy *atcphy);
+static void atcphy_usb2_power_off(struct apple_atcphy *atcphy);
+
+static inline void mask32(void __iomem *reg, u32 mask, u32 set)
+{
+	u32 value = readl(reg);
+
+	value &= ~mask;
+	value |= set;
+	writel(value, reg);
+}
+
+static inline void core_mask32(struct apple_atcphy *atcphy, u32 reg, u32 mask,
+			       u32 set)
+{
+	mask32(atcphy->regs.core + reg, mask, set);
+}
+
+static inline void set32(void __iomem *reg, u32 set)
+{
+	mask32(reg, 0, set);
+}
+
+static inline void core_set32(struct apple_atcphy *atcphy, u32 reg, u32 set)
+{
+	core_mask32(atcphy, reg, 0, set);
+}
+
+static inline void clear32(void __iomem *reg, u32 clear)
+{
+	mask32(reg, clear, 0);
+}
+
+static inline void core_clear32(struct apple_atcphy *atcphy, u32 reg, u32 clear)
+{
+	core_mask32(atcphy, reg, clear, 0);
+}
+
+static void atcphy_apply_tunables(struct apple_atcphy *atcphy,
+				  enum atcphy_mode mode)
+{
+	const int lane0 = atcphy->swap_lanes ? 1 : 0;
+	const int lane1 = atcphy->swap_lanes ? 0 : 1;
+
+	apple_apply_tunable(atcphy->regs.core, &atcphy->tunables.fuses);
+	apple_apply_tunable(atcphy->regs.axi2af, &atcphy->tunables.axi2af);
+	apple_apply_tunable(atcphy->regs.core, &atcphy->tunables.common);
+
+	switch (mode) {
+	case APPLE_ATCPHY_MODE_USB3:
+		apple_apply_tunable(atcphy->regs.core,
+				    &atcphy->tunables.lane_usb3[lane0]);
+		apple_apply_tunable(atcphy->regs.core,
+				    &atcphy->tunables.lane_usb3[lane1]);
+		break;
+
+	case APPLE_ATCPHY_MODE_USB3_DP:
+		apple_apply_tunable(atcphy->regs.core,
+				    &atcphy->tunables.lane_usb3[lane0]);
+		apple_apply_tunable(atcphy->regs.core,
+				    &atcphy->tunables.lane_displayport[lane1]);
+		break;
+
+	case APPLE_ATCPHY_MODE_DP:
+		apple_apply_tunable(atcphy->regs.core,
+				    &atcphy->tunables.lane_displayport[lane0]);
+		apple_apply_tunable(atcphy->regs.core,
+				    &atcphy->tunables.lane_displayport[lane1]);
+		break;
+
+	case APPLE_ATCPHY_MODE_TBT:
+	case APPLE_ATCPHY_MODE_USB4:
+		apple_apply_tunable(atcphy->regs.core,
+				    &atcphy->tunables.lane_usb4[lane0]);
+		apple_apply_tunable(atcphy->regs.core,
+				    &atcphy->tunables.lane_usb4[lane1]);
+		break;
+
+	case APPLE_ATCPHY_MODE_OFF:
+		break;
+	case APPLE_ATCPHY_MODE_USB2:
+		break;
+	}
+}
+
+static void atcphy_configure_lanes(struct apple_atcphy *atcphy,
+				   enum atcphy_mode mode)
+{
+	const struct atcphy_mode_configuration *mode_cfg;
+
+	if (atcphy->swap_lanes)
+		mode_cfg = &atcphy_modes[mode].swapped;
+	else
+		mode_cfg = &atcphy_modes[mode].normal;
+
+	core_mask32(atcphy, ACIOPHY_LANE_MODE, ACIOPHY_LANE_MODE_RX0,
+		    FIELD_PREP(ACIOPHY_LANE_MODE_RX0, mode_cfg->lane_mode[0]));
+	core_mask32(atcphy, ACIOPHY_LANE_MODE, ACIOPHY_LANE_MODE_TX0,
+		    FIELD_PREP(ACIOPHY_LANE_MODE_TX0, mode_cfg->lane_mode[0]));
+	core_mask32(atcphy, ACIOPHY_LANE_MODE, ACIOPHY_LANE_MODE_RX1,
+		    FIELD_PREP(ACIOPHY_LANE_MODE_RX1, mode_cfg->lane_mode[1]));
+	core_mask32(atcphy, ACIOPHY_LANE_MODE, ACIOPHY_LANE_MODE_TX1,
+		    FIELD_PREP(ACIOPHY_LANE_MODE_TX1, mode_cfg->lane_mode[1]));
+	core_mask32(atcphy, ACIOPHY_CROSSBAR, ACIOPHY_CROSSBAR_PROTOCOL,
+		    FIELD_PREP(ACIOPHY_CROSSBAR_PROTOCOL, mode_cfg->crossbar));
+
+	if (mode_cfg->set_swap)
+		core_set32(atcphy, ATCPHY_MISC, ATCPHY_MISC_LANE_SWAP);
+	else
+		core_clear32(atcphy, ATCPHY_MISC, ATCPHY_MISC_LANE_SWAP);
+
+	core_mask32(atcphy, ACIOPHY_CROSSBAR, ACIOPHY_CROSSBAR_DP_SINGLE_PMA,
+		    FIELD_PREP(ACIOPHY_CROSSBAR_DP_SINGLE_PMA,
+			       mode_cfg->crossbar_dp_single_pma));
+	if (mode_cfg->crossbar_dp_both_pma)
+		core_set32(atcphy, ACIOPHY_CROSSBAR,
+			   ACIOPHY_CROSSBAR_DP_BOTH_PMA);
+	else
+		core_clear32(atcphy, ACIOPHY_CROSSBAR,
+			     ACIOPHY_CROSSBAR_DP_BOTH_PMA);
+
+	if (mode_cfg->dp_lane[0]) {
+		core_set32(atcphy, LN0_AUSPMA_RX_TOP + LN_AUSPMA_RX_TOP_PMAFSM,
+			   LN_AUSPMA_RX_TOP_PMAFSM_PCS_OV);
+		udelay(10);
+		core_clear32(atcphy,
+			     LN0_AUSPMA_RX_TOP + LN_AUSPMA_RX_TOP_PMAFSM,
+			     LN_AUSPMA_RX_TOP_PMAFSM_PCS_REQ);
+	} else {
+		core_clear32(atcphy,
+			     LN0_AUSPMA_RX_TOP + LN_AUSPMA_RX_TOP_PMAFSM,
+			     LN_AUSPMA_RX_TOP_PMAFSM_PCS_OV);
+		udelay(10);
+	}
+
+	if (mode_cfg->dp_lane[1]) {
+		core_set32(atcphy, LN1_AUSPMA_RX_TOP + LN_AUSPMA_RX_TOP_PMAFSM,
+			   LN_AUSPMA_RX_TOP_PMAFSM_PCS_OV);
+		udelay(10);
+		core_clear32(atcphy,
+			     LN1_AUSPMA_RX_TOP + LN_AUSPMA_RX_TOP_PMAFSM,
+			     LN_AUSPMA_RX_TOP_PMAFSM_PCS_REQ);
+	} else {
+		core_clear32(atcphy,
+			     LN1_AUSPMA_RX_TOP + LN_AUSPMA_RX_TOP_PMAFSM,
+			     LN_AUSPMA_RX_TOP_PMAFSM_PCS_OV);
+		udelay(10);
+	}
+}
+
+static void atcphy_enable_dp_aux(struct apple_atcphy *atcphy)
+{
+	core_set32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0,
+		   DPTXPHY_PMA_LANE_RESET_N);
+	core_set32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0,
+		   DPTXPHY_PMA_LANE_RESET_N_OV);
+
+	core_mask32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0,
+		    DPRX_PCLK_SELECT, FIELD_PREP(DPRX_PCLK_SELECT, 1));
+	core_set32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0,
+		   DPRX_PCLK_ENABLE);
+
+	core_mask32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0,
+		    DPTX_PCLK1_SELECT, FIELD_PREP(DPTX_PCLK1_SELECT, 1));
+	core_set32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0,
+		   DPTX_PCLK1_ENABLE);
+
+	core_mask32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0,
+		    DPTX_PCLK2_SELECT, FIELD_PREP(DPTX_PCLK2_SELECT, 1));
+	core_set32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0,
+		   DPTX_PCLK2_ENABLE);
+
+	core_set32(atcphy, ACIOPHY_PLL_COMMON_CTRL,
+		   ACIOPHY_PLL_WAIT_FOR_CMN_READY_BEFORE_RESET_EXIT);
+
+	set32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL, LPDPTX_AUX_CLAMP_EN);
+	set32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL, LPDPTX_SLEEP_B_SML_IN);
+	udelay(10);
+	set32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL, LPDPTX_SLEEP_B_BIG_IN);
+	udelay(10);
+	clear32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL, LPDPTX_AUX_CLAMP_EN);
+	clear32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL, LPDPTX_AUX_PWN_DOWN);
+	clear32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL,
+		LPDPTX_TXTERM_CODEMSB);
+	mask32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL, LPDPTX_TXTERM_CODE,
+	       FIELD_PREP(LPDPTX_TXTERM_CODE, 0x16));
+
+	set32(atcphy->regs.lpdptx + LPDPTX_AUX_CFG_BLK_AUX_LDO_CTRL, 0x1c00);
+	mask32(atcphy->regs.lpdptx + LPDPTX_AUX_SHM_CFG_BLK_AUX_CTRL_REG1,
+	       LPDPTX_CFG_PMA_PHYS_ADJ, FIELD_PREP(LPDPTX_CFG_PMA_PHYS_ADJ, 5));
+	set32(atcphy->regs.lpdptx + LPDPTX_AUX_SHM_CFG_BLK_AUX_CTRL_REG1,
+	      LPDPTX_CFG_PMA_PHYS_ADJ_OV);
+
+	clear32(atcphy->regs.lpdptx + LPDPTX_AUX_CFG_BLK_AUX_MARGIN,
+		LPDPTX_MARGIN_RCAL_RXOFFSET_EN);
+
+	clear32(atcphy->regs.lpdptx + LPDPTX_AUX_CFG_BLK_AUX_CTRL,
+		LPDPTX_BLK_AUX_CTRL_PWRDN);
+	set32(atcphy->regs.lpdptx + LPDPTX_AUX_SHM_CFG_BLK_AUX_CTRL_REG0,
+	      LPDPTX_CFG_PMA_AUX_SEL_LF_DATA);
+	mask32(atcphy->regs.lpdptx + LPDPTX_AUX_CFG_BLK_AUX_CTRL,
+	       LPDPTX_BLK_AUX_RXOFFSET, FIELD_PREP(LPDPTX_BLK_AUX_RXOFFSET, 3));
+
+	mask32(atcphy->regs.lpdptx + LPDPTX_AUX_CFG_BLK_AUX_MARGIN,
+	       LPDPTX_AUX_MARGIN_RCAL_TXSWING,
+	       FIELD_PREP(LPDPTX_AUX_MARGIN_RCAL_TXSWING, 12));
+
+	atcphy->dp_link_rate = -1;
+}
+
+static void atcphy_disable_dp_aux(struct apple_atcphy *atcphy)
+{
+	set32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL, LPDPTX_AUX_PWN_DOWN);
+	set32(atcphy->regs.lpdptx + LPDPTX_AUX_CFG_BLK_AUX_CTRL,
+	      LPDPTX_BLK_AUX_CTRL_PWRDN);
+	set32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL, LPDPTX_AUX_CLAMP_EN);
+	clear32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL,
+		LPDPTX_SLEEP_B_SML_IN);
+	udelay(10);
+	clear32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL,
+		LPDPTX_SLEEP_B_BIG_IN);
+	udelay(10);
+
+	core_clear32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0,
+		     DPTXPHY_PMA_LANE_RESET_N);
+	core_clear32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0,
+		     DPRX_PCLK_ENABLE);
+	core_clear32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0,
+		     DPTX_PCLK1_ENABLE);
+	core_clear32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0,
+		     DPTX_PCLK2_ENABLE);
+}
+
+static int
+atcphy_dp_configure_lane(struct apple_atcphy *atcphy, enum atcphy_lane lane,
+			 const struct atcphy_dp_link_rate_configuration *cfg)
+{
+	void __iomem *tx_shm, *rx_shm, *rx_top;
+	unsigned int tx_cal_code;
+
+	lockdep_assert_held(&atcphy->lock);
+
+	switch (lane) {
+	case APPLE_ATCPHY_LANE_0:
+		tx_shm = atcphy->regs.core + LN0_AUSPMA_TX_SHM;
+		rx_shm = atcphy->regs.core + LN0_AUSPMA_RX_SHM;
+		rx_top = atcphy->regs.core + LN0_AUSPMA_RX_TOP;
+		break;
+	case APPLE_ATCPHY_LANE_1:
+		tx_shm = atcphy->regs.core + LN1_AUSPMA_TX_SHM;
+		rx_shm = atcphy->regs.core + LN1_AUSPMA_RX_SHM;
+		rx_top = atcphy->regs.core + LN1_AUSPMA_RX_TOP;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK, LN_LDOCLK_EN_SML);
+	set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK, LN_LDOCLK_EN_SML_OV);
+	udelay(10);
+
+	set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK, LN_LDOCLK_EN_BIG);
+	set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK, LN_LDOCLK_EN_BIG_OV);
+	udelay(10);
+
+	if (cfg->txa_ldoclk_bypass) {
+		set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK,
+		      LN_LDOCLK_BYPASS_SML);
+		set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK,
+		      LN_LDOCLK_BYPASS_SML_OV);
+		udelay(10);
+
+		set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK,
+		      LN_LDOCLK_BYPASS_BIG);
+		set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK,
+		      LN_LDOCLK_BYPASS_BIG_OV);
+		udelay(10);
+	} else {
+		clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK,
+			LN_LDOCLK_BYPASS_SML);
+		clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK,
+			LN_LDOCLK_BYPASS_SML_OV);
+		udelay(10);
+
+		clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK,
+			LN_LDOCLK_BYPASS_BIG);
+		clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK,
+			LN_LDOCLK_BYPASS_BIG_OV);
+		udelay(10);
+	}
+
+	set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG0,
+	      LN_BYTECLK_RESET_SYNC_SEL_OV);
+	set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG0,
+	      LN_BYTECLK_RESET_SYNC_EN);
+	set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG0,
+	      LN_BYTECLK_RESET_SYNC_EN_OV);
+	clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG0,
+		LN_BYTECLK_RESET_SYNC_CLR);
+	set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG0,
+	      LN_BYTECLK_RESET_SYNC_CLR_OV);
+
+	if (cfg->txa_div2_en)
+		set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG1,
+		      LN_TXA_DIV2_EN);
+	else
+		clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG1,
+			LN_TXA_DIV2_EN);
+	set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG1, LN_TXA_DIV2_EN_OV);
+	set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG1, LN_TXA_CLK_EN);
+	set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG1, LN_TXA_CLK_EN_OV);
+	clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG1, LN_TXA_DIV2_RESET);
+	set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG1,
+	      LN_TXA_DIV2_RESET_OV);
+
+	mask32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG0, LN_TXA_CAL_CTRL_BASE,
+	       FIELD_PREP(LN_TXA_CAL_CTRL_BASE, 0xf));
+	set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG0, LN_TXA_CAL_CTRL_BASE_OV);
+
+	tx_cal_code = FIELD_GET(AUS_UNK_A20_TX_CAL_CODE,
+				readl(atcphy->regs.core + AUS_UNK_A20));
+	mask32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG0, LN_TXA_CAL_CTRL,
+	       FIELD_PREP(LN_TXA_CAL_CTRL, (1 << tx_cal_code) - 1));
+	set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG0, LN_TXA_CAL_CTRL_OV);
+
+	clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG2, LN_TXA_MARGIN);
+	set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG2, LN_TXA_MARGIN_OV);
+	clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG2, LN_TXA_MARGIN_2R);
+	set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG2, LN_TXA_MARGIN_2R_OV);
+
+	clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_POST);
+	set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_POST_OV);
+	clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_POST_2R);
+	set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_POST_2R_OV);
+	clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_POST_4R);
+	set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_POST_4R_OV);
+	clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_PRE);
+	set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_PRE_OV);
+	clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_PRE_2R);
+	set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_PRE_2R_OV);
+	clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_PRE_4R);
+	set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_PRE_4R_OV);
+
+	clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG0, LN_TXA_HIZ);
+	set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG0, LN_TXA_HIZ_OV);
+
+	clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_AFE_CTRL1,
+		LN_RX_DIV20_RESET_N);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_AFE_CTRL1,
+	      LN_RX_DIV20_RESET_N_OV);
+	udelay(10);
+
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_AFE_CTRL1, LN_RX_DIV20_RESET_N);
+
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL12,
+	      LN_TX_BYTECLK_RESET_SYNC_EN);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL12,
+	      LN_TX_BYTECLK_RESET_SYNC_EN_OV);
+
+	mask32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_SAVOS_CTRL16, LN_TX_CAL_CODE,
+	       FIELD_PREP(LN_TX_CAL_CODE, tx_cal_code));
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_SAVOS_CTRL16, LN_TX_CAL_CODE_OV);
+
+	mask32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19,
+	       LN_TX_CLK_DLY_CTRL_TAPGEN,
+	       FIELD_PREP(LN_TX_CLK_DLY_CTRL_TAPGEN, 3));
+
+	clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL10, LN_DTVREG_ADJUST);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL13, LN_DTVREG_ADJUST_OV);
+
+	clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_SAVOS_CTRL16, LN_RXTERM_EN);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_SAVOS_CTRL16, LN_RXTERM_EN_OV);
+
+	clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19, LN_TX_TEST_EN);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19, LN_TX_TEST_EN_OV);
+
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22,
+	      LN_VREF_TEST_RXLPBKDT_EN);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22,
+	      LN_VREF_TEST_RXLPBKDT_EN_OV);
+	mask32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22,
+	       LN_VREF_LPBKIN_DATA, FIELD_PREP(LN_VREF_LPBKIN_DATA, 3));
+	mask32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22, LN_VREF_BIAS_SEL,
+	       FIELD_PREP(LN_VREF_BIAS_SEL, 2));
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22,
+	      LN_VREF_BIAS_SEL_OV);
+	mask32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22,
+	       LN_VREF_ADJUST_GRAY, FIELD_PREP(LN_VREF_ADJUST_GRAY, 0x18));
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22,
+	      LN_VREF_ADJUST_GRAY_OV);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22, LN_VREF_EN);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22, LN_VREF_EN_OV);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22, LN_VREF_BOOST_EN);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22,
+	      LN_VREF_BOOST_EN_OV);
+	udelay(10);
+
+	clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22, LN_VREF_BOOST_EN);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22,
+	      LN_VREF_BOOST_EN_OV);
+	udelay(10);
+
+	clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL13, LN_TX_PRE_EN);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL13, LN_TX_PRE_EN_OV);
+	clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL13, LN_TX_PST1_EN);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL13, LN_TX_PST1_EN_OV);
+
+	clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL12, LN_TX_PBIAS_EN);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL12, LN_TX_PBIAS_EN_OV);
+
+	clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_SAVOS_CTRL16,
+		LN_RXTERM_PULLUP_LEAK_EN);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_SAVOS_CTRL16,
+	      LN_RXTERM_PULLUP_LEAK_EN_OV);
+
+	set32(rx_top + LN_AUSPMA_RX_TOP_TJ_CFG_RX_TXMODE, LN_RX_TXMODE);
+
+	if (cfg->txa_div2_en)
+		set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19,
+		      LN_TX_CLK_DIV2_EN);
+	else
+		clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19,
+			LN_TX_CLK_DIV2_EN);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19,
+	      LN_TX_CLK_DIV2_EN_OV);
+
+	clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19,
+		LN_TX_CLK_DIV2_RST);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19,
+	      LN_TX_CLK_DIV2_RST_OV);
+
+	clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL12, LN_TX_HRCLK_SEL);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL12, LN_TX_HRCLK_SEL_OV);
+
+	clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL17, LN_TX_MARGIN);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL17, LN_TX_MARGIN_OV);
+	clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL17, LN_TX_MARGIN_LSB);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL17, LN_TX_MARGIN_LSB_OV);
+	clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL17, LN_TX_MARGIN_P1);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL17, LN_TX_MARGIN_P1_OV);
+	clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL17,
+		LN_TX_MARGIN_P1_LSB);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL17,
+	      LN_TX_MARGIN_P1_LSB_OV);
+
+	clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_P1_CODE);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_P1_CODE_OV);
+	clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_P1_LSB_CODE);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_P1_LSB_CODE_OV);
+	clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_MARGIN_PRE);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_MARGIN_PRE_OV);
+	clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18,
+		LN_TX_MARGIN_PRE_LSB);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18,
+	      LN_TX_MARGIN_PRE_LSB_OV);
+	clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_PRE_LSB_CODE);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18,
+	      LN_TX_PRE_LSB_CODE_OV);
+	clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_PRE_CODE);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_PRE_CODE_OV);
+
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL11, LN_DTVREG_SML_EN);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL11, LN_DTVREG_SML_EN_OV);
+	udelay(10);
+
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL11, LN_DTVREG_BIG_EN);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL11, LN_DTVREG_BIG_EN_OV);
+	udelay(10);
+
+	mask32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL10, LN_DTVREG_ADJUST,
+	       FIELD_PREP(LN_DTVREG_ADJUST, 0xa));
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL13, LN_DTVREG_ADJUST_OV);
+	udelay(10);
+
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19, LN_TX_EN);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19, LN_TX_EN_OV);
+	udelay(10);
+
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_CTLE_CTRL0, LN_TX_CLK_EN);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_CTLE_CTRL0, LN_TX_CLK_EN_OV);
+
+	clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL12,
+		LN_TX_BYTECLK_RESET_SYNC_CLR);
+	set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL12,
+	      LN_TX_BYTECLK_RESET_SYNC_CLR_OV);
+
+	return 0;
+}
+
+static int atcphy_auspll_apb_command(struct apple_atcphy *atcphy, u32 command)
+{
+	int ret;
+	u32 reg;
+
+	reg = readl(atcphy->regs.core + AUSPLL_APB_CMD_OVERRIDE);
+	reg &= ~AUSPLL_APB_CMD_OVERRIDE_CMD;
+	reg |= FIELD_PREP(AUSPLL_APB_CMD_OVERRIDE_CMD, command);
+	reg |= AUSPLL_APB_CMD_OVERRIDE_REQ;
+	reg |= AUSPLL_APB_CMD_OVERRIDE_UNK28;
+	writel(reg, atcphy->regs.core + AUSPLL_APB_CMD_OVERRIDE);
+
+	ret = readl_poll_timeout(atcphy->regs.core + AUSPLL_APB_CMD_OVERRIDE,
+				 reg, (reg & AUSPLL_APB_CMD_OVERRIDE_ACK), 100,
+				 100000);
+	if (ret)
+		dev_warn(
+			atcphy->dev,
+			"AUSPLL APB command was not acked, continuing and hoping for the best anyway but this Type-C port will probably not work\n");
+
+	core_clear32(atcphy, AUSPLL_APB_CMD_OVERRIDE,
+		     AUSPLL_APB_CMD_OVERRIDE_REQ);
+
+	return 0;
+}
+
+static int atcphy_dp_configure(struct apple_atcphy *atcphy,
+			       enum atcphy_dp_link_rate lr)
+{
+	const struct atcphy_dp_link_rate_configuration *cfg = &dp_lr_config[lr];
+	const struct atcphy_mode_configuration *mode_cfg;
+	int ret;
+	u32 reg;
+
+	if (atcphy->dp_link_rate == lr)
+		return 0;
+
+	if (atcphy->swap_lanes)
+		mode_cfg = &atcphy_modes[atcphy->mode].swapped;
+	else
+		mode_cfg = &atcphy_modes[atcphy->mode].normal;
+
+	ret = readl_poll_timeout(atcphy->regs.core + ACIOPHY_CMN_SHM_STS_REG0,
+				 reg,
+				 (reg & ACIOPHY_CMN_SHM_STS_REG0_CMD_READY),
+				 100, 100000);
+	if (ret) {
+		dev_err(atcphy->dev,
+			"ACIOPHY_CMN_SHM_STS_REG0_CMD_READY not set.\n");
+		return ret;
+	}
+
+	core_clear32(atcphy, AUSPLL_FREQ_CFG, AUSPLL_FREQ_REFCLK);
+
+	core_mask32(atcphy, AUSPLL_FREQ_DESC_A, AUSPLL_FD_FREQ_COUNT_TARGET,
+		    FIELD_PREP(AUSPLL_FD_FREQ_COUNT_TARGET,
+			       cfg->freqinit_count_target));
+	core_clear32(atcphy, AUSPLL_FREQ_DESC_A, AUSPLL_FD_FBDIVN_HALF);
+	core_clear32(atcphy, AUSPLL_FREQ_DESC_A, AUSPLL_FD_REV_DIVN);
+	core_mask32(atcphy, AUSPLL_FREQ_DESC_A, AUSPLL_FD_KI_MAN,
+		    FIELD_PREP(AUSPLL_FD_KI_MAN, 8));
+	core_mask32(atcphy, AUSPLL_FREQ_DESC_A, AUSPLL_FD_KI_EXP,
+		    FIELD_PREP(AUSPLL_FD_KI_EXP, 3));
+	core_mask32(atcphy, AUSPLL_FREQ_DESC_A, AUSPLL_FD_KP_MAN,
+		    FIELD_PREP(AUSPLL_FD_KP_MAN, 8));
+	core_mask32(atcphy, AUSPLL_FREQ_DESC_A, AUSPLL_FD_KP_EXP,
+		    FIELD_PREP(AUSPLL_FD_KP_EXP, 7));
+	core_clear32(atcphy, AUSPLL_FREQ_DESC_A, AUSPLL_FD_KPKI_SCALE_HBW);
+
+	core_mask32(atcphy, AUSPLL_FREQ_DESC_B, AUSPLL_FD_FBDIVN_FRAC_DEN,
+		    FIELD_PREP(AUSPLL_FD_FBDIVN_FRAC_DEN,
+			       cfg->fbdivn_frac_den));
+	core_mask32(atcphy, AUSPLL_FREQ_DESC_B, AUSPLL_FD_FBDIVN_FRAC_NUM,
+		    FIELD_PREP(AUSPLL_FD_FBDIVN_FRAC_NUM,
+			       cfg->fbdivn_frac_num));
+
+	core_clear32(atcphy, AUSPLL_FREQ_DESC_C, AUSPLL_FD_SDM_SSC_STEP);
+	core_clear32(atcphy, AUSPLL_FREQ_DESC_C, AUSPLL_FD_SDM_SSC_EN);
+	core_mask32(atcphy, AUSPLL_FREQ_DESC_C, AUSPLL_FD_PCLK_DIV_SEL,
+		    FIELD_PREP(AUSPLL_FD_PCLK_DIV_SEL, cfg->pclk_div_sel));
+	core_mask32(atcphy, AUSPLL_FREQ_DESC_C, AUSPLL_FD_LFSDM_DIV,
+		    FIELD_PREP(AUSPLL_FD_LFSDM_DIV, 1));
+	core_mask32(atcphy, AUSPLL_FREQ_DESC_C, AUSPLL_FD_LFCLK_CTRL,
+		    FIELD_PREP(AUSPLL_FD_LFCLK_CTRL, cfg->lfclk_ctrl));
+	core_mask32(atcphy, AUSPLL_FREQ_DESC_C, AUSPLL_FD_VCLK_OP_DIVN,
+		    FIELD_PREP(AUSPLL_FD_VCLK_OP_DIVN, cfg->vclk_op_divn));
+	core_set32(atcphy, AUSPLL_FREQ_DESC_C, AUSPLL_FD_VCLK_PRE_DIVN);
+
+	core_mask32(atcphy, AUSPLL_CLKOUT_DIV, AUSPLL_CLKOUT_PLLA_REFBUFCLK_DI,
+		    FIELD_PREP(AUSPLL_CLKOUT_PLLA_REFBUFCLK_DI, 7));
+
+	if (cfg->plla_clkout_vreg_bypass)
+		core_set32(atcphy, AUSPLL_CLKOUT_DTC_VREG,
+			   AUSPLL_DTC_VREG_BYPASS);
+	else
+		core_clear32(atcphy, AUSPLL_CLKOUT_DTC_VREG,
+			     AUSPLL_DTC_VREG_BYPASS);
+
+	core_set32(atcphy, AUSPLL_BGR, AUSPLL_BGR_CTRL_AVAIL);
+
+	core_set32(atcphy, AUSPLL_CLKOUT_MASTER,
+		   AUSPLL_CLKOUT_MASTER_PCLK_DRVR_EN);
+	core_set32(atcphy, AUSPLL_CLKOUT_MASTER,
+		   AUSPLL_CLKOUT_MASTER_PCLK2_DRVR_EN);
+	core_set32(atcphy, AUSPLL_CLKOUT_MASTER,
+		   AUSPLL_CLKOUT_MASTER_REFBUFCLK_DRVR_EN);
+
+	ret = atcphy_auspll_apb_command(atcphy, 0);
+	if (ret)
+		return ret;
+
+	ret = readl_poll_timeout(atcphy->regs.core + ACIOPHY_DP_PCLK_STAT, reg,
+				 (reg & ACIOPHY_AUSPLL_LOCK), 100, 100000);
+	if (ret) {
+		dev_err(atcphy->dev, "ACIOPHY_DP_PCLK did not lock.\n");
+		return ret;
+	}
+
+	ret = atcphy_auspll_apb_command(atcphy, 0x2800);
+	if (ret)
+		return ret;
+
+	if (mode_cfg->dp_lane[0]) {
+		ret = atcphy_dp_configure_lane(atcphy, APPLE_ATCPHY_LANE_0,
+					       cfg);
+		if (ret)
+			return ret;
+	}
+
+	if (mode_cfg->dp_lane[1]) {
+		ret = atcphy_dp_configure_lane(atcphy, APPLE_ATCPHY_LANE_1,
+					       cfg);
+		if (ret)
+			return ret;
+	}
+
+	core_clear32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0,
+		     DP_PMA_BYTECLK_RESET);
+	core_clear32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0,
+		     DP_MAC_DIV20_CLK_SEL);
+
+	atcphy->dp_link_rate = lr;
+	return 0;
+}
+
+static int atcphy_power_off(struct apple_atcphy *atcphy)
+{
+	u32 reg;
+	int ret;
+
+	atcphy_disable_dp_aux(atcphy);
+
+	/* enable all reset lines */
+	core_clear32(atcphy, ATCPHY_POWER_CTRL, ATCPHY_POWER_PHY_RESET_N);
+	core_set32(atcphy, ATCPHY_POWER_CTRL, ATCPHY_POWER_CLAMP_EN);
+	core_clear32(atcphy, ATCPHY_MISC,
+		     ATCPHY_MISC_RESET_N | ATCPHY_MISC_LANE_SWAP);
+	core_clear32(atcphy, ATCPHY_POWER_CTRL, ATCPHY_POWER_APB_RESET_N);
+
+	core_clear32(atcphy, ATCPHY_POWER_CTRL, ATCPHY_POWER_SLEEP_BIG);
+	ret = readl_poll_timeout(atcphy->regs.core + ATCPHY_POWER_STAT, reg,
+				 !(reg & ATCPHY_POWER_SLEEP_BIG), 100, 100000);
+	if (ret) {
+		dev_err(atcphy->dev, "failed to sleep atcphy \"big\"\n");
+		return ret;
+	}
+
+	core_clear32(atcphy, ATCPHY_POWER_CTRL, ATCPHY_POWER_SLEEP_SMALL);
+	ret = readl_poll_timeout(atcphy->regs.core + ATCPHY_POWER_STAT, reg,
+				 !(reg & ATCPHY_POWER_SLEEP_SMALL), 100,
+				 100000);
+	if (ret) {
+		dev_err(atcphy->dev, "failed to sleep atcphy \"small\"\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int atcphy_power_on(struct apple_atcphy *atcphy)
+{
+	u32 reg;
+	int ret;
+
+	core_set32(atcphy, ATCPHY_MISC, ATCPHY_MISC_RESET_N);
+
+	core_set32(atcphy, ATCPHY_POWER_CTRL, ATCPHY_POWER_SLEEP_SMALL);
+	ret = readl_poll_timeout(atcphy->regs.core + ATCPHY_POWER_STAT, reg,
+				 reg & ATCPHY_POWER_SLEEP_SMALL, 100, 100000);
+	if (ret) {
+		dev_err(atcphy->dev, "failed to wakeup atcphy \"small\"\n");
+		return ret;
+	}
+
+	core_set32(atcphy, ATCPHY_POWER_CTRL, ATCPHY_POWER_SLEEP_BIG);
+	ret = readl_poll_timeout(atcphy->regs.core + ATCPHY_POWER_STAT, reg,
+				 reg & ATCPHY_POWER_SLEEP_BIG, 100, 100000);
+	if (ret) {
+		dev_err(atcphy->dev, "failed to wakeup atcphy \"big\"\n");
+		return ret;
+	}
+
+	core_clear32(atcphy, ATCPHY_POWER_CTRL, ATCPHY_POWER_CLAMP_EN);
+	core_set32(atcphy, ATCPHY_POWER_CTRL, ATCPHY_POWER_APB_RESET_N);
+
+	return 0;
+}
+
+static int atcphy_configure(struct apple_atcphy *atcphy, enum atcphy_mode mode)
+{
+	int ret = 0;
+
+	lockdep_assert_held(&atcphy->lock);
+
+	if (mode == APPLE_ATCPHY_MODE_OFF) {
+		ret = atcphy_power_off(atcphy);
+		atcphy->mode = mode;
+		return ret;
+	}
+
+	ret = atcphy_power_on(atcphy);
+	if (ret)
+		return ret;
+
+	atcphy_apply_tunables(atcphy, mode);
+
+	core_set32(atcphy, AUSPLL_FSM_CTRL, 0x1fe000);
+	core_set32(atcphy, AUSPLL_APB_CMD_OVERRIDE,
+		   AUSPLL_APB_CMD_OVERRIDE_UNK28);
+
+	set32(atcphy->regs.core + ACIOPHY_CFG0, ACIOPHY_CFG0_COMMON_SMALL_OV);
+	udelay(10);
+	set32(atcphy->regs.core + ACIOPHY_CFG0, ACIOPHY_CFG0_COMMON_BIG_OV);
+	udelay(10);
+	set32(atcphy->regs.core + ACIOPHY_CFG0, ACIOPHY_CFG0_COMMON_CLAMP_OV);
+	udelay(10);
+
+	mask32(atcphy->regs.core + ACIOPHY_SLEEP_CTRL,
+	       ACIOPHY_SLEEP_CTRL_TX_SMALL_OV,
+	       FIELD_PREP(ACIOPHY_SLEEP_CTRL_TX_SMALL_OV, 3));
+	udelay(10);
+	mask32(atcphy->regs.core + ACIOPHY_SLEEP_CTRL,
+	       ACIOPHY_SLEEP_CTRL_TX_BIG_OV,
+	       FIELD_PREP(ACIOPHY_SLEEP_CTRL_TX_BIG_OV, 3));
+	udelay(10);
+	mask32(atcphy->regs.core + ACIOPHY_SLEEP_CTRL,
+	       ACIOPHY_SLEEP_CTRL_TX_CLAMP_OV,
+	       FIELD_PREP(ACIOPHY_SLEEP_CTRL_TX_CLAMP_OV, 3));
+	udelay(10);
+
+	mask32(atcphy->regs.core + ACIOPHY_CFG0, ACIOPHY_CFG0_RX_BIG_OV,
+	       FIELD_PREP(ACIOPHY_CFG0_RX_BIG_OV, 3));
+	udelay(10);
+	mask32(atcphy->regs.core + ACIOPHY_CFG0, ACIOPHY_CFG0_RX_SMALL_OV,
+	       FIELD_PREP(ACIOPHY_CFG0_RX_SMALL_OV, 3));
+	udelay(10);
+	mask32(atcphy->regs.core + ACIOPHY_CFG0, ACIOPHY_CFG0_RX_CLAMP_OV,
+	       FIELD_PREP(ACIOPHY_CFG0_RX_CLAMP_OV, 3));
+	udelay(10);
+
+	/* setup AUX channel if DP altmode is requested */
+	if (atcphy_modes[mode].enable_dp_aux)
+		atcphy_enable_dp_aux(atcphy);
+
+	/* enable clocks and configure lanes */
+	core_set32(atcphy, CIO3PLL_CLK_CTRL, CIO3PLL_CLK_PCLK_EN);
+	core_set32(atcphy, CIO3PLL_CLK_CTRL, CIO3PLL_CLK_REFCLK_EN);
+	atcphy_configure_lanes(atcphy, mode);
+
+	/* take the USB3 PHY out of reset */
+	core_set32(atcphy, ATCPHY_POWER_CTRL, ATCPHY_POWER_PHY_RESET_N);
+
+	atcphy->mode = mode;
+
+	return 0;
+}
+
+static int atcphy_pipehandler_lock(struct apple_atcphy *atcphy)
+{
+	int ret;
+	u32 reg;
+
+	if (readl(atcphy->regs.pipehandler + PIPEHANDLER_LOCK_REQ) &
+	    PIPEHANDLER_LOCK_EN) {
+		dev_warn(atcphy->dev, "pipehandler already locked\n");
+		return 0;
+	}
+
+	set32(atcphy->regs.pipehandler + PIPEHANDLER_LOCK_REQ,
+	      PIPEHANDLER_LOCK_EN);
+
+	ret = readl_poll_timeout(atcphy->regs.pipehandler +
+					 PIPEHANDLER_LOCK_ACK,
+				 reg, reg & PIPEHANDLER_LOCK_EN, 1000, 1000000);
+	if (ret) {
+		clear32(atcphy->regs.pipehandler + PIPEHANDLER_LOCK_REQ, 1);
+		dev_warn(
+			atcphy->dev,
+			"pipehandler lock not acked and we can't do much about it. this type-c port is probably dead until at least the next plug/unplug or possibly even until the next reboot.\n");
+	}
+
+	return ret;
+}
+
+static int atcphy_pipehandler_unlock(struct apple_atcphy *atcphy)
+{
+	int ret;
+	u32 reg;
+
+	clear32(atcphy->regs.pipehandler + PIPEHANDLER_LOCK_REQ,
+		PIPEHANDLER_LOCK_EN);
+	ret = readl_poll_timeout(
+		atcphy->regs.pipehandler + PIPEHANDLER_LOCK_ACK, reg,
+		!(reg & PIPEHANDLER_LOCK_EN), 1000, 1000000);
+	if (ret) {
+		dev_warn(
+			atcphy->dev,
+			"pipehandler lock release not acked and we can't do much about it. this type-c port is probably dead until at least the next plug/unplug or possibly even until the next reboot.\n");
+	}
+
+	return ret;
+}
+
+static void atcphy_usb2_power_on(struct apple_atcphy *atcphy)
+{
+	if (atcphy->is_host_mode)
+		set32(atcphy->regs.usb2phy + USB2PHY_SIG, USB2PHY_SIG_HOST);
+	else
+		clear32(atcphy->regs.usb2phy + USB2PHY_SIG, USB2PHY_SIG_HOST);
+
+	set32(atcphy->regs.usb2phy + USB2PHY_SIG,
+	      USB2PHY_SIG_VBUSDET_FORCE_VAL | USB2PHY_SIG_VBUSDET_FORCE_EN |
+		      USB2PHY_SIG_VBUSVLDEXT_FORCE_VAL |
+		      USB2PHY_SIG_VBUSVLDEXT_FORCE_EN);
+
+	udelay(10);
+
+	/* take the PHY out of its low power state */
+	clear32(atcphy->regs.usb2phy + USB2PHY_CTL, USB2PHY_CTL_SIDDQ);
+	udelay(10);
+
+	/* release reset */
+	clear32(atcphy->regs.usb2phy + USB2PHY_CTL, USB2PHY_CTL_RESET);
+	udelay(10);
+	clear32(atcphy->regs.usb2phy + USB2PHY_CTL, USB2PHY_CTL_PORT_RESET);
+	udelay(10);
+	set32(atcphy->regs.usb2phy + USB2PHY_CTL, USB2PHY_CTL_APB_RESET_N);
+	udelay(10);
+	clear32(atcphy->regs.usb2phy + USB2PHY_MISCTUNE,
+		USB2PHY_MISCTUNE_APBCLK_GATE_OFF);
+	clear32(atcphy->regs.usb2phy + USB2PHY_MISCTUNE,
+		USB2PHY_MISCTUNE_REFCLK_GATE_OFF);
+
+	writel(USB2PHY_USBCTL_RUN, atcphy->regs.usb2phy + USB2PHY_USBCTL);
+}
+
+static void atcphy_usb2_power_off(struct apple_atcphy *atcphy)
+{
+	writel(USB2PHY_USBCTL_ISOLATION, atcphy->regs.usb2phy + USB2PHY_USBCTL);
+
+	udelay(10);
+	/* switch the PHY to low power mode */
+	set32(atcphy->regs.usb2phy + USB2PHY_CTL, USB2PHY_CTL_SIDDQ);
+	udelay(10);
+	set32(atcphy->regs.usb2phy + USB2PHY_CTL, USB2PHY_CTL_PORT_RESET);
+	udelay(10);
+	set32(atcphy->regs.usb2phy + USB2PHY_CTL, USB2PHY_CTL_RESET);
+	udelay(10);
+	clear32(atcphy->regs.usb2phy + USB2PHY_CTL, USB2PHY_CTL_APB_RESET_N);
+	udelay(10);
+
+	set32(atcphy->regs.usb2phy + USB2PHY_MISCTUNE,
+	      USB2PHY_MISCTUNE_APBCLK_GATE_OFF);
+	set32(atcphy->regs.usb2phy + USB2PHY_MISCTUNE,
+	      USB2PHY_MISCTUNE_REFCLK_GATE_OFF);
+}
+
+static int atcphy_usb3_power_off(struct phy *phy)
+{
+	struct apple_atcphy *atcphy = phy_get_drvdata(phy);
+	guard(mutex)(&atcphy->lock);
+
+	atcphy_configure_pipehandler_dummy(atcphy);
+	atcphy->pipehandler_up = false;
+
+	if (atcphy->target_mode != atcphy->mode)
+		atcphy_configure(atcphy, atcphy->target_mode);
+
+	return 0;
+}
+
+static int atcphy_usb3_power_on(struct phy *phy)
+{
+	struct apple_atcphy *atcphy = phy_get_drvdata(phy);
+	guard(mutex)(&atcphy->lock);
+
+	return 0;
+}
+
+static int atcphy_usb3_set_mode(struct phy *phy, enum phy_mode mode,
+				int submode)
+{
+	struct apple_atcphy *atcphy = phy_get_drvdata(phy);
+	guard(mutex)(&atcphy->lock);
+
+	if (!atcphy->pipehandler_up)
+		atcphy_configure_pipehandler(atcphy);
+
+	return 0;
+}
+
+static const struct phy_ops apple_atc_usb2_phy_ops = {
+	.owner = THIS_MODULE,
+	/* Nothing to do for now, USB2 config handled around DWC3 reset */
+};
+
+static const struct phy_ops apple_atc_usb3_phy_ops = {
+	.owner = THIS_MODULE,
+	.power_on = atcphy_usb3_power_on,
+	.power_off = atcphy_usb3_power_off,
+	.set_mode = atcphy_usb3_set_mode,
+};
+
+static int atcphy_dpphy_set_mode(struct phy *phy, enum phy_mode mode,
+				 int submode)
+{
+	/* nothing to do here since the setup already happened in mux_set */
+	if (mode == PHY_MODE_DP && submode == 0)
+		return 0;
+	return -EINVAL;
+}
+
+static int atcphy_dpphy_set_mode_dp_only(struct phy *phy, enum phy_mode mode,
+					 int submode)
+{
+	struct apple_atcphy *atcphy = phy_get_drvdata(phy);
+	guard(mutex)(&atcphy->lock);
+
+	switch (mode) {
+	case PHY_MODE_DP:
+		atcphy->target_mode = APPLE_ATCPHY_MODE_DP;
+		return atcphy_configure(atcphy, APPLE_ATCPHY_MODE_DP);
+	default:
+		if (atcphy->mode == APPLE_ATCPHY_MODE_OFF)
+			return 0;
+		else
+			return atcphy_power_off(atcphy);
+	}
+}
+
+static int atcphy_dpphy_validate(struct phy *phy, enum phy_mode mode,
+				 int submode, union phy_configure_opts *opts_)
+{
+	struct phy_configure_opts_dp *opts = &opts_->dp;
+	struct apple_atcphy *atcphy = phy_get_drvdata(phy);
+
+	if (mode != PHY_MODE_DP)
+		return -EINVAL;
+	if (submode != 0)
+		return -EINVAL;
+
+	switch (atcphy->mode) {
+	case APPLE_ATCPHY_MODE_USB3_DP:
+		opts->lanes = 2;
+		break;
+	case APPLE_ATCPHY_MODE_DP:
+		opts->lanes = 4;
+		break;
+	default:
+		opts->lanes = 0;
+	}
+
+	return 0;
+}
+
+static int atcphy_dpphy_configure(struct phy *phy,
+				  union phy_configure_opts *opts_)
+{
+	struct phy_configure_opts_dp *opts = &opts_->dp;
+	struct apple_atcphy *atcphy = phy_get_drvdata(phy);
+	enum atcphy_dp_link_rate link_rate;
+
+	if (opts->set_voltages)
+		return -EINVAL;
+	if (opts->set_lanes)
+		return -EINVAL;
+
+	if (opts->set_rate) {
+		guard(mutex)(&atcphy->lock);
+
+		switch (opts->link_rate) {
+		case 1620:
+			link_rate = ATCPHY_DP_LINK_RATE_RBR;
+			break;
+		case 2700:
+			link_rate = ATCPHY_DP_LINK_RATE_HBR;
+			break;
+		case 5400:
+			link_rate = ATCPHY_DP_LINK_RATE_HBR2;
+			break;
+		case 8100:
+			link_rate = ATCPHY_DP_LINK_RATE_HBR3;
+			break;
+		case 0:
+			return 0;
+		default:
+			dev_err(atcphy->dev, "Unsupported link rate: %d\n",
+				opts->link_rate);
+			return -EINVAL;
+		}
+
+		return atcphy_dp_configure(atcphy, link_rate);
+	}
+
+	return 0;
+}
+
+static const struct phy_ops apple_atc_dp_phy_ops = {
+	.owner = THIS_MODULE,
+	.configure = atcphy_dpphy_configure,
+	.validate = atcphy_dpphy_validate,
+	.set_mode = atcphy_dpphy_set_mode,
+};
+
+static const struct phy_ops apple_atc_dp_only_phy_ops = {
+	.owner = THIS_MODULE,
+	.configure = atcphy_dpphy_configure,
+	.validate = atcphy_dpphy_validate,
+	.set_mode = atcphy_dpphy_set_mode_dp_only,
+};
+
+static struct phy *atcphy_xlate(struct device *dev,
+				const struct of_phandle_args *args)
+{
+	struct apple_atcphy *atcphy = dev_get_drvdata(dev);
+
+	switch (args->args[0]) {
+	case PHY_TYPE_USB2:
+		return atcphy->phy_usb2;
+	case PHY_TYPE_USB3:
+		return atcphy->phy_usb3;
+	case PHY_TYPE_DP:
+		return atcphy->phy_dp;
+	}
+	return ERR_PTR(-ENODEV);
+}
+
+static struct phy *atcphy_xlate_dp_only(struct device *dev,
+					const struct of_phandle_args *args)
+{
+	struct apple_atcphy *atcphy = dev_get_drvdata(dev);
+
+	if (args->args[0] != PHY_TYPE_DP)
+		return ERR_PTR(-ENODEV);
+	return atcphy->phy_dp;
+}
+
+static int atcphy_probe_phy_dp_only(struct apple_atcphy *atcphy)
+{
+	atcphy->phy_dp =
+		devm_phy_create(atcphy->dev, NULL, &apple_atc_dp_only_phy_ops);
+	if (IS_ERR(atcphy->phy_dp))
+		return PTR_ERR(atcphy->phy_dp);
+	phy_set_drvdata(atcphy->phy_dp, atcphy);
+
+	atcphy->phy_provider = devm_of_phy_provider_register(
+		atcphy->dev, atcphy_xlate_dp_only);
+	if (IS_ERR(atcphy->phy_provider))
+		return PTR_ERR(atcphy->phy_provider);
+
+	return 0;
+}
+
+static int atcphy_probe_phy(struct apple_atcphy *atcphy)
+{
+	struct {
+		struct phy **phy;
+		const struct phy_ops *ops;
+	} phys[] = {
+		{ &atcphy->phy_usb2, &apple_atc_usb2_phy_ops },
+		{ &atcphy->phy_usb3, &apple_atc_usb3_phy_ops },
+		{ &atcphy->phy_dp, &apple_atc_dp_phy_ops },
+	};
+
+	for (int i = 0; i < ARRAY_SIZE(phys); i++) {
+		*phys[i].phy = devm_phy_create(atcphy->dev, NULL, phys[i].ops);
+		if (IS_ERR(*phys[i].phy))
+			return PTR_ERR(*phys[i].phy);
+		phy_set_drvdata(*phys[i].phy, atcphy);
+	}
+
+	atcphy->phy_provider =
+		devm_of_phy_provider_register(atcphy->dev, atcphy_xlate);
+	if (IS_ERR(atcphy->phy_provider))
+		return PTR_ERR(atcphy->phy_provider);
+	return 0;
+}
+
+static void _atcphy_dwc3_reset_assert(struct apple_atcphy *atcphy)
+{
+	clear32(atcphy->regs.pipehandler + PIPEHANDLER_AON_GEN,
+		PIPEHANDLER_AON_GEN_DWC3_RESET_N);
+	set32(atcphy->regs.pipehandler + PIPEHANDLER_AON_GEN,
+	      PIPEHANDLER_AON_GEN_DWC3_FORCE_CLAMP_EN);
+}
+
+static int atcphy_dwc3_reset_assert(struct reset_controller_dev *rcdev,
+				    unsigned long id)
+{
+	struct apple_atcphy *atcphy =
+		container_of(rcdev, struct apple_atcphy, rcdev);
+
+	guard(mutex)(&atcphy->lock);
+
+	_atcphy_dwc3_reset_assert(atcphy);
+
+	if (atcphy->pipehandler_up) {
+		atcphy_configure_pipehandler_dummy(atcphy);
+		atcphy->pipehandler_up = false;
+	}
+
+	atcphy_usb2_power_off(atcphy);
+
+	atcphy->dwc3_running = false;
+
+	return 0;
+}
+
+static int atcphy_dwc3_reset_deassert(struct reset_controller_dev *rcdev,
+				      unsigned long id)
+{
+	struct apple_atcphy *atcphy =
+		container_of(rcdev, struct apple_atcphy, rcdev);
+
+	guard(mutex)(&atcphy->lock);
+
+	atcphy_usb2_power_on(atcphy);
+
+	clear32(atcphy->regs.pipehandler + PIPEHANDLER_AON_GEN,
+		PIPEHANDLER_AON_GEN_DWC3_FORCE_CLAMP_EN);
+	set32(atcphy->regs.pipehandler + PIPEHANDLER_AON_GEN,
+	      PIPEHANDLER_AON_GEN_DWC3_RESET_N);
+
+	atcphy->dwc3_running = true;
+
+	return 0;
+}
+
+const struct reset_control_ops atcphy_dwc3_reset_ops = {
+	.assert = atcphy_dwc3_reset_assert,
+	.deassert = atcphy_dwc3_reset_deassert,
+};
+
+static int atcphy_reset_xlate(struct reset_controller_dev *rcdev,
+			      const struct of_phandle_args *reset_spec)
+{
+	return 0;
+}
+
+static int atcphy_probe_rcdev(struct apple_atcphy *atcphy)
+{
+	atcphy->rcdev.owner = THIS_MODULE;
+	atcphy->rcdev.nr_resets = 1;
+	atcphy->rcdev.ops = &atcphy_dwc3_reset_ops;
+	atcphy->rcdev.of_node = atcphy->dev->of_node;
+	atcphy->rcdev.of_reset_n_cells = 0;
+	atcphy->rcdev.of_xlate = atcphy_reset_xlate;
+
+	return devm_reset_controller_register(atcphy->dev, &atcphy->rcdev);
+}
+
+static int atcphy_sw_set(struct typec_switch_dev *sw,
+			 enum typec_orientation orientation)
+{
+	struct apple_atcphy *atcphy = typec_switch_get_drvdata(sw);
+	guard(mutex)(&atcphy->lock);
+
+	switch (orientation) {
+	case TYPEC_ORIENTATION_NONE:
+		break;
+	case TYPEC_ORIENTATION_NORMAL:
+		atcphy->swap_lanes = false;
+		break;
+	case TYPEC_ORIENTATION_REVERSE:
+		atcphy->swap_lanes = true;
+		break;
+	}
+
+	return 0;
+}
+
+static int atcphy_probe_switch(struct apple_atcphy *atcphy)
+{
+	struct typec_switch_desc sw_desc = {
+		.drvdata = atcphy,
+		.fwnode = atcphy->dev->fwnode,
+		.set = atcphy_sw_set,
+	};
+
+	return PTR_ERR_OR_ZERO(typec_switch_register(atcphy->dev, &sw_desc));
+}
+
+static int atcphy_pipehandler_check(struct apple_atcphy *atcphy)
+{
+	lockdep_assert_held(&atcphy->lock);
+
+	if (readl(atcphy->regs.pipehandler + PIPEHANDLER_LOCK_ACK) &
+	    PIPEHANDLER_LOCK_EN) {
+		dev_err(atcphy->dev,
+			"pipehandler already locked, trying unlock and hoping for the best\n");
+
+		int ret = atcphy_pipehandler_unlock(atcphy);
+
+		if (ret) {
+			dev_err(atcphy->dev,
+				"Failed to unlock pipehandler, this port is probably dead until replug\n");
+			return -1;
+		}
+	}
+	return 0;
+}
+
+static void atcphy_configure_pipehandler_usb3(struct apple_atcphy *atcphy)
+{
+	int ret;
+	u32 reg;
+
+	if (atcphy_pipehandler_check(atcphy))
+		return;
+
+	if (atcphy->is_host_mode && atcphy->dwc3_running) {
+		/* Force disable link detection */
+		clear32(atcphy->regs.pipehandler + PIPEHANDLER_OVERRIDE_VALUES,
+			PIPEHANDLER_OVERRIDE_VAL_RXDETECT0 |
+				PIPEHANDLER_OVERRIDE_VAL_RXDETECT1);
+		set32(atcphy->regs.pipehandler + PIPEHANDLER_OVERRIDE,
+		      PIPEHANDLER_OVERRIDE_RXVALID);
+		set32(atcphy->regs.pipehandler + PIPEHANDLER_OVERRIDE,
+		      PIPEHANDLER_OVERRIDE_RXDETECT);
+
+		ret = atcphy_pipehandler_lock(atcphy);
+		if (ret) {
+			dev_err(atcphy->dev, "Failed to lock pipehandler");
+			return;
+		}
+
+		/* BIST dance */
+
+		core_set32(atcphy, ACIOPHY_TOP_BIST_PHY_CFG0,
+			   ACIOPHY_TOP_BIST_PHY_CFG0_LN0_RESET_N);
+		core_set32(atcphy, ACIOPHY_TOP_BIST_OV_CFG,
+			   ACIOPHY_TOP_BIST_OV_CFG_LN0_RESET_N_OV);
+		ret = readl_poll_timeout(
+			atcphy->regs.core + ACIOPHY_TOP_PHY_STAT, reg,
+			!(reg & ACIOPHY_TOP_PHY_STAT_LN0_UNK23), 100, 100000);
+		if (ret)
+			dev_err(atcphy->dev,
+				"timed out waiting for ACIOPHY_TOP_PHY_STAT_LN0_UNK23\n");
+
+		core_set32(atcphy, ACIOPHY_TOP_BIST_READ_CTRL,
+			   ACIOPHY_TOP_BIST_READ_CTRL_LN0_PHY_STATUS_RE);
+		core_clear32(atcphy, ACIOPHY_TOP_BIST_READ_CTRL,
+			     ACIOPHY_TOP_BIST_READ_CTRL_LN0_PHY_STATUS_RE);
+
+		core_mask32(atcphy, ACIOPHY_TOP_BIST_PHY_CFG1,
+			    ACIOPHY_TOP_BIST_PHY_CFG1_LN0_PWR_DOWN,
+			    FIELD_PREP(ACIOPHY_TOP_BIST_PHY_CFG1_LN0_PWR_DOWN,
+				       3));
+
+		core_set32(atcphy, ACIOPHY_TOP_BIST_OV_CFG,
+			   ACIOPHY_TOP_BIST_OV_CFG_LN0_PWR_DOWN_OV);
+		core_set32(atcphy, ACIOPHY_TOP_BIST_CIOPHY_CFG1,
+			   ACIOPHY_TOP_BIST_CIOPHY_CFG1_CLK_EN);
+		core_set32(atcphy, ACIOPHY_TOP_BIST_CIOPHY_CFG1,
+			   ACIOPHY_TOP_BIST_CIOPHY_CFG1_BIST_EN);
+		writel(0, atcphy->regs.core + ACIOPHY_TOP_BIST_CIOPHY_CFG1);
+
+		ret = readl_poll_timeout(
+			atcphy->regs.core + ACIOPHY_TOP_PHY_STAT, reg,
+			(reg & ACIOPHY_TOP_PHY_STAT_LN0_UNK0), 100, 100000);
+		if (ret)
+			dev_warn(
+				atcphy->dev,
+				"timed out waiting for ACIOPHY_TOP_PHY_STAT_LN0_UNK0\n");
+
+		ret = readl_poll_timeout(
+			atcphy->regs.core + ACIOPHY_TOP_PHY_STAT, reg,
+			!(reg & ACIOPHY_TOP_PHY_STAT_LN0_UNK23), 100, 100000);
+		if (ret)
+			dev_warn(
+				atcphy->dev,
+				"timed out waiting for ACIOPHY_TOP_PHY_STAT_LN0_UNK23\n");
+
+		/* Clear reset for non-selected USB3 PHY (?) */
+
+		mask32(atcphy->regs.pipehandler +
+			       PIPEHANDLER_NONSELECTED_OVERRIDE,
+		       PIPEHANDLER_NATIVE_POWER_DOWN, 0x3); // TOOD: FIELD_PREP
+		clear32(atcphy->regs.pipehandler +
+				PIPEHANDLER_NONSELECTED_OVERRIDE,
+			PIPEHANDLER_NATIVE_RESET);
+
+		/* More BIST stuff (?) */
+		writel(0, atcphy->regs.core + ACIOPHY_TOP_BIST_OV_CFG);
+		core_set32(atcphy, ACIOPHY_TOP_BIST_CIOPHY_CFG1,
+			   ACIOPHY_TOP_BIST_CIOPHY_CFG1_CLK_EN);
+		core_set32(atcphy, ACIOPHY_TOP_BIST_CIOPHY_CFG1,
+			   ACIOPHY_TOP_BIST_CIOPHY_CFG1_BIST_EN);
+	}
+
+	/* Configure PIPE mux to USB3 PHY */
+	mask32(atcphy->regs.pipehandler + PIPEHANDLER_MUX_CTRL,
+	       PIPEHANDLED_MUX_CTRL_CLK,
+	       FIELD_PREP(PIPEHANDLED_MUX_CTRL_CLK,
+			  PIPEHANDLED_MUX_CTRL_CLK_OFF));
+	udelay(10);
+	mask32(atcphy->regs.pipehandler + PIPEHANDLER_MUX_CTRL,
+	       PIPEHANDLED_MUX_CTRL_DATA,
+	       FIELD_PREP(PIPEHANDLED_MUX_CTRL_DATA,
+			  PIPEHANDLED_MUX_CTRL_DATA_USB3));
+	udelay(10);
+	mask32(atcphy->regs.pipehandler + PIPEHANDLER_MUX_CTRL,
+	       PIPEHANDLED_MUX_CTRL_CLK,
+	       FIELD_PREP(PIPEHANDLED_MUX_CTRL_CLK,
+			  PIPEHANDLED_MUX_CTRL_CLK_USB3));
+	udelay(10);
+
+	/* Remove link detection override */
+	clear32(atcphy->regs.pipehandler + PIPEHANDLER_OVERRIDE,
+		PIPEHANDLER_OVERRIDE_RXVALID);
+	clear32(atcphy->regs.pipehandler + PIPEHANDLER_OVERRIDE,
+		PIPEHANDLER_OVERRIDE_RXDETECT);
+
+	if (atcphy->is_host_mode && atcphy->dwc3_running) {
+		ret = atcphy_pipehandler_unlock(atcphy);
+		if (ret) {
+			dev_err(atcphy->dev, "Failed to unlock pipehandler");
+			return;
+		}
+	}
+}
+
+static void atcphy_configure_pipehandler_dummy(struct apple_atcphy *atcphy)
+{
+	int ret;
+
+	if (atcphy_pipehandler_check(atcphy))
+		return;
+
+	/* Force disable link detection */
+	clear32(atcphy->regs.pipehandler + PIPEHANDLER_OVERRIDE_VALUES,
+		PIPEHANDLER_OVERRIDE_VAL_RXDETECT0 |
+			PIPEHANDLER_OVERRIDE_VAL_RXDETECT1);
+	set32(atcphy->regs.pipehandler + PIPEHANDLER_OVERRIDE,
+	      PIPEHANDLER_OVERRIDE_RXVALID);
+	set32(atcphy->regs.pipehandler + PIPEHANDLER_OVERRIDE,
+	      PIPEHANDLER_OVERRIDE_RXDETECT);
+
+	if (atcphy->is_host_mode && atcphy->dwc3_running) {
+		ret = atcphy_pipehandler_lock(atcphy);
+		if (ret) {
+			dev_err(atcphy->dev, "Failed to lock pipehandler");
+			return;
+		}
+	}
+
+	/* Switch to dummy PHY */
+	mask32(atcphy->regs.pipehandler + PIPEHANDLER_MUX_CTRL,
+	       PIPEHANDLED_MUX_CTRL_CLK,
+	       FIELD_PREP(PIPEHANDLED_MUX_CTRL_CLK,
+			  PIPEHANDLED_MUX_CTRL_CLK_OFF));
+	udelay(10);
+	mask32(atcphy->regs.pipehandler + PIPEHANDLER_MUX_CTRL,
+	       PIPEHANDLED_MUX_CTRL_DATA,
+	       FIELD_PREP(PIPEHANDLED_MUX_CTRL_DATA,
+			  PIPEHANDLED_MUX_CTRL_DATA_DUMMY));
+	udelay(10);
+	mask32(atcphy->regs.pipehandler + PIPEHANDLER_MUX_CTRL,
+	       PIPEHANDLED_MUX_CTRL_CLK,
+	       FIELD_PREP(PIPEHANDLED_MUX_CTRL_CLK,
+			  PIPEHANDLED_MUX_CTRL_CLK_DUMMY));
+	udelay(10);
+
+	if (atcphy->is_host_mode && atcphy->dwc3_running) {
+		ret = atcphy_pipehandler_unlock(atcphy);
+		if (ret) {
+			dev_err(atcphy->dev, "Failed to unlock pipehandler");
+			return;
+		}
+	}
+
+	mask32(atcphy->regs.pipehandler + PIPEHANDLER_NONSELECTED_OVERRIDE,
+	       PIPEHANDLER_NATIVE_POWER_DOWN,
+	       FIELD_PREP(PIPEHANDLER_NATIVE_POWER_DOWN, 2));
+	set32(atcphy->regs.pipehandler + PIPEHANDLER_NONSELECTED_OVERRIDE,
+	      PIPEHANDLER_NATIVE_RESET);
+}
+
+static void atcphy_configure_pipehandler(struct apple_atcphy *atcphy)
+{
+	lockdep_assert_held(&atcphy->lock);
+
+	switch (atcphy_modes[atcphy->target_mode].pipehandler_state) {
+	case ATCPHY_PIPEHANDLER_STATE_INVALID:
+		dev_err(atcphy->dev,
+			"ATCPHY_PIPEHANDLER_STATE_INVALID state requested; falling through to USB2\n");
+		fallthrough;
+	case ATCPHY_PIPEHANDLER_STATE_DUMMY:
+		atcphy_configure_pipehandler_dummy(atcphy);
+		break;
+	case ATCPHY_PIPEHANDLER_STATE_USB3:
+		atcphy_configure_pipehandler_usb3(atcphy);
+		atcphy->pipehandler_up = true;
+		break;
+	case ATCPHY_PIPEHANDLER_STATE_USB4:
+		dev_err(atcphy->dev,
+			"ATCPHY_PIPEHANDLER_STATE_USB4 not implemented; falling back to USB2\n");
+		atcphy_configure_pipehandler_dummy(atcphy);
+		atcphy->pipehandler_up = true;
+		break;
+	}
+}
+
+static void atcphy_setup_pipehandler(struct apple_atcphy *atcphy)
+{
+	lockdep_assert_held(&atcphy->lock);
+	WARN_ON(atcphy->pipehandler_state != ATCPHY_PIPEHANDLER_STATE_INVALID);
+
+	mask32(atcphy->regs.pipehandler + PIPEHANDLER_MUX_CTRL,
+	       PIPEHANDLED_MUX_CTRL_CLK,
+	       FIELD_PREP(PIPEHANDLED_MUX_CTRL_CLK,
+			  PIPEHANDLED_MUX_CTRL_CLK_OFF));
+	udelay(10);
+	mask32(atcphy->regs.pipehandler + PIPEHANDLER_MUX_CTRL,
+	       PIPEHANDLED_MUX_CTRL_DATA,
+	       FIELD_PREP(PIPEHANDLED_MUX_CTRL_DATA,
+			  PIPEHANDLED_MUX_CTRL_DATA_DUMMY));
+	udelay(10);
+	mask32(atcphy->regs.pipehandler + PIPEHANDLER_MUX_CTRL,
+	       PIPEHANDLED_MUX_CTRL_CLK,
+	       FIELD_PREP(PIPEHANDLED_MUX_CTRL_CLK,
+			  PIPEHANDLED_MUX_CTRL_CLK_DUMMY));
+	udelay(10);
+
+	atcphy->pipehandler_state = ATCPHY_PIPEHANDLER_STATE_DUMMY;
+}
+
+static int atcphy_mux_set(struct typec_mux_dev *mux,
+			  struct typec_mux_state *state)
+{
+	struct apple_atcphy *atcphy = typec_mux_get_drvdata(mux);
+	guard(mutex)(&atcphy->lock);
+
+	atcphy->is_host_mode = state->data_role == TYPEC_HOST;
+
+	if (state->mode == TYPEC_STATE_SAFE) {
+		atcphy->target_mode = APPLE_ATCPHY_MODE_OFF;
+	} else if (state->mode == TYPEC_STATE_USB) {
+		atcphy->target_mode = APPLE_ATCPHY_MODE_USB3;
+	} else if (!state->alt && state->mode == TYPEC_MODE_USB4) {
+		struct enter_usb_data *data = state->data;
+		u32 eudo_usb_mode = FIELD_GET(EUDO_USB_MODE_MASK, data->eudo);
+
+		switch (eudo_usb_mode) {
+		case EUDO_USB_MODE_USB2:
+			atcphy->target_mode = APPLE_ATCPHY_MODE_USB2;
+			break;
+		case EUDO_USB_MODE_USB3:
+			atcphy->target_mode = APPLE_ATCPHY_MODE_USB3;
+			break;
+		case EUDO_USB_MODE_USB4:
+			atcphy->target_mode = APPLE_ATCPHY_MODE_USB4;
+			break;
+		default:
+			dev_warn(atcphy->dev,
+				 "Unsupported EUDO USB mode: 0x%x.\n",
+				 eudo_usb_mode);
+			atcphy->target_mode = APPLE_ATCPHY_MODE_OFF;
+		}
+	} else if (state->alt && state->alt->svid == USB_TYPEC_TBT_SID) {
+		atcphy->target_mode = APPLE_ATCPHY_MODE_TBT;
+	} else if (state->alt && state->alt->svid == USB_TYPEC_DP_SID) {
+		switch (state->mode) {
+		case TYPEC_DP_STATE_C:
+		case TYPEC_DP_STATE_E:
+			atcphy->target_mode = APPLE_ATCPHY_MODE_DP;
+			break;
+		case TYPEC_DP_STATE_D:
+			atcphy->target_mode = APPLE_ATCPHY_MODE_USB3_DP;
+			break;
+		default:
+			dev_warn(
+				atcphy->dev,
+				"Unsupported DP pin assignment: 0x%lx, your connected device will not work.\n",
+				state->mode);
+			atcphy->target_mode = APPLE_ATCPHY_MODE_OFF;
+		}
+	} else if (state->alt) {
+		dev_warn(
+			atcphy->dev,
+			"Unknown alternate mode SVID: 0x%x, your connected device will not work.\n",
+			state->alt->svid);
+		atcphy->target_mode = APPLE_ATCPHY_MODE_OFF;
+	} else {
+		dev_warn(
+			atcphy->dev,
+			"Unknown mode: 0x%lx, your connected device will not work.\n",
+			state->mode);
+		atcphy->target_mode = APPLE_ATCPHY_MODE_OFF;
+	}
+
+	if (atcphy->mode == atcphy->target_mode)
+		return 0;
+
+	/*
+	 * If the pipehandler is up the PHY has previously been up and we need
+	 * to wait for dwc3 to shut down before we can reconfigure the PHY.
+	 * Thus, defer reconfiguration to atcphy_usb3_power_off.
+	 * The Type-C port controller will ensure this is called through a role
+	 * switch to USB_ROLE_NONE (and then possibly to HOST/DEVICE if the
+	 * target mode isn't off).
+	 */
+	if (!atcphy->pipehandler_up)
+		return atcphy_configure(atcphy, atcphy->target_mode);
+	return 0;
+}
+
+static int atcphy_probe_mux(struct apple_atcphy *atcphy)
+{
+	struct typec_mux_desc mux_desc = {
+		.drvdata = atcphy,
+		.fwnode = atcphy->dev->fwnode,
+		.set = atcphy_mux_set,
+	};
+
+	return PTR_ERR_OR_ZERO(typec_mux_register(atcphy->dev, &mux_desc));
+}
+
+static int atcphy_load_tunables(struct apple_atcphy *atcphy)
+{
+	int ret;
+	struct {
+		const char *dt_name;
+		struct apple_tunable *tunable;
+	} tunables[] = {
+		{ "apple,tunable-fuses", &atcphy->tunables.fuses },
+		{ "apple,tunable-axi2af", &atcphy->tunables.axi2af },
+		{ "apple,tunable-common", &atcphy->tunables.common },
+		{ "apple,tunable-lane0-usb", &atcphy->tunables.lane_usb3[0] },
+		{ "apple,tunable-lane1-usb", &atcphy->tunables.lane_usb3[1] },
+		{ "apple,tunable-lane0-cio", &atcphy->tunables.lane_usb4[0] },
+		{ "apple,tunable-lane1-cio", &atcphy->tunables.lane_usb4[1] },
+		{ "apple,tunable-lane0-dp", &atcphy->tunables.lane_displayport[0] },
+		{ "apple,tunable-lane1-dp", &atcphy->tunables.lane_displayport[1] },
+	};
+
+	for (int i = 0; i < ARRAY_SIZE(tunables); i++) {
+		ret = devm_apple_parse_tunable(atcphy->dev, atcphy->np,
+					       tunables[i].tunable,
+					       tunables[i].dt_name);
+		if (ret) {
+			dev_err(atcphy->dev, "Failed to read tunable %s: %d\n",
+				tunables[i].dt_name, ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static void atcphy_detach_genpd(void *data)
+{
+	struct apple_atcphy *atcphy = data;
+	int i;
+
+	if (atcphy->pd_count <= 1)
+		return;
+
+	for (i = atcphy->pd_count - 1; i >= 0; i--) {
+		if (atcphy->pd_link[i])
+			device_link_del(atcphy->pd_link[i]);
+		if (!IS_ERR_OR_NULL(atcphy->pd_dev[i]))
+			dev_pm_domain_detach(atcphy->pd_dev[i], true);
+	}
+}
+
+static int atcphy_attach_genpd(struct apple_atcphy *atcphy)
+{
+	struct device *dev = atcphy->dev;
+	int i;
+
+	atcphy->pd_count = of_count_phandle_with_args(
+		dev->of_node, "power-domains", "#power-domain-cells");
+	if (atcphy->pd_count <= 1)
+		return 0;
+
+	atcphy->pd_dev = devm_kcalloc(dev, atcphy->pd_count,
+				      sizeof(*atcphy->pd_dev), GFP_KERNEL);
+	if (!atcphy->pd_dev)
+		return -ENOMEM;
+
+	atcphy->pd_link = devm_kcalloc(dev, atcphy->pd_count,
+				       sizeof(*atcphy->pd_link), GFP_KERNEL);
+	if (!atcphy->pd_link)
+		return -ENOMEM;
+
+	for (i = 0; i < atcphy->pd_count; i++) {
+		atcphy->pd_dev[i] = dev_pm_domain_attach_by_id(dev, i);
+		if (IS_ERR(atcphy->pd_dev[i])) {
+			atcphy_detach_genpd(atcphy);
+			return PTR_ERR(atcphy->pd_dev[i]);
+		}
+
+		atcphy->pd_link[i] =
+			device_link_add(dev, atcphy->pd_dev[i],
+					DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME |
+						DL_FLAG_RPM_ACTIVE);
+		if (!atcphy->pd_link[i]) {
+			atcphy_detach_genpd(atcphy);
+			return -EINVAL;
+		}
+	}
+
+	return devm_add_action_or_reset(dev, atcphy_detach_genpd, atcphy);
+}
+
+static int atcphy_probe_all(struct apple_atcphy *atcphy)
+{
+	int ret;
+
+	ret = atcphy_probe_rcdev(atcphy);
+	if (ret)
+		return dev_err_probe(atcphy->dev, ret, "Probing rcdev failed");
+	ret = atcphy_probe_mux(atcphy);
+	if (ret)
+		return dev_err_probe(atcphy->dev, ret, "Probing mux failed");
+	ret = atcphy_probe_switch(atcphy);
+	if (ret)
+		return dev_err_probe(atcphy->dev, ret, "Probing switch failed");
+	ret = atcphy_probe_phy(atcphy);
+	if (ret)
+		return dev_err_probe(atcphy->dev, ret, "Probing phy failed");
+
+	return 0;
+}
+
+static int atcphy_probe_dp_only(struct apple_atcphy *atcphy)
+{
+	int ret;
+
+	/*
+	 * This PHY is internally hard-wired to a DisplayPort-to-HDMI
+	 * converter with a constant lane orientation. We also don't
+	 * need any of the USB or Thunderbolt features.
+	 */
+	atcphy->swap_lanes = false;
+
+	ret = atcphy_probe_phy_dp_only(atcphy);
+	if (ret)
+		return dev_err_probe(atcphy->dev, ret,
+				     "Probing dp-only phy failed");
+
+	return 0;
+}
+
+static int atcphy_map_resources(struct platform_device *pdev,
+				struct apple_atcphy *atcphy)
+{
+	struct {
+		const char *name;
+		void __iomem **addr;
+	} resources[] = {
+		{ "core", &atcphy->regs.core },
+		{ "lpdptx", &atcphy->regs.lpdptx },
+		{ "axi2af", &atcphy->regs.axi2af },
+		{ "usb2phy", &atcphy->regs.usb2phy },
+		{ "pipehandler", &atcphy->regs.pipehandler },
+	};
+
+	for (int i = 0; i < ARRAY_SIZE(resources); i++) {
+		*resources[i].addr = devm_platform_ioremap_resource_byname(
+			pdev, resources[i].name);
+		if (IS_ERR(resources[i].addr))
+			return dev_err_probe(atcphy->dev,
+					     PTR_ERR(resources[i].addr),
+					     "Unable to map %s regs",
+					     resources[i].name);
+	}
+
+	return 0;
+}
+
+static int atcphy_probe(struct platform_device *pdev)
+{
+	struct apple_atcphy *atcphy;
+	struct device *dev = &pdev->dev;
+	int ret;
+
+	atcphy = devm_kzalloc(&pdev->dev, sizeof(*atcphy), GFP_KERNEL);
+	if (!atcphy)
+		return -ENOMEM;
+
+	atcphy->dev = dev;
+	atcphy->np = dev->of_node;
+	atcphy->hw = of_device_get_match_data(dev);
+	mutex_init(&atcphy->lock);
+	platform_set_drvdata(pdev, atcphy);
+
+	ret = atcphy_attach_genpd(atcphy);
+	if (ret < 0)
+		return dev_err_probe(dev, ret,
+				     "Failed to attach power domains");
+	ret = atcphy_map_resources(pdev, atcphy);
+	if (ret)
+		return ret;
+	ret = atcphy_load_tunables(atcphy);
+	if (ret)
+		return ret;
+
+	atcphy->mode = APPLE_ATCPHY_MODE_OFF;
+	atcphy->pipehandler_state = ATCPHY_PIPEHANDLER_STATE_INVALID;
+
+	mutex_lock(&atcphy->lock);
+	/* Reset dwc3 on probe, let dwc3 (consumer) deassert it */
+	_atcphy_dwc3_reset_assert(atcphy);
+	atcphy_power_off(atcphy);
+	atcphy_setup_pipehandler(atcphy);
+
+	if (atcphy->hw->dp_only)
+		ret = atcphy_probe_dp_only(atcphy);
+	else
+		ret = atcphy_probe_all(atcphy);
+	mutex_unlock(&atcphy->lock);
+
+	return ret;
+}
+
+static const struct apple_atcphy_hw atcphy_t8103 = {};
+
+static const struct apple_atcphy_hw atcphy_t6000_dp_only = {
+	.dp_only = true,
+};
+
+static const struct of_device_id atcphy_match[] = {
+	{
+		.compatible = "apple,t6000-atcphy",
+		.data = &atcphy_t8103,
+	},
+	{
+		.compatible = "apple,t6000-atcphy-dp-only",
+		.data = &atcphy_t6000_dp_only,
+	},
+	{
+		.compatible = "apple,t6020-atcphy",
+		.data = &atcphy_t8103,
+	},
+	{
+		.compatible = "apple,t8103-atcphy",
+		.data = &atcphy_t8103,
+	},
+	{
+		.compatible = "apple,t8112-atcphy",
+		.data = &atcphy_t8103,
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, atcphy_match);
+
+static struct platform_driver atcphy_driver = {
+	.driver = {
+		.name = "phy-apple-atc",
+		.of_match_table = atcphy_match,
+	},
+	.probe = atcphy_probe,
+};
+module_platform_driver(atcphy_driver);
+
+MODULE_AUTHOR("Sven Peter <sven at kernel.org>");
+MODULE_DESCRIPTION("Apple Type-C PHY driver");
+MODULE_LICENSE("GPL");

-- 
2.34.1




From sven at kernel.org  Thu Aug 21 08:39:07 2025
From: sven at kernel.org (Sven Peter)
Date: Thu, 21 Aug 2025 15:39:07 +0000
Subject: [PATCH RFC 15/22] usb: typec: tipd: Update partner identity when
 power status was updated
In-Reply-To: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
Message-ID: <20250821-atcphy-6-17-v1-15-172beda182b8@kernel.org>

From: Hector Martin <marcan at marcan.st>

Whenever the power status is changed make sure to also update the
partner identity to be able to detect changes once de-bouncing and mode
changes arre added for CD321x.

Signed-off-by: Hector Martin <marcan at marcan.st>
Signed-off-by: Sven Peter <sven at kernel.org>
---
 drivers/usb/typec/tipd/core.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c
index e369897bfa017ca96e559a8bd70da11207d4513a..b0fdd4dddd3a490dbc2a8ced21ea0803658f36a7 100644
--- a/drivers/usb/typec/tipd/core.c
+++ b/drivers/usb/typec/tipd/core.c
@@ -636,9 +636,16 @@ static irqreturn_t cd321x_interrupt(int irq, void *data)
 	if (!tps6598x_read_status(tps, &status))
 		goto err_unlock;
 
-	if (event & APPLE_CD_REG_INT_POWER_STATUS_UPDATE)
+	if (event & APPLE_CD_REG_INT_POWER_STATUS_UPDATE) {
 		if (!tps6598x_read_power_status(tps))
 			goto err_unlock;
+		if (TPS_POWER_STATUS_PWROPMODE(tps->pwr_status) == TYPEC_PWR_MODE_PD) {
+			if (tps6598x_read_partner_identity(tps)) {
+				dev_err(tps->dev, "%s: failed to partner identity\n", __func__);
+				tps->partner_identity = (struct usb_pd_identity) {0};
+			}
+		}
+	}
 
 	if (event & APPLE_CD_REG_INT_DATA_STATUS_UPDATE)
 		if (!tps->data->read_data_status(tps))

-- 
2.34.1




From sven at kernel.org  Thu Aug 21 08:39:12 2025
From: sven at kernel.org (Sven Peter)
Date: Thu, 21 Aug 2025 15:39:12 +0000
Subject: [PATCH RFC 20/22] soc: apple: Add hardware tunable support
In-Reply-To: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
Message-ID: <20250821-atcphy-6-17-v1-20-172beda182b8@kernel.org>

Various hardware, like the Type-C PHY or the Thunderbolt/USB4 NHI,
present on Apple SoCs need machine-specific tunables passed from our
bootloader m1n1 to the device tree. Add generic helpers so that we
don't have to duplicate this across multiple drivers.

Signed-off-by: Sven Peter <sven at kernel.org>
---
 drivers/soc/apple/Kconfig         |  4 ++
 drivers/soc/apple/Makefile        |  3 ++
 drivers/soc/apple/tunable.c       | 77 +++++++++++++++++++++++++++++++++++++++
 include/linux/soc/apple/tunable.h | 64 ++++++++++++++++++++++++++++++++
 4 files changed, 148 insertions(+)

diff --git a/drivers/soc/apple/Kconfig b/drivers/soc/apple/Kconfig
index 6388cbe1e56b5a9d90acad3ee2377ed6ac0d207d..f266b70fd9620cc940dc685f7eb2972c21a361df 100644
--- a/drivers/soc/apple/Kconfig
+++ b/drivers/soc/apple/Kconfig
@@ -41,6 +41,10 @@ config APPLE_SART
 
 	  Say 'y' here if you have an Apple SoC.
 
+config APPLE_TUNABLE
+	tristate
+	depends on ARCH_APPLE || COMPILE_TEST
+
 endmenu
 
 endif
diff --git a/drivers/soc/apple/Makefile b/drivers/soc/apple/Makefile
index 4d9ab8f3037b7159771d8817fa507ba29f99ae10..0b85ab61aefe131349a67d0aa80204edd8e89925 100644
--- a/drivers/soc/apple/Makefile
+++ b/drivers/soc/apple/Makefile
@@ -8,3 +8,6 @@ apple-rtkit-y = rtkit.o rtkit-crashlog.o
 
 obj-$(CONFIG_APPLE_SART) += apple-sart.o
 apple-sart-y = sart.o
+
+obj-$(CONFIG_APPLE_TUNABLE) += apple-tunable.o
+apple-tunable-y = tunable.o
diff --git a/drivers/soc/apple/tunable.c b/drivers/soc/apple/tunable.c
new file mode 100644
index 0000000000000000000000000000000000000000..3d9d47b3861f6fea637a3c82f270e5d321b1a48e
--- /dev/null
+++ b/drivers/soc/apple/tunable.c
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Apple Silicon hardware tunable support
+ *
+ * Each tunable is a list with each entry containing a offset into the MMIO
+ * region, a mask of bits to be cleared and a set of bits to be set. These
+ * tunables are passed along by the previous boot stages and vary from device
+ * to device such that they cannot be hardcoded in the individual drivers.
+ *
+ * Copyright (C) The Asahi Linux Contributors
+ */
+
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/soc/apple/tunable.h>
+
+int devm_apple_parse_tunable(struct device *dev, struct device_node *np,
+			     struct apple_tunable *tunable, const char *name)
+{
+	struct property *prop;
+	const __le32 *p = NULL;
+	int i;
+
+	prop = of_find_property(np, name, NULL);
+	if (!prop) {
+		dev_err(dev, "tunable %s not found\n", name);
+		return -ENOENT;
+	}
+
+	if (prop->length % (3 * sizeof(u32)))
+		return -EINVAL;
+
+	tunable->sz = prop->length / (3 * sizeof(u32));
+	tunable->values = devm_kcalloc(dev, tunable->sz,
+				       sizeof(*tunable->values), GFP_KERNEL);
+	if (!tunable->values) {
+		tunable->sz = 0;
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < tunable->sz; ++i) {
+		p = of_prop_next_u32(prop, p, &tunable->values[i].offset);
+		p = of_prop_next_u32(prop, p, &tunable->values[i].mask);
+		p = of_prop_next_u32(prop, p, &tunable->values[i].value);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(devm_apple_parse_tunable);
+
+void devm_apple_free_tunable(struct device *dev, struct apple_tunable *tunable)
+{
+	devm_kfree(dev, tunable->values);
+	tunable->sz = 0;
+}
+EXPORT_SYMBOL(devm_apple_free_tunable);
+
+void apple_apply_tunable(void __iomem *regs, struct apple_tunable *tunable)
+{
+	size_t i;
+
+	for (i = 0; i < tunable->sz; ++i) {
+		u32 val, old_val;
+
+		val = old_val = readl_relaxed(regs + tunable->values[i].offset);
+		val &= ~tunable->values[i].mask;
+		val |= tunable->values[i].value;
+		if (val != old_val)
+			writel_relaxed(val, regs + tunable->values[i].offset);
+	}
+}
+EXPORT_SYMBOL(apple_apply_tunable);
+
+MODULE_LICENSE("Dual MIT/GPL");
+MODULE_AUTHOR("Sven Peter <sven at svenpeter.dev>");
+MODULE_DESCRIPTION("Apple Silicon hardware tunable support");
diff --git a/include/linux/soc/apple/tunable.h b/include/linux/soc/apple/tunable.h
new file mode 100644
index 0000000000000000000000000000000000000000..4a149f0f210d0b4b9e17c213f0482e8fbe02355f
--- /dev/null
+++ b/include/linux/soc/apple/tunable.h
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
+/*
+ * Apple Silicon hardware tunable support
+ *
+ * Each tunable is a list with each entry containing a offset into the MMIO
+ * region, a mask of bits to be cleared and a set of bits to be set. These
+ * tunables are passed along by the previous boot stages and vary from device
+ * to device such that they cannot be hardcoded in the individual drivers.
+ *
+ * Copyright (C) The Asahi Linux Contributors
+ */
+
+#ifndef _LINUX_SOC_APPLE_TUNABLE_H_
+#define _LINUX_SOC_APPLE_TUNABLE_H_
+
+#include <linux/device.h>
+#include <linux/types.h>
+
+/*
+ * Struct to store a Apple Silicon hardware tunable.
+ *
+ * sz: number of [offset, mask, value] tuples stored in values.
+ * values: array containing the hardware tunables.
+ */
+struct apple_tunable {
+	size_t sz;
+	struct {
+		u32 offset;
+		u32 mask;
+		u32 value;
+	} *values;
+};
+
+/*
+ * Parse an array of hardware tunables from the device tree.
+ *
+ * Return 0 on success, -ENOMEM if the allocation failed and -ENOENT if the
+ * tunable could not be found or was in an invalid format.
+ *
+ * dev: Device node used for devm_kzalloc internally.
+ * np: Device node which contains the tunable array.
+ * tunable: Pointer to where the parsed tunables will be stored.
+ * name: Name of the device tree property which contains the tunables.
+ */
+int devm_apple_parse_tunable(struct device *dev, struct device_node *np,
+			     struct apple_tunable *tunable, const char *name);
+
+/*
+ * Apply a previously loaded hardware tunable.
+ *
+ * regs: MMIO to which the tunable will be applied.
+ * tunable: Pointer to the tunable.
+ */
+void apple_apply_tunable(void __iomem *regs, struct apple_tunable *tunable);
+
+/*
+ * Manually frees a previous allocated tunable.
+ *
+ * dev: Device node used for devm_apple_parse_tunable
+ * tunable: Tunable allocaated by devm_apple_parse_tunable
+ */
+void devm_apple_free_tunable(struct device *dev, struct apple_tunable *tunable);
+
+#endif

-- 
2.34.1




From sven at kernel.org  Thu Aug 21 08:39:11 2025
From: sven at kernel.org (Sven Peter)
Date: Thu, 21 Aug 2025 15:39:11 +0000
Subject: [PATCH RFC 19/22] usb: typec: tipd: Handle mode transitions for
 CD321x
In-Reply-To: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
Message-ID: <20250821-atcphy-6-17-v1-19-172beda182b8@kernel.org>

From: Hector Martin <marcan at marcan.st>

On Apple Silicon machines there is no control over which alt mode is
chosen. The CD321x' firmware negotiates the target mode on its own and
only lets the main CPU know after the mode has already been chosen.
Especially after plugging a new cable in this can result to quick mode
changes from e.g. power only -> USB3 only -> USB3+DisplayPort in a short
time. It is not possile to influence this in any way and we also do not
get direct access to the PDOs or VDOs exchanged via USB PD.

Additionally, mode changes must be tightly synchronized between DWC3 and
the Type C PHY and most mode changes require a full reset of DWC3 to
make the port work correctly.
On the machines the usb role change is used to reset the controller.
The role change is additionally done synchronously from the callback
instead of relying on a workqueue as usual in order to avoid any races
which can, in the worst case, result in resetting the entire SoC if
Type-C PHY and DWC3 are out of sync.

To be able to control all this we trigger the entire process in the
correct order directly from the TIPD driver and de-bounce any mode
changes to avoid tearing down and re-setting DWC3 back up multiple times
any time a new connection is made.

Signed-off-by: Hector Martin <marcan at marcan.st>
Co-developed-by: Sven Peter <sven at kernel.org>
Signed-off-by: Sven Peter <sven at kernel.org>
---
 drivers/usb/typec/tipd/core.c | 299 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 295 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c
index bada42fbe59b29a9e864e17644da41908a445102..cad6adba131b8289645b1cabadc8d4216f0f0eee 100644
--- a/drivers/usb/typec/tipd/core.c
+++ b/drivers/usb/typec/tipd/core.c
@@ -17,6 +17,7 @@
 #include <linux/usb/typec.h>
 #include <linux/usb/typec_altmode.h>
 #include <linux/usb/typec_dp.h>
+#include <linux/usb/typec_mux.h>
 #include <linux/usb/typec_tbt.h>
 #include <linux/usb/role.h>
 #include <linux/workqueue.h>
@@ -121,6 +122,9 @@ struct tps6598x_intel_vid_status_reg {
 #define TPS_TASK_TIMEOUT		1
 #define TPS_TASK_REJECTED		3
 
+/* Debounce delay for mode changes, in milliseconds */
+#define CD321X_DEBOUNCE_DELAY_MS 500
+
 enum {
 	TPS_MODE_APP,
 	TPS_MODE_BOOT,
@@ -146,6 +150,7 @@ struct tipd_data {
 	irq_handler_t irq_handler;
 	u64 irq_mask1;
 	size_t tps_struct_size;
+	void (*remove)(struct tps6598x *tps);
 	int (*register_port)(struct tps6598x *tps, struct fwnode_handle *node);
 	void (*unregister_port)(struct tps6598x *tps);
 	void (*trace_data_status)(u32 status);
@@ -156,6 +161,7 @@ struct tipd_data {
 	int (*switch_power_state)(struct tps6598x *tps, u8 target_state);
 	bool (*read_data_status)(struct tps6598x *tps);
 	int (*reset)(struct tps6598x *tps);
+	int (*connect)(struct tps6598x *tps, u32 status);
 };
 
 struct tps6598x {
@@ -184,6 +190,17 @@ struct tps6598x {
 	const struct tipd_data *data;
 };
 
+struct cd321x_status {
+	u32 status;
+	u32 pwr_status;
+	u32 data_status;
+	u32 status_changed;
+	struct usb_pd_identity partner_identity;
+	struct tps6598x_dp_sid_status_reg dp_sid_status;
+	struct tps6598x_intel_vid_status_reg intel_vid_status;
+	struct tps6598x_usb4_status_reg usb4_status;
+};
+
 struct cd321x {
 	struct tps6598x tps;
 
@@ -193,6 +210,13 @@ struct cd321x {
 
 	struct typec_altmode *port_altmode_dp;
 	struct typec_altmode *port_altmode_tbt;
+
+	struct typec_mux *mux;
+	struct typec_mux_state state;
+
+	struct cd321x_status update_status;
+	struct delayed_work update_work;
+	struct usb_pd_identity cur_partner_identity;
 };
 
 static enum power_supply_property tps6598x_psy_props[] = {
@@ -614,9 +638,238 @@ static void tps6598x_handle_plug_event(struct tps6598x *tps, u32 status)
 	}
 }
 
+static void cd321x_typec_update_mode(struct tps6598x *tps, struct cd321x_status *st)
+{
+	struct cd321x *cd321x = container_of(tps, struct cd321x, tps);
+
+	if (st->data_status & TPS_DATA_STATUS_USB_DATA_ROLE)
+		cd321x->state.data_role = TYPEC_DEVICE;
+	else
+		cd321x->state.data_role = TYPEC_HOST;
+
+	if (!(st->data_status & TPS_DATA_STATUS_DATA_CONNECTION)) {
+		if (cd321x->state.mode == TYPEC_STATE_SAFE)
+			return;
+		cd321x->state.alt = NULL;
+		cd321x->state.mode = TYPEC_STATE_SAFE;
+		cd321x->state.data = NULL;
+		typec_mux_set(cd321x->mux, &cd321x->state);
+	} else if (st->data_status & TPS_DATA_STATUS_DP_CONNECTION) {
+		struct typec_displayport_data dp_data;
+		unsigned long mode;
+
+		switch (TPS_DATA_STATUS_DP_SPEC_PIN_ASSIGNMENT(st->data_status)) {
+		case TPS_DATA_STATUS_DP_SPEC_PIN_ASSIGNMENT_A:
+			mode = TYPEC_DP_STATE_A;
+			break;
+		case TPS_DATA_STATUS_DP_SPEC_PIN_ASSIGNMENT_B:
+			mode = TYPEC_DP_STATE_B;
+			break;
+		case TPS_DATA_STATUS_DP_SPEC_PIN_ASSIGNMENT_C:
+			mode = TYPEC_DP_STATE_C;
+			break;
+		case TPS_DATA_STATUS_DP_SPEC_PIN_ASSIGNMENT_D:
+			mode = TYPEC_DP_STATE_D;
+			break;
+		case TPS_DATA_STATUS_DP_SPEC_PIN_ASSIGNMENT_E:
+			mode = TYPEC_DP_STATE_E;
+			break;
+		case TPS_DATA_STATUS_DP_SPEC_PIN_ASSIGNMENT_F:
+			mode = TYPEC_DP_STATE_F;
+			break;
+		default:
+			dev_err(tps->dev, "Invalid DP pin assignment\n");
+			return;
+		}
+
+		if (cd321x->state.alt == cd321x->port_altmode_dp &&
+		   cd321x->state.mode == mode) {
+			return;
+		}
+
+		dp_data.status = le32_to_cpu(st->dp_sid_status.status_rx);
+		dp_data.conf = le32_to_cpu(st->dp_sid_status.configure);
+		cd321x->state.alt = cd321x->port_altmode_dp;
+		cd321x->state.data = &dp_data;
+		cd321x->state.mode = mode;
+		typec_mux_set(cd321x->mux, &cd321x->state);
+	} else if (st->data_status & TPS_DATA_STATUS_TBT_CONNECTION) {
+		struct typec_thunderbolt_data tbt_data;
+
+		if (cd321x->state.alt == cd321x->port_altmode_tbt &&
+		   cd321x->state.mode == TYPEC_TBT_MODE)
+			return;
+
+		tbt_data.cable_mode = le16_to_cpu(st->intel_vid_status.cable_mode);
+		tbt_data.device_mode = le16_to_cpu(st->intel_vid_status.device_mode);
+		tbt_data.enter_vdo = le16_to_cpu(st->intel_vid_status.enter_vdo);
+		cd321x->state.alt = cd321x->port_altmode_tbt;
+		cd321x->state.mode = TYPEC_TBT_MODE;
+		cd321x->state.data = &tbt_data;
+		typec_mux_set(cd321x->mux, &cd321x->state);
+	} else if (st->data_status & CD321X_DATA_STATUS_USB4_CONNECTION) {
+		struct enter_usb_data eusb_data;
+
+		if (cd321x->state.alt == NULL && cd321x->state.mode == TYPEC_MODE_USB4)
+			return;
+
+		eusb_data.eudo = le32_to_cpu(st->usb4_status.eudo);
+		eusb_data.active_link_training =
+			!!(st->data_status & TPS_DATA_STATUS_ACTIVE_LINK_TRAIN);
+
+		cd321x->state.alt = NULL;
+		cd321x->state.data = &eusb_data;
+		cd321x->state.mode = TYPEC_MODE_USB4;
+		typec_mux_set(cd321x->mux, &cd321x->state);
+	} else {
+		if (cd321x->state.alt == NULL && cd321x->state.mode == TYPEC_STATE_USB)
+			return;
+		cd321x->state.alt = NULL;
+		cd321x->state.mode = TYPEC_STATE_USB;
+		cd321x->state.data = NULL;
+		typec_mux_set(cd321x->mux, &cd321x->state);
+	}
+}
+
+static void cd321x_update_work(struct work_struct *work)
+{
+	struct cd321x *cd321x = container_of(to_delayed_work(work),
+					    struct cd321x, update_work);
+	struct tps6598x *tps = &cd321x->tps;
+	struct cd321x_status st;
+	guard(mutex)(&tps->lock);
+
+	st = cd321x->update_status;
+	cd321x->update_status.status_changed = 0;
+
+	bool old_connected = !!tps->partner;
+	bool new_connected = st.status & TPS_STATUS_PLUG_PRESENT;
+	bool was_disconnected = st.status_changed & TPS_STATUS_PLUG_PRESENT;
+
+	bool usb_connection = st.data_status &
+			      (TPS_DATA_STATUS_USB2_CONNECTION | TPS_DATA_STATUS_USB3_CONNECTION);
+
+	enum usb_role old_role = usb_role_switch_get_role(tps->role_sw);
+	enum usb_role new_role = USB_ROLE_NONE;
+	enum typec_pwr_opmode pwr_opmode = TYPEC_PWR_MODE_USB;
+	enum typec_orientation orientation = TYPEC_ORIENTATION_NONE;
+
+	if (usb_connection) {
+		if (tps->data_status & TPS_DATA_STATUS_USB_DATA_ROLE)
+			new_role = USB_ROLE_DEVICE;
+		else
+			new_role = USB_ROLE_HOST;
+	}
+
+	if (new_connected) {
+		pwr_opmode = TPS_POWER_STATUS_PWROPMODE(st.pwr_status);
+		orientation = TPS_STATUS_TO_UPSIDE_DOWN(st.status) ?
+			TYPEC_ORIENTATION_REVERSE : TYPEC_ORIENTATION_NORMAL;
+	}
+
+	bool is_pd = pwr_opmode == TYPEC_PWR_MODE_PD;
+	bool partner_changed = old_connected && new_connected &&
+		(was_disconnected ||
+		 (is_pd && memcmp(&st.partner_identity,
+				  &cd321x->cur_partner_identity, sizeof(struct usb_pd_identity))));
+
+	/* If we are switching from an active role, transition to USB_ROLE_NONE first */
+	if (old_role != USB_ROLE_NONE && (new_role != old_role || was_disconnected))
+		usb_role_switch_set_role(tps->role_sw, USB_ROLE_NONE);
+
+	/* Process partner disconnection or change */
+	if (!new_connected || partner_changed) {
+		if (!IS_ERR(tps->partner))
+			typec_unregister_partner(tps->partner);
+		tps->partner = NULL;
+	}
+
+	/* If there was a disconnection, set PHY to off */
+	if (!new_connected || was_disconnected) {
+		cd321x->state.alt = NULL;
+		cd321x->state.mode = TYPEC_STATE_SAFE;
+		cd321x->state.data = NULL;
+		typec_set_mode(tps->port, TYPEC_STATE_SAFE);
+	}
+
+	/* Update Type-C properties */
+	typec_set_pwr_opmode(tps->port, pwr_opmode);
+	typec_set_pwr_role(tps->port, TPS_STATUS_TO_TYPEC_PORTROLE(st.status));
+	typec_set_vconn_role(tps->port, TPS_STATUS_TO_TYPEC_VCONN(st.status));
+	typec_set_orientation(tps->port, orientation);
+	typec_set_data_role(tps->port, TPS_STATUS_TO_TYPEC_DATAROLE(st.status));
+	power_supply_changed(tps->psy);
+
+	/* If the plug is disconnected, we are done */
+	if (!new_connected)
+		return;
+
+	/* Set up partner if we were previously disconnected (or changed). */
+	if (!tps->partner) {
+		struct typec_partner_desc desc;
+		desc.usb_pd = is_pd;
+		desc.accessory = TYPEC_ACCESSORY_NONE; /* XXX: handle accessories */
+		desc.identity = NULL;
+
+		if (desc.usb_pd)
+			desc.identity = &st.partner_identity;
+
+		tps->partner = typec_register_partner(tps->port, &desc);
+		if (IS_ERR(tps->partner))
+			dev_warn(tps->dev, "%s: failed to register partnet\n", __func__);
+
+		if (desc.identity) {
+			typec_partner_set_identity(tps->partner);
+			cd321x->cur_partner_identity = st.partner_identity;
+		}
+	}
+
+	/* Update the TypeC MUX/PHY state */
+	cd321x_typec_update_mode(tps, &st);
+
+	/* Launch the USB role switch */
+	usb_role_switch_set_role(tps->role_sw, new_role);
+
+	power_supply_changed(tps->psy);
+}
+
+static void cd321x_queue_status(struct tps6598x *tps)
+{
+	struct cd321x *cd321x = container_of(tps, struct cd321x, tps);
+
+	cd321x->update_status.status_changed |= cd321x->update_status.status ^ tps->status;
+
+	cd321x->update_status.status = tps->status;
+	cd321x->update_status.pwr_status = tps->pwr_status;
+	cd321x->update_status.data_status = tps->data_status;
+
+	cd321x->update_status.partner_identity = tps->partner_identity;
+	cd321x->update_status.dp_sid_status = cd321x->dp_sid_status;
+	cd321x->update_status.intel_vid_status = cd321x->intel_vid_status;
+	cd321x->update_status.usb4_status = cd321x->usb4_status;
+}
+
+static int cd321x_connect(struct tps6598x *tps, u32 status)
+{
+	struct cd321x *cd321x = container_of(tps, struct cd321x, tps);
+
+	/*
+	 * This is only called from _probe such that update_work can be
+	 * initialized and then scheduled for the first time to handle
+	 * plugs already connected at boot time.
+	 */
+	INIT_DELAYED_WORK(&cd321x->update_work, cd321x_update_work);
+	tps->status = status;
+	cd321x_queue_status(tps);
+	schedule_delayed_work(&cd321x->update_work, msecs_to_jiffies(CD321X_DEBOUNCE_DELAY_MS));
+
+	return 0;
+}
+
 static irqreturn_t cd321x_interrupt(int irq, void *data)
 {
 	struct tps6598x *tps = data;
+	struct cd321x *cd321x = container_of(tps, struct cd321x, tps);
 	u64 event = 0;
 	u32 status;
 	int ret;
@@ -653,9 +906,15 @@ static irqreturn_t cd321x_interrupt(int irq, void *data)
 		if (!tps->data->read_data_status(tps))
 			goto err_unlock;
 
-	/* Handle plug insert or removal */
-	if (event & APPLE_CD_REG_INT_PLUG_EVENT)
-		tps6598x_handle_plug_event(tps, status);
+	cd321x_queue_status(tps);
+	tps->status = status;
+
+	/*
+	 * Cancel pending work if not already running.
+	 * We will requeue the work after CD321X_DEBOUNCE_DELAY_MS regardless.
+	 */
+	cancel_delayed_work(&cd321x->update_work);
+	schedule_delayed_work(&cd321x->update_work, msecs_to_jiffies(CD321X_DEBOUNCE_DELAY_MS));
 
 err_unlock:
 	mutex_unlock(&tps->lock);
@@ -1023,10 +1282,26 @@ cd321x_register_port(struct tps6598x *tps, struct fwnode_handle *fwnode)
 	if (ret)
 		goto err_unregister_port;
 
+	cd321x->mux = fwnode_typec_mux_get(fwnode);
+	if (IS_ERR(cd321x->mux)) {
+		ret = PTR_ERR(cd321x->mux);
+		goto err_unregister_altmodes;
+	}
+
+	cd321x->state.alt = NULL;
+	cd321x->state.mode = TYPEC_STATE_SAFE;
+	cd321x->state.data = NULL;
 	typec_set_mode(tps->port, TYPEC_STATE_SAFE);
 
 	return 0;
 
+err_unregister_altmodes:
+	if (cd321x->port_altmode_dp)
+		typec_unregister_altmode(cd321x->port_altmode_dp);
+	if (cd321x->port_altmode_tbt)
+		typec_unregister_altmode(cd321x->port_altmode_tbt);
+	cd321x->port_altmode_dp = NULL;
+	cd321x->port_altmode_tbt = NULL;
 err_unregister_port:
 	typec_unregister_port(tps->port);
 	return ret;
@@ -1043,6 +1318,8 @@ cd321x_unregister_port(struct tps6598x *tps)
 {
 	struct cd321x *cd321x = container_of(tps, struct cd321x, tps);
 
+	if (cd321x->mux)
+		typec_mux_put(cd321x->mux);
 	if (cd321x->port_altmode_dp)
 		typec_unregister_altmode(cd321x->port_altmode_dp);
 	if (cd321x->port_altmode_tbt)
@@ -1457,6 +1734,13 @@ tps25750_register_port(struct tps6598x *tps, struct fwnode_handle *fwnode)
 	return 0;
 }
 
+static void cd321x_remove(struct tps6598x *tps)
+{
+	struct cd321x *cd321x = container_of(tps, struct cd321x, tps);
+
+	cancel_delayed_work_sync(&cd321x->update_work);
+}
+
 static int tps6598x_probe(struct i2c_client *client)
 {
 	const struct tipd_data *data;
@@ -1558,7 +1842,7 @@ static int tps6598x_probe(struct i2c_client *client)
 			goto err_unregister_port;
 		if (!tps->data->read_data_status(tps))
 			goto err_unregister_port;
-		ret = tps6598x_connect(tps, status);
+		ret = tps->data->connect(tps, status);
 		if (ret)
 			dev_err(&client->dev, "failed to register partner\n");
 	}
@@ -1615,6 +1899,9 @@ static void tps6598x_remove(struct i2c_client *client)
 	else
 		devm_free_irq(tps->dev, client->irq, tps);
 
+	if (tps->data->remove)
+		tps->data->remove(tps);
+
 	tps6598x_disconnect(tps, 0);
 	tps->data->unregister_port(tps);
 	usb_role_switch_put(tps->role_sw);
@@ -1685,6 +1972,7 @@ static const struct tipd_data cd321x_data = {
 		     APPLE_CD_REG_INT_DATA_STATUS_UPDATE |
 		     APPLE_CD_REG_INT_PLUG_EVENT,
 	.tps_struct_size = sizeof(struct cd321x),
+	.remove = cd321x_remove,
 	.register_port = cd321x_register_port,
 	.unregister_port = cd321x_unregister_port,
 	.trace_data_status = trace_cd321x_data_status,
@@ -1694,6 +1982,7 @@ static const struct tipd_data cd321x_data = {
 	.read_data_status = cd321x_read_data_status,
 	.reset = cd321x_reset,
 	.switch_power_state = cd321x_switch_power_state,
+	.connect = cd321x_connect,
 };
 
 static const struct tipd_data tps6598x_data = {
@@ -1711,6 +2000,7 @@ static const struct tipd_data tps6598x_data = {
 	.init = tps6598x_init,
 	.read_data_status = tps6598x_read_data_status,
 	.reset = tps6598x_reset,
+	.connect = tps6598x_connect,
 };
 
 static const struct tipd_data tps25750_data = {
@@ -1728,6 +2018,7 @@ static const struct tipd_data tps25750_data = {
 	.init = tps25750_init,
 	.read_data_status = tps6598x_read_data_status,
 	.reset = tps25750_reset,
+	.connect = tps6598x_connect,
 };
 
 static const struct of_device_id tps6598x_of_match[] = {

-- 
2.34.1




From sven at kernel.org  Thu Aug 21 08:39:06 2025
From: sven at kernel.org (Sven Peter)
Date: Thu, 21 Aug 2025 15:39:06 +0000
Subject: [PATCH RFC 14/22] usb: typec: tipd: Register DisplayPort and
 Thunderbolt altmodes for cd321x
In-Reply-To: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
Message-ID: <20250821-atcphy-6-17-v1-14-172beda182b8@kernel.org>

Ports equipped with a CD321x are only found on Apple Silicon machines
and always support DisplayPort, Thunderbolt and USB4. Register these
port modes unconditionally.

Signed-off-by: Sven Peter <sven at kernel.org>
---
 drivers/usb/typec/tipd/core.c | 87 +++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 84 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c
index 59d270eb50ea3dc49ad32ff71f8354e23c1083c9..e369897bfa017ca96e559a8bd70da11207d4513a 100644
--- a/drivers/usb/typec/tipd/core.c
+++ b/drivers/usb/typec/tipd/core.c
@@ -16,6 +16,8 @@
 #include <linux/interrupt.h>
 #include <linux/usb/typec.h>
 #include <linux/usb/typec_altmode.h>
+#include <linux/usb/typec_dp.h>
+#include <linux/usb/typec_tbt.h>
 #include <linux/usb/role.h>
 #include <linux/workqueue.h>
 #include <linux/firmware.h>
@@ -145,6 +147,7 @@ struct tipd_data {
 	u64 irq_mask1;
 	size_t tps_struct_size;
 	int (*register_port)(struct tps6598x *tps, struct fwnode_handle *node);
+	void (*unregister_port)(struct tps6598x *tps);
 	void (*trace_data_status)(u32 status);
 	void (*trace_power_status)(u16 status);
 	void (*trace_status)(u32 status);
@@ -186,6 +189,9 @@ struct cd321x {
 	struct tps6598x_dp_sid_status_reg dp_sid_status;
 	struct tps6598x_intel_vid_status_reg intel_vid_status;
 	struct tps6598x_usb4_status_reg usb4_status;
+
+	struct typec_altmode *port_altmode_dp;
+	struct typec_altmode *port_altmode_tbt;
 };
 
 static enum power_supply_property tps6598x_psy_props[] = {
@@ -965,6 +971,78 @@ tps6598x_register_port(struct tps6598x *tps, struct fwnode_handle *fwnode)
 	return 0;
 }
 
+static int cd321x_register_port_altmodes(struct cd321x *cd321x)
+{
+	struct typec_altmode_desc desc;
+	struct typec_altmode *amode;
+
+	memset(&desc, 0, sizeof(desc));
+	desc.svid = USB_TYPEC_DP_SID;
+	desc.mode = USB_TYPEC_DP_MODE;
+	desc.vdo = DP_CONF_SET_PIN_ASSIGN(BIT(DP_PIN_ASSIGN_C) | BIT(DP_PIN_ASSIGN_D));
+	desc.vdo |= DP_CAP_DFP_D;
+	amode = typec_port_register_altmode(cd321x->tps.port, &desc);
+	if (IS_ERR(amode))
+		return PTR_ERR(amode);
+	cd321x->port_altmode_dp = amode;
+
+	memset(&desc, 0, sizeof(desc));
+	desc.svid = USB_TYPEC_TBT_SID;
+	desc.mode = TYPEC_ANY_MODE;
+	amode = typec_port_register_altmode(cd321x->tps.port, &desc);
+	if (IS_ERR(amode)) {
+		typec_unregister_altmode(cd321x->port_altmode_dp);
+		cd321x->port_altmode_dp = NULL;
+		return PTR_ERR(amode);
+	}
+	cd321x->port_altmode_tbt = amode;
+
+	return 0;
+}
+
+static int
+cd321x_register_port(struct tps6598x *tps, struct fwnode_handle *fwnode)
+{
+	struct cd321x *cd321x = container_of(tps, struct cd321x, tps);
+	int ret;
+
+	ret = tps6598x_register_port(tps, fwnode);
+	if (ret)
+		return ret;
+
+	ret = cd321x_register_port_altmodes(cd321x);
+	if (ret)
+		goto err_unregister_port;
+
+	typec_set_mode(tps->port, TYPEC_STATE_SAFE);
+
+	return 0;
+
+err_unregister_port:
+	typec_unregister_port(tps->port);
+	return ret;
+}
+
+static void
+tps6598x_unregister_port(struct tps6598x *tps)
+{
+	typec_unregister_port(tps->port);
+}
+
+static void
+cd321x_unregister_port(struct tps6598x *tps)
+{
+	struct cd321x *cd321x = container_of(tps, struct cd321x, tps);
+
+	if (cd321x->port_altmode_dp)
+		typec_unregister_altmode(cd321x->port_altmode_dp);
+	if (cd321x->port_altmode_tbt)
+		typec_unregister_altmode(cd321x->port_altmode_tbt);
+	cd321x->port_altmode_dp = NULL;
+	cd321x->port_altmode_tbt = NULL;
+	typec_unregister_port(tps->port);
+}
+
 static int tps_request_firmware(struct tps6598x *tps, const struct firmware **fw,
 				const char **firmware_name)
 {
@@ -1506,7 +1584,7 @@ static int tps6598x_probe(struct i2c_client *client)
 err_disconnect:
 	tps6598x_disconnect(tps, 0);
 err_unregister_port:
-	typec_unregister_port(tps->port);
+	tps->data->unregister_port(tps);
 err_role_put:
 	usb_role_switch_put(tps->role_sw);
 err_fwnode_put:
@@ -1530,7 +1608,7 @@ static void tps6598x_remove(struct i2c_client *client)
 		devm_free_irq(tps->dev, client->irq, tps);
 
 	tps6598x_disconnect(tps, 0);
-	typec_unregister_port(tps->port);
+	tps->data->unregister_port(tps);
 	usb_role_switch_put(tps->role_sw);
 
 	/* Reset PD controller to remove any applied patch */
@@ -1599,7 +1677,8 @@ static const struct tipd_data cd321x_data = {
 		     APPLE_CD_REG_INT_DATA_STATUS_UPDATE |
 		     APPLE_CD_REG_INT_PLUG_EVENT,
 	.tps_struct_size = sizeof(struct cd321x),
-	.register_port = tps6598x_register_port,
+	.register_port = cd321x_register_port,
+	.unregister_port = cd321x_unregister_port,
 	.trace_data_status = trace_cd321x_data_status,
 	.trace_power_status = trace_tps6598x_power_status,
 	.trace_status = trace_tps6598x_status,
@@ -1616,6 +1695,7 @@ static const struct tipd_data tps6598x_data = {
 		     TPS_REG_INT_PLUG_EVENT,
 	.tps_struct_size = sizeof(struct tps6598x),
 	.register_port = tps6598x_register_port,
+	.unregister_port = tps6598x_unregister_port,
 	.trace_data_status = trace_tps6598x_data_status,
 	.trace_power_status = trace_tps6598x_power_status,
 	.trace_status = trace_tps6598x_status,
@@ -1632,6 +1712,7 @@ static const struct tipd_data tps25750_data = {
 		     TPS_REG_INT_PLUG_EVENT,
 	.tps_struct_size = sizeof(struct tps6598x),
 	.register_port = tps25750_register_port,
+	.unregister_port = tps6598x_unregister_port,
 	.trace_data_status = trace_tps6598x_data_status,
 	.trace_power_status = trace_tps25750_power_status,
 	.trace_status = trace_tps25750_status,

-- 
2.34.1




From prabhakar.csengg at gmail.com  Thu Aug 21 08:59:57 2025
From: prabhakar.csengg at gmail.com (Prabhakar)
Date: Thu, 21 Aug 2025 16:59:57 +0100
Subject: [PATCH] phy: renesas: rcar-gen3-usb2: Fix ID check logic with VBUS valid
Message-ID: <20250821155957.1088337-1-prabhakar.mahadev-lad.rj@bp.renesas.com>

From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>

The existing ID detection logic returned false when both IDDIG and
VBUSVALID were set, which caused incorrect role determination in some
cases. The condition:

    !(device && !vbus_valid)

did not properly reflect the intended relationship between IDDIG and
VBUSVALID signals.

Update the logic to:

    return vbus_valid ? device : !device;

This ensures that when VBUS is valid, the role follows the IDDIG value,
and when VBUS is not valid, the role is inverted, matching the expected
OTG behavior.

Fixes: b725741f1c21 ("phy: renesas: rcar-gen3-usb2: Add support for RZ/T2H SoC")
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
---
 drivers/phy/renesas/phy-rcar-gen3-usb2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index 7b4a6e8b7508..70498145f0f3 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -302,7 +302,7 @@ static bool rcar_gen3_check_id(struct rcar_gen3_chan *ch)
 		device = !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG);
 		vbus_valid = !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_VBUSVALID);
 
-		return !(device && !vbus_valid);
+		return vbus_valid ? device : !device;
 	}
 
 	if (!ch->uses_otg_pins)
-- 
2.51.0



From quic_nitirawa at quicinc.com  Thu Aug 21 09:02:35 2025
From: quic_nitirawa at quicinc.com (Nitin Rawat)
Date: Thu, 21 Aug 2025 21:32:35 +0530
Subject: [PATCH V3 2/2] phy: qcom-qmp-ufs: Add regulator loads for SM8650
 and SM8750
In-Reply-To: <ukxv7donvkulgci2dwrokuflzxzeyh4kohoyja2vywropntxnb@qepcssbe4wpc>
References: <20250819222832.8471-1-quic_nitirawa@quicinc.com>
 <20250819222832.8471-3-quic_nitirawa@quicinc.com>
 <ger4kizeltjwalfuwu4dpfjiskrv2okgo5c7d6n3pb24yaxgfo@nkcndblyx3il>
 <b453b8ff-a460-4ccd-9019-aed746a7d52d@quicinc.com>
 <ukxv7donvkulgci2dwrokuflzxzeyh4kohoyja2vywropntxnb@qepcssbe4wpc>
Message-ID: <9a38ec05-f7ab-4241-ba47-0d514b79e808@quicinc.com>



On 8/20/2025 5:24 PM, Dmitry Baryshkov wrote:
> On Wed, Aug 20, 2025 at 12:07:57PM +0530, Nitin Rawat wrote:
>>
>>
>> On 8/20/2025 6:19 AM, Dmitry Baryshkov wrote:
>>> On Wed, Aug 20, 2025 at 03:58:26AM +0530, Nitin Rawat wrote:
>>>> Add regulator load voting support for SM8650 and SM8750 platforms by
>>>> introducing dedicated regulator bulk data arrays with their load
>>>> values.
>>>>
>>>> The load requirements are:
>>>> - SM8650: vdda-phy (205mA), vdda-pll (17.5mA)
>>>> - SM8750: vdda-phy (213mA), vdda-pll (18.3mA)
>>>>
>>>> This ensures stable operation and proper power management for these
>>>> platforms where regulators are shared between the QMP USB PHY and
>>>> other IP blocks by setting appropriate regulator load currents during PHY
>>>> operations.
>>>>
>>>> Configurations without specific load requirements will continue to work
>>>> unchanged, as init_load_uA remains zero-initialized when .init_load_uA
>>>> is not provided.
>>>
>>> Can we please get configuration for the rest of the platforms?
>>
>> Hi Dmitry,
>>
>> If you're okay with it, can I merge the configuration for the remaining
>> platforms in the next patch series after I complete testing on all remaining
>> platforms.
> 
> You don't need to test, finding MSM8996 or 98 might be troublesome. Just
> fill in the values from the hardware documentation.

Hi Dmitry,

While implementing changes for all remaining platform, I noticed that 
the "regulator-allow-set-load" property is defined only for SM8750 and 
SM8850 within the PMIC PHY and PLL device tree nodes which means that 
even if the UFS PHY driver is updated to vote for this configuration on 
other platforms, it will have no impact.

Should I still proceed with applying the change across all platform, or 
limit it to just the SM8750 and SM8850 drivers? What?s your recommendation?

===========================================================================
// Device tree:
vreg_l1j_0p91: ldo1 {
     regulator-name = "vreg_l1j_0p91";
     regulator-min-microvolt = <880000>;
     regulator-max-microvolt = <920000>;
     regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
     regulator-allow-set-load;
     regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM 
RPMH_REGULATOR_MODE_HPM>;
};

===========================================================================
drivers/regulator/of_regulator.c


if (of_property_read_bool(np, "regulator-allow-set-load"))
		constraints->valid_ops_mask |= REGULATOR_CHANGE_DRMS;

===========================================================================
//drivers/regulator/core.c
static int drms_uA_update(struct regulator_dev *rdev)
{
     ...
     if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_DRMS)) {
         rdev_dbg(rdev, "DRMS operation not allowed\n");
         return 0;
     }
     ...
}


Regards,
Nitin




> 



From j at jannau.net  Thu Aug 21 09:33:20 2025
From: j at jannau.net (Janne Grunau)
Date: Thu, 21 Aug 2025 18:33:20 +0200
Subject: [PATCH RFC 03/22] dt-bindings: phy: Add Apple Type-C PHY
In-Reply-To: <20250821-atcphy-6-17-v1-3-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
 <20250821-atcphy-6-17-v1-3-172beda182b8@kernel.org>
Message-ID: <20250821163320.GE1270980@robin.jannau.net>

On Thu, Aug 21, 2025 at 03:38:55PM +0000, Sven Peter wrote:
> Apple's Type-C PHY (ATCPHY) is a PHY for USB 2.0, USB 3.x,
> USB4/Thunderbolt, and DisplayPort connectivity found in Apple Silicon
> SoCs.
> 
> The PHY handles muxing between these different protocols and also provides
> the reset controller for the attached dwc3 USB controller.
> 
> Signed-off-by: Sven Peter <sven at kernel.org>
> ---
>  .../devicetree/bindings/phy/apple,atcphy.yaml      | 210 +++++++++++++++++++++
>  MAINTAINERS                                        |   1 +
>  2 files changed, 211 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/phy/apple,atcphy.yaml b/Documentation/devicetree/bindings/phy/apple,atcphy.yaml
> new file mode 100644
> index 0000000000000000000000000000000000000000..eb14010557c94f313b54b528e2d4039fe540062a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/apple,atcphy.yaml
> @@ -0,0 +1,210 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/phy/apple,atcphy.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Apple Type-C PHY (ATCPHY)
> +
> +maintainers:
> +  - Sven Peter <sven at kernel.org>
> +
> +description:
> +  The Apple Type-C PHY (ATCPHY) is a PHY for USB 2.0, USB 3.x,
> +  USB4/Thunderbolt, and DisplayPort connectivity found in Apple Silicon SoCs.
> +
> +  The PHY handles muxing between these different protocols and also provides the
> +  reset controller for the attached dwc3 USB controller.
> +
> +  The PHY is designed for USB4 operation and does not handle individual
> +  differential pairs as distinct DisplayPort lanes. Any reference to lane in
> +  this binding hence refers to two differential pairs (RX and TX) as used in USB
> +  terminology.
> +
> +properties:
> +  compatible:
> +    enum:
> +      - apple,t6000-atcphy
> +      - apple,t6000-atcphy-dp-only # PHY hardwired to DP-to-HDMI converter on M2 Pro MacBook

The comment is misleading, "t6000-atcphy-dp-only" would be for M1
Pro/Max Macbooks. M2 Pro/Max Macbooks use the same design so the
corresponding "apple,t6020-atcphy-dp-only" compatible is missing.
I'm not sure this is the correct design though as the HW block is
identical to "apple,t6000-atcphy".
I think it might be better to have either the DRM KMS driver or a
custom DP->HDMI drm_bridge switch the mode to DP-only.
Or atcphy could initialize itself to DP-only based on the available
ports.

> +      - apple,t6020-atcphy
> +      - apple,t8103-atcphy
> +      - apple,t8112-atcphy
> +
> +  reg:
> +    minItems: 5
> +    maxItems: 5
> +
> +  reg-names:
> +    items:
> +      - const: core
> +      - const: lpdptx
> +      - const: axi2af
> +      - const: usb2phy
> +      - const: pipehandler
> +
> +  "#phy-cells":
> +    const: 1
> +
> +  "#reset-cells":
> +    const: 0
> +
> +  orientation-switch:
> +    type: boolean
> +    description:
> +      The PHY handles swapping lanes if the Type-C connector is flipped.
> +
> +  mode-switch:
> +    type: boolean
> +    description:
> +      The PHY handles muxing between USB 2.0, USB 3.x, USB4/Thunderbolt, and DisplayPort.

These two properties could be referenced from
/schemas/usb/usb-switch.yaml, see
https://lore.kernel.org/linux-devicetree/20250807-topic-4ln_dp_respin-v4-1-43272d6eca92 at oss.qualcomm.com/

> +  power-domains:
> +    minItems: 1
> +    maxItems: 1
> +
> +  ports:
> +    $ref: /schemas/graph.yaml#/properties/ports
> +    properties:
> +      port at 0:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description: Output endpoint of the PHY to the Type-C connector

Not sure if it's justified to mention the hardwired DP->HDMI converter
in 14-/16-inch Macbooks Pro here as well.

> +      port at 1:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description: Incoming endpoint from the USB3 controller
> +
> +      port at 2:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description: Incoming endpoint from the DisplayPort controller
> +
> +      port at 3:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description: Incoming endpoint from the USB4/Thunderbolt controller
> +
> +  apple,tunable-axi2af:
> +    $ref: /schemas/types.yaml#/definitions/uint32-array
> +    description:
> +      AXI2AF tunables.
> +
> +      This array is filled with 3-tuples each containing three 32-bit values
> +      <register offset>, <mask>, and <value> by the bootloader.
> +      The driver will use these to configure the PHY by reading from each
> +      register, ANDing it with <mask>, ORing it with <value>, and storing the
> +      result back to the register.
> +      These values slightly differ even between different chips of the same
> +      generation and are likely calibration values determined by Apple at
> +      manufacturing time.
> +
> +  apple,tunable-common:
> +    $ref: /schemas/types.yaml#/definitions/uint32-array
> +    description:
> +      Common tunables required for all modes, see apple,tunable-axi2af for details.
> +
> +  apple,tunable-fuses:
> +    $ref: /schemas/types.yaml#/definitions/uint32-array
> +    description:
> +      Fuse based tunables required for all modes, see apple,tunable-axi2af for details.
> +
> +  apple,tunable-lane0-usb:
> +    $ref: /schemas/types.yaml#/definitions/uint32-array
> +    description:
> +      USB tunables on lane 0, see apple,tunable-axi2af for details.
> +
> +  apple,tunable-lane1-usb:
> +    $ref: /schemas/types.yaml#/definitions/uint32-array
> +    description:
> +      USB tunables on lane 1, see apple,tunable-axi2af for details.
> +
> +  apple,tunable-lane0-cio:
> +    $ref: /schemas/types.yaml#/definitions/uint32-array
> +    description:
> +      USB4/Thunderbolt ("converged IO") tunables on lane 0, see apple,tunable-axi2af for details.
> +
> +  apple,tunable-lane1-cio:
> +    $ref: /schemas/types.yaml#/definitions/uint32-array
> +    description:
> +      USB4/Thunderbolt ("converged IO") tunables on lane 1, see apple,tunable-axi2af for details.
> +
> +  apple,tunable-lane0-dp:
> +    $ref: /schemas/types.yaml#/definitions/uint32-array
> +    description:
> +      DisplayPort tunables on lane 0, see apple,tunable-axi2af for details.
> +
> +      Note that lane here refers to a USB RX and TX pair re-used for DisplayPort
> +      and not to an individual DisplayPort differential lane.
> +
> +  apple,tunable-lane1-dp:
> +    $ref: /schemas/types.yaml#/definitions/uint32-array
> +    description:
> +      DisplayPort tunables on lane 1, see apple,tunable-axi2af for details.
> +
> +      Note that lane here refers to a USB RX and TX pair re-used for DisplayPort
> +      and not to an individual DisplayPort differential lane.
> +
> +required:
> +  - compatible
> +  - reg
> +  - reg-names
> +  - "#phy-cells"
> +  - "#reset-cells"
> +  - orientation-switch
> +  - mode-switch

any reason not to require "ports"? This would be carried over from
usb-switch

Janne


From j at jannau.net  Thu Aug 21 09:46:10 2025
From: j at jannau.net (Janne Grunau)
Date: Thu, 21 Aug 2025 18:46:10 +0200
Subject: [PATCH RFC 13/22] usb: typec: tipd: Read USB4, Thunderbolt and
 DisplayPort status for cd321x
In-Reply-To: <20250821-atcphy-6-17-v1-13-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
 <20250821-atcphy-6-17-v1-13-172beda182b8@kernel.org>
Message-ID: <20250821164610.GF1270980@robin.jannau.net>

On Thu, Aug 21, 2025 at 03:39:05PM +0000, Sven Peter wrote:
> CD321x supports various alternate modes and stores information once
> these are entered into separate status registers. Read those when they
> are active when reading TPS_DATA_STATUS to prepare supporting these.
> 
> Signed-off-by: Sven Peter <sven at kernel.org>
> ---
>  drivers/usb/typec/tipd/core.c | 81 ++++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 77 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c
> index 51b0f3be8b66a743ddc3ea96c1b25f597a1e8f6c..59d270eb50ea3dc49ad32ff71f8354e23c1083c9 100644
> --- a/drivers/usb/typec/tipd/core.c
> +++ b/drivers/usb/typec/tipd/core.c
> @@ -35,14 +35,19 @@
>  #define TPS_REG_INT_MASK2		0x17
>  #define TPS_REG_INT_CLEAR1		0x18
>  #define TPS_REG_INT_CLEAR2		0x19
> -#define TPS_REG_SYSTEM_POWER_STATE	0x20
>  #define TPS_REG_STATUS			0x1a
> +#define TPS_REG_SYSTEM_POWER_STATE	0x20
> +#define TPS_REG_USB4_STATUS		0x24
> +#define TPS_REG_DP_SID_STATUS		0x58

TPS_REG_DP_SID_STATUS is added twice, below in the correct order

>  #define TPS_REG_SYSTEM_CONF		0x28
>  #define TPS_REG_CTRL_CONF		0x29
>  #define TPS_REG_BOOT_STATUS		0x2D
>  #define TPS_REG_POWER_STATUS		0x3f
>  #define TPS_REG_PD_STATUS		0x40
>  #define TPS_REG_RX_IDENTITY_SOP		0x48
> +#define TPS_REG_CF_VID_STATUS		0x5e
> +#define TPS_REG_DP_SID_STATUS		0x58

here

Janne


From quic_nitirawa at quicinc.com  Thu Aug 21 12:39:30 2025
From: quic_nitirawa at quicinc.com (Nitin Rawat)
Date: Fri, 22 Aug 2025 01:09:30 +0530
Subject: [PATCH V3 2/2] phy: qcom-qmp-ufs: Add regulator loads for SM8650
 and SM8750
In-Reply-To: <9a38ec05-f7ab-4241-ba47-0d514b79e808@quicinc.com>
References: <20250819222832.8471-1-quic_nitirawa@quicinc.com>
 <20250819222832.8471-3-quic_nitirawa@quicinc.com>
 <ger4kizeltjwalfuwu4dpfjiskrv2okgo5c7d6n3pb24yaxgfo@nkcndblyx3il>
 <b453b8ff-a460-4ccd-9019-aed746a7d52d@quicinc.com>
 <ukxv7donvkulgci2dwrokuflzxzeyh4kohoyja2vywropntxnb@qepcssbe4wpc>
 <9a38ec05-f7ab-4241-ba47-0d514b79e808@quicinc.com>
Message-ID: <f0de58d4-3b2b-4e8d-90cf-fc6ef37dc88c@quicinc.com>



On 8/21/2025 9:32 PM, Nitin Rawat wrote:
> 
> 
> On 8/20/2025 5:24 PM, Dmitry Baryshkov wrote:
>> On Wed, Aug 20, 2025 at 12:07:57PM +0530, Nitin Rawat wrote:
>>>
>>>
>>> On 8/20/2025 6:19 AM, Dmitry Baryshkov wrote:
>>>> On Wed, Aug 20, 2025 at 03:58:26AM +0530, Nitin Rawat wrote:
>>>>> Add regulator load voting support for SM8650 and SM8750 platforms by
>>>>> introducing dedicated regulator bulk data arrays with their load
>>>>> values.
>>>>>
>>>>> The load requirements are:
>>>>> - SM8650: vdda-phy (205mA), vdda-pll (17.5mA)
>>>>> - SM8750: vdda-phy (213mA), vdda-pll (18.3mA)
>>>>>
>>>>> This ensures stable operation and proper power management for these
>>>>> platforms where regulators are shared between the QMP USB PHY and
>>>>> other IP blocks by setting appropriate regulator load currents 
>>>>> during PHY
>>>>> operations.
>>>>>
>>>>> Configurations without specific load requirements will continue to 
>>>>> work
>>>>> unchanged, as init_load_uA remains zero-initialized when .init_load_uA
>>>>> is not provided.
>>>>
>>>> Can we please get configuration for the rest of the platforms?
>>>
>>> Hi Dmitry,
>>>
>>> If you're okay with it, can I merge the configuration for the remaining
>>> platforms in the next patch series after I complete testing on all 
>>> remaining
>>> platforms.
>>
>> You don't need to test, finding MSM8996 or 98 might be troublesome. Just
>> fill in the values from the hardware documentation.
> 
> Hi Dmitry,
> 
> While implementing changes for all remaining platform, I noticed that 
> the "regulator-allow-set-load" property is defined only for SM8750 and 
> SM8850 within the PMIC PHY and PLL device tree nodes which means that 
> even if the UFS PHY driver is updated to vote for this configuration on 
> other platforms, it will have no impact.
> 
> Should I still proceed with applying the change across all platform, or 
> limit it to just the SM8750 and *SM8850* drivers? What?s your recommendation?

Sorry for the typo. It's SM8650 and SM8750.

> 
> ===========================================================================
> // Device tree:
> vreg_l1j_0p91: ldo1 {
>  ??? regulator-name = "vreg_l1j_0p91";
>  ??? regulator-min-microvolt = <880000>;
>  ??? regulator-max-microvolt = <920000>;
>  ??? regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
>  ??? regulator-allow-set-load;
>  ??? regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM 
> RPMH_REGULATOR_MODE_HPM>;
> };
> 
> ===========================================================================
> drivers/regulator/of_regulator.c
> 
> 
> if (of_property_read_bool(np, "regulator-allow-set-load"))
>  ??????? constraints->valid_ops_mask |= REGULATOR_CHANGE_DRMS;
> 
> ===========================================================================
> //drivers/regulator/core.c
> static int drms_uA_update(struct regulator_dev *rdev)
> {
>  ??? ...
>  ??? if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_DRMS)) {
>  ??????? rdev_dbg(rdev, "DRMS operation not allowed\n");
>  ??????? return 0;
>  ??? }
>  ??? ...
> }
> 
> 
> Regards,
> Nitin
> 
> 
> 
> 
>>
> 



From robh at kernel.org  Thu Aug 21 12:48:27 2025
From: robh at kernel.org (Rob Herring (Arm))
Date: Thu, 21 Aug 2025 14:48:27 -0500
Subject: [PATCH v2 1/4] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy:
 Document the Glymur QMP PCIe PHY
In-Reply-To: <20250821-glymur_pcie5-v2-1-cd516784ef20@oss.qualcomm.com>
References: <20250821-glymur_pcie5-v2-0-cd516784ef20@oss.qualcomm.com>
 <20250821-glymur_pcie5-v2-1-cd516784ef20@oss.qualcomm.com>
Message-ID: <175580569944.470925.12622150205137529754.robh@kernel.org>


On Thu, 21 Aug 2025 02:44:28 -0700, Wenbin Yao wrote:
> From: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
> 
> The fifth PCIe instance on Glymur has a Gen5 4-lane PHY. Document it as a
> separate compatible.
> 
> Signed-off-by: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
> Signed-off-by: Wenbin Yao <wenbin.yao at oss.qualcomm.com>
> ---
>  Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml | 3 +++
>  1 file changed, 3 insertions(+)
> 


Please add Acked-by/Reviewed-by tags when posting new versions. However,
there's no need to repost patches *only* to add the tags. The upstream
maintainer will do that for acks received on the version they apply.

If a tag was not added on purpose, please state why and what changed.

Missing tags:

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





From robh at kernel.org  Thu Aug 21 12:48:42 2025
From: robh at kernel.org (Rob Herring (Arm))
Date: Thu, 21 Aug 2025 14:48:42 -0500
Subject: [PATCH v2 2/4] dt-bindings: PCI: qcom: Document the Glymur PCIe
 Controller
In-Reply-To: <20250821-glymur_pcie5-v2-2-cd516784ef20@oss.qualcomm.com>
References: <20250821-glymur_pcie5-v2-0-cd516784ef20@oss.qualcomm.com>
 <20250821-glymur_pcie5-v2-2-cd516784ef20@oss.qualcomm.com>
Message-ID: <175580571576.471370.10486560769596957109.robh@kernel.org>


On Thu, 21 Aug 2025 02:44:29 -0700, Wenbin Yao wrote:
> From: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
> 
> On the Qualcomm Glymur platform the PCIe host is compatible with the DWC
> controller present on the X1E80100 platform. So document the PCIe
> controllers found on Glymur and use the X1E80100 compatible string as a
> fallback in the schema.
> 
> Signed-off-by: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
> Signed-off-by: Wenbin Yao <wenbin.yao at oss.qualcomm.com>
> ---
>  Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 


Please add Acked-by/Reviewed-by tags when posting new versions. However,
there's no need to repost patches *only* to add the tags. The upstream
maintainer will do that for acks received on the version they apply.

If a tag was not added on purpose, please state why and what changed.

Missing tags:

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





From Frank.Li at nxp.com  Thu Aug 21 13:15:35 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 21 Aug 2025 16:15:35 -0400
Subject: [PATCH v3 00/31] media: add imx93 mipi/controller csi support
Message-ID: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>

Totally rewrite CSI part driver compared to V1.

This only includes CSI related patches.

DTS part: see https://lore.kernel.org/imx/20250701-95_cam-v1-6-c5172bab387b at nxp.com/
PHY part: see https://lore.kernel.org/imx/20250701-95_cam-v1-4-c5172bab387b at nxp.com/
AP1302 part: see https://lore.kernel.org/imx/20250701-95_cam-v1-7-c5172bab387b at nxp.com/
	upstream: https://lore.kernel.org/imx/20250623-ap1302-v3-0-c9ca5b791494 at nxp.com/

First 3 patches add some common helper function to simple code and remove
duplicated code in difference CSI2 drivers.

Clean up stage imx6 old version csi2 driver, and prepare create common
dw csi2 library for difference IP version.

Move stage driver under driver/media/synosis.

Create simple platform driver for common dw csi2 use case.

TODO:
	1. create bus, to probe phy driver under "test_if" interface for
specific phys under CSI2.
	2. support to combine phy, (which connect to both dw CSI and DSI's
test_if). Need use DSI's test_if to config combo phy to switch to RX mode.
and also need config RX part's phy register by use CSI's testif.
	3. move other vendor's csi driver to use this common DWC CSI
library.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Changes in v3:
- update binding doc
- combine two add helper function's patch to one. and use media_bus_fmt_info
data structure.
- Link to v2: https://lore.kernel.org/r/20250808-95_cam-v2-0-4b29fa6919a7 at nxp.com

Changes in v2:
- totally rewrite, see above section
- Link to v1: https://lore.kernel.org/r/20250701-95_cam-v1-0-c5172bab387b at nxp.com

---
Eugen Hristev (1):
      dt-bindings: media: add DW MIPI CSI-2 Host support

Frank Li (30):
      media: v4l2-common: Add helper function v4l_get_required_align_by_bpp()
      media: v4l2-common: Add helper function media_bus_fmt_to_csi2_(bpp|dt)()
      media: staging: media: imx6-mipi-csi2: replace space with tab for alignment
      media: staging: media: imx6-mipi-csi2: use devm_add_action_or_reset() to simplify code
      media: staging: media: imx6-mipi-csi2: use devm_clk_bulk_get_all() to fetch clocks
      media: staging: media: imx6-mipi-csi2: use devm_mutex_init() to simplify code
      media: staging: media: imx6-mipi-csi2: use guard() to simplify code
      media: staging: media: imx6-mipi-csi2: use register structure to match hardware
      media: staging: media: imx6-mipi-csi2: use devm_platform_ioremap_resource() simplify code
      media: staging: media: imx6-mipi-csi2: move probe part to imx6-csi2.c
      media: staging: media: imx6-mipi-csi2: move sd imx6's specific initialization into imx6-sci2.c
      media: staging: media: imx6-mipi-csi2: move csi2ipu_gasket_init() to imx6-csi2.c
      media: staging: media: imx6-mipi-csi2: move number pad macro define into imx6-csi2.c
      media: staging: media: imx6-mipi-csi2: move dphy init part to imx6-csi2.c
      media: staging: media: imx6-mipi-csi2: use runtime_pm frame to control clks
      media: synopsys: move imx6-mipi-csi2.c to synopsys/mipi-csi2.c
      media: synopsys: csi2: Remove deprecated s_stream and use v4l2_subdev_pad_ops
      media: synopsys: csi2: Add phy interface support
      media: synopsys: csi2: Add basic v150* version register
      media: synopsys: csi2: Add irq support to record error count
      media: synopsys: csi2: Handle alignment requirement for width
      media: synopsys: csi2: Add register prefix to register field definitions
      media: synopsys: csi2: Add need_dphy_reset in config
      media: synopsys: csi2: Add default simple dw_csi2_subdev_init_state
      media: synopsys: csi2: Add v150 lane stop state register bit define
      media: synopsys: csi2: use standard v4l2_subdev_get_fmt() function
      media: synopsys: csi2: Add customize get_frame_desc() callback
      media: synopsys: csi2: Add Image Pixel Interface (IPI) support for v150
      media: synopsys: csi2: Remove source pad connected check at dw_csi2_enable_streams()
      media: synopsys: csi2: Add simple synopsys platform driver

 .../bindings/media/snps,dw-mipi-csi2-v150.yaml     |  151 +++
 MAINTAINERS                                        |    1 +
 drivers/media/platform/synopsys/Kconfig            |   20 +
 drivers/media/platform/synopsys/Makefile           |    3 +
 drivers/media/platform/synopsys/mipi-csi2-simple.c |   75 ++
 drivers/media/platform/synopsys/mipi-csi2.c        | 1260 ++++++++++++++++++++
 drivers/media/v4l2-core/v4l2-common.c              |  149 +++
 drivers/staging/media/imx/Kconfig                  |    1 +
 drivers/staging/media/imx/Makefile                 |    2 +-
 drivers/staging/media/imx/imx6-csi2.c              |  181 +++
 drivers/staging/media/imx/imx6-mipi-csi2.c         |  846 -------------
 include/media/dw-mipi-csi2.h                       |  120 ++
 include/media/mipi-csi2.h                          |   30 +
 include/media/v4l2-common.h                        |   30 +
 14 files changed, 2022 insertions(+), 847 deletions(-)
---
base-commit: ad0a162e543964443feec3a6a9395a64fe6c35c9
change-id: 20250606-95_cam-b74c094ad1fb

Best regards,
--
Frank Li <Frank.Li at nxp.com>



From Frank.Li at nxp.com  Thu Aug 21 13:15:36 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 21 Aug 2025 16:15:36 -0400
Subject: [PATCH v3 01/31] dt-bindings: media: add DW MIPI CSI-2 Host
 support
In-Reply-To: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
References: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
Message-ID: <20250821-95_cam-v3-1-c9286fbb34b9@nxp.com>

From: Eugen Hristev <eugen.hristev at linaro.org>

Add bindings for Synopsys DesignWare MIPI CSI-2 host, which used at i.MX93
and i.MX95 platform.

Signed-off-by: Luis Oliveira <lolivei at synopsys.com>
Signed-off-by: Eugen Hristev <eugen.hristev at linaro.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change in v3
- drop remote-endpoint: true
- drop clock-lanes

Change in v2
- remove Eugen Hristev <eugen.hristev at microchip.com> from mantainer.
- update ugen Hristev's s-o-b tag to align original author's email address
- remove single snps,dw-mipi-csi2-v150 compatible string
- move additionalProperties after required
---
 .../bindings/media/snps,dw-mipi-csi2-v150.yaml     | 151 +++++++++++++++++++++
 MAINTAINERS                                        |   1 +
 2 files changed, 152 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/snps,dw-mipi-csi2-v150.yaml b/Documentation/devicetree/bindings/media/snps,dw-mipi-csi2-v150.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..d950daa4ee9cfd504ef84b83271b2a1b710ffd6b
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/snps,dw-mipi-csi2-v150.yaml
@@ -0,0 +1,151 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/snps,dw-mipi-csi2-v150.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Synopsys DesignWare CSI-2 Host controller (csi2host)
+
+maintainers:
+  - Frank Li <Frank.Li at nxp.com>
+
+description:
+  CSI2HOST is used to receive image coming from an MIPI CSI-2 compatible
+  camera. It will convert the incoming CSI-2 stream into a dedicated
+  interface called the Synopsys IDI (Image Data Interface).
+  This interface is a 32-bit SoC internal only, and can be assimilated
+  with a CSI-2 interface.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - fsl,imx93-mipi-csi2
+      - const: snps,dw-mipi-csi2-v150
+
+  reg:
+    items:
+      - description: MIPI CSI-2 core register
+
+  reg-names:
+    items:
+      - const: core
+
+  clocks:
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: per
+      - const: pixel
+
+  phys:
+    maxItems: 1
+    description: MIPI D-PHY
+
+  phy-names:
+    items:
+      - const: rx
+
+  resets:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port at 0:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description:
+          Input port node, single endpoint describing the input port.
+
+        properties:
+          endpoint:
+            $ref: video-interfaces.yaml#
+            unevaluatedProperties: false
+            description: Endpoint connected to input device
+
+            properties:
+              bus-type:
+                const: 4
+
+              data-lanes:
+                minItems: 1
+                maxItems: 4
+                items:
+                  maximum: 4
+
+      port at 1:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description:
+          Output port node, single endpoint describing the output port.
+
+        properties:
+          endpoint:
+            unevaluatedProperties: false
+            $ref: video-interfaces.yaml#
+            description: Endpoint connected to output device
+
+            properties:
+              bus-type:
+                const: 4
+
+    required:
+      - port at 0
+      - port at 1
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - interrupts
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+    csi at 3000 {
+        compatible = "fsl,imx93-mipi-csi2", "snps,dw-mipi-csi2-v150";
+        reg = <0x03000 0x1000>;
+        reg-names = "core";
+        phys = <&mipi_dphy_rx 0>;
+        phy-names = "rx";
+        resets = <&dw_rst 1>;
+        interrupts = <2>;
+
+        ports {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            port at 0 {
+                reg = <0>;
+
+                endpoint {
+                    bus-type = <4>; /* MIPI CSI2 D-PHY */
+                    remote-endpoint = <&camera_1>;
+                    data-lanes = <1 2>;
+                    clock-lanes = <0>;
+                };
+            };
+
+            port at 1 {
+                reg = <1>;
+
+                endpoint {
+                    remote-endpoint = <&idi_receiver>;
+                    bus-type = <4>;
+                };
+            };
+        };
+    };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 9d9d2be7be8037dfa96f1c9edd24a0cf997b9393..ecb7bc7cc8ad797f43173075ca8973804bf335f7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15334,6 +15334,7 @@ F:	Documentation/devicetree/bindings/media/fsl,imx93-parallel-csi.yaml
 F:	Documentation/devicetree/bindings/media/nxp,imx-mipi-csi2.yaml
 F:	Documentation/devicetree/bindings/media/nxp,imx7-csi.yaml
 F:	Documentation/devicetree/bindings/media/nxp,imx8mq-mipi-csi2.yaml
+F:	Documentation/devicetree/bindings/media/snps,dw-mipi-csi2-v150.yaml
 F:	drivers/media/platform/nxp/imx-mipi-csis.c
 F:	drivers/media/platform/nxp/imx-parallel-csi.c
 F:	drivers/media/platform/nxp/imx7-media-csi.c

-- 
2.34.1



From Frank.Li at nxp.com  Thu Aug 21 13:15:37 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 21 Aug 2025 16:15:37 -0400
Subject: [PATCH v3 02/31] media: v4l2-common: Add helper function
 v4l_get_required_align_by_bpp()
In-Reply-To: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
References: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
Message-ID: <20250821-95_cam-v3-2-c9286fbb34b9@nxp.com>

Add helper v4l_get_required_align_by_bpp() to help get width alignment
requirement. Basic replace below logic and enhance to any 2^[0..31] in
drivers/media/platform/nxp/imx-mipi-csis.c

mipi_csis_set_fmt(
{
        ...

        switch (csis_fmt->width % 8) {
        case 0:
                align = 0;
                break;
        case 4:
                align = 1;
                break;
        case 2:
        case 6:
                align = 2;
                break;
        default:
                /* 1, 3, 5, 7 */
                align = 3;
                break;
        }
	...
}

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
The same patch will be see at https://lore.kernel.org/imx/20250729-imx8qxp_pcam-v4-2-4dfca4ed2f87 at nxp.com/
dw csi2 patch also this
---
 include/media/v4l2-common.h | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index 39dd0c78d70f7b935c2e10f9767646d2cedd3079..0a9da5e8daaddf26903d9ff4bed08b283dcd38b2 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -704,4 +704,34 @@ static inline bool v4l2_is_quant_valid(__u8 quantization)
 	       quantization == V4L2_QUANTIZATION_LIM_RANGE;
 }
 
+/**
+ * v4l_get_required_align_by_bpp - get align requirement for
+ *	v4l_bound_align_image(). (bpp * width) % (1 << align) have to be 0.
+ *	given number bpp, get width's alignment requirement. For example,
+ *	if align is 3, means require bpp * width must be multiples of 8.
+ *	    bpp     return  width's requirememnt
+ *	    0       0       none
+ *	    1       3       8 (need 3 zero bits)
+ *	    2       2       4
+ *	    3       3       8
+ *	    4       1       2
+ *	    5       3       8
+ *	    6       2       4
+ *	    7       3       8
+ * @bpp: input bpp
+ * @align: expected alignment, 2^(align).
+ *
+ * return: required alignment.
+ */
+static inline u32 v4l_get_required_align_by_bpp(u32 bpp, u32 align)
+{
+	int pos;
+
+	if (bpp == 0)
+		return 0;
+
+	pos = ffs(bpp) - 1;
+	return pos > align ? 0 : align - pos;
+}
+
 #endif /* V4L2_COMMON_H_ */

-- 
2.34.1



From Frank.Li at nxp.com  Thu Aug 21 13:15:38 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 21 Aug 2025 16:15:38 -0400
Subject: [PATCH v3 03/31] media: v4l2-common: Add helper function
 media_bus_fmt_to_csi2_(bpp|dt)()
In-Reply-To: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
References: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
Message-ID: <20250821-95_cam-v3-3-c9286fbb34b9@nxp.com>

Add helper function media_bus_fmt_to_csi2_bpp() to get media bus fmt's bpp
to reduce codes such as

	static const struct imx7_csi_pixfmt pixel_formats[] = {
        {
                .fourcc = V4L2_PIX_FMT_UYVY,
                .codes  = IMX_BUS_FMTS(
                        MEDIA_BUS_FMT_UYVY8_2X8,
                        MEDIA_BUS_FMT_UYVY8_1X16
                ),
                .yuv    = true,
                .bpp    = 16,
        },
	....

.bpp can be removed from pixel_formats with this helper function.

CSI2 data type is defined by MIPI Camera Serial Interface 2 Spec Ver4.1.
See section 9.4.

Add helper function media_bus_fmt_to_csi2_dt() to convert media bus fmt to
MIPI defined data type and avoid below duplicated static array in each CSI2
drivers.

	{
		.code = MEDIA_BUS_FMT_UYVY8_1X16,
		.data_type = MIPI_CSI2_DT_YUV422_8B,
	}

Only add known map for dt type. Need update media_bus_fmt_info when new
mapping used.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Change in v3:
- squash two help function patch to one.
- use media_bus_fmt_info to do map.
---
 drivers/media/v4l2-core/v4l2-common.c | 149 ++++++++++++++++++++++++++++++++++
 include/media/mipi-csi2.h             |  30 +++++++
 2 files changed, 179 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
index a5334aa35992e5f57fb228c33d40c51fdafdc135..a75987aa5fc69d6368709b7d521bede666da9513 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -46,6 +46,7 @@
 #include <linux/uaccess.h>
 #include <asm/io.h>
 #include <asm/div64.h>
+#include <media/mipi-csi2.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ctrls.h>
@@ -757,3 +758,151 @@ struct clk *devm_v4l2_sensor_clk_get(struct device *dev, const char *id)
 	return clk_hw->clk;
 }
 EXPORT_SYMBOL_GPL(devm_v4l2_sensor_clk_get);
+
+static const struct media_bus_fmt_info media_bus_fmt_info[] = {
+	{ .fmt = MEDIA_BUS_FMT_RGB444_1X12, .bpp = 12},
+	{ .fmt = MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE, .bpp = 16},
+	{ .fmt = MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE, .bpp = 16},
+	{ .fmt = MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, .bpp = 16},
+	{ .fmt = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, .bpp = 16},
+	{ .fmt = MEDIA_BUS_FMT_RGB565_1X16, .dt = MIPI_CSI2_DT_RGB565, .bpp = 16},
+	{ .fmt = MEDIA_BUS_FMT_BGR565_2X8_BE, .dt = MIPI_CSI2_DT_RGB565, .bpp = 16},
+	{ .fmt = MEDIA_BUS_FMT_BGR565_2X8_LE, .dt = MIPI_CSI2_DT_RGB565, .bpp = 16},
+	{ .fmt = MEDIA_BUS_FMT_RGB565_2X8_BE, .dt = MIPI_CSI2_DT_RGB565, .bpp = 16},
+	{ .fmt = MEDIA_BUS_FMT_RGB565_2X8_LE, .dt = MIPI_CSI2_DT_RGB565, .bpp = 16},
+	{ .fmt = MEDIA_BUS_FMT_RGB666_1X18, .bpp = 18},
+	{ .fmt = MEDIA_BUS_FMT_RGB666_2X9_BE, .bpp = 18},
+	{ .fmt = MEDIA_BUS_FMT_BGR666_1X18, .bpp = 18},
+	{ .fmt = MEDIA_BUS_FMT_RBG888_1X24, .dt = MIPI_CSI2_DT_RGB888, .bpp = 24},
+	{ .fmt = MEDIA_BUS_FMT_RGB666_1X24_CPADHI, .dt = MIPI_CSI2_DT_RGB888, .bpp = 24},
+	{ .fmt = MEDIA_BUS_FMT_BGR666_1X24_CPADHI, .dt = MIPI_CSI2_DT_RGB888, .bpp = 24},
+	{ .fmt = MEDIA_BUS_FMT_RGB565_1X24_CPADHI, .dt = MIPI_CSI2_DT_RGB888, .bpp = 24},
+	{ .fmt = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, .bpp = 21},
+	{ .fmt = MEDIA_BUS_FMT_BGR888_1X24, .dt = MIPI_CSI2_DT_RGB888, .bpp = 24},
+	{ .fmt = MEDIA_BUS_FMT_BGR888_3X8, .dt = MIPI_CSI2_DT_RGB888, .bpp = 24},
+	{ .fmt = MEDIA_BUS_FMT_GBR888_1X24, .dt = MIPI_CSI2_DT_RGB888, .bpp = 24},
+	{ .fmt = MEDIA_BUS_FMT_RGB888_1X24, .dt = MIPI_CSI2_DT_RGB888, .bpp = 24},
+	{ .fmt = MEDIA_BUS_FMT_RGB888_2X12_BE, .bpp = 24},
+	{ .fmt = MEDIA_BUS_FMT_RGB888_2X12_LE, .bpp = 24},
+	{ .fmt = MEDIA_BUS_FMT_RGB888_3X8, .dt = MIPI_CSI2_DT_RGB888, .bpp = 24},
+	{ .fmt = MEDIA_BUS_FMT_RGB888_3X8_DELTA, .bpp = 24},
+	{ .fmt = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, .bpp = 28},
+	{ .fmt = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, .bpp = 28},
+	{ .fmt = MEDIA_BUS_FMT_RGB666_1X30_CPADLO, .bpp = 30},
+	{ .fmt = MEDIA_BUS_FMT_RGB888_1X30_CPADLO, .bpp = 30},
+	{ .fmt = MEDIA_BUS_FMT_ARGB8888_1X32, .bpp = 32},
+	{ .fmt = MEDIA_BUS_FMT_RGB888_1X32_PADHI, .bpp = 32},
+	{ .fmt = MEDIA_BUS_FMT_RGB101010_1X30, .bpp = 30},
+	{ .fmt = MEDIA_BUS_FMT_RGB101010_1X7X5_SPWG, .bpp = 35},
+	{ .fmt = MEDIA_BUS_FMT_RGB101010_1X7X5_JEIDA, .bpp = 35},
+	{ .fmt = MEDIA_BUS_FMT_RGB666_1X36_CPADLO, .bpp = 36},
+	{ .fmt = MEDIA_BUS_FMT_RGB888_1X36_CPADLO, .bpp = 36},
+	{ .fmt = MEDIA_BUS_FMT_RGB121212_1X36, .bpp = 36},
+	{ .fmt = MEDIA_BUS_FMT_RGB161616_1X48, .bpp = 48},
+
+	{ .fmt = MEDIA_BUS_FMT_Y8_1X8, .dt = MIPI_CSI2_DT_RAW8, .bpp = 8},
+	{ .fmt = MEDIA_BUS_FMT_UV8_1X8, .bpp = 8},
+	{ .fmt = MEDIA_BUS_FMT_UYVY8_1_5X8, .bpp = 40},
+	{ .fmt = MEDIA_BUS_FMT_VYUY8_1_5X8, .bpp = 40},
+	{ .fmt = MEDIA_BUS_FMT_YUYV8_1_5X8, .bpp = 40},
+	{ .fmt = MEDIA_BUS_FMT_YVYU8_1_5X8, .bpp = 40},
+	{ .fmt = MEDIA_BUS_FMT_UYVY8_2X8, .dt = MIPI_CSI2_DT_YUV422_8B, .bpp = 16},
+	{ .fmt = MEDIA_BUS_FMT_VYUY8_2X8, .dt = MIPI_CSI2_DT_YUV422_8B, .bpp = 16},
+	{ .fmt = MEDIA_BUS_FMT_YUYV8_2X8, .dt = MIPI_CSI2_DT_YUV422_8B, .bpp = 16},
+	{ .fmt = MEDIA_BUS_FMT_YVYU8_2X8, .dt = MIPI_CSI2_DT_YUV422_8B, .bpp = 16},
+	{ .fmt = MEDIA_BUS_FMT_Y10_1X10, .dt = MIPI_CSI2_DT_RAW10, .bpp = 10},
+	{ .fmt = MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, .bpp = 16},
+	{ .fmt = MEDIA_BUS_FMT_UYVY10_2X10, .dt = MIPI_CSI2_DT_YUV422_10B, .bpp = 20},
+	{ .fmt = MEDIA_BUS_FMT_VYUY10_2X10, .dt = MIPI_CSI2_DT_YUV422_10B, .bpp = 20},
+	{ .fmt = MEDIA_BUS_FMT_YUYV10_2X10, .dt = MIPI_CSI2_DT_YUV422_10B, .bpp = 20},
+	{ .fmt = MEDIA_BUS_FMT_YVYU10_2X10, .dt = MIPI_CSI2_DT_YUV422_10B, .bpp = 20},
+	{ .fmt = MEDIA_BUS_FMT_Y12_1X12, .dt = MIPI_CSI2_DT_RAW12, .bpp = 12},
+	{ .fmt = MEDIA_BUS_FMT_UYVY12_2X12, .bpp = 24},
+	{ .fmt = MEDIA_BUS_FMT_VYUY12_2X12, .bpp = 24},
+	{ .fmt = MEDIA_BUS_FMT_YUYV12_2X12, .bpp = 24},
+	{ .fmt = MEDIA_BUS_FMT_YVYU12_2X12, .bpp = 24},
+	{ .fmt = MEDIA_BUS_FMT_Y14_1X14, .dt = MIPI_CSI2_DT_RAW14, .bpp = 14},
+	{ .fmt = MEDIA_BUS_FMT_Y16_1X16, .dt = MIPI_CSI2_DT_RAW16, .bpp = 16},
+	{ .fmt = MEDIA_BUS_FMT_UYVY8_1X16, .dt = MIPI_CSI2_DT_YUV422_8B, .bpp = 16},
+	{ .fmt = MEDIA_BUS_FMT_VYUY8_1X16, .dt = MIPI_CSI2_DT_YUV422_8B, .bpp = 16},
+	{ .fmt = MEDIA_BUS_FMT_YUYV8_1X16, .dt = MIPI_CSI2_DT_YUV422_8B, .bpp = 16},
+	{ .fmt = MEDIA_BUS_FMT_YVYU8_1X16, .dt = MIPI_CSI2_DT_YUV422_8B, .bpp = 16},
+	{ .fmt = MEDIA_BUS_FMT_YDYUYDYV8_1X16, .bpp = 16},
+	{ .fmt = MEDIA_BUS_FMT_UYVY10_1X20, .dt = MIPI_CSI2_DT_YUV422_10B, .bpp = 20},
+	{ .fmt = MEDIA_BUS_FMT_VYUY10_1X20, .dt = MIPI_CSI2_DT_YUV422_10B, .bpp = 20},
+	{ .fmt = MEDIA_BUS_FMT_YUYV10_1X20, .dt = MIPI_CSI2_DT_YUV422_10B, .bpp = 20},
+	{ .fmt = MEDIA_BUS_FMT_YVYU10_1X20, .dt = MIPI_CSI2_DT_YUV422_10B, .bpp = 20},
+	{ .fmt = MEDIA_BUS_FMT_VUY8_1X24, .bpp = 24},
+	{ .fmt = MEDIA_BUS_FMT_YUV8_1X24, .bpp = 24},
+	{ .fmt = MEDIA_BUS_FMT_UYYVYY8_0_5X24, .dt = MIPI_CSI2_DT_YUV420_8B, .bpp = 120},
+	{ .fmt = MEDIA_BUS_FMT_UYVY12_1X24, .bpp = 24},
+	{ .fmt = MEDIA_BUS_FMT_VYUY12_1X24, .bpp = 24},
+	{ .fmt = MEDIA_BUS_FMT_YUYV12_1X24, .bpp = 24},
+	{ .fmt = MEDIA_BUS_FMT_YVYU12_1X24, .bpp = 24},
+	{ .fmt = MEDIA_BUS_FMT_YUV10_1X30, .bpp = 30},
+	{ .fmt = MEDIA_BUS_FMT_UYYVYY10_0_5X30, .bpp = 150},
+	{ .fmt = MEDIA_BUS_FMT_AYUV8_1X32, .bpp = 32},
+	{ .fmt = MEDIA_BUS_FMT_UYYVYY12_0_5X36, .bpp = 180},
+	{ .fmt = MEDIA_BUS_FMT_YUV12_1X36, .bpp = 36},
+	{ .fmt = MEDIA_BUS_FMT_YUV16_1X48, .bpp = 48},
+	{ .fmt = MEDIA_BUS_FMT_UYYVYY16_0_5X48, .bpp = 240},
+
+	{ .fmt = MEDIA_BUS_FMT_SBGGR8_1X8, .dt = MIPI_CSI2_DT_RAW8, .bpp = 8},
+	{ .fmt = MEDIA_BUS_FMT_SGBRG8_1X8, .dt = MIPI_CSI2_DT_RAW8, .bpp = 8},
+	{ .fmt = MEDIA_BUS_FMT_SGRBG8_1X8, .dt = MIPI_CSI2_DT_RAW8, .bpp = 8},
+	{ .fmt = MEDIA_BUS_FMT_SRGGB8_1X8, .dt = MIPI_CSI2_DT_RAW8, .bpp = 8},
+	{ .fmt = MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8, .bpp = 8},
+	{ .fmt = MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8, .bpp = 8},
+	{ .fmt = MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8, .bpp = 8},
+	{ .fmt = MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8, .bpp = 8},
+	{ .fmt = MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8, .bpp = 8},
+	{ .fmt = MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8, .bpp = 8},
+	{ .fmt = MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, .bpp = 8},
+	{ .fmt = MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8, .bpp = 8},
+	{ .fmt = MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE, .bpp = 16},
+	{ .fmt = MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, .bpp = 16},
+	{ .fmt = MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE, .bpp = 16},
+	{ .fmt = MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE, .bpp = 16},
+	{ .fmt = MEDIA_BUS_FMT_SBGGR10_1X10, .dt = MIPI_CSI2_DT_RAW10, .bpp = 10},
+	{ .fmt = MEDIA_BUS_FMT_SGBRG10_1X10, .dt = MIPI_CSI2_DT_RAW10, .bpp = 10},
+	{ .fmt = MEDIA_BUS_FMT_SGRBG10_1X10, .dt = MIPI_CSI2_DT_RAW10, .bpp = 10},
+	{ .fmt = MEDIA_BUS_FMT_SRGGB10_1X10, .dt = MIPI_CSI2_DT_RAW10, .bpp = 10},
+	{ .fmt = MEDIA_BUS_FMT_SBGGR12_1X12, .dt = MIPI_CSI2_DT_RAW12, .bpp = 12},
+	{ .fmt = MEDIA_BUS_FMT_SGBRG12_1X12, .dt = MIPI_CSI2_DT_RAW12, .bpp = 12},
+	{ .fmt = MEDIA_BUS_FMT_SGRBG12_1X12, .dt = MIPI_CSI2_DT_RAW12, .bpp = 12},
+	{ .fmt = MEDIA_BUS_FMT_SRGGB12_1X12, .dt = MIPI_CSI2_DT_RAW12, .bpp = 12},
+	{ .fmt = MEDIA_BUS_FMT_SBGGR14_1X14, .dt = MIPI_CSI2_DT_RAW14, .bpp = 14},
+	{ .fmt = MEDIA_BUS_FMT_SGBRG14_1X14, .dt = MIPI_CSI2_DT_RAW14, .bpp = 14},
+	{ .fmt = MEDIA_BUS_FMT_SGRBG14_1X14, .dt = MIPI_CSI2_DT_RAW14, .bpp = 14},
+	{ .fmt = MEDIA_BUS_FMT_SRGGB14_1X14, .dt = MIPI_CSI2_DT_RAW14, .bpp = 14},
+	{ .fmt = MEDIA_BUS_FMT_SBGGR16_1X16, .dt = MIPI_CSI2_DT_RAW16, .bpp = 16},
+	{ .fmt = MEDIA_BUS_FMT_SGBRG16_1X16, .dt = MIPI_CSI2_DT_RAW16, .bpp = 16},
+	{ .fmt = MEDIA_BUS_FMT_SGRBG16_1X16, .dt = MIPI_CSI2_DT_RAW16, .bpp = 16},
+	{ .fmt = MEDIA_BUS_FMT_SRGGB16_1X16, .dt = MIPI_CSI2_DT_RAW16, .bpp = 16},
+
+	{ .fmt = MEDIA_BUS_FMT_JPEG_1X8, .bpp = 8},
+
+	{ .fmt = MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8, .bpp = 8},
+
+	{ .fmt = MEDIA_BUS_FMT_AHSV8888_1X32, .bpp = 8},
+
+	{ .fmt = MEDIA_BUS_FMT_META_8, .bpp = 8},
+	{ .fmt = MEDIA_BUS_FMT_META_10, .bpp = 10},
+	{ .fmt = MEDIA_BUS_FMT_META_12, .bpp = 12},
+	{ .fmt = MEDIA_BUS_FMT_META_14, .bpp = 14},
+	{ .fmt = MEDIA_BUS_FMT_META_16, .bpp = 16},
+	{ .fmt = MEDIA_BUS_FMT_META_20, .bpp = 20},
+	{ .fmt = MEDIA_BUS_FMT_META_24, .bpp = 24},
+};
+
+const struct media_bus_fmt_info *media_bus_fmt_info_get(u32 bus_fmt)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(media_bus_fmt_info); i++)
+		if (media_bus_fmt_info[i].fmt == bus_fmt)
+			return &media_bus_fmt_info[i];
+
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(media_bus_fmt_info_get);
diff --git a/include/media/mipi-csi2.h b/include/media/mipi-csi2.h
index 40fc0264250d779ab5dfa7d2fe16e6f1382c07d4..3227d28224b7c32ef2745548391da9e792cfa559 100644
--- a/include/media/mipi-csi2.h
+++ b/include/media/mipi-csi2.h
@@ -8,6 +8,8 @@
 #ifndef _MEDIA_MIPI_CSI2_H
 #define _MEDIA_MIPI_CSI2_H
 
+/* DT value ref to MIPI Camera Serial Interface 2 Spec Ver4.1 section 9.4 */
+
 /* Short packet data types */
 #define MIPI_CSI2_DT_FS			0x00
 #define MIPI_CSI2_DT_FE			0x01
@@ -44,4 +46,32 @@
 #define MIPI_CSI2_DT_RAW20		0x2f
 #define MIPI_CSI2_DT_USER_DEFINED(n)	(0x30 + (n))	/* 0..7 */
 
+/**
+ * struct media_bus_fmt_info - information about a media bus format
+ * @fmt: media bus format identifier (MEDIA_BUS_FMT_*)
+ * @dt: data type define in MIPI spec (MIPI_CSI2_DT *)
+ * @bpp: bit width per pixel
+ */
+struct media_bus_fmt_info {
+	u32 fmt;
+	u32 dt;
+	u8 bpp;
+};
+
+const struct media_bus_fmt_info *media_bus_fmt_info_get(u32 bus_fmt);
+
+static inline int media_bus_fmt_to_csi2_dt(int bus_fmt)
+{
+	const struct media_bus_fmt_info *info = media_bus_fmt_info_get(bus_fmt);
+
+	return info ? info->dt : 0;
+}
+
+static inline int media_bus_fmt_to_csi2_bpp(int bus_fmt)
+{
+	const struct media_bus_fmt_info *info = media_bus_fmt_info_get(bus_fmt);
+
+	return info ? info->bpp : 0;
+}
+
 #endif /* _MEDIA_MIPI_CSI2_H */

-- 
2.34.1



From Frank.Li at nxp.com  Thu Aug 21 13:15:39 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 21 Aug 2025 16:15:39 -0400
Subject: [PATCH v3 04/31] media: staging: media: imx6-mipi-csi2: replace
 space with tab for alignment
In-Reply-To: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
References: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
Message-ID: <20250821-95_cam-v3-4-c9286fbb34b9@nxp.com>

Replace space with tab to follow coding convention. No functional change.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/staging/media/imx/imx6-mipi-csi2.c | 92 +++++++++++++++---------------
 1 file changed, 46 insertions(+), 46 deletions(-)

diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index dd8c7b3233bccfc34b59e0f0ff813b36752e1526..42256441b881d9f132ad7ff899d6f1e35643b4ac 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -23,65 +23,65 @@
  * there must be 5 pads: 1 input pad from sensor, and
  * the 4 virtual channel output pads
  */
-#define CSI2_SINK_PAD       0
-#define CSI2_NUM_SINK_PADS  1
-#define CSI2_NUM_SRC_PADS   4
-#define CSI2_NUM_PADS       5
+#define CSI2_SINK_PAD		0
+#define CSI2_NUM_SINK_PADS	1
+#define CSI2_NUM_SRC_PADS	4
+#define CSI2_NUM_PADS		5
 
 /*
  * The default maximum bit-rate per lane in Mbps, if the
  * source subdev does not provide V4L2_CID_LINK_FREQ.
  */
-#define CSI2_DEFAULT_MAX_MBPS 849
+#define CSI2_DEFAULT_MAX_MBPS	849
 
 struct csi2_dev {
-	struct device          *dev;
-	struct v4l2_subdev      sd;
-	struct v4l2_async_notifier notifier;
-	struct media_pad       pad[CSI2_NUM_PADS];
-	struct clk             *dphy_clk;
-	struct clk             *pllref_clk;
-	struct clk             *pix_clk; /* what is this? */
-	void __iomem           *base;
-
-	struct v4l2_subdev	*remote;
-	unsigned int		remote_pad;
-	unsigned short		data_lanes;
+	struct device			*dev;
+	struct v4l2_subdev		sd;
+	struct v4l2_async_notifier	notifier;
+	struct media_pad		pad[CSI2_NUM_PADS];
+	struct clk			*dphy_clk;
+	struct clk			*pllref_clk;
+	struct clk			*pix_clk; /* what is this? */
+	void __iomem			*base;
+
+	struct v4l2_subdev		*remote;
+	unsigned int			remote_pad;
+	unsigned short			data_lanes;
 
 	/* lock to protect all members below */
-	struct mutex lock;
+	struct mutex			lock;
 
-	struct v4l2_mbus_framefmt format_mbus;
+	struct v4l2_mbus_framefmt	format_mbus;
 
-	int                     stream_count;
-	struct v4l2_subdev      *src_sd;
-	bool                    sink_linked[CSI2_NUM_SRC_PADS];
+	int				stream_count;
+	struct v4l2_subdev		*src_sd;
+	bool				sink_linked[CSI2_NUM_SRC_PADS];
 };
 
 #define DEVICE_NAME "imx6-mipi-csi2"
 
 /* Register offsets */
-#define CSI2_VERSION            0x000
-#define CSI2_N_LANES            0x004
-#define CSI2_PHY_SHUTDOWNZ      0x008
-#define CSI2_DPHY_RSTZ          0x00c
-#define CSI2_RESETN             0x010
-#define CSI2_PHY_STATE          0x014
-#define PHY_STOPSTATEDATA_BIT   4
-#define PHY_STOPSTATEDATA(n)    BIT(PHY_STOPSTATEDATA_BIT + (n))
-#define PHY_RXCLKACTIVEHS       BIT(8)
-#define PHY_RXULPSCLKNOT        BIT(9)
-#define PHY_STOPSTATECLK        BIT(10)
-#define CSI2_DATA_IDS_1         0x018
-#define CSI2_DATA_IDS_2         0x01c
-#define CSI2_ERR1               0x020
-#define CSI2_ERR2               0x024
-#define CSI2_MSK1               0x028
-#define CSI2_MSK2               0x02c
-#define CSI2_PHY_TST_CTRL0      0x030
+#define CSI2_VERSION		0x000
+#define CSI2_N_LANES		0x004
+#define CSI2_PHY_SHUTDOWNZ	0x008
+#define CSI2_DPHY_RSTZ		0x00c
+#define CSI2_RESETN		0x010
+#define CSI2_PHY_STATE		0x014
+#define PHY_STOPSTATEDATA_BIT	4
+#define PHY_STOPSTATEDATA(n)	BIT(PHY_STOPSTATEDATA_BIT + (n))
+#define PHY_RXCLKACTIVEHS	BIT(8)
+#define PHY_RXULPSCLKNOT	BIT(9)
+#define PHY_STOPSTATECLK	BIT(10)
+#define CSI2_DATA_IDS_1		0x018
+#define CSI2_DATA_IDS_2		0x01c
+#define CSI2_ERR1		0x020
+#define CSI2_ERR2		0x024
+#define CSI2_MSK1		0x028
+#define CSI2_MSK2		0x02c
+#define CSI2_PHY_TST_CTRL0	0x030
 #define PHY_TESTCLR		BIT(0)
 #define PHY_TESTCLK		BIT(1)
-#define CSI2_PHY_TST_CTRL1      0x034
+#define CSI2_PHY_TST_CTRL1	0x034
 #define PHY_TESTEN		BIT(16)
 /*
  * i.MX CSI2IPU Gasket registers follow. The CSI2IPU gasket is
@@ -106,13 +106,13 @@ static inline struct csi2_dev *notifier_to_dev(struct v4l2_async_notifier *n)
  * reference manual is as follows:
  *
  * 1. Deassert presetn signal (global reset).
- *        It's not clear what this "global reset" signal is (maybe APB
- *        global reset), but in any case this step would be probably
- *        be carried out during driver load in csi2_probe().
+ *	It's not clear what this "global reset" signal is (maybe APB
+ *	global reset), but in any case this step would be probably
+ *	be carried out during driver load in csi2_probe().
  *
  * 2. Configure MIPI Camera Sensor to put all Tx lanes in LP-11 state.
- *        This must be carried out by the MIPI sensor's s_power(ON) subdev
- *        op.
+ *	This must be carried out by the MIPI sensor's s_power(ON) subdev
+ *	op.
  *
  * 3. D-PHY initialization.
  * 4. CSI2 Controller programming (Set N_LANES, deassert PHY_SHUTDOWNZ,

-- 
2.34.1



From Frank.Li at nxp.com  Thu Aug 21 13:15:40 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 21 Aug 2025 16:15:40 -0400
Subject: [PATCH v3 05/31] media: staging: media: imx6-mipi-csi2: use
 devm_add_action_or_reset() to simplify code
In-Reply-To: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
References: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
Message-ID: <20250821-95_cam-v3-5-c9286fbb34b9@nxp.com>

Use devm_add_action_or_reset() to simplify the code. No functional change.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/staging/media/imx/imx6-mipi-csi2.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index 42256441b881d9f132ad7ff899d6f1e35643b4ac..eba9a650030f5e380aa900b94728ad375171c6a5 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -716,6 +716,14 @@ static int csi2_async_register(struct csi2_dev *csi2)
 	return ret;
 }
 
+static void csi2_nf_cleanup(void *data)
+{
+	struct csi2_dev *csi2 = data;
+
+	v4l2_async_nf_unregister(&csi2->notifier);
+	v4l2_async_nf_cleanup(&csi2->notifier);
+}
+
 static int csi2_probe(struct platform_device *pdev)
 {
 	struct csi2_dev *csi2;
@@ -749,6 +757,10 @@ static int csi2_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	ret = devm_add_action_or_reset(&pdev->dev, csi2_nf_cleanup, csi2);
+	if (ret)
+		return ret;
+
 	csi2->pllref_clk = devm_clk_get(&pdev->dev, "ref");
 	if (IS_ERR(csi2->pllref_clk)) {
 		v4l2_err(&csi2->sd, "failed to get pll reference clock\n");
@@ -800,8 +812,6 @@ static int csi2_probe(struct platform_device *pdev)
 	return 0;
 
 clean_notifier:
-	v4l2_async_nf_unregister(&csi2->notifier);
-	v4l2_async_nf_cleanup(&csi2->notifier);
 	clk_disable_unprepare(csi2->dphy_clk);
 pllref_off:
 	clk_disable_unprepare(csi2->pllref_clk);
@@ -815,8 +825,6 @@ static void csi2_remove(struct platform_device *pdev)
 	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
 	struct csi2_dev *csi2 = sd_to_dev(sd);
 
-	v4l2_async_nf_unregister(&csi2->notifier);
-	v4l2_async_nf_cleanup(&csi2->notifier);
 	v4l2_async_unregister_subdev(sd);
 	clk_disable_unprepare(csi2->dphy_clk);
 	clk_disable_unprepare(csi2->pllref_clk);

-- 
2.34.1



From Frank.Li at nxp.com  Thu Aug 21 13:15:41 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 21 Aug 2025 16:15:41 -0400
Subject: [PATCH v3 06/31] media: staging: media: imx6-mipi-csi2: use
 devm_clk_bulk_get_all() to fetch clocks
In-Reply-To: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
References: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
Message-ID: <20250821-95_cam-v3-6-c9286fbb34b9@nxp.com>

Use devm_clk_bulk_get_all_enabled() helper to simplify clock handling.

Defer all clock prepare and enable to csi2_start(), which previous only
enable pix clock here.

We can safely do that because there are not register access before
csi2_start().

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/staging/media/imx/imx6-mipi-csi2.c | 52 ++++++------------------------
 1 file changed, 9 insertions(+), 43 deletions(-)

diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index eba9a650030f5e380aa900b94728ad375171c6a5..32ddcef7ec8535a44e121754bb621c0d2e226369 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -39,11 +39,11 @@ struct csi2_dev {
 	struct v4l2_subdev		sd;
 	struct v4l2_async_notifier	notifier;
 	struct media_pad		pad[CSI2_NUM_PADS];
-	struct clk			*dphy_clk;
-	struct clk			*pllref_clk;
-	struct clk			*pix_clk; /* what is this? */
 	void __iomem			*base;
 
+	struct clk_bulk_data		*clks;
+	int				num_clks;
+
 	struct v4l2_subdev		*remote;
 	unsigned int			remote_pad;
 	unsigned short			data_lanes;
@@ -343,7 +343,7 @@ static int csi2_start(struct csi2_dev *csi2)
 	unsigned int lanes;
 	int ret;
 
-	ret = clk_prepare_enable(csi2->pix_clk);
+	ret = clk_bulk_prepare_enable(csi2->num_clks, csi2->clks);
 	if (ret)
 		return ret;
 
@@ -390,7 +390,7 @@ static int csi2_start(struct csi2_dev *csi2)
 err_assert_reset:
 	csi2_enable(csi2, false);
 err_disable_clk:
-	clk_disable_unprepare(csi2->pix_clk);
+	clk_bulk_disable_unprepare(csi2->num_clks, csi2->clks);
 	return ret;
 }
 
@@ -401,7 +401,7 @@ static void csi2_stop(struct csi2_dev *csi2)
 	v4l2_subdev_call(csi2->src_sd, video, post_streamoff);
 
 	csi2_enable(csi2, false);
-	clk_disable_unprepare(csi2->pix_clk);
+	clk_bulk_disable_unprepare(csi2->num_clks, csi2->clks);
 }
 
 /*
@@ -761,24 +761,6 @@ static int csi2_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	csi2->pllref_clk = devm_clk_get(&pdev->dev, "ref");
-	if (IS_ERR(csi2->pllref_clk)) {
-		v4l2_err(&csi2->sd, "failed to get pll reference clock\n");
-		return PTR_ERR(csi2->pllref_clk);
-	}
-
-	csi2->dphy_clk = devm_clk_get(&pdev->dev, "dphy");
-	if (IS_ERR(csi2->dphy_clk)) {
-		v4l2_err(&csi2->sd, "failed to get dphy clock\n");
-		return PTR_ERR(csi2->dphy_clk);
-	}
-
-	csi2->pix_clk = devm_clk_get(&pdev->dev, "pix");
-	if (IS_ERR(csi2->pix_clk)) {
-		v4l2_err(&csi2->sd, "failed to get pixel clock\n");
-		return PTR_ERR(csi2->pix_clk);
-	}
-
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
 		v4l2_err(&csi2->sd, "failed to get platform resources\n");
@@ -791,19 +773,9 @@ static int csi2_probe(struct platform_device *pdev)
 
 	mutex_init(&csi2->lock);
 
-	ret = clk_prepare_enable(csi2->pllref_clk);
-	if (ret) {
-		v4l2_err(&csi2->sd, "failed to enable pllref_clk\n");
-		goto rmmutex;
-	}
-
-	ret = clk_prepare_enable(csi2->dphy_clk);
-	if (ret) {
-		v4l2_err(&csi2->sd, "failed to enable dphy_clk\n");
-		goto pllref_off;
-	}
-
-	platform_set_drvdata(pdev, &csi2->sd);
+	csi2->num_clks = devm_clk_bulk_get_all(&pdev->dev, &csi2->clks);
+	if (csi2->num_clks < 0)
+		return dev_err_probe(&pdev->dev, csi2->num_clks, "Failed to get clocks\n");
 
 	ret = csi2_async_register(csi2);
 	if (ret)
@@ -812,10 +784,6 @@ static int csi2_probe(struct platform_device *pdev)
 	return 0;
 
 clean_notifier:
-	clk_disable_unprepare(csi2->dphy_clk);
-pllref_off:
-	clk_disable_unprepare(csi2->pllref_clk);
-rmmutex:
 	mutex_destroy(&csi2->lock);
 	return ret;
 }
@@ -826,8 +794,6 @@ static void csi2_remove(struct platform_device *pdev)
 	struct csi2_dev *csi2 = sd_to_dev(sd);
 
 	v4l2_async_unregister_subdev(sd);
-	clk_disable_unprepare(csi2->dphy_clk);
-	clk_disable_unprepare(csi2->pllref_clk);
 	mutex_destroy(&csi2->lock);
 	media_entity_cleanup(&sd->entity);
 }

-- 
2.34.1



From Frank.Li at nxp.com  Thu Aug 21 13:15:42 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 21 Aug 2025 16:15:42 -0400
Subject: [PATCH v3 07/31] media: staging: media: imx6-mipi-csi2: use
 devm_mutex_init() to simplify code
In-Reply-To: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
References: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
Message-ID: <20250821-95_cam-v3-7-c9286fbb34b9@nxp.com>

Use devm_mutex_init() to simplify the code. No functional change.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/staging/media/imx/imx6-mipi-csi2.c | 15 ++++-----------
 1 file changed, 4 insertions(+), 11 deletions(-)

diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index 32ddcef7ec8535a44e121754bb621c0d2e226369..f8d0b3b8b250774af51f2aba731e639131aceff9 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -771,30 +771,23 @@ static int csi2_probe(struct platform_device *pdev)
 	if (!csi2->base)
 		return -ENOMEM;
 
-	mutex_init(&csi2->lock);
+	ret = devm_mutex_init(&pdev->dev, &csi2->lock);
+	if (ret)
+		return ret;
 
 	csi2->num_clks = devm_clk_bulk_get_all(&pdev->dev, &csi2->clks);
 	if (csi2->num_clks < 0)
 		return dev_err_probe(&pdev->dev, csi2->num_clks, "Failed to get clocks\n");
 
-	ret = csi2_async_register(csi2);
-	if (ret)
-		goto clean_notifier;
+	return csi2_async_register(csi2);
 
-	return 0;
-
-clean_notifier:
-	mutex_destroy(&csi2->lock);
-	return ret;
 }
 
 static void csi2_remove(struct platform_device *pdev)
 {
 	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
-	struct csi2_dev *csi2 = sd_to_dev(sd);
 
 	v4l2_async_unregister_subdev(sd);
-	mutex_destroy(&csi2->lock);
 	media_entity_cleanup(&sd->entity);
 }
 

-- 
2.34.1



From Frank.Li at nxp.com  Thu Aug 21 13:15:43 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 21 Aug 2025 16:15:43 -0400
Subject: [PATCH v3 08/31] media: staging: media: imx6-mipi-csi2: use
 guard() to simplify code
In-Reply-To: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
References: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
Message-ID: <20250821-95_cam-v3-8-c9286fbb34b9@nxp.com>

Use guard() to simplify mutex locking. No functional change.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/staging/media/imx/imx6-mipi-csi2.c | 54 +++++++++++-------------------
 1 file changed, 19 insertions(+), 35 deletions(-)

diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index f8d0b3b8b250774af51f2aba731e639131aceff9..54e9491d3428686288a5bc9bb58a5a0a25aca696 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -413,21 +413,17 @@ static int csi2_s_stream(struct v4l2_subdev *sd, int enable)
 	struct csi2_dev *csi2 = sd_to_dev(sd);
 	int i, ret = 0;
 
-	mutex_lock(&csi2->lock);
+	guard(mutex)(&csi2->lock);
 
-	if (!csi2->src_sd) {
-		ret = -EPIPE;
-		goto out;
-	}
+	if (!csi2->src_sd)
+		return -EPIPE;
 
 	for (i = 0; i < CSI2_NUM_SRC_PADS; i++) {
 		if (csi2->sink_linked[i])
 			break;
 	}
-	if (i >= CSI2_NUM_SRC_PADS) {
-		ret = -EPIPE;
-		goto out;
-	}
+	if (i >= CSI2_NUM_SRC_PADS)
+		return -EPIPE;
 
 	/*
 	 * enable/disable streaming only if stream_count is
@@ -442,14 +438,12 @@ static int csi2_s_stream(struct v4l2_subdev *sd, int enable)
 	else
 		csi2_stop(csi2);
 	if (ret)
-		goto out;
+		return ret;
 
 update_count:
 	csi2->stream_count += enable ? 1 : -1;
 	if (csi2->stream_count < 0)
 		csi2->stream_count = 0;
-out:
-	mutex_unlock(&csi2->lock);
 	return ret;
 }
 
@@ -467,32 +461,28 @@ static int csi2_link_setup(struct media_entity *entity,
 
 	remote_sd = media_entity_to_v4l2_subdev(remote->entity);
 
-	mutex_lock(&csi2->lock);
+	guard(mutex)(&csi2->lock);
 
 	if (local->flags & MEDIA_PAD_FL_SOURCE) {
 		if (flags & MEDIA_LNK_FL_ENABLED) {
-			if (csi2->sink_linked[local->index - 1]) {
-				ret = -EBUSY;
-				goto out;
-			}
+			if (csi2->sink_linked[local->index - 1])
+				return -EBUSY;
+
 			csi2->sink_linked[local->index - 1] = true;
 		} else {
 			csi2->sink_linked[local->index - 1] = false;
 		}
 	} else {
 		if (flags & MEDIA_LNK_FL_ENABLED) {
-			if (csi2->src_sd) {
-				ret = -EBUSY;
-				goto out;
-			}
+			if (csi2->src_sd)
+				return -EBUSY;
+
 			csi2->src_sd = remote_sd;
 		} else {
 			csi2->src_sd = NULL;
 		}
 	}
 
-out:
-	mutex_unlock(&csi2->lock);
 	return ret;
 }
 
@@ -513,14 +503,12 @@ static int csi2_get_fmt(struct v4l2_subdev *sd,
 	struct csi2_dev *csi2 = sd_to_dev(sd);
 	struct v4l2_mbus_framefmt *fmt;
 
-	mutex_lock(&csi2->lock);
+	guard(mutex)(&csi2->lock);
 
 	fmt = __csi2_get_fmt(csi2, sd_state, sdformat->pad, sdformat->which);
 
 	sdformat->format = *fmt;
 
-	mutex_unlock(&csi2->lock);
-
 	return 0;
 }
 
@@ -530,17 +518,14 @@ static int csi2_set_fmt(struct v4l2_subdev *sd,
 {
 	struct csi2_dev *csi2 = sd_to_dev(sd);
 	struct v4l2_mbus_framefmt *fmt;
-	int ret = 0;
 
 	if (sdformat->pad >= CSI2_NUM_PADS)
 		return -EINVAL;
 
-	mutex_lock(&csi2->lock);
+	guard(mutex)(&csi2->lock);
 
-	if (csi2->stream_count > 0) {
-		ret = -EBUSY;
-		goto out;
-	}
+	if (csi2->stream_count > 0)
+		return -EBUSY;
 
 	/* Output pads mirror active input pad, no limits on input pads */
 	if (sdformat->pad != CSI2_SINK_PAD)
@@ -549,9 +534,8 @@ static int csi2_set_fmt(struct v4l2_subdev *sd,
 	fmt = __csi2_get_fmt(csi2, sd_state, sdformat->pad, sdformat->which);
 
 	*fmt = sdformat->format;
-out:
-	mutex_unlock(&csi2->lock);
-	return ret;
+
+	return 0;
 }
 
 static int csi2_registered(struct v4l2_subdev *sd)

-- 
2.34.1



From Frank.Li at nxp.com  Thu Aug 21 13:15:44 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 21 Aug 2025 16:15:44 -0400
Subject: [PATCH v3 09/31] media: staging: media: imx6-mipi-csi2: use
 register structure to match hardware
In-Reply-To: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
References: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
Message-ID: <20250821-95_cam-v3-9-c9286fbb34b9@nxp.com>

Use register structure to handle different versions of the DesignWare CSI2
controller, as register offsets slightly differ between versions. Add
register existence bits to detect invalid register access when using
different versions of the CSI2 controller.

No functional change.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/staging/media/imx/imx6-mipi-csi2.c | 165 +++++++++++++++++------------
 1 file changed, 96 insertions(+), 69 deletions(-)

diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index 54e9491d3428686288a5bc9bb58a5a0a25aca696..b04c1b98c088b8bfa66eb3f61cca8bb735b7eae4 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -34,12 +34,30 @@
  */
 #define CSI2_DEFAULT_MAX_MBPS	849
 
+struct dw_csi2_regs {
+	u32	version;
+	u32	n_lanes;
+	u32	phy_shutdownz;
+	u32	dphy_rstz;
+	u32	resetn;
+	u32	phy_state;
+	u32	data_ids_1;
+	u32	data_ids_2;
+	u32	err1;
+	u32	err2;
+	u32	msk1;
+	u32	msk2;
+	u32	phy_tst_ctrl0;
+	u32	phy_tst_ctrl1;
+};
+
 struct csi2_dev {
 	struct device			*dev;
 	struct v4l2_subdev		sd;
 	struct v4l2_async_notifier	notifier;
 	struct media_pad		pad[CSI2_NUM_PADS];
 	void __iomem			*base;
+	const struct dw_csi2_regs	*regs;
 
 	struct clk_bulk_data		*clks;
 	int				num_clks;
@@ -60,28 +78,53 @@ struct csi2_dev {
 
 #define DEVICE_NAME "imx6-mipi-csi2"
 
-/* Register offsets */
-#define CSI2_VERSION		0x000
-#define CSI2_N_LANES		0x004
-#define CSI2_PHY_SHUTDOWNZ	0x008
-#define CSI2_DPHY_RSTZ		0x00c
-#define CSI2_RESETN		0x010
-#define CSI2_PHY_STATE		0x014
+/* Help check wrong access unexisted register at difference IP version */
+#define DW_REG_EXIST		0x80000000
+#define DW_REG(x)		(DW_REG_EXIST | (x))
+
+/* Register offsets for v0 */
+static const struct dw_csi2_regs dw_csi2_v0 = {
+	.version = DW_REG(0x0),
+	.n_lanes = DW_REG(0x4),
+	.phy_shutdownz = DW_REG(0x8),
+	.dphy_rstz = DW_REG(0xc),
+	.resetn = DW_REG(0x10),
+	.phy_state = DW_REG(0x14),
+	.data_ids_1 = DW_REG(0x18),
+	.data_ids_2 = DW_REG(0x1c),
+	.err1 = DW_REG(0x20),
+	.err2 = DW_REG(0x24),
+	.msk1 = DW_REG(0x28),
+	.msk2 = DW_REG(0x2c),
+	.phy_tst_ctrl0 = DW_REG(0x30),
+	.phy_tst_ctrl1 = DW_REG(0x34),
+};
+
+static int dw_csi2_reg_err(struct csi2_dev *csi2, const char *name)
+{
+	dev_err_once(csi2->dev, "access to unexisted register: %s", name);
+	return 0;
+}
+
+#define dw_reg_exist(csi2, __name) ((csi2)->regs->__name & DW_REG_EXIST)
+
+#define dw_writel(csi2, value, __name) (dw_reg_exist((csi2), __name) ? \
+writel(value, (csi2)->base + (csi2->regs->__name & ~DW_REG_EXIST)) : \
+dw_csi2_reg_err((csi2), #__name))
+
+#define dw_readl(csi2, __name) (dw_reg_exist((csi2), __name) ? \
+readl((csi2)->base + ((csi2)->regs->__name & ~DW_REG_EXIST)) : \
+dw_csi2_reg_err(csi2, #__name))
+
 #define PHY_STOPSTATEDATA_BIT	4
 #define PHY_STOPSTATEDATA(n)	BIT(PHY_STOPSTATEDATA_BIT + (n))
 #define PHY_RXCLKACTIVEHS	BIT(8)
 #define PHY_RXULPSCLKNOT	BIT(9)
 #define PHY_STOPSTATECLK	BIT(10)
-#define CSI2_DATA_IDS_1		0x018
-#define CSI2_DATA_IDS_2		0x01c
-#define CSI2_ERR1		0x020
-#define CSI2_ERR2		0x024
-#define CSI2_MSK1		0x028
-#define CSI2_MSK2		0x02c
-#define CSI2_PHY_TST_CTRL0	0x030
+
 #define PHY_TESTCLR		BIT(0)
 #define PHY_TESTCLK		BIT(1)
-#define CSI2_PHY_TST_CTRL1	0x034
+
 #define PHY_TESTEN		BIT(16)
 /*
  * i.MX CSI2IPU Gasket registers follow. The CSI2IPU gasket is
@@ -132,42 +175,42 @@ static inline struct csi2_dev *notifier_to_dev(struct v4l2_async_notifier *n)
 static void csi2_enable(struct csi2_dev *csi2, bool enable)
 {
 	if (enable) {
-		writel(0x1, csi2->base + CSI2_PHY_SHUTDOWNZ);
-		writel(0x1, csi2->base + CSI2_DPHY_RSTZ);
-		writel(0x1, csi2->base + CSI2_RESETN);
+		dw_writel(csi2, 0x1, phy_shutdownz);
+		dw_writel(csi2, 0x1, dphy_rstz);
+		dw_writel(csi2, 0x1, resetn);
 	} else {
-		writel(0x0, csi2->base + CSI2_PHY_SHUTDOWNZ);
-		writel(0x0, csi2->base + CSI2_DPHY_RSTZ);
-		writel(0x0, csi2->base + CSI2_RESETN);
+		dw_writel(csi2, 0x0, phy_shutdownz);
+		dw_writel(csi2, 0x0, dphy_rstz);
+		dw_writel(csi2, 0x0, resetn);
 	}
 }
 
 static void csi2_set_lanes(struct csi2_dev *csi2, unsigned int lanes)
 {
-	writel(lanes - 1, csi2->base + CSI2_N_LANES);
+	dw_writel(csi2, lanes - 1, n_lanes);
 }
 
 static void dw_mipi_csi2_phy_write(struct csi2_dev *csi2,
 				   u32 test_code, u32 test_data)
 {
 	/* Clear PHY test interface */
-	writel(PHY_TESTCLR, csi2->base + CSI2_PHY_TST_CTRL0);
-	writel(0x0, csi2->base + CSI2_PHY_TST_CTRL1);
-	writel(0x0, csi2->base + CSI2_PHY_TST_CTRL0);
+	dw_writel(csi2, PHY_TESTCLR, phy_tst_ctrl0);
+	dw_writel(csi2, 0x0, phy_tst_ctrl1);
+	dw_writel(csi2, 0x0, phy_tst_ctrl0);
 
 	/* Raise test interface strobe signal */
-	writel(PHY_TESTCLK, csi2->base + CSI2_PHY_TST_CTRL0);
+	dw_writel(csi2, PHY_TESTCLK, phy_tst_ctrl0);
 
 	/* Configure address write on falling edge and lower strobe signal */
-	writel(PHY_TESTEN | test_code, csi2->base + CSI2_PHY_TST_CTRL1);
-	writel(0x0, csi2->base + CSI2_PHY_TST_CTRL0);
+	dw_writel(csi2, PHY_TESTEN | test_code, phy_tst_ctrl1);
+	dw_writel(csi2, 0x0, phy_tst_ctrl0);
 
 	/* Configure data write on rising edge and raise strobe signal */
-	writel(test_data, csi2->base + CSI2_PHY_TST_CTRL1);
-	writel(PHY_TESTCLK, csi2->base + CSI2_PHY_TST_CTRL0);
+	dw_writel(csi2, test_data, phy_tst_ctrl1);
+	dw_writel(csi2, PHY_TESTCLK, phy_tst_ctrl0);
 
 	/* Clear strobe signal */
-	writel(0x0, csi2->base + CSI2_PHY_TST_CTRL0);
+	dw_writel(csi2, 0x0, phy_tst_ctrl0);
 }
 
 /*
@@ -233,16 +276,15 @@ static int __maybe_unused csi2_dphy_wait_ulp(struct csi2_dev *csi2)
 	int ret;
 
 	/* wait for ULP on clock lane */
-	ret = readl_poll_timeout(csi2->base + CSI2_PHY_STATE, reg,
-				 !(reg & PHY_RXULPSCLKNOT), 0, 500000);
+	ret = read_poll_timeout(dw_readl, reg, !(reg & PHY_RXULPSCLKNOT),
+				0, 500000, 0, csi2, phy_state);
 	if (ret) {
 		v4l2_err(&csi2->sd, "ULP timeout, phy_state = 0x%08x\n", reg);
 		return ret;
 	}
 
 	/* wait until no errors on bus */
-	ret = readl_poll_timeout(csi2->base + CSI2_ERR1, reg,
-				 reg == 0x0, 0, 500000);
+	ret = read_poll_timeout(dw_readl, reg, reg == 0x0, 0, 500000, 0, csi2, err1);
 	if (ret) {
 		v4l2_err(&csi2->sd, "stable bus timeout, err1 = 0x%08x\n", reg);
 		return ret;
@@ -259,8 +301,7 @@ static void csi2_dphy_wait_stopstate(struct csi2_dev *csi2, unsigned int lanes)
 
 	mask = PHY_STOPSTATECLK | (((1 << lanes) - 1) << PHY_STOPSTATEDATA_BIT);
 
-	ret = readl_poll_timeout(csi2->base + CSI2_PHY_STATE, reg,
-				 (reg & mask) == mask, 0, 500000);
+	ret = read_poll_timeout(dw_readl, reg, (reg & mask) == mask, 0, 500000, 0, csi2, phy_state);
 	if (ret) {
 		v4l2_warn(&csi2->sd, "LP-11 wait timeout, likely a sensor driver bug, expect capture failures.\n");
 		v4l2_warn(&csi2->sd, "phy_state = 0x%08x\n", reg);
@@ -273,8 +314,8 @@ static int csi2_dphy_wait_clock_lane(struct csi2_dev *csi2)
 	u32 reg;
 	int ret;
 
-	ret = readl_poll_timeout(csi2->base + CSI2_PHY_STATE, reg,
-				 (reg & PHY_RXCLKACTIVEHS), 0, 500000);
+	ret = read_poll_timeout(dw_readl, reg, (reg & PHY_RXCLKACTIVEHS),
+				0, 500000, 0, csi2, phy_state);
 	if (ret) {
 		v4l2_err(&csi2->sd, "clock lane timeout, phy_state = 0x%08x\n",
 			 reg);
@@ -556,34 +597,20 @@ static int csi2_log_status(struct v4l2_subdev *sd)
 	struct csi2_dev *csi2 = sd_to_dev(sd);
 
 	v4l2_info(sd, "-----MIPI CSI status-----\n");
-	v4l2_info(sd, "VERSION: 0x%x\n",
-		  readl(csi2->base + CSI2_VERSION));
-	v4l2_info(sd, "N_LANES: 0x%x\n",
-		  readl(csi2->base + CSI2_N_LANES));
-	v4l2_info(sd, "PHY_SHUTDOWNZ: 0x%x\n",
-		  readl(csi2->base + CSI2_PHY_SHUTDOWNZ));
-	v4l2_info(sd, "DPHY_RSTZ: 0x%x\n",
-		  readl(csi2->base + CSI2_DPHY_RSTZ));
-	v4l2_info(sd, "RESETN: 0x%x\n",
-		  readl(csi2->base + CSI2_RESETN));
-	v4l2_info(sd, "PHY_STATE: 0x%x\n",
-		  readl(csi2->base + CSI2_PHY_STATE));
-	v4l2_info(sd, "DATA_IDS_1: 0x%x\n",
-		  readl(csi2->base + CSI2_DATA_IDS_1));
-	v4l2_info(sd, "DATA_IDS_2: 0x%x\n",
-		  readl(csi2->base + CSI2_DATA_IDS_2));
-	v4l2_info(sd, "ERR1: 0x%x\n",
-		  readl(csi2->base + CSI2_ERR1));
-	v4l2_info(sd, "ERR2: 0x%x\n",
-		  readl(csi2->base + CSI2_ERR2));
-	v4l2_info(sd, "MSK1: 0x%x\n",
-		  readl(csi2->base + CSI2_MSK1));
-	v4l2_info(sd, "MSK2: 0x%x\n",
-		  readl(csi2->base + CSI2_MSK2));
-	v4l2_info(sd, "PHY_TST_CTRL0: 0x%x\n",
-		  readl(csi2->base + CSI2_PHY_TST_CTRL0));
-	v4l2_info(sd, "PHY_TST_CTRL1: 0x%x\n",
-		  readl(csi2->base + CSI2_PHY_TST_CTRL1));
+	v4l2_info(sd, "VERSION: 0x%x\n", dw_readl(csi2, version));
+	v4l2_info(sd, "N_LANES: 0x%x\n", dw_readl(csi2, n_lanes));
+	v4l2_info(sd, "PHY_SHUTDOWNZ: 0x%x\n", dw_readl(csi2, phy_shutdownz));
+	v4l2_info(sd, "DPHY_RSTZ: 0x%x\n", dw_readl(csi2, dphy_rstz));
+	v4l2_info(sd, "RESETN: 0x%x\n", dw_readl(csi2, resetn));
+	v4l2_info(sd, "PHY_STATE: 0x%x\n", dw_readl(csi2, phy_state));
+	v4l2_info(sd, "DATA_IDS_1: 0x%x\n", dw_readl(csi2, data_ids_1));
+	v4l2_info(sd, "DATA_IDS_2: 0x%x\n", dw_readl(csi2, data_ids_2));
+	v4l2_info(sd, "ERR1: 0x%x\n", dw_readl(csi2, err1));
+	v4l2_info(sd, "ERR2: 0x%x\n", dw_readl(csi2, err2));
+	v4l2_info(sd, "MSK1: 0x%x\n", dw_readl(csi2, msk1));
+	v4l2_info(sd, "MSK2: 0x%x\n", dw_readl(csi2, msk2));
+	v4l2_info(sd, "PHY_TST_CTRL0: 0x%x\n", dw_readl(csi2, phy_tst_ctrl0));
+	v4l2_info(sd, "PHY_TST_CTRL1: 0x%x\n", dw_readl(csi2, phy_tst_ctrl1));
 
 	return 0;
 }
@@ -719,7 +746,7 @@ static int csi2_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	csi2->dev = &pdev->dev;
-
+	csi2->regs = &dw_csi2_v0;
 	v4l2_subdev_init(&csi2->sd, &csi2_subdev_ops);
 	v4l2_set_subdevdata(&csi2->sd, &pdev->dev);
 	csi2->sd.internal_ops = &csi2_internal_ops;
@@ -776,7 +803,7 @@ static void csi2_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id csi2_dt_ids[] = {
-	{ .compatible = "fsl,imx6-mipi-csi2", },
+	{ .compatible = "fsl,imx6-mipi-csi2"},
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, csi2_dt_ids);

-- 
2.34.1



From Frank.Li at nxp.com  Thu Aug 21 13:15:45 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 21 Aug 2025 16:15:45 -0400
Subject: [PATCH v3 10/31] media: staging: media: imx6-mipi-csi2: use
 devm_platform_ioremap_resource() simplify code
In-Reply-To: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
References: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
Message-ID: <20250821-95_cam-v3-10-c9286fbb34b9@nxp.com>

Use devm_platform_ioremap_resource() simplify code. No functional change.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/staging/media/imx/imx6-mipi-csi2.c | 14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index b04c1b98c088b8bfa66eb3f61cca8bb735b7eae4..7b8911bea3fad8187fafb1d0916d730fd6fa671c 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -738,7 +738,6 @@ static void csi2_nf_cleanup(void *data)
 static int csi2_probe(struct platform_device *pdev)
 {
 	struct csi2_dev *csi2;
-	struct resource *res;
 	int i, ret;
 
 	csi2 = devm_kzalloc(&pdev->dev, sizeof(*csi2), GFP_KERNEL);
@@ -772,15 +771,10 @@ static int csi2_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		v4l2_err(&csi2->sd, "failed to get platform resources\n");
-		return -ENODEV;
-	}
-
-	csi2->base = devm_ioremap(&pdev->dev, res->start, PAGE_SIZE);
-	if (!csi2->base)
-		return -ENOMEM;
+	csi2->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(csi2->base))
+		return dev_err_probe(&pdev->dev, -ENOMEM,
+				     "failed to get platform resources");
 
 	ret = devm_mutex_init(&pdev->dev, &csi2->lock);
 	if (ret)

-- 
2.34.1



From Frank.Li at nxp.com  Thu Aug 21 13:15:46 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 21 Aug 2025 16:15:46 -0400
Subject: [PATCH v3 11/31] media: staging: media: imx6-mipi-csi2: move probe
 part to imx6-csi2.c
In-Reply-To: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
References: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
Message-ID: <20250821-95_cam-v3-11-c9286fbb34b9@nxp.com>

Prepare create common dw mipi csi2 library from imx6-mipi-csi2.c.

Move probe part to imx6-csi.c.

Rename struct csi2_dev to struct dw_mipi_csi2_dev and move it
include/media/dw-mipi-csi2.h.

Create two API dw_mipi_csi2_init() and dw_mipi_csi2_deinit().

No functional change.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/staging/media/imx/Makefile         |   2 +-
 drivers/staging/media/imx/imx6-csi2.c      |  61 ++++++++++++++
 drivers/staging/media/imx/imx6-mipi-csi2.c | 130 ++++++++---------------------
 include/media/dw-mipi-csi2.h               |  62 ++++++++++++++
 4 files changed, 159 insertions(+), 96 deletions(-)

diff --git a/drivers/staging/media/imx/Makefile b/drivers/staging/media/imx/Makefile
index 330e0825f506bd98d6a8093a58d3b7d06a94a626..064a6c6c069aa440c72a483080cbedf89d370193 100644
--- a/drivers/staging/media/imx/Makefile
+++ b/drivers/staging/media/imx/Makefile
@@ -11,4 +11,4 @@ imx6-media-csi-objs := imx-media-csi.o imx-media-fim.o
 obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx-media-common.o
 obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx6-media.o
 obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx6-media-csi.o
-obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx6-mipi-csi2.o
+obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx6-mipi-csi2.o imx6-csi2.o
diff --git a/drivers/staging/media/imx/imx6-csi2.c b/drivers/staging/media/imx/imx6-csi2.c
new file mode 100644
index 0000000000000000000000000000000000000000..72eff685fad99b3def46cf2866565191b7de9a8b
--- /dev/null
+++ b/drivers/staging/media/imx/imx6-csi2.c
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * MIPI CSI-2 Receiver Subdev for Freescale i.MX6 SOC.
+ *
+ * Copyright (c) 2012-2017 Mentor Graphics Inc.
+ */
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+#include <media/dw-mipi-csi2.h>
+#include "imx-media.h"
+
+struct imx6_csi2 {
+	struct dw_mipi_csi2_dev dw;
+};
+
+static int csi2_probe(struct platform_device *pdev)
+{
+	struct imx6_csi2 *csi2;
+
+	csi2 = devm_kzalloc(&pdev->dev, sizeof(*csi2), GFP_KERNEL);
+	if (!csi2)
+		return -ENOMEM;
+
+	return dw_mipi_csi2_init(pdev, &csi2->dw, NULL);
+}
+
+static void csi2_remove(struct platform_device *pdev)
+{
+	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
+	struct dw_mipi_csi2_dev *csi2 = sd_to_dw_mipi_csi2_dev(sd);
+
+	dw_mipi_csi2_deinit(csi2);
+}
+
+static const struct of_device_id csi2_dt_ids[] = {
+	{ .compatible = "fsl,imx6-mipi-csi2"},
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, csi2_dt_ids);
+
+static struct platform_driver csi2_driver = {
+	.driver = {
+		.name = "imx6-mipi-csi2",
+		.of_match_table = csi2_dt_ids,
+	},
+	.probe = csi2_probe,
+	.remove = csi2_remove,
+};
+
+module_platform_driver(csi2_driver);
+
+MODULE_DESCRIPTION("i.MX5/6 MIPI CSI-2 Receiver driver");
+MODULE_AUTHOR("Steve Longerbeam <steve_longerbeam at mentor.com>");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index 7b8911bea3fad8187fafb1d0916d730fd6fa671c..b5911a37972be868e10c115ada1910fa04b2765c 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -4,6 +4,7 @@
  *
  * Copyright (c) 2012-2017 Mentor Graphics Inc.
  */
+#include <linux/export.h>
 #include <linux/clk.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -12,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/of_graph.h>
 #include <linux/platform_device.h>
+#include <media/dw-mipi-csi2.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-fwnode.h>
@@ -19,15 +21,6 @@
 #include <media/v4l2-subdev.h>
 #include "imx-media.h"
 
-/*
- * there must be 5 pads: 1 input pad from sensor, and
- * the 4 virtual channel output pads
- */
-#define CSI2_SINK_PAD		0
-#define CSI2_NUM_SINK_PADS	1
-#define CSI2_NUM_SRC_PADS	4
-#define CSI2_NUM_PADS		5
-
 /*
  * The default maximum bit-rate per lane in Mbps, if the
  * source subdev does not provide V4L2_CID_LINK_FREQ.
@@ -51,31 +44,6 @@ struct dw_csi2_regs {
 	u32	phy_tst_ctrl1;
 };
 
-struct csi2_dev {
-	struct device			*dev;
-	struct v4l2_subdev		sd;
-	struct v4l2_async_notifier	notifier;
-	struct media_pad		pad[CSI2_NUM_PADS];
-	void __iomem			*base;
-	const struct dw_csi2_regs	*regs;
-
-	struct clk_bulk_data		*clks;
-	int				num_clks;
-
-	struct v4l2_subdev		*remote;
-	unsigned int			remote_pad;
-	unsigned short			data_lanes;
-
-	/* lock to protect all members below */
-	struct mutex			lock;
-
-	struct v4l2_mbus_framefmt	format_mbus;
-
-	int				stream_count;
-	struct v4l2_subdev		*src_sd;
-	bool				sink_linked[CSI2_NUM_SRC_PADS];
-};
-
 #define DEVICE_NAME "imx6-mipi-csi2"
 
 /* Help check wrong access unexisted register at difference IP version */
@@ -100,7 +68,7 @@ static const struct dw_csi2_regs dw_csi2_v0 = {
 	.phy_tst_ctrl1 = DW_REG(0x34),
 };
 
-static int dw_csi2_reg_err(struct csi2_dev *csi2, const char *name)
+static int dw_csi2_reg_err(struct dw_mipi_csi2_dev *csi2, const char *name)
 {
 	dev_err_once(csi2->dev, "access to unexisted register: %s", name);
 	return 0;
@@ -134,14 +102,11 @@ dw_csi2_reg_err(csi2, #__name))
 #define CSI2IPU_GASKET		0xf00
 #define CSI2IPU_YUV422_YUYV	BIT(2)
 
-static inline struct csi2_dev *sd_to_dev(struct v4l2_subdev *sdev)
-{
-	return container_of(sdev, struct csi2_dev, sd);
-}
+#define sd_to_dev sd_to_dw_mipi_csi2_dev
 
-static inline struct csi2_dev *notifier_to_dev(struct v4l2_async_notifier *n)
+static inline struct dw_mipi_csi2_dev *notifier_to_dev(struct v4l2_async_notifier *n)
 {
-	return container_of(n, struct csi2_dev, notifier);
+	return container_of(n, struct dw_mipi_csi2_dev, notifier);
 }
 
 /*
@@ -172,7 +137,7 @@ static inline struct csi2_dev *notifier_to_dev(struct v4l2_async_notifier *n)
  * steps 5 and 7.
  */
 
-static void csi2_enable(struct csi2_dev *csi2, bool enable)
+static void csi2_enable(struct dw_mipi_csi2_dev *csi2, bool enable)
 {
 	if (enable) {
 		dw_writel(csi2, 0x1, phy_shutdownz);
@@ -185,12 +150,12 @@ static void csi2_enable(struct csi2_dev *csi2, bool enable)
 	}
 }
 
-static void csi2_set_lanes(struct csi2_dev *csi2, unsigned int lanes)
+static void csi2_set_lanes(struct dw_mipi_csi2_dev *csi2, unsigned int lanes)
 {
 	dw_writel(csi2, lanes - 1, n_lanes);
 }
 
-static void dw_mipi_csi2_phy_write(struct csi2_dev *csi2,
+static void dw_mipi_csi2_phy_write(struct dw_mipi_csi2_dev *csi2,
 				   u32 test_code, u32 test_data)
 {
 	/* Clear PHY test interface */
@@ -243,7 +208,7 @@ static int max_mbps_to_hsfreqrange_sel(u32 max_mbps)
 	return -EINVAL;
 }
 
-static int csi2_dphy_init(struct csi2_dev *csi2)
+static int csi2_dphy_init(struct dw_mipi_csi2_dev *csi2)
 {
 	struct v4l2_ctrl *ctrl;
 	u32 mbps_per_lane;
@@ -270,7 +235,7 @@ static int csi2_dphy_init(struct csi2_dev *csi2)
  * Waits for ultra-low-power state on D-PHY clock lane. This is currently
  * unused and may not be needed at all, but keep around just in case.
  */
-static int __maybe_unused csi2_dphy_wait_ulp(struct csi2_dev *csi2)
+static int __maybe_unused csi2_dphy_wait_ulp(struct dw_mipi_csi2_dev *csi2)
 {
 	u32 reg;
 	int ret;
@@ -294,7 +259,7 @@ static int __maybe_unused csi2_dphy_wait_ulp(struct csi2_dev *csi2)
 }
 
 /* Waits for low-power LP-11 state on data and clock lanes. */
-static void csi2_dphy_wait_stopstate(struct csi2_dev *csi2, unsigned int lanes)
+static void csi2_dphy_wait_stopstate(struct dw_mipi_csi2_dev *csi2, unsigned int lanes)
 {
 	u32 mask, reg;
 	int ret;
@@ -309,7 +274,7 @@ static void csi2_dphy_wait_stopstate(struct csi2_dev *csi2, unsigned int lanes)
 }
 
 /* Wait for active clock on the clock lane. */
-static int csi2_dphy_wait_clock_lane(struct csi2_dev *csi2)
+static int csi2_dphy_wait_clock_lane(struct dw_mipi_csi2_dev *csi2)
 {
 	u32 reg;
 	int ret;
@@ -326,7 +291,7 @@ static int csi2_dphy_wait_clock_lane(struct csi2_dev *csi2)
 }
 
 /* Setup the i.MX CSI2IPU Gasket */
-static void csi2ipu_gasket_init(struct csi2_dev *csi2)
+static void csi2ipu_gasket_init(struct dw_mipi_csi2_dev *csi2)
 {
 	u32 reg = 0;
 
@@ -342,7 +307,7 @@ static void csi2ipu_gasket_init(struct csi2_dev *csi2)
 	writel(reg, csi2->base + CSI2IPU_GASKET);
 }
 
-static int csi2_get_active_lanes(struct csi2_dev *csi2, unsigned int *lanes)
+static int csi2_get_active_lanes(struct dw_mipi_csi2_dev *csi2, unsigned int *lanes)
 {
 	struct v4l2_mbus_config mbus_config = { 0 };
 	int ret;
@@ -379,7 +344,7 @@ static int csi2_get_active_lanes(struct csi2_dev *csi2, unsigned int *lanes)
 	return 0;
 }
 
-static int csi2_start(struct csi2_dev *csi2)
+static int csi2_start(struct dw_mipi_csi2_dev *csi2)
 {
 	unsigned int lanes;
 	int ret;
@@ -435,7 +400,7 @@ static int csi2_start(struct csi2_dev *csi2)
 	return ret;
 }
 
-static void csi2_stop(struct csi2_dev *csi2)
+static void csi2_stop(struct dw_mipi_csi2_dev *csi2)
 {
 	/* stop upstream */
 	v4l2_subdev_call(csi2->src_sd, video, s_stream, 0);
@@ -451,7 +416,7 @@ static void csi2_stop(struct csi2_dev *csi2)
 
 static int csi2_s_stream(struct v4l2_subdev *sd, int enable)
 {
-	struct csi2_dev *csi2 = sd_to_dev(sd);
+	struct dw_mipi_csi2_dev *csi2 = sd_to_dev(sd);
 	int i, ret = 0;
 
 	guard(mutex)(&csi2->lock);
@@ -493,7 +458,7 @@ static int csi2_link_setup(struct media_entity *entity,
 			   const struct media_pad *remote, u32 flags)
 {
 	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
-	struct csi2_dev *csi2 = sd_to_dev(sd);
+	struct dw_mipi_csi2_dev *csi2 = sd_to_dev(sd);
 	struct v4l2_subdev *remote_sd;
 	int ret = 0;
 
@@ -528,7 +493,7 @@ static int csi2_link_setup(struct media_entity *entity,
 }
 
 static struct v4l2_mbus_framefmt *
-__csi2_get_fmt(struct csi2_dev *csi2, struct v4l2_subdev_state *sd_state,
+__csi2_get_fmt(struct dw_mipi_csi2_dev *csi2, struct v4l2_subdev_state *sd_state,
 	       unsigned int pad, enum v4l2_subdev_format_whence which)
 {
 	if (which == V4L2_SUBDEV_FORMAT_TRY)
@@ -541,7 +506,7 @@ static int csi2_get_fmt(struct v4l2_subdev *sd,
 			struct v4l2_subdev_state *sd_state,
 			struct v4l2_subdev_format *sdformat)
 {
-	struct csi2_dev *csi2 = sd_to_dev(sd);
+	struct dw_mipi_csi2_dev *csi2 = sd_to_dev(sd);
 	struct v4l2_mbus_framefmt *fmt;
 
 	guard(mutex)(&csi2->lock);
@@ -557,7 +522,7 @@ static int csi2_set_fmt(struct v4l2_subdev *sd,
 			struct v4l2_subdev_state *sd_state,
 			struct v4l2_subdev_format *sdformat)
 {
-	struct csi2_dev *csi2 = sd_to_dev(sd);
+	struct dw_mipi_csi2_dev *csi2 = sd_to_dev(sd);
 	struct v4l2_mbus_framefmt *fmt;
 
 	if (sdformat->pad >= CSI2_NUM_PADS)
@@ -581,7 +546,7 @@ static int csi2_set_fmt(struct v4l2_subdev *sd,
 
 static int csi2_registered(struct v4l2_subdev *sd)
 {
-	struct csi2_dev *csi2 = sd_to_dev(sd);
+	struct dw_mipi_csi2_dev *csi2 = sd_to_dev(sd);
 
 	/* set a default mbus format  */
 	return imx_media_init_mbus_fmt(&csi2->format_mbus,
@@ -594,7 +559,7 @@ static int csi2_registered(struct v4l2_subdev *sd)
 
 static int csi2_log_status(struct v4l2_subdev *sd)
 {
-	struct csi2_dev *csi2 = sd_to_dev(sd);
+	struct dw_mipi_csi2_dev *csi2 = sd_to_dev(sd);
 
 	v4l2_info(sd, "-----MIPI CSI status-----\n");
 	v4l2_info(sd, "VERSION: 0x%x\n", dw_readl(csi2, version));
@@ -649,7 +614,7 @@ static int csi2_notify_bound(struct v4l2_async_notifier *notifier,
 			     struct v4l2_subdev *sd,
 			     struct v4l2_async_connection *asd)
 {
-	struct csi2_dev *csi2 = notifier_to_dev(notifier);
+	struct dw_mipi_csi2_dev *csi2 = notifier_to_dev(notifier);
 	struct media_pad *sink = &csi2->sd.entity.pads[CSI2_SINK_PAD];
 	int pad;
 
@@ -672,7 +637,7 @@ static void csi2_notify_unbind(struct v4l2_async_notifier *notifier,
 			       struct v4l2_subdev *sd,
 			       struct v4l2_async_connection *asd)
 {
-	struct csi2_dev *csi2 = notifier_to_dev(notifier);
+	struct dw_mipi_csi2_dev *csi2 = notifier_to_dev(notifier);
 
 	csi2->remote = NULL;
 }
@@ -682,7 +647,7 @@ static const struct v4l2_async_notifier_operations csi2_notify_ops = {
 	.unbind = csi2_notify_unbind,
 };
 
-static int csi2_async_register(struct csi2_dev *csi2)
+static int csi2_async_register(struct dw_mipi_csi2_dev *csi2)
 {
 	struct v4l2_fwnode_endpoint vep = {
 		.bus_type = V4L2_MBUS_CSI2_DPHY,
@@ -729,21 +694,17 @@ static int csi2_async_register(struct csi2_dev *csi2)
 
 static void csi2_nf_cleanup(void *data)
 {
-	struct csi2_dev *csi2 = data;
+	struct dw_mipi_csi2_dev *csi2 = data;
 
 	v4l2_async_nf_unregister(&csi2->notifier);
 	v4l2_async_nf_cleanup(&csi2->notifier);
 }
 
-static int csi2_probe(struct platform_device *pdev)
+int dw_mipi_csi2_init(struct platform_device *pdev, struct dw_mipi_csi2_dev *csi2,
+		      const struct dw_mipi_csi2_config *config)
 {
-	struct csi2_dev *csi2;
 	int i, ret;
 
-	csi2 = devm_kzalloc(&pdev->dev, sizeof(*csi2), GFP_KERNEL);
-	if (!csi2)
-		return -ENOMEM;
-
 	csi2->dev = &pdev->dev;
 	csi2->regs = &dw_csi2_v0;
 	v4l2_subdev_init(&csi2->sd, &csi2_subdev_ops);
@@ -787,32 +748,11 @@ static int csi2_probe(struct platform_device *pdev)
 	return csi2_async_register(csi2);
 
 }
+EXPORT_SYMBOL_GPL(dw_mipi_csi2_init);
 
-static void csi2_remove(struct platform_device *pdev)
+void dw_mipi_csi2_deinit(struct dw_mipi_csi2_dev *csi2)
 {
-	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
-
-	v4l2_async_unregister_subdev(sd);
-	media_entity_cleanup(&sd->entity);
+	v4l2_async_unregister_subdev(&csi2->sd);
+	media_entity_cleanup(&csi2->sd.entity);
 }
-
-static const struct of_device_id csi2_dt_ids[] = {
-	{ .compatible = "fsl,imx6-mipi-csi2"},
-	{ /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, csi2_dt_ids);
-
-static struct platform_driver csi2_driver = {
-	.driver = {
-		.name = DEVICE_NAME,
-		.of_match_table = csi2_dt_ids,
-	},
-	.probe = csi2_probe,
-	.remove = csi2_remove,
-};
-
-module_platform_driver(csi2_driver);
-
-MODULE_DESCRIPTION("i.MX5/6 MIPI CSI-2 Receiver driver");
-MODULE_AUTHOR("Steve Longerbeam <steve_longerbeam at mentor.com>");
-MODULE_LICENSE("GPL");
+EXPORT_SYMBOL_GPL(dw_mipi_csi2_deinit);
diff --git a/include/media/dw-mipi-csi2.h b/include/media/dw-mipi-csi2.h
new file mode 100644
index 0000000000000000000000000000000000000000..4e656f09c81db9dc9f232ed061f70803a5478c85
--- /dev/null
+++ b/include/media/dw-mipi-csi2.h
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef __DW_MIPI_CSI2_COMMON_
+#define __DW_MIPI_CSI2_COMMON_
+
+#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-mc.h>
+#include <media/v4l2-subdev.h>
+
+struct dw_mipi_csi2_config {
+};
+
+/*
+ * there must be 5 pads: 1 input pad from sensor, and
+ * the 4 virtual channel output pads
+ */
+#define CSI2_SINK_PAD		0
+#define CSI2_NUM_SINK_PADS	1
+#define CSI2_NUM_SRC_PADS	4
+#define CSI2_NUM_PADS		5
+
+struct dw_mipi_csi2_dev {
+	struct device			*dev;
+	struct v4l2_subdev		sd;
+	struct v4l2_async_notifier	notifier;
+	struct media_pad		pad[CSI2_NUM_PADS];
+	void __iomem			*base;
+	const struct dw_csi2_regs	*regs;
+
+	struct clk_bulk_data		*clks;
+	int				num_clks;
+
+	struct v4l2_subdev		*remote;
+	unsigned int			remote_pad;
+	unsigned short			data_lanes;
+
+	/* lock to protect all members below */
+	struct mutex			lock;
+
+	struct v4l2_mbus_framefmt	format_mbus;
+
+	int				stream_count;
+	struct v4l2_subdev		*src_sd;
+	bool				sink_linked[CSI2_NUM_SRC_PADS];
+};
+
+static inline struct dw_mipi_csi2_dev *
+sd_to_dw_mipi_csi2_dev(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct dw_mipi_csi2_dev, sd);
+}
+
+int dw_mipi_csi2_init(struct platform_device *pdev,
+		      struct dw_mipi_csi2_dev *csi2,
+		      const struct dw_mipi_csi2_config *config);
+
+void dw_mipi_csi2_deinit(struct dw_mipi_csi2_dev *csi2);
+
+#endif
+

-- 
2.34.1



From Frank.Li at nxp.com  Thu Aug 21 13:15:47 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 21 Aug 2025 16:15:47 -0400
Subject: [PATCH v3 12/31] media: staging: media: imx6-mipi-csi2: move sd
 imx6's specific initialization into imx6-sci2.c
In-Reply-To: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
References: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
Message-ID: <20250821-95_cam-v3-12-c9286fbb34b9@nxp.com>

Move imx6's specific sd's owner, name, csi2_internal_ops, grp_id into
imx6-sci2.c.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/staging/media/imx/imx6-csi2.c      | 23 +++++++++++++++++++++++
 drivers/staging/media/imx/imx6-mipi-csi2.c | 29 ++++++-----------------------
 include/media/dw-mipi-csi2.h               |  4 ++++
 3 files changed, 33 insertions(+), 23 deletions(-)

diff --git a/drivers/staging/media/imx/imx6-csi2.c b/drivers/staging/media/imx/imx6-csi2.c
index 72eff685fad99b3def46cf2866565191b7de9a8b..66274d8d73b67b35682bb82a9eb745bb24da7ae4 100644
--- a/drivers/staging/media/imx/imx6-csi2.c
+++ b/drivers/staging/media/imx/imx6-csi2.c
@@ -19,6 +19,29 @@ struct imx6_csi2 {
 	struct dw_mipi_csi2_dev dw;
 };
 
+static int csi2_registered(struct v4l2_subdev *sd)
+{
+	struct dw_mipi_csi2_dev *csi2 = sd_to_dw_mipi_csi2_dev(sd);
+
+	/* set a default mbus format  */
+	return imx_media_init_mbus_fmt(&csi2->format_mbus,
+				      IMX_MEDIA_DEF_PIX_WIDTH,
+				      IMX_MEDIA_DEF_PIX_HEIGHT, 0,
+				      V4L2_FIELD_NONE, NULL);
+}
+
+static const struct v4l2_subdev_internal_ops csi2_internal_ops = {
+	.init_state = imx_media_init_state,
+	.registered = csi2_registered,
+};
+
+static const struct dw_mipi_csi2_config imx6_config = {
+	.module = THIS_MODULE,
+	.name = "imx6-mipi-csi2",
+	.internal_ops = &csi2_internal_ops,
+	.grp_id = IMX_MEDIA_GRP_ID_CSI2,
+};
+
 static int csi2_probe(struct platform_device *pdev)
 {
 	struct imx6_csi2 *csi2;
diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index b5911a37972be868e10c115ada1910fa04b2765c..ff06a739b957b305625d145c04c06999d0c13cae 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -15,11 +15,11 @@
 #include <linux/platform_device.h>
 #include <media/dw-mipi-csi2.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-fwnode.h>
 #include <media/v4l2-mc.h>
 #include <media/v4l2-subdev.h>
-#include "imx-media.h"
 
 /*
  * The default maximum bit-rate per lane in Mbps, if the
@@ -44,8 +44,6 @@ struct dw_csi2_regs {
 	u32	phy_tst_ctrl1;
 };
 
-#define DEVICE_NAME "imx6-mipi-csi2"
-
 /* Help check wrong access unexisted register at difference IP version */
 #define DW_REG_EXIST		0x80000000
 #define DW_REG(x)		(DW_REG_EXIST | (x))
@@ -544,17 +542,6 @@ static int csi2_set_fmt(struct v4l2_subdev *sd,
 	return 0;
 }
 
-static int csi2_registered(struct v4l2_subdev *sd)
-{
-	struct dw_mipi_csi2_dev *csi2 = sd_to_dev(sd);
-
-	/* set a default mbus format  */
-	return imx_media_init_mbus_fmt(&csi2->format_mbus,
-				      IMX_MEDIA_DEF_PIX_WIDTH,
-				      IMX_MEDIA_DEF_PIX_HEIGHT, 0,
-				      V4L2_FIELD_NONE, NULL);
-}
-
 /* --------------- CORE OPS --------------- */
 
 static int csi2_log_status(struct v4l2_subdev *sd)
@@ -605,11 +592,6 @@ static const struct v4l2_subdev_ops csi2_subdev_ops = {
 	.pad = &csi2_pad_ops,
 };
 
-static const struct v4l2_subdev_internal_ops csi2_internal_ops = {
-	.init_state = imx_media_init_state,
-	.registered = csi2_registered,
-};
-
 static int csi2_notify_bound(struct v4l2_async_notifier *notifier,
 			     struct v4l2_subdev *sd,
 			     struct v4l2_async_connection *asd)
@@ -709,14 +691,15 @@ int dw_mipi_csi2_init(struct platform_device *pdev, struct dw_mipi_csi2_dev *csi
 	csi2->regs = &dw_csi2_v0;
 	v4l2_subdev_init(&csi2->sd, &csi2_subdev_ops);
 	v4l2_set_subdevdata(&csi2->sd, &pdev->dev);
-	csi2->sd.internal_ops = &csi2_internal_ops;
 	csi2->sd.entity.ops = &csi2_entity_ops;
 	csi2->sd.dev = &pdev->dev;
-	csi2->sd.owner = THIS_MODULE;
 	csi2->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
-	strscpy(csi2->sd.name, DEVICE_NAME, sizeof(csi2->sd.name));
 	csi2->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
-	csi2->sd.grp_id = IMX_MEDIA_GRP_ID_CSI2;
+
+	csi2->sd.owner = config->module;
+	strscpy(csi2->sd.name, config->name, sizeof(csi2->sd.name));
+	csi2->sd.internal_ops = config->internal_ops;
+	csi2->sd.grp_id = config->grp_id;
 
 	for (i = 0; i < CSI2_NUM_PADS; i++) {
 		csi2->pad[i].flags = (i == CSI2_SINK_PAD) ?
diff --git a/include/media/dw-mipi-csi2.h b/include/media/dw-mipi-csi2.h
index 4e656f09c81db9dc9f232ed061f70803a5478c85..dfd25e23ea93fd53b064471b6a9557ef9c070fe7 100644
--- a/include/media/dw-mipi-csi2.h
+++ b/include/media/dw-mipi-csi2.h
@@ -10,6 +10,10 @@
 #include <media/v4l2-subdev.h>
 
 struct dw_mipi_csi2_config {
+	struct module *module;
+	const char *name;
+	int grp_id;
+	const struct v4l2_subdev_internal_ops *internal_ops;
 };
 
 /*

-- 
2.34.1



From Frank.Li at nxp.com  Thu Aug 21 13:15:48 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 21 Aug 2025 16:15:48 -0400
Subject: [PATCH v3 13/31] media: staging: media: imx6-mipi-csi2: move
 csi2ipu_gasket_init() to imx6-csi2.c
In-Reply-To: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
References: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
Message-ID: <20250821-95_cam-v3-13-c9286fbb34b9@nxp.com>

Move platform specific csi2ipu_gasket_init() to imx6-csi2.c.

Create callback function in struct dw_mipi_csi2_config.

Prepare create common library for dw MIPI CSI2.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/staging/media/imx/imx6-csi2.c      | 28 +++++++++++++++++++++++++++-
 drivers/staging/media/imx/imx6-mipi-csi2.c | 28 +++-------------------------
 include/media/dw-mipi-csi2.h               |  6 ++++++
 3 files changed, 36 insertions(+), 26 deletions(-)

diff --git a/drivers/staging/media/imx/imx6-csi2.c b/drivers/staging/media/imx/imx6-csi2.c
index 66274d8d73b67b35682bb82a9eb745bb24da7ae4..b7ea710df07cba33465d79ef57be4792c503958a 100644
--- a/drivers/staging/media/imx/imx6-csi2.c
+++ b/drivers/staging/media/imx/imx6-csi2.c
@@ -15,10 +15,35 @@
 #include <media/dw-mipi-csi2.h>
 #include "imx-media.h"
 
+/*
+ * i.MX CSI2IPU Gasket registers follow. The CSI2IPU gasket is
+ * not part of the MIPI CSI-2 core, but its registers fall in the
+ * same register map range.
+ */
+#define CSI2IPU_GASKET		0xf00
+#define CSI2IPU_YUV422_YUYV	BIT(2)
+
 struct imx6_csi2 {
 	struct dw_mipi_csi2_dev dw;
 };
 
+/* Setup the i.MX CSI2IPU Gasket */
+static void csi2ipu_gasket_init(struct dw_mipi_csi2_dev *csi2)
+{
+	u32 reg = 0;
+
+	switch (csi2->format_mbus.code) {
+	case MEDIA_BUS_FMT_YUYV8_2X8:
+	case MEDIA_BUS_FMT_YUYV8_1X16:
+		reg = CSI2IPU_YUV422_YUYV;
+		break;
+	default:
+		break;
+	}
+
+	writel(reg, csi2->base + CSI2IPU_GASKET);
+}
+
 static int csi2_registered(struct v4l2_subdev *sd)
 {
 	struct dw_mipi_csi2_dev *csi2 = sd_to_dw_mipi_csi2_dev(sd);
@@ -40,6 +65,7 @@ static const struct dw_mipi_csi2_config imx6_config = {
 	.name = "imx6-mipi-csi2",
 	.internal_ops = &csi2_internal_ops,
 	.grp_id = IMX_MEDIA_GRP_ID_CSI2,
+	.gasket_init = csi2ipu_gasket_init,
 };
 
 static int csi2_probe(struct platform_device *pdev)
@@ -50,7 +76,7 @@ static int csi2_probe(struct platform_device *pdev)
 	if (!csi2)
 		return -ENOMEM;
 
-	return dw_mipi_csi2_init(pdev, &csi2->dw, NULL);
+	return dw_mipi_csi2_init(pdev, &csi2->dw, &imx6_config);
 }
 
 static void csi2_remove(struct platform_device *pdev)
diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index ff06a739b957b305625d145c04c06999d0c13cae..e5593f23253b92def63040fa70fcf5fb50ec2fd2 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -92,13 +92,6 @@ dw_csi2_reg_err(csi2, #__name))
 #define PHY_TESTCLK		BIT(1)
 
 #define PHY_TESTEN		BIT(16)
-/*
- * i.MX CSI2IPU Gasket registers follow. The CSI2IPU gasket is
- * not part of the MIPI CSI-2 core, but its registers fall in the
- * same register map range.
- */
-#define CSI2IPU_GASKET		0xf00
-#define CSI2IPU_YUV422_YUYV	BIT(2)
 
 #define sd_to_dev sd_to_dw_mipi_csi2_dev
 
@@ -288,23 +281,6 @@ static int csi2_dphy_wait_clock_lane(struct dw_mipi_csi2_dev *csi2)
 	return 0;
 }
 
-/* Setup the i.MX CSI2IPU Gasket */
-static void csi2ipu_gasket_init(struct dw_mipi_csi2_dev *csi2)
-{
-	u32 reg = 0;
-
-	switch (csi2->format_mbus.code) {
-	case MEDIA_BUS_FMT_YUYV8_2X8:
-	case MEDIA_BUS_FMT_YUYV8_1X16:
-		reg = CSI2IPU_YUV422_YUYV;
-		break;
-	default:
-		break;
-	}
-
-	writel(reg, csi2->base + CSI2IPU_GASKET);
-}
-
 static int csi2_get_active_lanes(struct dw_mipi_csi2_dev *csi2, unsigned int *lanes)
 {
 	struct v4l2_mbus_config mbus_config = { 0 };
@@ -352,7 +328,8 @@ static int csi2_start(struct dw_mipi_csi2_dev *csi2)
 		return ret;
 
 	/* setup the gasket */
-	csi2ipu_gasket_init(csi2);
+	if (csi2->config && csi2->config->gasket_init)
+		csi2->config->gasket_init(csi2);
 
 	/* Step 3 */
 	ret = csi2_dphy_init(csi2);
@@ -700,6 +677,7 @@ int dw_mipi_csi2_init(struct platform_device *pdev, struct dw_mipi_csi2_dev *csi
 	strscpy(csi2->sd.name, config->name, sizeof(csi2->sd.name));
 	csi2->sd.internal_ops = config->internal_ops;
 	csi2->sd.grp_id = config->grp_id;
+	csi2->config = config;
 
 	for (i = 0; i < CSI2_NUM_PADS; i++) {
 		csi2->pad[i].flags = (i == CSI2_SINK_PAD) ?
diff --git a/include/media/dw-mipi-csi2.h b/include/media/dw-mipi-csi2.h
index dfd25e23ea93fd53b064471b6a9557ef9c070fe7..d3e1c334df692c5dff10b467d759fe4da45b7b5f 100644
--- a/include/media/dw-mipi-csi2.h
+++ b/include/media/dw-mipi-csi2.h
@@ -9,11 +9,15 @@
 #include <media/v4l2-mc.h>
 #include <media/v4l2-subdev.h>
 
+struct dw_mipi_csi2_dev;
+
 struct dw_mipi_csi2_config {
 	struct module *module;
 	const char *name;
 	int grp_id;
 	const struct v4l2_subdev_internal_ops *internal_ops;
+	/* Deprecated, should go through phy interface */
+	void (*gasket_init)(struct dw_mipi_csi2_dev *dev);
 };
 
 /*
@@ -48,6 +52,8 @@ struct dw_mipi_csi2_dev {
 	int				stream_count;
 	struct v4l2_subdev		*src_sd;
 	bool				sink_linked[CSI2_NUM_SRC_PADS];
+
+	const struct dw_mipi_csi2_config *config;
 };
 
 static inline struct dw_mipi_csi2_dev *

-- 
2.34.1



From Frank.Li at nxp.com  Thu Aug 21 13:15:49 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 21 Aug 2025 16:15:49 -0400
Subject: [PATCH v3 14/31] media: staging: media: imx6-mipi-csi2: move
 number pad macro define into imx6-csi2.c
In-Reply-To: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
References: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
Message-ID: <20250821-95_cam-v3-14-c9286fbb34b9@nxp.com>

Move number of pad macro to imx6-csi2.c. The number of pads is platform
related feature.

This version just support maximum 32 pads.

Prepare to create common library for dw MIPI CSI2 controller.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/staging/media/imx/imx6-csi2.c      | 12 ++++++++++++
 drivers/staging/media/imx/imx6-mipi-csi2.c | 27 ++++++++++++++++++---------
 include/media/dw-mipi-csi2.h               | 21 +++++++++------------
 3 files changed, 39 insertions(+), 21 deletions(-)

diff --git a/drivers/staging/media/imx/imx6-csi2.c b/drivers/staging/media/imx/imx6-csi2.c
index b7ea710df07cba33465d79ef57be4792c503958a..062db72a36ef294566272d9f39d82e9414640e9a 100644
--- a/drivers/staging/media/imx/imx6-csi2.c
+++ b/drivers/staging/media/imx/imx6-csi2.c
@@ -4,6 +4,7 @@
  *
  * Copyright (c) 2012-2017 Mentor Graphics Inc.
  */
+#include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -60,12 +61,23 @@ static const struct v4l2_subdev_internal_ops csi2_internal_ops = {
 	.registered = csi2_registered,
 };
 
+/*
+ * there must be 5 pads: 1 input pad from sensor, and
+ * the 4 virtual channel output pads
+ */
+#define CSI2_SINK_PAD		0
+#define CSI2_NUM_SINK_PADS	1
+#define CSI2_NUM_SRC_PADS	4
+#define CSI2_NUM_PADS		5
+
 static const struct dw_mipi_csi2_config imx6_config = {
 	.module = THIS_MODULE,
 	.name = "imx6-mipi-csi2",
 	.internal_ops = &csi2_internal_ops,
 	.grp_id = IMX_MEDIA_GRP_ID_CSI2,
 	.gasket_init = csi2ipu_gasket_init,
+	.num_pads = CSI2_NUM_PADS,
+	.sink_pad_mask = BIT(CSI2_NUM_SINK_PADS),
 };
 
 static int csi2_probe(struct platform_device *pdev)
diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index e5593f23253b92def63040fa70fcf5fb50ec2fd2..d591288d2240c9042851f3a862299d372af9775c 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -399,11 +399,11 @@ static int csi2_s_stream(struct v4l2_subdev *sd, int enable)
 	if (!csi2->src_sd)
 		return -EPIPE;
 
-	for (i = 0; i < CSI2_NUM_SRC_PADS; i++) {
+	for (i = 0; i < csi2->num_sink_pads; i++) {
 		if (csi2->sink_linked[i])
 			break;
 	}
-	if (i >= CSI2_NUM_SRC_PADS)
+	if (i >= csi2->num_sink_pads)
 		return -EPIPE;
 
 	/*
@@ -500,7 +500,7 @@ static int csi2_set_fmt(struct v4l2_subdev *sd,
 	struct dw_mipi_csi2_dev *csi2 = sd_to_dev(sd);
 	struct v4l2_mbus_framefmt *fmt;
 
-	if (sdformat->pad >= CSI2_NUM_PADS)
+	if (sdformat->pad >= (csi2->num_src_pads + csi2->num_sink_pads))
 		return -EINVAL;
 
 	guard(mutex)(&csi2->lock);
@@ -509,7 +509,7 @@ static int csi2_set_fmt(struct v4l2_subdev *sd,
 		return -EBUSY;
 
 	/* Output pads mirror active input pad, no limits on input pads */
-	if (sdformat->pad != CSI2_SINK_PAD)
+	if (!(csi2->config->sink_pad_mask & BIT(sdformat->pad)))
 		sdformat->format = csi2->format_mbus;
 
 	fmt = __csi2_get_fmt(csi2, sd_state, sdformat->pad, sdformat->which);
@@ -574,7 +574,8 @@ static int csi2_notify_bound(struct v4l2_async_notifier *notifier,
 			     struct v4l2_async_connection *asd)
 {
 	struct dw_mipi_csi2_dev *csi2 = notifier_to_dev(notifier);
-	struct media_pad *sink = &csi2->sd.entity.pads[CSI2_SINK_PAD];
+	int sink_index = ffs(csi2->config->sink_pad_mask) - 1;
+	struct media_pad *sink = &csi2->sd.entity.pads[sink_index];
 	int pad;
 
 	pad = media_entity_get_fwnode_pad(&sd->entity, asd->match.fwnode,
@@ -679,12 +680,20 @@ int dw_mipi_csi2_init(struct platform_device *pdev, struct dw_mipi_csi2_dev *csi
 	csi2->sd.grp_id = config->grp_id;
 	csi2->config = config;
 
-	for (i = 0; i < CSI2_NUM_PADS; i++) {
-		csi2->pad[i].flags = (i == CSI2_SINK_PAD) ?
-		MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
+	if (!config)
+		return -EINVAL;
+
+	for (i = 0; i < config->num_pads; i++) {
+		if (config->sink_pad_mask & BIT(i)) {
+			csi2->pad[i].flags = MEDIA_PAD_FL_SINK;
+			csi2->num_sink_pads++;
+		} else {
+			csi2->pad[i].flags = MEDIA_PAD_FL_SOURCE;
+			csi2->num_src_pads++;
+		}
 	}
 
-	ret = media_entity_pads_init(&csi2->sd.entity, CSI2_NUM_PADS,
+	ret = media_entity_pads_init(&csi2->sd.entity, config->num_pads,
 				     csi2->pad);
 	if (ret)
 		return ret;
diff --git a/include/media/dw-mipi-csi2.h b/include/media/dw-mipi-csi2.h
index d3e1c334df692c5dff10b467d759fe4da45b7b5f..12e1db1d149513fcd0db8c191c801cb144d18143 100644
--- a/include/media/dw-mipi-csi2.h
+++ b/include/media/dw-mipi-csi2.h
@@ -11,6 +11,8 @@
 
 struct dw_mipi_csi2_dev;
 
+#define DW_MAX_PAD_NUM		32
+
 struct dw_mipi_csi2_config {
 	struct module *module;
 	const char *name;
@@ -18,22 +20,18 @@ struct dw_mipi_csi2_config {
 	const struct v4l2_subdev_internal_ops *internal_ops;
 	/* Deprecated, should go through phy interface */
 	void (*gasket_init)(struct dw_mipi_csi2_dev *dev);
+	u32	num_pads;	/* Max 64 pad now */
+	u32	sink_pad_mask;
 };
 
-/*
- * there must be 5 pads: 1 input pad from sensor, and
- * the 4 virtual channel output pads
- */
-#define CSI2_SINK_PAD		0
-#define CSI2_NUM_SINK_PADS	1
-#define CSI2_NUM_SRC_PADS	4
-#define CSI2_NUM_PADS		5
-
 struct dw_mipi_csi2_dev {
 	struct device			*dev;
 	struct v4l2_subdev		sd;
 	struct v4l2_async_notifier	notifier;
-	struct media_pad		pad[CSI2_NUM_PADS];
+	struct media_pad		pad[DW_MAX_PAD_NUM];
+	int				num_src_pads;
+	int				num_sink_pads;
+
 	void __iomem			*base;
 	const struct dw_csi2_regs	*regs;
 
@@ -51,8 +49,7 @@ struct dw_mipi_csi2_dev {
 
 	int				stream_count;
 	struct v4l2_subdev		*src_sd;
-	bool				sink_linked[CSI2_NUM_SRC_PADS];
-
+	bool				sink_linked[DW_MAX_PAD_NUM];
 	const struct dw_mipi_csi2_config *config;
 };
 

-- 
2.34.1



From Frank.Li at nxp.com  Thu Aug 21 13:15:50 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 21 Aug 2025 16:15:50 -0400
Subject: [PATCH v3 15/31] media: staging: media: imx6-mipi-csi2: move dphy
 init part to imx6-csi2.c
In-Reply-To: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
References: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
Message-ID: <20250821-95_cam-v3-15-c9286fbb34b9@nxp.com>

Move dphy init part to imx6-csi.c.

Prepare create common library for dw MIPI CSI2 controller.

Add callback for dphy_init in struct dw_mipi_csi2_config. New driver should
use phy interface.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/staging/media/imx/imx6-csi2.c      | 55 +++++++++++++++++++++++
 drivers/staging/media/imx/imx6-mipi-csi2.c | 72 ++++++------------------------
 include/media/dw-mipi-csi2.h               | 21 +++++++++
 3 files changed, 89 insertions(+), 59 deletions(-)

diff --git a/drivers/staging/media/imx/imx6-csi2.c b/drivers/staging/media/imx/imx6-csi2.c
index 062db72a36ef294566272d9f39d82e9414640e9a..696644aa04c83b1f2877b2b2315202627d927e96 100644
--- a/drivers/staging/media/imx/imx6-csi2.c
+++ b/drivers/staging/media/imx/imx6-csi2.c
@@ -16,6 +16,12 @@
 #include <media/dw-mipi-csi2.h>
 #include "imx-media.h"
 
+/*
+ * The default maximum bit-rate per lane in Mbps, if the
+ * source subdev does not provide V4L2_CID_LINK_FREQ.
+ */
+#define CSI2_DEFAULT_MAX_MBPS	849
+
 /*
  * i.MX CSI2IPU Gasket registers follow. The CSI2IPU gasket is
  * not part of the MIPI CSI-2 core, but its registers fall in the
@@ -28,6 +34,54 @@ struct imx6_csi2 {
 	struct dw_mipi_csi2_dev dw;
 };
 
+static const struct {
+	u32 max_mbps;
+	u32 hsfreqrange_sel;
+} hsfreq_map[] = {
+	{ 90, 0x00}, {100, 0x20}, {110, 0x40}, {125, 0x02},
+	{140, 0x22}, {150, 0x42}, {160, 0x04}, {180, 0x24},
+	{200, 0x44}, {210, 0x06}, {240, 0x26}, {250, 0x46},
+	{270, 0x08}, {300, 0x28}, {330, 0x48}, {360, 0x2a},
+	{400, 0x4a}, {450, 0x0c}, {500, 0x2c}, {550, 0x0e},
+	{600, 0x2e}, {650, 0x10}, {700, 0x30}, {750, 0x12},
+	{800, 0x32}, {850, 0x14}, {900, 0x34}, {950, 0x54},
+	{1000, 0x74},
+};
+
+static int max_mbps_to_hsfreqrange_sel(u32 max_mbps)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(hsfreq_map); i++)
+		if (hsfreq_map[i].max_mbps > max_mbps)
+			return hsfreq_map[i].hsfreqrange_sel;
+
+	return -EINVAL;
+}
+
+static int csi2_dphy_init(struct dw_mipi_csi2_dev *csi2)
+{
+	struct v4l2_ctrl *ctrl;
+	u32 mbps_per_lane;
+	int sel;
+
+	ctrl = v4l2_ctrl_find(csi2->src_sd->ctrl_handler,
+			      V4L2_CID_LINK_FREQ);
+	if (!ctrl)
+		mbps_per_lane = CSI2_DEFAULT_MAX_MBPS;
+	else
+		mbps_per_lane = DIV_ROUND_UP_ULL(2 * ctrl->qmenu_int[ctrl->val],
+						 USEC_PER_SEC);
+
+	sel = max_mbps_to_hsfreqrange_sel(mbps_per_lane);
+	if (sel < 0)
+		return sel;
+
+	dw_mipi_csi2_tstif_write(csi2, 0x44, sel);
+
+	return 0;
+}
+
 /* Setup the i.MX CSI2IPU Gasket */
 static void csi2ipu_gasket_init(struct dw_mipi_csi2_dev *csi2)
 {
@@ -74,6 +128,7 @@ static const struct dw_mipi_csi2_config imx6_config = {
 	.module = THIS_MODULE,
 	.name = "imx6-mipi-csi2",
 	.internal_ops = &csi2_internal_ops,
+	.dphy_init = csi2_dphy_init,
 	.grp_id = IMX_MEDIA_GRP_ID_CSI2,
 	.gasket_init = csi2ipu_gasket_init,
 	.num_pads = CSI2_NUM_PADS,
diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index d591288d2240c9042851f3a862299d372af9775c..8a8741e1c688756ee755e9a13991ccca893e5b5c 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -21,12 +21,6 @@
 #include <media/v4l2-mc.h>
 #include <media/v4l2-subdev.h>
 
-/*
- * The default maximum bit-rate per lane in Mbps, if the
- * source subdev does not provide V4L2_CID_LINK_FREQ.
- */
-#define CSI2_DEFAULT_MAX_MBPS	849
-
 struct dw_csi2_regs {
 	u32	version;
 	u32	n_lanes;
@@ -146,9 +140,11 @@ static void csi2_set_lanes(struct dw_mipi_csi2_dev *csi2, unsigned int lanes)
 	dw_writel(csi2, lanes - 1, n_lanes);
 }
 
-static void dw_mipi_csi2_phy_write(struct dw_mipi_csi2_dev *csi2,
-				   u32 test_code, u32 test_data)
+static int dw_mipi_csi2_phy_write(struct dw_mipi_tstif *tstif,
+				  u32 test_code, u32 test_data)
 {
+	struct dw_mipi_csi2_dev *csi2 = container_of(tstif, struct dw_mipi_csi2_dev, tstif);
+
 	/* Clear PHY test interface */
 	dw_writel(csi2, PHY_TESTCLR, phy_tst_ctrl0);
 	dw_writel(csi2, 0x0, phy_tst_ctrl1);
@@ -167,6 +163,8 @@ static void dw_mipi_csi2_phy_write(struct dw_mipi_csi2_dev *csi2,
 
 	/* Clear strobe signal */
 	dw_writel(csi2, 0x0, phy_tst_ctrl0);
+
+	return 0;
 }
 
 /*
@@ -174,54 +172,6 @@ static void dw_mipi_csi2_phy_write(struct dw_mipi_csi2_dev *csi2,
  * https://community.nxp.com/docs/DOC-94312. It assumes
  * a 27MHz D-PHY pll reference clock.
  */
-static const struct {
-	u32 max_mbps;
-	u32 hsfreqrange_sel;
-} hsfreq_map[] = {
-	{ 90, 0x00}, {100, 0x20}, {110, 0x40}, {125, 0x02},
-	{140, 0x22}, {150, 0x42}, {160, 0x04}, {180, 0x24},
-	{200, 0x44}, {210, 0x06}, {240, 0x26}, {250, 0x46},
-	{270, 0x08}, {300, 0x28}, {330, 0x48}, {360, 0x2a},
-	{400, 0x4a}, {450, 0x0c}, {500, 0x2c}, {550, 0x0e},
-	{600, 0x2e}, {650, 0x10}, {700, 0x30}, {750, 0x12},
-	{800, 0x32}, {850, 0x14}, {900, 0x34}, {950, 0x54},
-	{1000, 0x74},
-};
-
-static int max_mbps_to_hsfreqrange_sel(u32 max_mbps)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(hsfreq_map); i++)
-		if (hsfreq_map[i].max_mbps > max_mbps)
-			return hsfreq_map[i].hsfreqrange_sel;
-
-	return -EINVAL;
-}
-
-static int csi2_dphy_init(struct dw_mipi_csi2_dev *csi2)
-{
-	struct v4l2_ctrl *ctrl;
-	u32 mbps_per_lane;
-	int sel;
-
-	ctrl = v4l2_ctrl_find(csi2->src_sd->ctrl_handler,
-			      V4L2_CID_LINK_FREQ);
-	if (!ctrl)
-		mbps_per_lane = CSI2_DEFAULT_MAX_MBPS;
-	else
-		mbps_per_lane = DIV_ROUND_UP_ULL(2 * ctrl->qmenu_int[ctrl->val],
-						 USEC_PER_SEC);
-
-	sel = max_mbps_to_hsfreqrange_sel(mbps_per_lane);
-	if (sel < 0)
-		return sel;
-
-	dw_mipi_csi2_phy_write(csi2, 0x44, sel);
-
-	return 0;
-}
-
 /*
  * Waits for ultra-low-power state on D-PHY clock lane. This is currently
  * unused and may not be needed at all, but keep around just in case.
@@ -332,9 +282,11 @@ static int csi2_start(struct dw_mipi_csi2_dev *csi2)
 		csi2->config->gasket_init(csi2);
 
 	/* Step 3 */
-	ret = csi2_dphy_init(csi2);
-	if (ret)
-		goto err_disable_clk;
+	if (csi2->config && csi2->config->dphy_init) {
+		ret = csi2->config->dphy_init(csi2);
+		if (ret)
+			goto err_disable_clk;
+	}
 
 	ret = csi2_get_active_lanes(csi2, &lanes);
 	if (ret)
@@ -680,6 +632,8 @@ int dw_mipi_csi2_init(struct platform_device *pdev, struct dw_mipi_csi2_dev *csi
 	csi2->sd.grp_id = config->grp_id;
 	csi2->config = config;
 
+	csi2->tstif.write = dw_mipi_csi2_phy_write;
+
 	if (!config)
 		return -EINVAL;
 
diff --git a/include/media/dw-mipi-csi2.h b/include/media/dw-mipi-csi2.h
index 12e1db1d149513fcd0db8c191c801cb144d18143..935c664440aae82d69f0253a551b91ec4ff2724e 100644
--- a/include/media/dw-mipi-csi2.h
+++ b/include/media/dw-mipi-csi2.h
@@ -20,10 +20,26 @@ struct dw_mipi_csi2_config {
 	const struct v4l2_subdev_internal_ops *internal_ops;
 	/* Deprecated, should go through phy interface */
 	void (*gasket_init)(struct dw_mipi_csi2_dev *dev);
+	int (*dphy_init)(struct dw_mipi_csi2_dev *dev);
 	u32	num_pads;	/* Max 64 pad now */
 	u32	sink_pad_mask;
 };
 
+struct dw_mipi_tstif {
+	int (*write)(struct dw_mipi_tstif *tstif, u32 indice, u32 data);
+};
+
+static inline int dw_mipi_tstif_write(struct dw_mipi_tstif *tstif, u32 indice, u32 data)
+{
+	if (!tstif)
+		return -EINVAL;
+
+	if (!tstif->write)
+		return -EINVAL;
+
+	return  tstif->write(tstif, indice, data);
+}
+
 struct dw_mipi_csi2_dev {
 	struct device			*dev;
 	struct v4l2_subdev		sd;
@@ -51,8 +67,13 @@ struct dw_mipi_csi2_dev {
 	struct v4l2_subdev		*src_sd;
 	bool				sink_linked[DW_MAX_PAD_NUM];
 	const struct dw_mipi_csi2_config *config;
+
+	struct dw_mipi_tstif		tstif;
 };
 
+#define dw_mipi_csi2_tstif_write(csi2, indice, data)		\
+dw_mipi_tstif_write(&(csi2)->tstif, indice, data)
+
 static inline struct dw_mipi_csi2_dev *
 sd_to_dw_mipi_csi2_dev(struct v4l2_subdev *sd)
 {

-- 
2.34.1



From Frank.Li at nxp.com  Thu Aug 21 13:15:51 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 21 Aug 2025 16:15:51 -0400
Subject: [PATCH v3 16/31] media: staging: media: imx6-mipi-csi2: use
 runtime_pm frame to control clks
In-Reply-To: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
References: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
Message-ID: <20250821-95_cam-v3-16-c9286fbb34b9@nxp.com>

Enable runtime pm and use runtime pm API to control clocks.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/staging/media/imx/imx6-csi2.c      |  4 ++++
 drivers/staging/media/imx/imx6-mipi-csi2.c | 11 ++++++++---
 include/media/dw-mipi-csi2.h               | 18 ++++++++++++++++++
 3 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/media/imx/imx6-csi2.c b/drivers/staging/media/imx/imx6-csi2.c
index 696644aa04c83b1f2877b2b2315202627d927e96..e5192bcd886958a27f4255fca1055ae0a94866ef 100644
--- a/drivers/staging/media/imx/imx6-csi2.c
+++ b/drivers/staging/media/imx/imx6-csi2.c
@@ -154,6 +154,9 @@ static void csi2_remove(struct platform_device *pdev)
 	dw_mipi_csi2_deinit(csi2);
 }
 
+static DEFINE_RUNTIME_DEV_PM_OPS(imx6_csi2_pm_ops, dw_mipi_csi2_runtime_suspend,
+				 dw_mipi_csi2_runtime_resume, NULL);
+
 static const struct of_device_id csi2_dt_ids[] = {
 	{ .compatible = "fsl,imx6-mipi-csi2"},
 	{ /* sentinel */ }
@@ -164,6 +167,7 @@ static struct platform_driver csi2_driver = {
 	.driver = {
 		.name = "imx6-mipi-csi2",
 		.of_match_table = csi2_dt_ids,
+		.pm = pm_ptr(&imx6_csi2_pm_ops),
 	},
 	.probe = csi2_probe,
 	.remove = csi2_remove,
diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index 8a8741e1c688756ee755e9a13991ccca893e5b5c..22e0021fab17f3c8e9a6c41c2f2109f5112dd6e5 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -273,7 +273,7 @@ static int csi2_start(struct dw_mipi_csi2_dev *csi2)
 	unsigned int lanes;
 	int ret;
 
-	ret = clk_bulk_prepare_enable(csi2->num_clks, csi2->clks);
+	ret = pm_runtime_resume_and_get(csi2->dev);
 	if (ret)
 		return ret;
 
@@ -323,7 +323,7 @@ static int csi2_start(struct dw_mipi_csi2_dev *csi2)
 err_assert_reset:
 	csi2_enable(csi2, false);
 err_disable_clk:
-	clk_bulk_disable_unprepare(csi2->num_clks, csi2->clks);
+	pm_runtime_put(csi2->dev);
 	return ret;
 }
 
@@ -334,7 +334,8 @@ static void csi2_stop(struct dw_mipi_csi2_dev *csi2)
 	v4l2_subdev_call(csi2->src_sd, video, post_streamoff);
 
 	csi2_enable(csi2, false);
-	clk_bulk_disable_unprepare(csi2->num_clks, csi2->clks);
+
+	pm_runtime_put(csi2->dev);
 }
 
 /*
@@ -634,6 +635,8 @@ int dw_mipi_csi2_init(struct platform_device *pdev, struct dw_mipi_csi2_dev *csi
 
 	csi2->tstif.write = dw_mipi_csi2_phy_write;
 
+	platform_set_drvdata(pdev, csi2);
+
 	if (!config)
 		return -EINVAL;
 
@@ -669,6 +672,8 @@ int dw_mipi_csi2_init(struct platform_device *pdev, struct dw_mipi_csi2_dev *csi
 	if (csi2->num_clks < 0)
 		return dev_err_probe(&pdev->dev, csi2->num_clks, "Failed to get clocks\n");
 
+	devm_pm_runtime_enable(&pdev->dev);
+
 	return csi2_async_register(csi2);
 
 }
diff --git a/include/media/dw-mipi-csi2.h b/include/media/dw-mipi-csi2.h
index 935c664440aae82d69f0253a551b91ec4ff2724e..3d70c1f4f38e7d663f9b043d8903ce57d630d1b1 100644
--- a/include/media/dw-mipi-csi2.h
+++ b/include/media/dw-mipi-csi2.h
@@ -3,6 +3,8 @@
 #ifndef __DW_MIPI_CSI2_COMMON_
 #define __DW_MIPI_CSI2_COMMON_
 
+#include <linux/pm_runtime.h>
+
 #include <media/v4l2-common.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-fwnode.h>
@@ -86,5 +88,21 @@ int dw_mipi_csi2_init(struct platform_device *pdev,
 
 void dw_mipi_csi2_deinit(struct dw_mipi_csi2_dev *csi2);
 
+static inline int dw_mipi_csi2_runtime_suspend(struct device *dev)
+{
+	struct dw_mipi_csi2_dev *csi2 = dev_get_drvdata(dev);
+
+	clk_bulk_disable_unprepare(csi2->num_clks, csi2->clks);
+
+	return 0;
+}
+
+static inline int dw_mipi_csi2_runtime_resume(struct device *dev)
+{
+	struct dw_mipi_csi2_dev *csi2 = dev_get_drvdata(dev);
+
+	return clk_bulk_prepare_enable(csi2->num_clks, csi2->clks);
+}
+
 #endif
 

-- 
2.34.1



From Frank.Li at nxp.com  Thu Aug 21 13:15:52 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 21 Aug 2025 16:15:52 -0400
Subject: [PATCH v3 17/31] media: synopsys: move imx6-mipi-csi2.c to
 synopsys/mipi-csi2.c
In-Reply-To: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
References: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
Message-ID: <20250821-95_cam-v3-17-c9286fbb34b9@nxp.com>

Move dw MIPI CSI2 common part drivers/staging/media/imx/imx6-mipi-csi2.c
under synopsys to let more SoC can reuse it.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/media/platform/synopsys/Kconfig                      | 12 ++++++++++++
 drivers/media/platform/synopsys/Makefile                     |  2 ++
 .../imx6-mipi-csi2.c => media/platform/synopsys/mipi-csi2.c} |  0
 drivers/staging/media/imx/Kconfig                            |  1 +
 drivers/staging/media/imx/Makefile                           |  2 +-
 5 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/synopsys/Kconfig b/drivers/media/platform/synopsys/Kconfig
index 4fd521f78425a96985fa3b6b017deef36631d1a9..e54dad835349d420dead6d5313c0623567c28c0b 100644
--- a/drivers/media/platform/synopsys/Kconfig
+++ b/drivers/media/platform/synopsys/Kconfig
@@ -1,3 +1,15 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
+config VIDEO_SYNOPSYS_MIPI_CSI2
+        tristate "Synopsys DesignWare MIPI CSI2 Receiver common library"
+        depends on VIDEO_DEV
+        select MEDIA_CONTROLLER
+        select VIDEO_V4L2_SUBDEV_API
+        select VIDEOBUF2_DMA_CONTIG
+        help
+          Common library for MIPI CSI2 Controller.
+
+          To compile this driver as a module, choose M here. The module
+          will be called synopsys_hdmirx
+
 source "drivers/media/platform/synopsys/hdmirx/Kconfig"
diff --git a/drivers/media/platform/synopsys/Makefile b/drivers/media/platform/synopsys/Makefile
index 3b12c574dd67c072901108d88cad64ca3a723938..045ed3177738e6d28aa223804b79e6774e141dc8 100644
--- a/drivers/media/platform/synopsys/Makefile
+++ b/drivers/media/platform/synopsys/Makefile
@@ -1,2 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-y += hdmirx/
+
+obj-$(CONFIG_VIDEO_SYNOPSYS_MIPI_CSI2) += mipi-csi2.o
diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/media/platform/synopsys/mipi-csi2.c
similarity index 100%
rename from drivers/staging/media/imx/imx6-mipi-csi2.c
rename to drivers/media/platform/synopsys/mipi-csi2.c
diff --git a/drivers/staging/media/imx/Kconfig b/drivers/staging/media/imx/Kconfig
index 1cd48028b6416ae16ed69c68186281b6c6bcbec8..53e5c1546ac53e4942974a9acdcf078de1cb6073 100644
--- a/drivers/staging/media/imx/Kconfig
+++ b/drivers/staging/media/imx/Kconfig
@@ -10,6 +10,7 @@ config VIDEO_IMX_MEDIA
 	select V4L2_MEM2MEM_DEV
 	select VIDEOBUF2_DMA_CONTIG
 	select VIDEO_V4L2_SUBDEV_API
+	select VIDEO_SYNOPSYS_MIPI_CSI2
 	help
 	  Say yes here to enable support for video4linux media controller
 	  drivers for the i.MX5/6 SOC.
diff --git a/drivers/staging/media/imx/Makefile b/drivers/staging/media/imx/Makefile
index 064a6c6c069aa440c72a483080cbedf89d370193..1978b82fd1876566acbb952a4d14cf9aca35e996 100644
--- a/drivers/staging/media/imx/Makefile
+++ b/drivers/staging/media/imx/Makefile
@@ -11,4 +11,4 @@ imx6-media-csi-objs := imx-media-csi.o imx-media-fim.o
 obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx-media-common.o
 obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx6-media.o
 obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx6-media-csi.o
-obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx6-mipi-csi2.o imx6-csi2.o
+obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx6-csi2.o

-- 
2.34.1



From Frank.Li at nxp.com  Thu Aug 21 13:15:53 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 21 Aug 2025 16:15:53 -0400
Subject: [PATCH v3 18/31] media: synopsys: csi2: Remove deprecated s_stream
 and use v4l2_subdev_pad_ops
In-Reply-To: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
References: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
Message-ID: <20250821-95_cam-v3-18-c9286fbb34b9@nxp.com>

Use new v4l2_subdev_pad_ops.enable_streams(disalbe_stream) replace
deprecated s_stream interface.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/media/platform/synopsys/mipi-csi2.c | 52 +++++++++++++++++------------
 1 file changed, 31 insertions(+), 21 deletions(-)

diff --git a/drivers/media/platform/synopsys/mipi-csi2.c b/drivers/media/platform/synopsys/mipi-csi2.c
index 22e0021fab17f3c8e9a6c41c2f2109f5112dd6e5..922b59670383db7c920625f8a149009fa4dc5f22 100644
--- a/drivers/media/platform/synopsys/mipi-csi2.c
+++ b/drivers/media/platform/synopsys/mipi-csi2.c
@@ -342,7 +342,9 @@ static void csi2_stop(struct dw_mipi_csi2_dev *csi2)
  * V4L2 subdev operations.
  */
 
-static int csi2_s_stream(struct v4l2_subdev *sd, int enable)
+static int dw_csi2_enable_streams(struct v4l2_subdev *sd,
+				  struct v4l2_subdev_state *state, u32 pad,
+				  u64 streams_mask)
 {
 	struct dw_mipi_csi2_dev *csi2 = sd_to_dev(sd);
 	int i, ret = 0;
@@ -359,28 +361,39 @@ static int csi2_s_stream(struct v4l2_subdev *sd, int enable)
 	if (i >= csi2->num_sink_pads)
 		return -EPIPE;
 
-	/*
-	 * enable/disable streaming only if stream_count is
-	 * going from 0 to 1 / 1 to 0.
-	 */
-	if (csi2->stream_count != !enable)
-		goto update_count;
+	if (csi2->stream_count)
+		return 0;
 
-	dev_dbg(csi2->dev, "stream %s\n", enable ? "ON" : "OFF");
-	if (enable)
-		ret = csi2_start(csi2);
-	else
-		csi2_stop(csi2);
+	ret = csi2_start(csi2);
 	if (ret)
 		return ret;
 
-update_count:
-	csi2->stream_count += enable ? 1 : -1;
-	if (csi2->stream_count < 0)
-		csi2->stream_count = 0;
+	csi2->stream_count++;
+
 	return ret;
 }
 
+static int dw_csi2_disable_streams(struct v4l2_subdev *sd,
+				   struct v4l2_subdev_state *state, u32 pad,
+				   u64 streams_mask)
+{
+	struct dw_mipi_csi2_dev *csi2 = sd_to_dev(sd);
+
+	guard(mutex)(&csi2->lock);
+
+	if (!csi2->stream_count) {
+		dev_err(csi2->dev, "Error: csi2 enable count already be 0\n");
+		return 0;
+	}
+
+	csi2->stream_count--;
+
+	if (!csi2->stream_count)
+		csi2_stop(csi2);
+
+	return 0;
+}
+
 static int csi2_link_setup(struct media_entity *entity,
 			   const struct media_pad *local,
 			   const struct media_pad *remote, u32 flags)
@@ -507,18 +520,15 @@ static const struct media_entity_operations csi2_entity_ops = {
 	.get_fwnode_pad = v4l2_subdev_get_fwnode_pad_1_to_1,
 };
 
-static const struct v4l2_subdev_video_ops csi2_video_ops = {
-	.s_stream = csi2_s_stream,
-};
-
 static const struct v4l2_subdev_pad_ops csi2_pad_ops = {
 	.get_fmt = csi2_get_fmt,
 	.set_fmt = csi2_set_fmt,
+	.enable_streams = dw_csi2_enable_streams,
+	.disable_streams = dw_csi2_disable_streams,
 };
 
 static const struct v4l2_subdev_ops csi2_subdev_ops = {
 	.core = &csi2_core_ops,
-	.video = &csi2_video_ops,
 	.pad = &csi2_pad_ops,
 };
 

-- 
2.34.1



From Frank.Li at nxp.com  Thu Aug 21 13:15:54 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 21 Aug 2025 16:15:54 -0400
Subject: [PATCH v3 19/31] media: synopsys: csi2: Add phy interface support
In-Reply-To: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
References: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
Message-ID: <20250821-95_cam-v3-19-c9286fbb34b9@nxp.com>

Add standard phy interface support.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/media/platform/synopsys/mipi-csi2.c | 91 +++++++++++++++++++++++++++--
 include/media/dw-mipi-csi2.h                |  4 ++
 2 files changed, 90 insertions(+), 5 deletions(-)

diff --git a/drivers/media/platform/synopsys/mipi-csi2.c b/drivers/media/platform/synopsys/mipi-csi2.c
index 922b59670383db7c920625f8a149009fa4dc5f22..27d802b3c3937473c8e08defa661b55b0655f758 100644
--- a/drivers/media/platform/synopsys/mipi-csi2.c
+++ b/drivers/media/platform/synopsys/mipi-csi2.c
@@ -14,6 +14,7 @@
 #include <linux/of_graph.h>
 #include <linux/platform_device.h>
 #include <media/dw-mipi-csi2.h>
+#include <media/mipi-csi2.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
@@ -268,7 +269,63 @@ static int csi2_get_active_lanes(struct dw_mipi_csi2_dev *csi2, unsigned int *la
 	return 0;
 }
 
-static int csi2_start(struct dw_mipi_csi2_dev *csi2)
+static int dw_csi2_get_dphy_configuration(struct dw_mipi_csi2_dev *csi2,
+					  union phy_configure_opts *opts,
+					  int bpp)
+{
+	struct phy_configure_opts_mipi_dphy *cfg = &opts->mipi_dphy;
+	struct v4l2_subdev *source = csi2->src_sd;
+	s64 link_freq;
+
+	link_freq = v4l2_get_link_freq(source->ctrl_handler,
+				       bpp,
+				       csi2->data_lanes * 2);
+	if (link_freq < 0) {
+		dev_err(csi2->dev, "Unable to obtain link frequency: %d\n",
+			(int)link_freq);
+		return link_freq;
+	}
+
+	memset(cfg, 0x0, sizeof(*cfg));
+	cfg->hs_clk_rate = link_freq * 2;
+	cfg->lanes = csi2->data_lanes;
+
+	return 0;
+}
+
+static int dw_mipi_csi2_phy_prep(struct dw_mipi_csi2_dev *csi2, int bpp)
+{
+	union phy_configure_opts opts;
+	int ret;
+
+	ret = dw_csi2_get_dphy_configuration(csi2, &opts, bpp);
+	if (ret)
+		return ret;
+
+	ret = phy_init(csi2->phy);
+	if (ret)
+		return ret;
+
+	ret = phy_reset(csi2->phy);
+	if (ret)
+		goto exit;
+
+	ret = phy_set_mode(csi2->phy, PHY_MODE_MIPI_DPHY);
+	if (ret)
+		goto exit;
+
+	ret = phy_configure(csi2->phy, &opts);
+	if (ret)
+		goto exit;
+
+	return 0;
+
+exit:
+	phy_exit(csi2->phy);
+	return ret;
+}
+
+static int csi2_start(struct dw_mipi_csi2_dev *csi2, int bpp)
 {
 	unsigned int lanes;
 	int ret;
@@ -277,6 +334,10 @@ static int csi2_start(struct dw_mipi_csi2_dev *csi2)
 	if (ret)
 		return ret;
 
+	ret = dw_mipi_csi2_phy_prep(csi2, bpp);
+	if (ret)
+		goto err_phy_prep;
+
 	/* setup the gasket */
 	if (csi2->config && csi2->config->gasket_init)
 		csi2->config->gasket_init(csi2);
@@ -285,15 +346,20 @@ static int csi2_start(struct dw_mipi_csi2_dev *csi2)
 	if (csi2->config && csi2->config->dphy_init) {
 		ret = csi2->config->dphy_init(csi2);
 		if (ret)
-			goto err_disable_clk;
+			goto err_dphy_init;
 	}
 
 	ret = csi2_get_active_lanes(csi2, &lanes);
 	if (ret)
-		goto err_disable_clk;
+		goto err_active_lanes;
 
 	/* Step 4 */
 	csi2_set_lanes(csi2, lanes);
+
+	ret = phy_power_on(csi2->phy);
+	if (ret)
+		goto err_phy_power_on;
+
 	csi2_enable(csi2, true);
 
 	/* Step 5 */
@@ -322,13 +388,21 @@ static int csi2_start(struct dw_mipi_csi2_dev *csi2)
 	v4l2_subdev_call(csi2->src_sd, video, post_streamoff);
 err_assert_reset:
 	csi2_enable(csi2, false);
-err_disable_clk:
+err_phy_power_on:
+	phy_power_off(csi2->phy);
+err_active_lanes:
+err_dphy_init:
+	phy_exit(csi2->phy);
+err_phy_prep:
 	pm_runtime_put(csi2->dev);
 	return ret;
 }
 
 static void csi2_stop(struct dw_mipi_csi2_dev *csi2)
 {
+	phy_power_off(csi2->phy);
+	phy_exit(csi2->phy);
+
 	/* stop upstream */
 	v4l2_subdev_call(csi2->src_sd, video, s_stream, 0);
 	v4l2_subdev_call(csi2->src_sd, video, post_streamoff);
@@ -364,7 +438,7 @@ static int dw_csi2_enable_streams(struct v4l2_subdev *sd,
 	if (csi2->stream_count)
 		return 0;
 
-	ret = csi2_start(csi2);
+	ret = csi2_start(csi2, media_bus_fmt_to_csi2_bpp(csi2->format_mbus.code));
 	if (ret)
 		return ret;
 
@@ -682,6 +756,13 @@ int dw_mipi_csi2_init(struct platform_device *pdev, struct dw_mipi_csi2_dev *csi
 	if (csi2->num_clks < 0)
 		return dev_err_probe(&pdev->dev, csi2->num_clks, "Failed to get clocks\n");
 
+	if (config->has_phy) {
+		csi2->phy = devm_phy_get(&pdev->dev, "rx");
+		if (IS_ERR(csi2->phy))
+			return dev_err_probe(&pdev->dev, PTR_ERR(csi2->phy),
+					     "Failed to get DPHY Rx\n");
+	}
+
 	devm_pm_runtime_enable(&pdev->dev);
 
 	return csi2_async_register(csi2);
diff --git a/include/media/dw-mipi-csi2.h b/include/media/dw-mipi-csi2.h
index 3d70c1f4f38e7d663f9b043d8903ce57d630d1b1..14a80c09fd273c334f91ea70d955dcf92b6646ce 100644
--- a/include/media/dw-mipi-csi2.h
+++ b/include/media/dw-mipi-csi2.h
@@ -3,6 +3,7 @@
 #ifndef __DW_MIPI_CSI2_COMMON_
 #define __DW_MIPI_CSI2_COMMON_
 
+#include <linux/phy/phy.h>
 #include <linux/pm_runtime.h>
 
 #include <media/v4l2-common.h>
@@ -25,6 +26,7 @@ struct dw_mipi_csi2_config {
 	int (*dphy_init)(struct dw_mipi_csi2_dev *dev);
 	u32	num_pads;	/* Max 64 pad now */
 	u32	sink_pad_mask;
+	bool	has_phy: 1;
 };
 
 struct dw_mipi_tstif {
@@ -56,6 +58,8 @@ struct dw_mipi_csi2_dev {
 	struct clk_bulk_data		*clks;
 	int				num_clks;
 
+	struct phy			*phy;
+
 	struct v4l2_subdev		*remote;
 	unsigned int			remote_pad;
 	unsigned short			data_lanes;

-- 
2.34.1



From Frank.Li at nxp.com  Thu Aug 21 13:15:55 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 21 Aug 2025 16:15:55 -0400
Subject: [PATCH v3 20/31] media: synopsys: csi2: Add basic v150* version
 register
In-Reply-To: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
References: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
Message-ID: <20250821-95_cam-v3-20-c9286fbb34b9@nxp.com>

Add basic v150* version register and auto detect IP version by read version
register, which located position 0 for both version.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/media/platform/synopsys/mipi-csi2.c | 37 ++++++++++++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/synopsys/mipi-csi2.c b/drivers/media/platform/synopsys/mipi-csi2.c
index 27d802b3c3937473c8e08defa661b55b0655f758..4d67ab978db56d8075824ba515876193499c0c97 100644
--- a/drivers/media/platform/synopsys/mipi-csi2.c
+++ b/drivers/media/platform/synopsys/mipi-csi2.c
@@ -61,6 +61,19 @@ static const struct dw_csi2_regs dw_csi2_v0 = {
 	.phy_tst_ctrl1 = DW_REG(0x34),
 };
 
+static const struct dw_csi2_regs dw_csi2_v150 = {
+	.version = DW_REG(0x0),
+	.n_lanes = DW_REG(0x4),
+	.resetn = DW_REG(0x8),
+	.data_ids_1 = DW_REG(0x10),
+	.data_ids_2 = DW_REG(0x14),
+	.phy_shutdownz = DW_REG(0x40),
+	.dphy_rstz = DW_REG(0x44),
+	.phy_state = DW_REG(0x48),
+	.phy_tst_ctrl0 = DW_REG(0x50),
+	.phy_tst_ctrl1 = DW_REG(0x54),
+};
+
 static int dw_csi2_reg_err(struct dw_mipi_csi2_dev *csi2, const char *name)
 {
 	dev_err_once(csi2->dev, "access to unexisted register: %s", name);
@@ -697,13 +710,31 @@ static void csi2_nf_cleanup(void *data)
 	v4l2_async_nf_cleanup(&csi2->notifier);
 }
 
+static int dw_detect_version(struct dw_mipi_csi2_dev *csi2)
+{
+	int ret;
+	int ver;
+
+	ret = pm_runtime_resume_and_get(csi2->dev);
+	if (ret)
+		return ret;
+
+	/* version is first register for known chips */
+	ver = readl(csi2->base);
+	if (ver >= 0x3135302a) /* ASCII "150*" */
+		csi2->regs = &dw_csi2_v150;
+	else
+		csi2->regs = &dw_csi2_v0;
+
+	return 0;
+}
+
 int dw_mipi_csi2_init(struct platform_device *pdev, struct dw_mipi_csi2_dev *csi2,
 		      const struct dw_mipi_csi2_config *config)
 {
 	int i, ret;
 
 	csi2->dev = &pdev->dev;
-	csi2->regs = &dw_csi2_v0;
 	v4l2_subdev_init(&csi2->sd, &csi2_subdev_ops);
 	v4l2_set_subdevdata(&csi2->sd, &pdev->dev);
 	csi2->sd.entity.ops = &csi2_entity_ops;
@@ -765,6 +796,10 @@ int dw_mipi_csi2_init(struct platform_device *pdev, struct dw_mipi_csi2_dev *csi
 
 	devm_pm_runtime_enable(&pdev->dev);
 
+	ret = dw_detect_version(csi2);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "Failed to detect IP version");
+
 	return csi2_async_register(csi2);
 
 }

-- 
2.34.1



From Frank.Li at nxp.com  Thu Aug 21 13:15:56 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 21 Aug 2025 16:15:56 -0400
Subject: [PATCH v3 21/31] media: synopsys: csi2: Add irq support to record
 error count
In-Reply-To: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
References: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
Message-ID: <20250821-95_cam-v3-21-c9286fbb34b9@nxp.com>

Add irq support to record error count. Use debugfs to show such error
count.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/media/platform/synopsys/mipi-csi2.c | 171 ++++++++++++++++++++++++++++
 include/media/dw-mipi-csi2.h                |   8 ++
 2 files changed, 179 insertions(+)

diff --git a/drivers/media/platform/synopsys/mipi-csi2.c b/drivers/media/platform/synopsys/mipi-csi2.c
index 4d67ab978db56d8075824ba515876193499c0c97..e628cc67046b05bf0178c002a8bdf4bbcd64b30e 100644
--- a/drivers/media/platform/synopsys/mipi-csi2.c
+++ b/drivers/media/platform/synopsys/mipi-csi2.c
@@ -4,6 +4,7 @@
  *
  * Copyright (c) 2012-2017 Mentor Graphics Inc.
  */
+#include <linux/debugfs.h>
 #include <linux/export.h>
 #include <linux/clk.h>
 #include <linux/interrupt.h>
@@ -37,6 +38,19 @@ struct dw_csi2_regs {
 	u32	msk2;
 	u32	phy_tst_ctrl0;
 	u32	phy_tst_ctrl1;
+	u32	int_st_main;
+	u32	int_st_dphy_fatal;
+	u32	int_msk_dphy_fatal;
+	u32	int_force_dphy_fatal;
+	u32	int_st_pkt_fatal;
+	u32	int_msk_pkt_fatal;
+	u32	int_force_pkt_fatal;
+	u32	int_st_dphy;
+	u32	int_msk_dphy;
+	u32	int_force_dphy;
+	u32	int_st_ipi_fatal;
+	u32	int_msk_ipi_fatal;
+	u32	int_force_ipi_fatal;
 };
 
 /* Help check wrong access unexisted register at difference IP version */
@@ -65,6 +79,7 @@ static const struct dw_csi2_regs dw_csi2_v150 = {
 	.version = DW_REG(0x0),
 	.n_lanes = DW_REG(0x4),
 	.resetn = DW_REG(0x8),
+	.int_st_main = DW_REG(0xc),
 	.data_ids_1 = DW_REG(0x10),
 	.data_ids_2 = DW_REG(0x14),
 	.phy_shutdownz = DW_REG(0x40),
@@ -72,8 +87,48 @@ static const struct dw_csi2_regs dw_csi2_v150 = {
 	.phy_state = DW_REG(0x48),
 	.phy_tst_ctrl0 = DW_REG(0x50),
 	.phy_tst_ctrl1 = DW_REG(0x54),
+	.int_st_dphy_fatal = DW_REG(0xe0),
+	.int_msk_dphy_fatal = DW_REG(0xe4),
+	.int_force_dphy_fatal = DW_REG(0xe8),
+	.int_st_pkt_fatal = DW_REG(0xf0),
+	.int_msk_pkt_fatal = DW_REG(0xf4),
+	.int_force_pkt_fatal = DW_REG(0xf8),
+	.int_st_dphy = DW_REG(0x110),
+	.int_msk_dphy = DW_REG(0x114),
+	.int_force_dphy = DW_REG(0x118),
+	.int_st_ipi_fatal = DW_REG(0x140),
+	.int_msk_ipi_fatal = DW_REG(0x144),
+	.int_force_ipi_fatal = DW_REG(0x148),
 };
 
+#define INT_ST_MAIN_FATAL_ERR_PHY		BIT(0)
+#define INT_ST_MAIN_FATAL_ERR_PKT		BIT(1)
+#define INT_ST_MAIN_FATAL_ERR_BNDRY_FRAMEL	BIT(2)
+#define INT_ST_MAIN_FATAL_ERR_SEQ_FRAME		BIT(3)
+#define INT_ST_MAIN_FATAL_ERR_CRC_FRAME		BIT(4)
+#define INT_ST_MAIN_FATAL_ERR_PLD_CRC		BIT(5)
+#define INT_ST_MAIN_ERR_DID			BIT(6)
+#define INT_ST_MAIN_ERR_ECC			BIT(7)
+#define INT_ST_MAIN_ERR_PHY			BIT(16)
+#define INT_ST_MAIN_FATAL_ERR_IPI		BIT(18)
+
+#define INT_MSK_DPHY_FATAL_ERR_SOT_LANE0	BIT(0)
+#define INT_MSK_DPHY_FATAL_ERR_SOT_LANE1	BIT(1)
+
+#define INT_ST_PKT_FATAL_ERR_ECC		BIT(0)
+#define INT_ST_PKT_FATAL_ERR_PAYLOAD	BIT(1)
+
+#define INT_MSK_PKT_FATAL_ERR_ECC		BIT(0)
+#define INT_MSK_PKT_FATAL_ERR_PAYLOAD		BIT(1)
+
+#define INT_ST_IPI_FATAL_ERR_IFFIFO_UNDERFLOW	BIT(0)
+#define INT_ST_IPI_FATAL_ERR_IFFIFO_OVERFLOW	BIT(1)
+#define INT_ST_IPI_FATAL_ERR_FRAME_SYNC		BIT(2)
+#define INT_ST_IPI_FATAL_ERR_FIFO_NOT_EMPTY	BIT(3)
+#define INT_ST_IPI_FATAL_ERR_HLINE_TIME		BIT(4)
+#define INT_ST_IPI_FATAL_ERR_FIFO_OVERFLOW	BIT(5)
+#define INT_ST_IPI_FATAL_ERR_PD_FIFO_OVERFLOW	BIT(6)
+
 static int dw_csi2_reg_err(struct dw_mipi_csi2_dev *csi2, const char *name)
 {
 	dev_err_once(csi2->dev, "access to unexisted register: %s", name);
@@ -108,6 +163,25 @@ static inline struct dw_mipi_csi2_dev *notifier_to_dev(struct v4l2_async_notifie
 	return container_of(n, struct dw_mipi_csi2_dev, notifier);
 }
 
+struct dw_csi2_event {
+	u32 mask;
+	const char * const name;
+	u32 counter;
+};
+
+static const struct dw_csi2_event dw_events[] = {
+	{ INT_ST_MAIN_FATAL_ERR_IPI, "IPI Interface Fatal Error" },
+	{ INT_ST_MAIN_ERR_PHY, "PHY Error" },
+	{ INT_ST_MAIN_ERR_ECC, "Header Single Bit Error" },
+	{ INT_ST_MAIN_ERR_DID, "Data ID Error" },
+	{ INT_ST_MAIN_FATAL_ERR_PLD_CRC, "Payload CRC Fatal Error" },
+	{ INT_ST_MAIN_FATAL_ERR_CRC_FRAME, "Frame CRC Fatal Error" },
+	{ INT_ST_MAIN_FATAL_ERR_SEQ_FRAME, "Frame Sequence Fatal Error" },
+	{ INT_ST_MAIN_FATAL_ERR_BNDRY_FRAMEL, "Frame Boundaries Fatal Error" },
+	{ INT_ST_MAIN_FATAL_ERR_PKT, "Packet Construction Fatal Error" },
+	{ INT_ST_MAIN_FATAL_ERR_PHY, "PHY Fatal Error" },
+};
+
 /*
  * The required sequence of MIPI CSI-2 startup as specified in the i.MX6
  * reference manual is as follows:
@@ -338,6 +412,40 @@ static int dw_mipi_csi2_phy_prep(struct dw_mipi_csi2_dev *csi2, int bpp)
 	return ret;
 }
 
+static void dw_csi2_enable_irq(struct dw_mipi_csi2_dev *csi2)
+{
+	u32 val;
+
+	/* Define errors to be enabled */
+	val = INT_MSK_DPHY_FATAL_ERR_SOT_LANE0 |
+	      INT_MSK_DPHY_FATAL_ERR_SOT_LANE0;
+	dw_writel(csi2, val, int_msk_dphy_fatal);
+
+	val = INT_ST_PKT_FATAL_ERR_ECC | INT_ST_PKT_FATAL_ERR_PAYLOAD;
+	dw_writel(csi2, val, int_msk_pkt_fatal);
+
+	val = INT_MSK_PKT_FATAL_ERR_ECC | INT_MSK_PKT_FATAL_ERR_PAYLOAD;
+	dw_writel(csi2, val, int_msk_dphy);
+
+	val = INT_ST_IPI_FATAL_ERR_IFFIFO_UNDERFLOW |
+	      INT_ST_IPI_FATAL_ERR_IFFIFO_OVERFLOW |
+	      INT_ST_IPI_FATAL_ERR_FRAME_SYNC |
+	      INT_ST_IPI_FATAL_ERR_FIFO_NOT_EMPTY |
+	      INT_ST_IPI_FATAL_ERR_HLINE_TIME |
+	      INT_ST_IPI_FATAL_ERR_FIFO_OVERFLOW |
+	      INT_ST_IPI_FATAL_ERR_PD_FIFO_OVERFLOW;
+
+	dw_writel(csi2, val, int_msk_ipi_fatal);
+}
+
+static void dw_csi2_disable_irq(struct dw_mipi_csi2_dev *csi2)
+{
+	dw_writel(csi2, 0, int_msk_dphy_fatal);
+	dw_writel(csi2, 0, int_msk_pkt_fatal);
+	dw_writel(csi2, 0, int_msk_dphy);
+	dw_writel(csi2, 0, int_msk_ipi_fatal);
+}
+
 static int csi2_start(struct dw_mipi_csi2_dev *csi2, int bpp)
 {
 	unsigned int lanes;
@@ -393,6 +501,8 @@ static int csi2_start(struct dw_mipi_csi2_dev *csi2, int bpp)
 	if (ret)
 		goto err_stop_upstream;
 
+	dw_csi2_enable_irq(csi2);
+
 	return 0;
 
 err_stop_upstream:
@@ -422,6 +532,8 @@ static void csi2_stop(struct dw_mipi_csi2_dev *csi2)
 
 	csi2_enable(csi2, false);
 
+	dw_csi2_disable_irq(csi2);
+
 	pm_runtime_put(csi2->dev);
 }
 
@@ -729,6 +841,42 @@ static int dw_detect_version(struct dw_mipi_csi2_dev *csi2)
 	return 0;
 }
 
+static irqreturn_t dw_csi2_irq_handler(int irq, void *priv)
+{
+	struct dw_mipi_csi2_dev *csi2 = priv;
+	u32 status;
+	int i;
+
+	/* Hardware auto clean after read */
+	status = dw_readl(csi2, int_st_main);
+
+	for (i = 0; i < csi2->num_event; i++) {
+		struct dw_csi2_event *event = &csi2->event[i];
+
+		if (status & event->mask)
+			event->counter++;
+	}
+
+	return IRQ_HANDLED;
+}
+
+static void dw_mipi_csi_create_debugfs(struct dw_mipi_csi2_dev *csi2)
+{
+	int i;
+
+	csi2->debugfs_root = debugfs_create_dir(dev_name(csi2->dev), NULL);
+
+	if (!csi2->debugfs_root)
+		return;
+
+	for (i = 0; i < csi2->num_event; i++) {
+		struct dw_csi2_event *event = &csi2->event[i];
+
+		debugfs_create_u32(event->name, 0600, csi2->debugfs_root,
+				   &event->counter);
+	}
+}
+
 int dw_mipi_csi2_init(struct platform_device *pdev, struct dw_mipi_csi2_dev *csi2,
 		      const struct dw_mipi_csi2_config *config)
 {
@@ -800,6 +948,27 @@ int dw_mipi_csi2_init(struct platform_device *pdev, struct dw_mipi_csi2_dev *csi
 	if (ret)
 		return dev_err_probe(&pdev->dev, ret, "Failed to detect IP version");
 
+	if (config->has_irq) {
+		int irq;
+
+		csi2->event = devm_kmemdup(&pdev->dev, dw_events, sizeof(dw_events), GFP_KERNEL);
+		csi2->num_event = ARRAY_SIZE(dw_events);
+
+		if (!csi2->event)
+			return -ENOMEM;
+
+		irq = platform_get_irq(pdev, 0);
+		if (irq < 0)
+			return dev_err_probe(&pdev->dev, irq, "Failed to get IRQ\n");
+
+		ret = devm_request_irq(&pdev->dev, irq, dw_csi2_irq_handler, 0,
+				       dev_name(&pdev->dev), csi2);
+		if (ret < 0)
+			return dev_err_probe(&pdev->dev, ret, "Failed to request IRQ\n");
+	}
+
+	dw_mipi_csi_create_debugfs(csi2);
+
 	return csi2_async_register(csi2);
 
 }
@@ -809,5 +978,7 @@ void dw_mipi_csi2_deinit(struct dw_mipi_csi2_dev *csi2)
 {
 	v4l2_async_unregister_subdev(&csi2->sd);
 	media_entity_cleanup(&csi2->sd.entity);
+
+	debugfs_remove(csi2->debugfs_root);
 }
 EXPORT_SYMBOL_GPL(dw_mipi_csi2_deinit);
diff --git a/include/media/dw-mipi-csi2.h b/include/media/dw-mipi-csi2.h
index 14a80c09fd273c334f91ea70d955dcf92b6646ce..20ce6a21f0674cad54f01edb508dce14cd07a8dd 100644
--- a/include/media/dw-mipi-csi2.h
+++ b/include/media/dw-mipi-csi2.h
@@ -27,6 +27,7 @@ struct dw_mipi_csi2_config {
 	u32	num_pads;	/* Max 64 pad now */
 	u32	sink_pad_mask;
 	bool	has_phy: 1;
+	bool	has_irq: 1;
 };
 
 struct dw_mipi_tstif {
@@ -44,6 +45,8 @@ static inline int dw_mipi_tstif_write(struct dw_mipi_tstif *tstif, u32 indice, u
 	return  tstif->write(tstif, indice, data);
 }
 
+struct dw_csi2_event;
+
 struct dw_mipi_csi2_dev {
 	struct device			*dev;
 	struct v4l2_subdev		sd;
@@ -74,6 +77,11 @@ struct dw_mipi_csi2_dev {
 	bool				sink_linked[DW_MAX_PAD_NUM];
 	const struct dw_mipi_csi2_config *config;
 
+	struct dw_csi2_event		*event;
+	int				num_event;
+
+	struct dentry			*debugfs_root;
+
 	struct dw_mipi_tstif		tstif;
 };
 

-- 
2.34.1



From Frank.Li at nxp.com  Thu Aug 21 13:15:57 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 21 Aug 2025 16:15:57 -0400
Subject: [PATCH v3 22/31] media: synopsys: csi2: Handle alignment
 requirement for width
In-Reply-To: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
References: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
Message-ID: <20250821-95_cam-v3-22-c9286fbb34b9@nxp.com>

bpp * width must align to 8. Use media_bus_fmt_to_csi2_bpp() and
v4l_get_required_align_by_bpp() to get width's alignment requirement.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/media/platform/synopsys/mipi-csi2.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/media/platform/synopsys/mipi-csi2.c b/drivers/media/platform/synopsys/mipi-csi2.c
index e628cc67046b05bf0178c002a8bdf4bbcd64b30e..5435b58de55d21aa957fc635c950ba2ae25a8dcc 100644
--- a/drivers/media/platform/synopsys/mipi-csi2.c
+++ b/drivers/media/platform/synopsys/mipi-csi2.c
@@ -11,6 +11,7 @@
 #include <linux/io.h>
 #include <linux/iopoll.h>
 #include <linux/irq.h>
+#include <linux/limits.h>
 #include <linux/module.h>
 #include <linux/of_graph.h>
 #include <linux/platform_device.h>
@@ -664,15 +665,31 @@ static int csi2_set_fmt(struct v4l2_subdev *sd,
 {
 	struct dw_mipi_csi2_dev *csi2 = sd_to_dev(sd);
 	struct v4l2_mbus_framefmt *fmt;
+	u32 align;
+	u32 bpp;
 
 	if (sdformat->pad >= (csi2->num_src_pads + csi2->num_sink_pads))
 		return -EINVAL;
 
+	/*
+	 * The CSIS can't transcode in any way, the source format can't be
+	 * modified.
+	 */
+	if (sdformat->pad < csi2->num_src_pads)
+		return v4l2_subdev_get_fmt(sd, sd_state, sdformat);
+
 	guard(mutex)(&csi2->lock);
 
 	if (csi2->stream_count > 0)
 		return -EBUSY;
 
+	bpp = media_bus_fmt_to_csi2_bpp(sdformat->format.code);
+
+	align = v4l_get_required_align_by_bpp(bpp, 3); /* need align to 2^3 */
+
+	v4l_bound_align_image(&sdformat->format.width, 1, U16_MAX, align,
+			      &sdformat->format.height, 1, U16_MAX, 0, 0);
+
 	/* Output pads mirror active input pad, no limits on input pads */
 	if (!(csi2->config->sink_pad_mask & BIT(sdformat->pad)))
 		sdformat->format = csi2->format_mbus;

-- 
2.34.1



From Frank.Li at nxp.com  Thu Aug 21 13:15:58 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 21 Aug 2025 16:15:58 -0400
Subject: [PATCH v3 23/31] media: synopsys: csi2: Add register prefix to
 register field definitions
In-Reply-To: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
References: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
Message-ID: <20250821-95_cam-v3-23-c9286fbb34b9@nxp.com>

Add register prefix to register field definitions to improve readability.

No functional change.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/media/platform/synopsys/mipi-csi2.c | 30 ++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/media/platform/synopsys/mipi-csi2.c b/drivers/media/platform/synopsys/mipi-csi2.c
index 5435b58de55d21aa957fc635c950ba2ae25a8dcc..d6eb666646b916c2609a279f8badc1e8af557121 100644
--- a/drivers/media/platform/synopsys/mipi-csi2.c
+++ b/drivers/media/platform/synopsys/mipi-csi2.c
@@ -146,16 +146,16 @@ dw_csi2_reg_err((csi2), #__name))
 readl((csi2)->base + ((csi2)->regs->__name & ~DW_REG_EXIST)) : \
 dw_csi2_reg_err(csi2, #__name))
 
-#define PHY_STOPSTATEDATA_BIT	4
-#define PHY_STOPSTATEDATA(n)	BIT(PHY_STOPSTATEDATA_BIT + (n))
-#define PHY_RXCLKACTIVEHS	BIT(8)
-#define PHY_RXULPSCLKNOT	BIT(9)
-#define PHY_STOPSTATECLK	BIT(10)
+#define PHY_STATE_STOPSTATEDATA_BIT	4
+#define PHY_STATE_STOPSTATEDATA(n)	BIT(PHY_STATE_STOPSTATEDATA_BIT + (n))
+#define PHY_STATE_RXCLKACTIVEHS	BIT(8)
+#define PHY_STATE_RXULPSCLKNOT	BIT(9)
+#define PHY_STATE_STOPSTATECLK	BIT(10)
 
-#define PHY_TESTCLR		BIT(0)
-#define PHY_TESTCLK		BIT(1)
+#define DPHY_TEST_CTRL0_TEST_CLR		BIT(0)
+#define DPHY_TEST_CTRL0_TEST_CLKEN	BIT(1)
 
-#define PHY_TESTEN		BIT(16)
+#define DPHY_TEST_CTRL1_TEST_EN		BIT(16)
 
 #define sd_to_dev sd_to_dw_mipi_csi2_dev
 
@@ -235,20 +235,20 @@ static int dw_mipi_csi2_phy_write(struct dw_mipi_tstif *tstif,
 	struct dw_mipi_csi2_dev *csi2 = container_of(tstif, struct dw_mipi_csi2_dev, tstif);
 
 	/* Clear PHY test interface */
-	dw_writel(csi2, PHY_TESTCLR, phy_tst_ctrl0);
+	dw_writel(csi2, DPHY_TEST_CTRL0_TEST_CLR, phy_tst_ctrl0);
 	dw_writel(csi2, 0x0, phy_tst_ctrl1);
 	dw_writel(csi2, 0x0, phy_tst_ctrl0);
 
 	/* Raise test interface strobe signal */
-	dw_writel(csi2, PHY_TESTCLK, phy_tst_ctrl0);
+	dw_writel(csi2, DPHY_TEST_CTRL0_TEST_CLKEN, phy_tst_ctrl0);
 
 	/* Configure address write on falling edge and lower strobe signal */
-	dw_writel(csi2, PHY_TESTEN | test_code, phy_tst_ctrl1);
+	dw_writel(csi2, DPHY_TEST_CTRL1_TEST_EN | test_code, phy_tst_ctrl1);
 	dw_writel(csi2, 0x0, phy_tst_ctrl0);
 
 	/* Configure data write on rising edge and raise strobe signal */
 	dw_writel(csi2, test_data, phy_tst_ctrl1);
-	dw_writel(csi2, PHY_TESTCLK, phy_tst_ctrl0);
+	dw_writel(csi2, DPHY_TEST_CTRL0_TEST_CLKEN, phy_tst_ctrl0);
 
 	/* Clear strobe signal */
 	dw_writel(csi2, 0x0, phy_tst_ctrl0);
@@ -271,7 +271,7 @@ static int __maybe_unused csi2_dphy_wait_ulp(struct dw_mipi_csi2_dev *csi2)
 	int ret;
 
 	/* wait for ULP on clock lane */
-	ret = read_poll_timeout(dw_readl, reg, !(reg & PHY_RXULPSCLKNOT),
+	ret = read_poll_timeout(dw_readl, reg, !(reg & PHY_STATE_RXULPSCLKNOT),
 				0, 500000, 0, csi2, phy_state);
 	if (ret) {
 		v4l2_err(&csi2->sd, "ULP timeout, phy_state = 0x%08x\n", reg);
@@ -294,7 +294,7 @@ static void csi2_dphy_wait_stopstate(struct dw_mipi_csi2_dev *csi2, unsigned int
 	u32 mask, reg;
 	int ret;
 
-	mask = PHY_STOPSTATECLK | (((1 << lanes) - 1) << PHY_STOPSTATEDATA_BIT);
+	mask = PHY_STATE_STOPSTATECLK | (((1 << lanes) - 1) << PHY_STATE_STOPSTATEDATA_BIT);
 
 	ret = read_poll_timeout(dw_readl, reg, (reg & mask) == mask, 0, 500000, 0, csi2, phy_state);
 	if (ret) {
@@ -309,7 +309,7 @@ static int csi2_dphy_wait_clock_lane(struct dw_mipi_csi2_dev *csi2)
 	u32 reg;
 	int ret;
 
-	ret = read_poll_timeout(dw_readl, reg, (reg & PHY_RXCLKACTIVEHS),
+	ret = read_poll_timeout(dw_readl, reg, (reg & PHY_STATE_RXCLKACTIVEHS),
 				0, 500000, 0, csi2, phy_state);
 	if (ret) {
 		v4l2_err(&csi2->sd, "clock lane timeout, phy_state = 0x%08x\n",

-- 
2.34.1



From Frank.Li at nxp.com  Thu Aug 21 13:15:59 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 21 Aug 2025 16:15:59 -0400
Subject: [PATCH v3 24/31] media: synopsys: csi2: Add need_dphy_reset in
 config
In-Reply-To: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
References: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
Message-ID: <20250821-95_cam-v3-24-c9286fbb34b9@nxp.com>

Add need_dphy_reset in config to indicate need keep dphy reset state during
config dphy because some SoC like i.MX93 need it.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/media/platform/synopsys/mipi-csi2.c | 45 +++++++++++++++++++++++++++++
 include/media/dw-mipi-csi2.h                |  1 +
 2 files changed, 46 insertions(+)

diff --git a/drivers/media/platform/synopsys/mipi-csi2.c b/drivers/media/platform/synopsys/mipi-csi2.c
index d6eb666646b916c2609a279f8badc1e8af557121..632ae5fd7da7850374c79dcff63b6ee4aee7b611 100644
--- a/drivers/media/platform/synopsys/mipi-csi2.c
+++ b/drivers/media/platform/synopsys/mipi-csi2.c
@@ -447,6 +447,45 @@ static void dw_csi2_disable_irq(struct dw_mipi_csi2_dev *csi2)
 	dw_writel(csi2, 0, int_msk_ipi_fatal);
 }
 
+static void dw_csi2_dphy_reset(struct dw_mipi_csi2_dev *csi2)
+{
+	u32 val;
+
+	/* Release synopsis DPHY test codes from reset */
+	dw_writel(csi2, 0, dphy_rstz);
+	dw_writel(csi2, 0, phy_shutdownz);
+
+	val = dw_readl(csi2, phy_tst_ctrl0);
+	val &= ~DPHY_TEST_CTRL0_TEST_CLR;
+	dw_writel(csi2, val, phy_tst_ctrl0);
+
+	/*
+	 * ndelay is not necessary have MMIO operation, need dummy read to make
+	 * sure above write reach target.
+	 */
+	val = dw_readl(csi2, phy_tst_ctrl0);
+	/* Wait for at least 15ns */
+	ndelay(15);
+	val |= DPHY_TEST_CTRL0_TEST_CLR;
+	dw_writel(csi2, val, phy_tst_ctrl0);
+}
+
+static void dw_csi2_dphy_release_reset(struct dw_mipi_csi2_dev *csi2)
+{
+	/* Release PHY from reset */
+	dw_writel(csi2, 0x1, phy_shutdownz);
+	/*
+	 * ndelay is not necessary have MMIO operation, need dummy read to make
+	 * sure above write reach target.
+	 */
+	dw_readl(csi2, phy_shutdownz);
+	ndelay(5);
+	dw_writel(csi2, 0x1, dphy_rstz);
+
+	dw_readl(csi2, dphy_rstz);
+	ndelay(5);
+}
+
 static int csi2_start(struct dw_mipi_csi2_dev *csi2, int bpp)
 {
 	unsigned int lanes;
@@ -460,6 +499,9 @@ static int csi2_start(struct dw_mipi_csi2_dev *csi2, int bpp)
 	if (ret)
 		goto err_phy_prep;
 
+	if (csi2->config->need_dphy_reset)
+		dw_csi2_dphy_reset(csi2);
+
 	/* setup the gasket */
 	if (csi2->config && csi2->config->gasket_init)
 		csi2->config->gasket_init(csi2);
@@ -482,6 +524,9 @@ static int csi2_start(struct dw_mipi_csi2_dev *csi2, int bpp)
 	if (ret)
 		goto err_phy_power_on;
 
+	if (csi2->config->need_dphy_reset)
+		dw_csi2_dphy_release_reset(csi2);
+
 	csi2_enable(csi2, true);
 
 	/* Step 5 */
diff --git a/include/media/dw-mipi-csi2.h b/include/media/dw-mipi-csi2.h
index 20ce6a21f0674cad54f01edb508dce14cd07a8dd..d1afd8c6d95457c28d7e1de6935908437372572d 100644
--- a/include/media/dw-mipi-csi2.h
+++ b/include/media/dw-mipi-csi2.h
@@ -28,6 +28,7 @@ struct dw_mipi_csi2_config {
 	u32	sink_pad_mask;
 	bool	has_phy: 1;
 	bool	has_irq: 1;
+	bool	need_dphy_reset: 1;
 };
 
 struct dw_mipi_tstif {

-- 
2.34.1



From Frank.Li at nxp.com  Thu Aug 21 13:16:00 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 21 Aug 2025 16:16:00 -0400
Subject: [PATCH v3 25/31] media: synopsys: csi2: Add default simple
 dw_csi2_subdev_init_state
In-Reply-To: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
References: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
Message-ID: <20250821-95_cam-v3-25-c9286fbb34b9@nxp.com>

Add default simple dw_csi2_subdev_init_state, which have 1 sink and 1
source pad, 1920x1080p and MEDIA_BUS_FMT_UYVY8_1X16 format.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/media/platform/synopsys/mipi-csi2.c | 57 ++++++++++++++++++++++++++++-
 1 file changed, 56 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/synopsys/mipi-csi2.c b/drivers/media/platform/synopsys/mipi-csi2.c
index 632ae5fd7da7850374c79dcff63b6ee4aee7b611..0b3bb099329017e81d2fb41387a3671e429dfe1c 100644
--- a/drivers/media/platform/synopsys/mipi-csi2.c
+++ b/drivers/media/platform/synopsys/mipi-csi2.c
@@ -831,6 +831,59 @@ static const struct v4l2_async_notifier_operations csi2_notify_ops = {
 	.unbind = csi2_notify_unbind,
 };
 
+static const struct v4l2_mbus_framefmt dwc_csi_default_fmt = {
+	.code = MEDIA_BUS_FMT_UYVY8_1X16,
+	.width = 1920,
+	.height = 1080,
+	.field = V4L2_FIELD_NONE,
+	.colorspace = V4L2_COLORSPACE_SMPTE170M,
+	.xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(V4L2_COLORSPACE_SMPTE170M),
+	.ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(V4L2_COLORSPACE_SMPTE170M),
+	.quantization = V4L2_QUANTIZATION_LIM_RANGE,
+};
+
+static int dw_csi2_subdev_set_routing(struct v4l2_subdev *sd,
+				      struct v4l2_subdev_state *state,
+				      struct v4l2_subdev_krouting *routing)
+{
+	int ret;
+
+	if (routing->num_routes > V4L2_FRAME_DESC_ENTRY_MAX)
+		return -EINVAL;
+
+	ret = v4l2_subdev_routing_validate(sd, routing,
+					   V4L2_SUBDEV_ROUTING_ONLY_1_TO_1);
+	if (ret)
+		return ret;
+
+	return v4l2_subdev_set_routing_with_fmt(sd, state, routing, &dwc_csi_default_fmt);
+}
+
+static int dw_csi2_subdev_init_state_simple(struct v4l2_subdev *sd,
+					    struct v4l2_subdev_state *sd_state)
+{
+	struct v4l2_subdev_route routes[] = {
+		{
+			.sink_pad = 0,
+			.sink_stream = 0,
+			.source_pad = 1,
+			.source_stream = 0,
+			.flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,
+		},
+	};
+
+	struct v4l2_subdev_krouting routing = {
+		.num_routes = ARRAY_SIZE(routes),
+		.routes = routes,
+	};
+
+	return dw_csi2_subdev_set_routing(sd, sd_state, &routing);
+}
+
+static const struct v4l2_subdev_internal_ops dw_csi2_simple_internal_ops = {
+	.init_state = dw_csi2_subdev_init_state_simple,
+};
+
 static int csi2_async_register(struct dw_mipi_csi2_dev *csi2)
 {
 	struct v4l2_fwnode_endpoint vep = {
@@ -954,7 +1007,9 @@ int dw_mipi_csi2_init(struct platform_device *pdev, struct dw_mipi_csi2_dev *csi
 
 	csi2->sd.owner = config->module;
 	strscpy(csi2->sd.name, config->name, sizeof(csi2->sd.name));
-	csi2->sd.internal_ops = config->internal_ops;
+	csi2->sd.internal_ops = config->internal_ops ?
+					config->internal_ops :
+					&dw_csi2_simple_internal_ops;
 	csi2->sd.grp_id = config->grp_id;
 	csi2->config = config;
 

-- 
2.34.1



From Frank.Li at nxp.com  Thu Aug 21 13:16:01 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 21 Aug 2025 16:16:01 -0400
Subject: [PATCH v3 26/31] media: synopsys: csi2: Add v150 lane stop state
 register bit define
In-Reply-To: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
References: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
Message-ID: <20250821-95_cam-v3-26-c9286fbb34b9@nxp.com>

v150 move lane stop state into new register phy_stopstate and field
position also changed.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/media/platform/synopsys/mipi-csi2.c | 40 +++++++++++++++++++++++++++--
 1 file changed, 38 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/synopsys/mipi-csi2.c b/drivers/media/platform/synopsys/mipi-csi2.c
index 0b3bb099329017e81d2fb41387a3671e429dfe1c..7225285c772edf6ca3372408dd3cb0637b47e0c0 100644
--- a/drivers/media/platform/synopsys/mipi-csi2.c
+++ b/drivers/media/platform/synopsys/mipi-csi2.c
@@ -31,6 +31,7 @@ struct dw_csi2_regs {
 	u32	dphy_rstz;
 	u32	resetn;
 	u32	phy_state;
+	u32	phy_stopstate;
 	u32	data_ids_1;
 	u32	data_ids_2;
 	u32	err1;
@@ -86,6 +87,7 @@ static const struct dw_csi2_regs dw_csi2_v150 = {
 	.phy_shutdownz = DW_REG(0x40),
 	.dphy_rstz = DW_REG(0x44),
 	.phy_state = DW_REG(0x48),
+	.phy_stopstate = DW_REG(0x4c),
 	.phy_tst_ctrl0 = DW_REG(0x50),
 	.phy_tst_ctrl1 = DW_REG(0x54),
 	.int_st_dphy_fatal = DW_REG(0xe0),
@@ -147,10 +149,13 @@ readl((csi2)->base + ((csi2)->regs->__name & ~DW_REG_EXIST)) : \
 dw_csi2_reg_err(csi2, #__name))
 
 #define PHY_STATE_STOPSTATEDATA_BIT	4
+#define PHY_STATE_STOPSTATEDATA_BIT_V150	0
 #define PHY_STATE_STOPSTATEDATA(n)	BIT(PHY_STATE_STOPSTATEDATA_BIT + (n))
 #define PHY_STATE_RXCLKACTIVEHS	BIT(8)
+#define PHY_STATE_RXCLKACTIVEHS_V150	BIT(17)
 #define PHY_STATE_RXULPSCLKNOT	BIT(9)
 #define PHY_STATE_STOPSTATECLK	BIT(10)
+#define PHY_STATE_STOPSTATECLK_V150		BIT(16)
 
 #define DPHY_TEST_CTRL0_TEST_CLR		BIT(0)
 #define DPHY_TEST_CTRL0_TEST_CLKEN	BIT(1)
@@ -289,7 +294,8 @@ static int __maybe_unused csi2_dphy_wait_ulp(struct dw_mipi_csi2_dev *csi2)
 }
 
 /* Waits for low-power LP-11 state on data and clock lanes. */
-static void csi2_dphy_wait_stopstate(struct dw_mipi_csi2_dev *csi2, unsigned int lanes)
+static void csi2_dphy_wait_stopstate_v0(struct dw_mipi_csi2_dev *csi2,
+					unsigned int lanes)
 {
 	u32 mask, reg;
 	int ret;
@@ -303,13 +309,43 @@ static void csi2_dphy_wait_stopstate(struct dw_mipi_csi2_dev *csi2, unsigned int
 	}
 }
 
+static void csi2_dphy_wait_stopstate_v150(struct dw_mipi_csi2_dev *csi2,
+					  unsigned int lanes)
+{
+	u32 mask, reg;
+	int ret;
+
+	mask = PHY_STATE_STOPSTATECLK_V150 | (((1 << lanes) - 1) <<
+	       PHY_STATE_STOPSTATEDATA_BIT_V150);
+
+	ret = read_poll_timeout(dw_readl, reg, (reg & mask) == mask, 0, 500000,
+				0, csi2, phy_stopstate);
+	if (ret) {
+		v4l2_warn(&csi2->sd, "LP-11 wait timeout, likely a sensor driver bug, expect capture failures.\n");
+		v4l2_warn(&csi2->sd, "phy_state = 0x%08x\n", reg);
+	}
+}
+
+static void csi2_dphy_wait_stopstate(struct dw_mipi_csi2_dev *csi2,
+				     unsigned int lanes)
+{
+	if (csi2->regs == &dw_csi2_v0)
+		return csi2_dphy_wait_stopstate_v0(csi2, lanes);
+
+	csi2_dphy_wait_stopstate_v150(csi2, lanes);
+}
+
 /* Wait for active clock on the clock lane. */
 static int csi2_dphy_wait_clock_lane(struct dw_mipi_csi2_dev *csi2)
 {
+	u32 mask;
 	u32 reg;
 	int ret;
 
-	ret = read_poll_timeout(dw_readl, reg, (reg & PHY_STATE_RXCLKACTIVEHS),
+	mask = csi2->regs == &dw_csi2_v0 ?  PHY_STATE_RXCLKACTIVEHS :
+					    PHY_STATE_RXCLKACTIVEHS_V150;
+
+	ret = read_poll_timeout(dw_readl, reg, (reg & mask),
 				0, 500000, 0, csi2, phy_state);
 	if (ret) {
 		v4l2_err(&csi2->sd, "clock lane timeout, phy_state = 0x%08x\n",

-- 
2.34.1



From Frank.Li at nxp.com  Thu Aug 21 13:16:02 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 21 Aug 2025 16:16:02 -0400
Subject: [PATCH v3 27/31] media: synopsys: csi2: use standard
 v4l2_subdev_get_fmt() function
In-Reply-To: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
References: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
Message-ID: <20250821-95_cam-v3-27-c9286fbb34b9@nxp.com>

Use standard v4l2_subdev_get_fmt() to simple code and add missed call
v4l2_subdev_init_finalize().

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/media/platform/synopsys/mipi-csi2.c | 49 ++++++++++-------------------
 1 file changed, 16 insertions(+), 33 deletions(-)

diff --git a/drivers/media/platform/synopsys/mipi-csi2.c b/drivers/media/platform/synopsys/mipi-csi2.c
index 7225285c772edf6ca3372408dd3cb0637b47e0c0..5ed65e89d4d9a75b245ebc6f28df989dcbd00b7b 100644
--- a/drivers/media/platform/synopsys/mipi-csi2.c
+++ b/drivers/media/platform/synopsys/mipi-csi2.c
@@ -714,38 +714,13 @@ static int csi2_link_setup(struct media_entity *entity,
 	return ret;
 }
 
-static struct v4l2_mbus_framefmt *
-__csi2_get_fmt(struct dw_mipi_csi2_dev *csi2, struct v4l2_subdev_state *sd_state,
-	       unsigned int pad, enum v4l2_subdev_format_whence which)
-{
-	if (which == V4L2_SUBDEV_FORMAT_TRY)
-		return v4l2_subdev_state_get_format(sd_state, pad);
-	else
-		return &csi2->format_mbus;
-}
-
-static int csi2_get_fmt(struct v4l2_subdev *sd,
-			struct v4l2_subdev_state *sd_state,
-			struct v4l2_subdev_format *sdformat)
-{
-	struct dw_mipi_csi2_dev *csi2 = sd_to_dev(sd);
-	struct v4l2_mbus_framefmt *fmt;
-
-	guard(mutex)(&csi2->lock);
-
-	fmt = __csi2_get_fmt(csi2, sd_state, sdformat->pad, sdformat->which);
-
-	sdformat->format = *fmt;
-
-	return 0;
-}
-
 static int csi2_set_fmt(struct v4l2_subdev *sd,
 			struct v4l2_subdev_state *sd_state,
 			struct v4l2_subdev_format *sdformat)
 {
 	struct dw_mipi_csi2_dev *csi2 = sd_to_dev(sd);
 	struct v4l2_mbus_framefmt *fmt;
+	int i;
 	u32 align;
 	u32 bpp;
 
@@ -756,7 +731,7 @@ static int csi2_set_fmt(struct v4l2_subdev *sd,
 	 * The CSIS can't transcode in any way, the source format can't be
 	 * modified.
 	 */
-	if (sdformat->pad < csi2->num_src_pads)
+	if (csi2->pad[sdformat->pad].flags == MEDIA_PAD_FL_SOURCE)
 		return v4l2_subdev_get_fmt(sd, sd_state, sdformat);
 
 	guard(mutex)(&csi2->lock);
@@ -771,13 +746,17 @@ static int csi2_set_fmt(struct v4l2_subdev *sd,
 	v4l_bound_align_image(&sdformat->format.width, 1, U16_MAX, align,
 			      &sdformat->format.height, 1, U16_MAX, 0, 0);
 
-	/* Output pads mirror active input pad, no limits on input pads */
-	if (!(csi2->config->sink_pad_mask & BIT(sdformat->pad)))
-		sdformat->format = csi2->format_mbus;
+	fmt = v4l2_subdev_state_get_format(sd_state, sdformat->pad);
+	*fmt = sdformat->format;
 
-	fmt = __csi2_get_fmt(csi2, sd_state, sdformat->pad, sdformat->which);
+	/* Output pads mirror active input pad, no limits on input pads */
+	for (i = 0; i < csi2->config->num_pads; i++)
+		if (csi2->pad[i].flags == MEDIA_PAD_FL_SOURCE) {
+			fmt = v4l2_subdev_state_get_format(sd_state, i);
+			*fmt = sdformat->format;
+		}
 
-	*fmt = sdformat->format;
+	csi2->format_mbus = *fmt;
 
 	return 0;
 }
@@ -818,7 +797,7 @@ static const struct media_entity_operations csi2_entity_ops = {
 };
 
 static const struct v4l2_subdev_pad_ops csi2_pad_ops = {
-	.get_fmt = csi2_get_fmt,
+	.get_fmt = v4l2_subdev_get_fmt,
 	.set_fmt = csi2_set_fmt,
 	.enable_streams = dw_csi2_enable_streams,
 	.disable_streams = dw_csi2_disable_streams,
@@ -1071,6 +1050,10 @@ int dw_mipi_csi2_init(struct platform_device *pdev, struct dw_mipi_csi2_dev *csi
 	if (ret)
 		return ret;
 
+	ret = v4l2_subdev_init_finalize(&csi2->sd);
+	if (ret)
+		return ret;
+
 	ret = devm_add_action_or_reset(&pdev->dev, csi2_nf_cleanup, csi2);
 	if (ret)
 		return ret;

-- 
2.34.1



From Frank.Li at nxp.com  Thu Aug 21 13:16:03 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 21 Aug 2025 16:16:03 -0400
Subject: [PATCH v3 28/31] media: synopsys: csi2: Add customize
 get_frame_desc() callback
In-Reply-To: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
References: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
Message-ID: <20250821-95_cam-v3-28-c9286fbb34b9@nxp.com>

Add customize get_frame_desc() callback to work with existed isi drivers.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/media/platform/synopsys/mipi-csi2.c | 73 +++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)

diff --git a/drivers/media/platform/synopsys/mipi-csi2.c b/drivers/media/platform/synopsys/mipi-csi2.c
index 5ed65e89d4d9a75b245ebc6f28df989dcbd00b7b..695159f463f872ee0775c271b8e1c4e1d289de20 100644
--- a/drivers/media/platform/synopsys/mipi-csi2.c
+++ b/drivers/media/platform/synopsys/mipi-csi2.c
@@ -761,6 +761,78 @@ static int csi2_set_fmt(struct v4l2_subdev *sd,
 	return 0;
 }
 
+static int dw_csi2_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
+				  struct v4l2_mbus_frame_desc *fd)
+{
+	struct dw_mipi_csi2_dev *csi2 = sd_to_dev(sd);
+	struct v4l2_mbus_frame_desc source_fd;
+	struct v4l2_subdev_route *route;
+	struct v4l2_subdev_state *state;
+	int data_type;
+	int ret;
+
+	if (!(csi2->pad[pad].flags & MEDIA_PAD_FL_SOURCE))
+		return -EINVAL;
+
+	memset(fd, 0, sizeof(*fd));
+
+	data_type = media_bus_fmt_to_csi2_dt(csi2->format_mbus.code);
+
+	ret = v4l2_subdev_call(csi2->src_sd, pad, get_frame_desc,
+			       csi2->remote_pad, &source_fd);
+	if (ret < 0) {
+		dev_info(csi2->dev,
+			 "Remote sub-device on pad %d should implement .get_frame_desc! Forcing VC = 0 and DT = %x\n",
+			 pad, data_type);
+		fd->type = V4L2_MBUS_FRAME_DESC_TYPE_CSI2;
+		fd->num_entries = 1;
+		fd->entry[0].pixelcode = csi2->format_mbus.code;
+		fd->entry[0].bus.csi2.vc = 0;
+		fd->entry[0].bus.csi2.dt = data_type;
+
+		return 0;
+	}
+
+	fd->type = V4L2_MBUS_FRAME_DESC_TYPE_CSI2;
+
+	state = v4l2_subdev_lock_and_get_active_state(sd);
+
+	for_each_active_route(&state->routing, route) {
+		struct v4l2_mbus_frame_desc_entry *entry = NULL;
+		unsigned int i;
+
+		if (route->source_pad != pad)
+			continue;
+
+		for (i = 0; i < source_fd.num_entries; ++i) {
+			if (source_fd.entry[i].stream == route->sink_stream) {
+				entry = &source_fd.entry[i];
+				break;
+			}
+		}
+
+		if (!entry) {
+			dev_err(csi2->dev,
+				"Failed to find stream from source frames desc\n");
+			ret = -EPIPE;
+			goto out_unlock;
+		}
+
+		fd->entry[fd->num_entries].stream = route->source_stream;
+		fd->entry[fd->num_entries].flags = entry->flags;
+		fd->entry[fd->num_entries].length = entry->length;
+		fd->entry[fd->num_entries].pixelcode = entry->pixelcode;
+		fd->entry[fd->num_entries].bus.csi2.vc = entry->bus.csi2.vc;
+		fd->entry[fd->num_entries].bus.csi2.dt = entry->bus.csi2.dt;
+
+		fd->num_entries++;
+	}
+
+out_unlock:
+	v4l2_subdev_unlock_state(state);
+	return ret;
+}
+
 /* --------------- CORE OPS --------------- */
 
 static int csi2_log_status(struct v4l2_subdev *sd)
@@ -799,6 +871,7 @@ static const struct media_entity_operations csi2_entity_ops = {
 static const struct v4l2_subdev_pad_ops csi2_pad_ops = {
 	.get_fmt = v4l2_subdev_get_fmt,
 	.set_fmt = csi2_set_fmt,
+	.get_frame_desc = dw_csi2_get_frame_desc,
 	.enable_streams = dw_csi2_enable_streams,
 	.disable_streams = dw_csi2_disable_streams,
 };

-- 
2.34.1



From Frank.Li at nxp.com  Thu Aug 21 13:16:04 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 21 Aug 2025 16:16:04 -0400
Subject: [PATCH v3 29/31] media: synopsys: csi2: Add Image Pixel Interface
 (IPI) support for v150
In-Reply-To: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
References: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
Message-ID: <20250821-95_cam-v3-29-c9286fbb34b9@nxp.com>

Add Image Pixel Interface (IPI) support for v150. Check the ipi_mode
register to determine whether the hardware supports IPI.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/media/platform/synopsys/mipi-csi2.c | 82 +++++++++++++++++++++++++++++
 1 file changed, 82 insertions(+)

diff --git a/drivers/media/platform/synopsys/mipi-csi2.c b/drivers/media/platform/synopsys/mipi-csi2.c
index 695159f463f872ee0775c271b8e1c4e1d289de20..8ccd3d4960801cccd8d24647f726e4653955f90c 100644
--- a/drivers/media/platform/synopsys/mipi-csi2.c
+++ b/drivers/media/platform/synopsys/mipi-csi2.c
@@ -40,6 +40,11 @@ struct dw_csi2_regs {
 	u32	msk2;
 	u32	phy_tst_ctrl0;
 	u32	phy_tst_ctrl1;
+	u32	ipi_softrstn;
+	u32	ipi_datatype;
+	u32	ipi_vcid;
+	u32	ipi_mode;
+	u32	ipi_mem_flush;
 	u32	int_st_main;
 	u32	int_st_dphy_fatal;
 	u32	int_msk_dphy_fatal;
@@ -90,6 +95,11 @@ static const struct dw_csi2_regs dw_csi2_v150 = {
 	.phy_stopstate = DW_REG(0x4c),
 	.phy_tst_ctrl0 = DW_REG(0x50),
 	.phy_tst_ctrl1 = DW_REG(0x54),
+	.ipi_mode = DW_REG(0x80),
+	.ipi_vcid = DW_REG(0x84),
+	.ipi_datatype = DW_REG(0x88),
+	.ipi_mem_flush = DW_REG(0x8c),
+	.ipi_softrstn = DW_REG(0xa0),
 	.int_st_dphy_fatal = DW_REG(0xe0),
 	.int_msk_dphy_fatal = DW_REG(0xe4),
 	.int_force_dphy_fatal = DW_REG(0xe8),
@@ -115,6 +125,31 @@ static const struct dw_csi2_regs dw_csi2_v150 = {
 #define INT_ST_MAIN_ERR_PHY			BIT(16)
 #define INT_ST_MAIN_FATAL_ERR_IPI		BIT(18)
 
+#define IPI_VCID_VC(x)				FIELD_PREP(GENMASK(1, 0), (x))
+#define IPI_VCID_VC_0_1(x)			FIELD_PREP(GENMASK(3, 2), (x))
+#define IPI_VCID_VC_2				BIT(4)
+
+#define IPI_DATA_TYPE_DT(x)			FIELD_PREP(GENMASK(5, 0), (x))
+#define IPI_DATA_TYPE_EMB_DATA_EN		BIT(8)
+
+#define IPI_MODE_CONTROLLER			BIT(1)
+#define IPI_MODE_COLOR_MODE16			BIT(8)
+#define IPI_MODE_CUT_THROUGH			BIT(16)
+#define IPI_MODE_ENABLE				BIT(24)
+
+#define IPI_MEM_FLUSH_AUTO			BIT(8)
+
+#define INT_ST_MAIN_FATAL_ERR_PHY		BIT(0)
+#define INT_ST_MAIN_FATAL_ERR_PKT		BIT(1)
+#define INT_ST_MAIN_FATAL_ERR_BNDRY_FRAMEL	BIT(2)
+#define INT_ST_MAIN_FATAL_ERR_SEQ_FRAME		BIT(3)
+#define INT_ST_MAIN_FATAL_ERR_CRC_FRAME		BIT(4)
+#define INT_ST_MAIN_FATAL_ERR_PLD_CRC		BIT(5)
+#define INT_ST_MAIN_ERR_DID			BIT(6)
+#define INT_ST_MAIN_ERR_ECC			BIT(7)
+#define INT_ST_MAIN_ERR_PHY			BIT(16)
+#define INT_ST_MAIN_FATAL_ERR_IPI		BIT(18)
+
 #define INT_MSK_DPHY_FATAL_ERR_SOT_LANE0	BIT(0)
 #define INT_MSK_DPHY_FATAL_ERR_SOT_LANE1	BIT(1)
 
@@ -449,6 +484,48 @@ static int dw_mipi_csi2_phy_prep(struct dw_mipi_csi2_dev *csi2, int bpp)
 	return ret;
 }
 
+static void dw_csi2_device_ipi_config(struct dw_mipi_csi2_dev *csi2)
+{
+	int dt = media_bus_fmt_to_csi2_dt(csi2->format_mbus.code);
+	u32 val;
+
+	/* Do IPI soft reset */
+	dw_writel(csi2, 0x0, ipi_softrstn);
+	dw_writel(csi2, 0x1, ipi_softrstn);
+
+	/* Select virtual channel and data type to be processed by IPI */
+	val = IPI_DATA_TYPE_DT(dt);
+	dw_writel(csi2, val, ipi_datatype);
+
+	/* Set virtual channel 0 as default */
+	val  = IPI_VCID_VC(0);
+	dw_writel(csi2, val, ipi_vcid);
+
+	/*
+	 * Select IPI camera timing mode and allow the pixel stream
+	 * to be non-continuous when pixel interface FIFO is empty
+	 */
+	val = dw_readl(csi2, ipi_mode);
+	val &= ~IPI_MODE_CONTROLLER;
+	val &= ~IPI_MODE_COLOR_MODE16;
+	val |= IPI_MODE_CUT_THROUGH;
+	dw_writel(csi2, val, ipi_mode);
+}
+
+static void dw_csi2_ipi_enable(struct dw_mipi_csi2_dev *csi2)
+{
+	u32 val;
+
+	/* Memory is automatically flushed at each Frame Start */
+	val = IPI_MEM_FLUSH_AUTO;
+	dw_writel(csi2, val, ipi_mem_flush);
+
+	/* Enable IPI */
+	val = dw_readl(csi2, ipi_mode);
+	val |= IPI_MODE_ENABLE;
+	dw_writel(csi2, val, ipi_mode);
+}
+
 static void dw_csi2_enable_irq(struct dw_mipi_csi2_dev *csi2)
 {
 	u32 val;
@@ -583,6 +660,11 @@ static int csi2_start(struct dw_mipi_csi2_dev *csi2, int bpp)
 	if (ret)
 		goto err_stop_upstream;
 
+	if (csi2->regs->ipi_mode) {
+		dw_csi2_device_ipi_config(csi2);
+		dw_csi2_ipi_enable(csi2);
+	}
+
 	dw_csi2_enable_irq(csi2);
 
 	return 0;

-- 
2.34.1



From Frank.Li at nxp.com  Thu Aug 21 13:16:05 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 21 Aug 2025 16:16:05 -0400
Subject: [PATCH v3 30/31] media: synopsys: csi2: Remove source pad
 connected check at dw_csi2_enable_streams()
In-Reply-To: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
References: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
Message-ID: <20250821-95_cam-v3-30-c9286fbb34b9@nxp.com>

link_setup() callback is not called if remote linked subdev use flag
MEDIA_LNK_FL_ENABLED.

Driver needn't track if source pad is connected since framework already do
that. So remove these check and related variable.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/media/platform/synopsys/mipi-csi2.c | 21 +++------------------
 include/media/dw-mipi-csi2.h                |  1 -
 2 files changed, 3 insertions(+), 19 deletions(-)

diff --git a/drivers/media/platform/synopsys/mipi-csi2.c b/drivers/media/platform/synopsys/mipi-csi2.c
index 8ccd3d4960801cccd8d24647f726e4653955f90c..66207a601c228bfd3d79b7a2053458870622b039 100644
--- a/drivers/media/platform/synopsys/mipi-csi2.c
+++ b/drivers/media/platform/synopsys/mipi-csi2.c
@@ -710,18 +710,12 @@ static int dw_csi2_enable_streams(struct v4l2_subdev *sd,
 				  u64 streams_mask)
 {
 	struct dw_mipi_csi2_dev *csi2 = sd_to_dev(sd);
-	int i, ret = 0;
+	int ret = 0;
 
 	guard(mutex)(&csi2->lock);
 
-	if (!csi2->src_sd)
-		return -EPIPE;
 
-	for (i = 0; i < csi2->num_sink_pads; i++) {
-		if (csi2->sink_linked[i])
-			break;
-	}
-	if (i >= csi2->num_sink_pads)
+	if (!csi2->src_sd)
 		return -EPIPE;
 
 	if (csi2->stream_count)
@@ -773,16 +767,7 @@ static int csi2_link_setup(struct media_entity *entity,
 
 	guard(mutex)(&csi2->lock);
 
-	if (local->flags & MEDIA_PAD_FL_SOURCE) {
-		if (flags & MEDIA_LNK_FL_ENABLED) {
-			if (csi2->sink_linked[local->index - 1])
-				return -EBUSY;
-
-			csi2->sink_linked[local->index - 1] = true;
-		} else {
-			csi2->sink_linked[local->index - 1] = false;
-		}
-	} else {
+	if (local->flags & MEDIA_PAD_FL_SINK) {
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (csi2->src_sd)
 				return -EBUSY;
diff --git a/include/media/dw-mipi-csi2.h b/include/media/dw-mipi-csi2.h
index d1afd8c6d95457c28d7e1de6935908437372572d..977a9e27cc50ad6ecfb47ebf8d42f115bc51c1ae 100644
--- a/include/media/dw-mipi-csi2.h
+++ b/include/media/dw-mipi-csi2.h
@@ -75,7 +75,6 @@ struct dw_mipi_csi2_dev {
 
 	int				stream_count;
 	struct v4l2_subdev		*src_sd;
-	bool				sink_linked[DW_MAX_PAD_NUM];
 	const struct dw_mipi_csi2_config *config;
 
 	struct dw_csi2_event		*event;

-- 
2.34.1



From Frank.Li at nxp.com  Thu Aug 21 13:16:06 2025
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 21 Aug 2025 16:16:06 -0400
Subject: [PATCH v3 31/31] media: synopsys: csi2: Add simple synopsys
 platform driver
In-Reply-To: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
References: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
Message-ID: <20250821-95_cam-v3-31-c9286fbb34b9@nxp.com>

Add simple synosys platform driver, which use standard PHY interface and
only 1 sink and 1 source pad. No format convert between source and sink
pad.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/media/platform/synopsys/Kconfig            |  8 +++
 drivers/media/platform/synopsys/Makefile           |  1 +
 drivers/media/platform/synopsys/mipi-csi2-simple.c | 75 ++++++++++++++++++++++
 3 files changed, 84 insertions(+)

diff --git a/drivers/media/platform/synopsys/Kconfig b/drivers/media/platform/synopsys/Kconfig
index e54dad835349d420dead6d5313c0623567c28c0b..642b7dcd8dfb1bafa3b6dbdba1a1d99559d3c01a 100644
--- a/drivers/media/platform/synopsys/Kconfig
+++ b/drivers/media/platform/synopsys/Kconfig
@@ -12,4 +12,12 @@ config VIDEO_SYNOPSYS_MIPI_CSI2
           To compile this driver as a module, choose M here. The module
           will be called synopsys_hdmirx
 
+config VIDEO_SYNOPSYS_MIPI_CSI2_SIMPLE
+	tristate "Simple Synopsys DesignWare HDMI Receiver platform driver"
+	depends on VIDEO_SYNOPSYS_MIPI_CSI2
+	help
+	  Simple platform Synopsys MIPI CSI2 platform driver, which not format
+	  convert between sink and source pad. Only 1 source pad and 1 sink
+	  pad, use standard PHY interface to initialize DPHY.
+
 source "drivers/media/platform/synopsys/hdmirx/Kconfig"
diff --git a/drivers/media/platform/synopsys/Makefile b/drivers/media/platform/synopsys/Makefile
index 045ed3177738e6d28aa223804b79e6774e141dc8..cac610c8e08abeebdbf14157d8edcdc5a635dd00 100644
--- a/drivers/media/platform/synopsys/Makefile
+++ b/drivers/media/platform/synopsys/Makefile
@@ -2,3 +2,4 @@
 obj-y += hdmirx/
 
 obj-$(CONFIG_VIDEO_SYNOPSYS_MIPI_CSI2) += mipi-csi2.o
+obj-$(CONFIG_VIDEO_SYNOPSYS_MIPI_CSI2_SIMPLE) += mipi-csi2-simple.o
diff --git a/drivers/media/platform/synopsys/mipi-csi2-simple.c b/drivers/media/platform/synopsys/mipi-csi2-simple.c
new file mode 100644
index 0000000000000000000000000000000000000000..bf34a515b41290339db06d74d7135c575a8bf031
--- /dev/null
+++ b/drivers/media/platform/synopsys/mipi-csi2-simple.c
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Synosis MIPI CSI-2 Simple platform driver
+ *
+ * Copyright (c) 2025 NXP.
+ */
+#include <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+
+#include <media/dw-mipi-csi2.h>
+
+struct simple_csi2 {
+	struct dw_mipi_csi2_dev dw;
+};
+
+static const struct dw_mipi_csi2_config simple_config = {
+	.module = THIS_MODULE,
+	.name = "dw-mipi-csi2",
+	.num_pads = 2,
+	.sink_pad_mask = BIT(0),
+	.has_irq = true,
+	.has_phy = true,
+	.need_dphy_reset = true,
+};
+
+static DEFINE_RUNTIME_DEV_PM_OPS(csi2_pm_ops, dw_mipi_csi2_runtime_suspend,
+				 dw_mipi_csi2_runtime_resume, NULL);
+
+static int csi2_probe(struct platform_device *pdev)
+{
+	struct simple_csi2 *csi2;
+
+	csi2 = devm_kzalloc(&pdev->dev, sizeof(*csi2), GFP_KERNEL);
+	if (!csi2)
+		return -ENOMEM;
+
+	return dw_mipi_csi2_init(pdev, &csi2->dw, &simple_config);
+}
+
+static void csi2_remove(struct platform_device *pdev)
+{
+	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
+	struct dw_mipi_csi2_dev *csi2 = sd_to_dw_mipi_csi2_dev(sd);
+
+	dw_mipi_csi2_deinit(csi2);
+}
+
+static const struct of_device_id csi2_dt_ids[] = {
+	{ .compatible = "snps,dw-mipi-csi2-v150" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, csi2_dt_ids);
+
+static struct platform_driver csi2_driver = {
+	.driver = {
+		.name = "dw-mipi-csi2",
+		.of_match_table = csi2_dt_ids,
+		.pm = pm_ptr(&csi2_pm_ops),
+	},
+	.probe = csi2_probe,
+	.remove = csi2_remove,
+};
+
+module_platform_driver(csi2_driver);
+
+MODULE_DESCRIPTION("Simple Synosis MIPI CSI-2 Receiver platform driver");
+MODULE_AUTHOR("Frank Li <Frank.li at nxp.com>");
+MODULE_LICENSE("GPL");

-- 
2.34.1



From lkp at intel.com  Thu Aug 21 14:28:14 2025
From: lkp at intel.com (kernel test robot)
Date: Fri, 22 Aug 2025 05:28:14 +0800
Subject: [PATCH v6 6/6] phy: exynos5-usbdrd: support SS combo phy for
 ExynosAutov920
In-Reply-To: <20250821073703.2498302-7-pritam.sutar@samsung.com>
References: <20250821073703.2498302-7-pritam.sutar@samsung.com>
Message-ID: <202508220553.lm7ExAxG-lkp@intel.com>

Hi Pritam,

kernel test robot noticed the following build warnings:

[auto build test WARNING on robh/for-next]
[also build test WARNING on krzk/for-next linus/master v6.17-rc2 next-20250821]
[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/Pritam-Manohar-Sutar/dt-bindings-phy-samsung-usb3-drd-phy-add-ExynosAutov920-HS-phy-compatible/20250821-153122
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
patch link:    https://lore.kernel.org/r/20250821073703.2498302-7-pritam.sutar%40samsung.com
patch subject: [PATCH v6 6/6] phy: exynos5-usbdrd: support SS combo phy for ExynosAutov920
config: arc-randconfig-001-20250822 (https://download.01.org/0day-ci/archive/20250822/202508220553.lm7ExAxG-lkp at intel.com/config)
compiler: arc-linux-gcc (GCC) 8.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250822/202508220553.lm7ExAxG-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/202508220553.lm7ExAxG-lkp at intel.com/

All warnings (new ones prefixed by >>):

   drivers/phy/samsung/phy-exynos5-usbdrd.c: In function 'exynosautov920_usb31drd_cr_write':
>> drivers/phy/samsung/phy-exynos5-usbdrd.c:2167:17: warning: unused variable 'dev' [-Wunused-variable]
     struct device *dev = phy_drd->dev;
                    ^~~
   drivers/phy/samsung/phy-exynos5-usbdrd.c: In function 'exynosautov920_usb31drd_port_phy_ready':
>> drivers/phy/samsung/phy-exynos5-usbdrd.c:2137:6: warning: 'reg' is used uninitialized in this function [-Wuninitialized]
     reg &= ~(PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK |
     ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR);
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   during RTL pass: mach
   drivers/phy/samsung/phy-exynos5-usbdrd.c: In function 'exynos5_usbdrd_phy_probe':
   drivers/phy/samsung/phy-exynos5-usbdrd.c:3056:1: internal compiler error: in arc_ifcvt, at config/arc/arc.c:9110
    }
    ^
   Please submit a full bug report,
   with preprocessed source if appropriate.
   See <https://gcc.gnu.org/bugs/> for instructions.


vim +/dev +2167 drivers/phy/samsung/phy-exynos5-usbdrd.c

  2125	
  2126	static void
  2127	exynosautov920_usb31drd_port_phy_ready(struct exynos5_usbdrd_phy *phy_drd)
  2128	{
  2129		struct device *dev = phy_drd->dev;
  2130		void __iomem *reg_phy = phy_drd->reg_phy;
  2131		static const unsigned int timeout_us = 20000;
  2132		static const unsigned int sleep_us = 40;
  2133		u32 reg;
  2134		int err;
  2135	
  2136		/* Clear cr_para_con */
> 2137		reg &= ~(PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK |
  2138				PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR);
  2139		reg |= PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL;
  2140		writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
  2141		writel(0x0, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON1);
  2142		writel(0x0, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2);
  2143	
  2144		exynosautov920_usb31drd_cr_clk(phy_drd, true);
  2145		exynosautov920_usb31drd_cr_clk(phy_drd, false);
  2146	
  2147		/*
  2148		 * The maximum time from phy reset de-assertion to de-assertion of
  2149		 * tx/rx_ack can be as high as 5ms in fast simulation mode.
  2150		 * Time to phy ready is < 20ms
  2151		 */
  2152		err = readl_poll_timeout(reg_phy +
  2153					EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0,
  2154				reg, !(reg & PHY_CR_PARA_CON0_PHY0_CR_PARA_ACK),
  2155				sleep_us, timeout_us);
  2156		if (err)
  2157			dev_err(dev, "timed out waiting for rx/tx_ack: %#.8x\n", reg);
  2158	
  2159		reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK;
  2160		writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
  2161	}
  2162	
  2163	static void
  2164	exynosautov920_usb31drd_cr_write(struct exynos5_usbdrd_phy *phy_drd,
  2165					 u16 addr, u16 data)
  2166	{
> 2167		struct device *dev = phy_drd->dev;
  2168		void __iomem *reg_phy = phy_drd->reg_phy;
  2169		u32 cnt = 0;
  2170		u32 reg;
  2171	
  2172		/* Pre Clocking */
  2173		reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
  2174		reg |= PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL;
  2175		writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
  2176	
  2177		/*
  2178		 * tx clks must be available prior to assertion of tx req.
  2179		 * tx pstate p2 to p0 transition directly is not permitted.
  2180		 * tx clk ready must be asserted synchronously on tx clk prior
  2181		 * to internal transmit clk alignment sequence in the phy
  2182		 * when entering from p2 to p1 to p0.
  2183		 */
  2184		do {
  2185			exynosautov920_usb31drd_cr_clk(phy_drd, true);
  2186			exynosautov920_usb31drd_cr_clk(phy_drd, false);
  2187			cnt++;
  2188		} while (cnt < 15);
  2189	
  2190		reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL;
  2191		writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
  2192	
  2193		/*
  2194		 * tx data path is active when tx lane is in p0 state
  2195		 * and tx data en asserted. enable cr_para_wr_en.
  2196		 */
  2197		reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2);
  2198		reg &= ~PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_DATA;
  2199		reg |= FIELD_PREP(PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_DATA, data) |
  2200			PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_EN;
  2201		writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2);
  2202	
  2203		/* write addr */
  2204		reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
  2205		reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR;
  2206		reg |= FIELD_PREP(PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR, addr) |
  2207			PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK |
  2208			PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL;
  2209		writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
  2210	
  2211		/* check cr_para_ack*/
  2212		cnt = 0;
  2213		do {
  2214			/*
  2215			 * data symbols are captured by phy on rising edge of the
  2216			 * tx_clk when tx data enabled.
  2217			 * completion of the write cycle is acknowledged by assertion
  2218			 * of the cr_para_ack.
  2219			 */
  2220			exynosautov920_usb31drd_cr_clk(phy_drd, true);
  2221			reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
  2222			if ((reg & PHY_CR_PARA_CON0_PHY0_CR_PARA_ACK))
  2223				break;
  2224	
  2225			exynosautov920_usb31drd_cr_clk(phy_drd, false);
  2226	
  2227			/*
  2228			 * wait for minimum of 10 cr_para_clk cycles after phy reset
  2229			 * is negated, before accessing control regs to allow for
  2230			 * internal resets.
  2231			 */
  2232			cnt++;
  2233		} while (cnt < 10);
  2234	
  2235		if (cnt < 10)
  2236			exynosautov920_usb31drd_cr_clk(phy_drd, false);
  2237	}
  2238	

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


From Thinh.Nguyen at synopsys.com  Thu Aug 21 15:18:42 2025
From: Thinh.Nguyen at synopsys.com (Thinh Nguyen)
Date: Thu, 21 Aug 2025 22:18:42 +0000
Subject: [PATCH RFC 07/22] usb: dwc3: apple: Adjust vendor-specific
 registers during init
In-Reply-To: <20250821-atcphy-6-17-v1-7-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
 <20250821-atcphy-6-17-v1-7-172beda182b8@kernel.org>
Message-ID: <20250821221832.zsn4rk7nomsbgytx@synopsys.com>

Hi,

On Thu, Aug 21, 2025, Sven Peter wrote:
> From: Hector Martin <marcan at marcan.st>
> 
> When tracing Apple's dwc3 driver under our hypervisor and comparing its
> MMIO access with their kernel debug output these vendor-specific
> registers have been identified. We don't know exactly what these do
> or why they are required but without changing these parameters sometimes
> USB3 devices don't work or take an additional 5 seconds to be recognized.
> 
> Signed-off-by: Hector Martin <marcan at marcan.st>
> Co-developed-by: Sven Peter <sven at kernel.org>
> Signed-off-by: Sven Peter <sven at kernel.org>
> ---
>  drivers/usb/dwc3/core.c | 17 +++++++++++++++++
>  drivers/usb/dwc3/core.h | 18 ++++++++++++++++++
>  2 files changed, 35 insertions(+)
> 
> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index f8013ba2bdc22fa5e719df0841b12b84d9465b62..e018e80778cf39a9981d438c7e54534b26cddf63 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -1366,6 +1366,23 @@ static int dwc3_core_init(struct dwc3 *dwc)
>  	 */
>  	dwc3_writel(dwc->regs, DWC3_GUID, LINUX_VERSION_CODE);
>  
> +	/* Apply Apple quirks */
> +	if (of_device_is_compatible(dwc->dev->of_node, "apple,t8103-dwc3")) {
> +		dwc3_writel(dwc->regs,
> +			    APPLE_DWC3_CIO_LFPS_OFFSET,
> +			    APPLE_DWC3_CIO_LFPS_OFFSET_VALUE);
> +		dwc3_writel(dwc->regs,
> +			    APPLE_DWC3_CIO_BW_NGT_OFFSET,
> +			    APPLE_DWC3_CIO_BW_NGT_OFFSET_VALUE);
> +
> +		u32 link_timer = dwc3_readl(dwc->regs, APPLE_DWC3_CIO_LINK_TIMER);
> +
> +		link_timer &= ~APPLE_DWC3_CIO_PENDING_HP_TIMER;
> +		link_timer |= FIELD_PREP(APPLE_DWC3_CIO_PENDING_HP_TIMER,
> +					 APPLE_DWC3_CIO_PENDING_HP_TIMER_VALUE);
> +		dwc3_writel(dwc->regs, APPLE_DWC3_CIO_LINK_TIMER, link_timer);
> +	}
> +
>  	ret = dwc3_phy_setup(dwc);
>  	if (ret)
>  		return ret;
> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
> index 98e748cc348dfd9de1962c93fcf9f6a6690c2388..1caa46ca8b2ffb74dd3e58b174122e8f8216dd48 100644
> --- a/drivers/usb/dwc3/core.h
> +++ b/drivers/usb/dwc3/core.h
> @@ -181,6 +181,24 @@
>  
>  #define DWC3_LLUCTL(n)		(0xd024 + ((n) * 0x80))
>  
> +/*
> + * Apple Silicon dwc3 vendor-specific registers
> + *
> + * These registers were identified by tracing XNU's memory access patterns
> + * and correlating them with debug output over serial to determine their names.
> + * We don't exactly know what these do but without these USB3 devices sometimes
> + * don't work.
> + */
> +#define APPLE_DWC3_CIO_LFPS_OFFSET 0xcd38
> +#define APPLE_DWC3_CIO_LFPS_OFFSET_VALUE 0xf800f80
> +
> +#define APPLE_DWC3_CIO_BW_NGT_OFFSET 0xcd3c
> +#define APPLE_DWC3_CIO_BW_NGT_OFFSET_VALUE 0xfc00fc0
> +
> +#define APPLE_DWC3_CIO_LINK_TIMER 0xcd40
> +#define APPLE_DWC3_CIO_PENDING_HP_TIMER GENMASK(23, 16)
> +#define APPLE_DWC3_CIO_PENDING_HP_TIMER_VALUE 0x14
> +
>  /* Bit fields */
>  
>  /* Global SoC Bus Configuration INCRx Register 0 */
> 
> -- 
> 2.34.1
> 
> 

This is really great that you got to this point!

For this patch, however, I'd prefer these vendor-specific settings to be
in their own glue driver. I can only imagine more changes will be
introduced in the future with this vendor. See if we can use the new
glue interface in glue.h (some call this the new "flatten" model) when
creating a glue driver.

Thanks,
Thinh

From Thinh.Nguyen at synopsys.com  Thu Aug 21 15:28:46 2025
From: Thinh.Nguyen at synopsys.com (Thinh Nguyen)
Date: Thu, 21 Aug 2025 22:28:46 +0000
Subject: [PATCH RFC 05/22] usb: dwc3: apple: Do not use host-vbus-glitches
 workaround
In-Reply-To: <20250821-atcphy-6-17-v1-5-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
 <20250821-atcphy-6-17-v1-5-172beda182b8@kernel.org>
Message-ID: <20250821222842.fqrxjp56czc7ubok@synopsys.com>

On Thu, Aug 21, 2025, Sven Peter wrote:
> From: Janne Grunau <j at jannau.net>
> 
> It results in SErrors during init presumedly because MMIO accesses fail
> while certain parts are shutdown.
> 
> Signed-off-by: Janne Grunau <j at jannau.net>
> Signed-off-by: Sven Peter <sven at kernel.org>
> ---
>  drivers/usb/dwc3/core.c | 1 +
>  drivers/usb/dwc3/core.h | 2 ++
>  drivers/usb/dwc3/host.c | 5 ++++-
>  3 files changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index 26aa507a738f001409a97ef563c6561433a1cac5..8d2dc7fa18114102cc8893c4ca0e745e16f30754 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -2273,6 +2273,7 @@ int dwc3_core_probe(const struct dwc3_probe_data *data)
>  
>  			dwc->dr_mode = USB_DR_MODE_OTG;
>  			dwc->role_switch_reset_quirk = true;
> +			dwc->no_early_roothub_poweroff = true;
>  		}
>  	}
>  
> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
> index 38f32f2a6193c1b2662ab4f38f4d20cf4b0e198d..3c3a36ec37345b2f9e71444ba3b90b52dbd24443 100644
> --- a/drivers/usb/dwc3/core.h
> +++ b/drivers/usb/dwc3/core.h
> @@ -1155,6 +1155,7 @@ struct dwc3_scratchpad_array {
>   * @susphy_state: state of DWC3_GUSB2PHYCFG_SUSPHY + DWC3_GUSB3PIPECTL_SUSPHY
>   *		  before PM suspend.
>   * @role_switch_reset_quirk: set to force reinitialization after any role switch
> + * @no_early_roothub_poweroff: set to skip early root hub port power off
>   * @imod_interval: set the interrupt moderation interval in 250ns
>   *			increments or 0 to disable.
>   * @max_cfg_eps: current max number of IN eps used across all USB configs.
> @@ -1394,6 +1395,7 @@ struct dwc3 {
>  	unsigned		susphy_state:1;
>  
>  	unsigned		role_switch_reset_quirk:1;
> +	unsigned		no_early_roothub_poweroff:1;
>  
>  	u16			imod_interval;
>  
> diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c
> index f7a71e6f9d80aca632f1f970d900a3de8a76f0a7..f7c3a0fc5fe258705311f89c1ba11ff599c01afe 100644
> --- a/drivers/usb/dwc3/host.c
> +++ b/drivers/usb/dwc3/host.c
> @@ -134,8 +134,11 @@ int dwc3_host_init(struct dwc3 *dwc)
>  	/*
>  	 * Some platforms need to power off all Root hub ports immediately after DWC3 set to host
>  	 * mode to avoid VBUS glitch happen when xhci get reset later.
> +	 * On Apple platforms we must not touch any MMIO yet because dwc3
> +	 * will not work correctly before its PHY has been initialized.

This doesn't make sense, the phy should've been initialized by this
point. We already access MMIO before this. Even your [PATCH RFC 7/22]
attempts to access MMIO before this, yet accessing here causes problem.
Do we know when the phy get initialized then?

BR,
Thinh

>  	 */
> -	dwc3_power_off_all_roothub_ports(dwc);
> +	if (!dwc->no_early_roothub_poweroff)
> +		dwc3_power_off_all_roothub_ports(dwc);
>  
>  	irq = dwc3_host_get_irq(dwc);
>  	if (irq < 0)
> 
> -- 
> 2.34.1
> 
> 

From robh at kernel.org  Thu Aug 21 15:39:51 2025
From: robh at kernel.org (Rob Herring (Arm))
Date: Thu, 21 Aug 2025 17:39:51 -0500
Subject: [PATCH RFC 02/22] dt-bindings: usb: Add Apple dwc3
In-Reply-To: <20250821-atcphy-6-17-v1-2-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
 <20250821-atcphy-6-17-v1-2-172beda182b8@kernel.org>
Message-ID: <175581575858.1136316.14856911628324128636.robh@kernel.org>


On Thu, 21 Aug 2025 15:38:54 +0000, Sven Peter wrote:
> Apple Silicon uses Synopsys DesignWare dwc3 based USB controllers for
> their Type-C ports.
> 
> Signed-off-by: Sven Peter <sven at kernel.org>
> ---
>  .../devicetree/bindings/usb/apple,dwc3.yaml        | 82 ++++++++++++++++++++++
>  MAINTAINERS                                        |  1 +
>  2 files changed, 83 insertions(+)
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:
./Documentation/devicetree/bindings/usb/apple,dwc3.yaml:33:9: [warning] wrong indentation: expected 10 but found 8 (indentation)
./Documentation/devicetree/bindings/usb/apple,dwc3.yaml:40:9: [warning] wrong indentation: expected 10 but found 8 (indentation)

dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/usb/apple,dwc3.example.dtb: usb at 82280000 (apple,t8103-dwc3): 'resets' is a required property
	from schema $id: http://devicetree.org/schemas/usb/apple,dwc3.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/usb/apple,dwc3.example.dtb: usb at 82280000 (apple,t8103-dwc3): 'power-domains' is a required property
	from schema $id: http://devicetree.org/schemas/usb/apple,dwc3.yaml#

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20250821-atcphy-6-17-v1-2-172beda182b8 at kernel.org

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 robh at kernel.org  Thu Aug 21 15:39:50 2025
From: robh at kernel.org (Rob Herring (Arm))
Date: Thu, 21 Aug 2025 17:39:50 -0500
Subject: [PATCH RFC 01/22] dt-bindings: usb: snps,dwc3: Allow multiple
 iommus
In-Reply-To: <20250821-atcphy-6-17-v1-1-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
 <20250821-atcphy-6-17-v1-1-172beda182b8@kernel.org>
Message-ID: <175581575751.1136230.16771549350883688048.robh@kernel.org>


On Thu, 21 Aug 2025 15:38:53 +0000, Sven Peter wrote:
> Apple's dwc3 variant requires two iommus.
> 
> Signed-off-by: Sven Peter <sven at kernel.org>
> ---
>  Documentation/devicetree/bindings/usb/snps,dwc3.yaml | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 

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/usb/qcom,dwc3.example.dtb: usb at a6f8800 (qcom,sdm845-dwc3): usb at a600000:iommus: [[4294967295, 1856, 0]] is too short
	from schema $id: http://devicetree.org/schemas/usb/qcom,dwc3.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/usb/qcom,dwc3.example.dtb: usb at a6f8800 (qcom,sdm845-dwc3): usb at a600000: Unevaluated properties are not allowed ('iommus' was unexpected)
	from schema $id: http://devicetree.org/schemas/usb/qcom,dwc3.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/usb/qcom,dwc3.example.dtb: usb at a6f8800 (qcom,sdm845-dwc3): usb at a600000: Unevaluated properties are not allowed ('iommus' was unexpected)
	from schema $id: http://devicetree.org/schemas/usb/qcom,dwc3.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/usb/qcom,dwc3.example.dtb: usb at a600000 (snps,dwc3): iommus: [[4294967295, 1856, 0]] is too short
	from schema $id: http://devicetree.org/schemas/usb/snps,dwc3.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/usb/qcom,dwc3.example.dtb: usb at a600000 (snps,dwc3): Unevaluated properties are not allowed ('iommus' was unexpected)
	from schema $id: http://devicetree.org/schemas/usb/snps,dwc3.yaml#

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20250821-atcphy-6-17-v1-1-172beda182b8 at kernel.org

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 robh at kernel.org  Thu Aug 21 15:39:52 2025
From: robh at kernel.org (Rob Herring (Arm))
Date: Thu, 21 Aug 2025 17:39:52 -0500
Subject: [PATCH RFC 03/22] dt-bindings: phy: Add Apple Type-C PHY
In-Reply-To: <20250821-atcphy-6-17-v1-3-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
 <20250821-atcphy-6-17-v1-3-172beda182b8@kernel.org>
Message-ID: <175581575975.1136737.15772006298653971684.robh@kernel.org>


On Thu, 21 Aug 2025 15:38:55 +0000, Sven Peter wrote:
> Apple's Type-C PHY (ATCPHY) is a PHY for USB 2.0, USB 3.x,
> USB4/Thunderbolt, and DisplayPort connectivity found in Apple Silicon
> SoCs.
> 
> The PHY handles muxing between these different protocols and also provides
> the reset controller for the attached dwc3 USB controller.
> 
> Signed-off-by: Sven Peter <sven at kernel.org>
> ---
>  .../devicetree/bindings/phy/apple,atcphy.yaml      | 210 +++++++++++++++++++++
>  MAINTAINERS                                        |   1 +
>  2 files changed, 211 insertions(+)
> 

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/phy/apple,atcphy.yaml: properties:power-domains: 'anyOf' conditional failed, one must be fixed:
	'minItems' is not one of ['maxItems', 'description', 'deprecated']
		hint: Only "maxItems" is required for a single entry if there are no constraints defined for the values.
	'minItems' is not one of ['description', 'deprecated', 'const', 'enum', 'minimum', 'maximum', 'multipleOf', 'default', '$ref', 'oneOf']
	'maxItems' is not one of ['description', 'deprecated', 'const', 'enum', 'minimum', 'maximum', 'multipleOf', 'default', '$ref', 'oneOf']
	1 is less than the minimum of 2
		hint: Arrays must be described with a combination of minItems/maxItems/items
	hint: cell array properties must define how many entries and what the entries are when there is more than one entry.
	from schema $id: http://devicetree.org/meta-schemas/power-domain.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/phy/apple,atcphy.example.dtb: phy at 383000000 (apple,t8103-atcphy): reg: [[3, 2197815296], [0, 311296], [3, 2198142976], [0, 32768], [3, 2147483648], [0, 16384], [3, 2192113664], [0, 16384], [3, 2192064512], [0, 16384]] is too long
	from schema $id: http://devicetree.org/schemas/phy/apple,atcphy.yaml#

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20250821-atcphy-6-17-v1-3-172beda182b8 at kernel.org

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 robh at kernel.org  Thu Aug 21 16:00:27 2025
From: robh at kernel.org (Rob Herring)
Date: Thu, 21 Aug 2025 18:00:27 -0500
Subject: [PATCH RFC 03/22] dt-bindings: phy: Add Apple Type-C PHY
In-Reply-To: <20250821163320.GE1270980@robin.jannau.net>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
 <20250821-atcphy-6-17-v1-3-172beda182b8@kernel.org> <20250821163320.GE1270980@robin.jannau.net>
Message-ID: <CAL_JsqL=y2OT4YrzT8z0O0T2hpM5X1k2pFEb8XjBRPoNMdO5kw@mail.gmail.com>

On Thu, Aug 21, 2025 at 11:33?AM Janne Grunau <j at jannau.net> wrote:
>
> On Thu, Aug 21, 2025 at 03:38:55PM +0000, Sven Peter wrote:
> > Apple's Type-C PHY (ATCPHY) is a PHY for USB 2.0, USB 3.x,
> > USB4/Thunderbolt, and DisplayPort connectivity found in Apple Silicon
> > SoCs.
> >
> > The PHY handles muxing between these different protocols and also provides
> > the reset controller for the attached dwc3 USB controller.
> >
> > Signed-off-by: Sven Peter <sven at kernel.org>
> > ---
> >  .../devicetree/bindings/phy/apple,atcphy.yaml      | 210 +++++++++++++++++++++
> >  MAINTAINERS                                        |   1 +
> >  2 files changed, 211 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/phy/apple,atcphy.yaml b/Documentation/devicetree/bindings/phy/apple,atcphy.yaml
> > new file mode 100644
> > index 0000000000000000000000000000000000000000..eb14010557c94f313b54b528e2d4039fe540062a
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/phy/apple,atcphy.yaml
> > @@ -0,0 +1,210 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/phy/apple,atcphy.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Apple Type-C PHY (ATCPHY)
> > +
> > +maintainers:
> > +  - Sven Peter <sven at kernel.org>
> > +
> > +description:
> > +  The Apple Type-C PHY (ATCPHY) is a PHY for USB 2.0, USB 3.x,
> > +  USB4/Thunderbolt, and DisplayPort connectivity found in Apple Silicon SoCs.
> > +
> > +  The PHY handles muxing between these different protocols and also provides the
> > +  reset controller for the attached dwc3 USB controller.
> > +
> > +  The PHY is designed for USB4 operation and does not handle individual
> > +  differential pairs as distinct DisplayPort lanes. Any reference to lane in
> > +  this binding hence refers to two differential pairs (RX and TX) as used in USB
> > +  terminology.
> > +
> > +properties:
> > +  compatible:
> > +    enum:
> > +      - apple,t6000-atcphy
> > +      - apple,t6000-atcphy-dp-only # PHY hardwired to DP-to-HDMI converter on M2 Pro MacBook
>
> The comment is misleading, "t6000-atcphy-dp-only" would be for M1
> Pro/Max Macbooks. M2 Pro/Max Macbooks use the same design so the
> corresponding "apple,t6020-atcphy-dp-only" compatible is missing.
> I'm not sure this is the correct design though as the HW block is
> identical to "apple,t6000-atcphy".
> I think it might be better to have either the DRM KMS driver or a
> custom DP->HDMI drm_bridge switch the mode to DP-only.
> Or atcphy could initialize itself to DP-only based on the available
> ports.

Doesn't sound like this should be a different compatible. There's a
'phy-mode' property or you can define the mode in the 'phys' cells for
the DP controller.

Rob


From Thinh.Nguyen at synopsys.com  Thu Aug 21 16:25:51 2025
From: Thinh.Nguyen at synopsys.com (Thinh Nguyen)
Date: Thu, 21 Aug 2025 23:25:51 +0000
Subject: [PATCH RFC 04/22] usb: dwc3: apple: Reset dwc3 during role
 switches
In-Reply-To: <20250821-atcphy-6-17-v1-4-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
 <20250821-atcphy-6-17-v1-4-172beda182b8@kernel.org>
Message-ID: <20250821232547.qzplkafogsacnbti@synopsys.com>

On Thu, Aug 21, 2025, Sven Peter wrote:
> As mad as it sounds, the dwc3 controller present on the Apple M1 must be
> reset and reinitialized whenever a device is unplugged from the root
> port or when the PHY mode is changed.
> 
> This is required for at least the following reasons:
> 
>   - The USB2 D+/D- lines are connected through a stateful eUSB2 repeater
>     which in turn is controlled by a variant of the TI TPS6598x USB PD
>     chip. When the USB PD controller detects a hotplug event it resets
>     the eUSB2 repeater. Afterwards, no new device is recognized before
>     the DWC3 core and PHY are reset as well because the eUSB2 repeater
>     and the PHY/dwc3 block disagree about the current state.
> 
>   - It's possible to completely break the dwc3 controller by switching
>     it to device mode and unplugging the cable at just the wrong time.
>     If this happens dwc3 behaves as if no device is connected.
>     CORESOFTRESET will also never clear after it has been set. The only
>     workaround is to trigger a hard reset of the entire dwc3 core with
>     its external reset line.
> 
>   - Whenever the PHY mode is changed (to e.g. transition to DisplayPort
>     alternate mode or USB4) dwc3 has to be shutdown and reinitialized.
>     Otherwise the Type-C port will not be usable until the entire SoC
>     has been reset.
> 
> All of this can be easily worked around by respecting transitions to
> USB_ROLE_NONE and making sure the external reset line is asserted when
> switching roles. We additionally have to ensure that the PHY is
> suspended during init.
> 
> Signed-off-by: Sven Peter <sven at kernel.org>
> ---
>  drivers/usb/dwc3/core.c | 61 +++++++++++++++++++++++++++++++++++++++++++++----
>  drivers/usb/dwc3/core.h |  3 +++
>  drivers/usb/dwc3/drd.c  | 11 ++++++++-
>  drivers/usb/dwc3/host.c |  3 ++-
>  4 files changed, 72 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index 8002c23a5a02acb8f3e87b2662a53998a4cf4f5c..26aa507a738f001409a97ef563c6561433a1cac5 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -158,6 +158,9 @@ void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode, bool ignore_susphy)
>  	dwc->current_dr_role = mode;
>  }
>  
> +static void dwc3_core_exit(struct dwc3 *dwc);
> +static int dwc3_core_init_for_resume(struct dwc3 *dwc);
> +
>  static void __dwc3_set_mode(struct work_struct *work)
>  {
>  	struct dwc3 *dwc = work_to_dwc(work);
> @@ -177,7 +180,7 @@ static void __dwc3_set_mode(struct work_struct *work)
>  	if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_OTG)
>  		dwc3_otg_update(dwc, 0);
>  
> -	if (!desired_dr_role)
> +	if (!desired_dr_role && !dwc->role_switch_reset_quirk)
>  		goto out;
>  
>  	if (desired_dr_role == dwc->current_dr_role)
> @@ -205,13 +208,32 @@ static void __dwc3_set_mode(struct work_struct *work)
>  		break;
>  	}
>  
> +	if (dwc->role_switch_reset_quirk) {
> +		if (dwc->current_dr_role) {
> +			dwc->current_dr_role = 0;

The current_dr_role should not be used this way. The value of the
current_dr_role should not be cleared on the call of __dwc3_set_mode.
This will mess up suspend/resume and will be difficult to maintain.
Also, any synchronization/locking?

> +			dwc3_core_exit(dwc);
> +		}
> +
> +		if (desired_dr_role) {
> +			ret = dwc3_core_init_for_resume(dwc);

The dwc3_core_init_for_resume() is for PM, reusing this with its
current name is confusing.

> +			if (ret) {
> +				dev_err(dwc->dev,
> +				    "failed to reinitialize core\n");
> +				goto out;
> +			}
> +		} else {
> +			goto out;
> +		}
> +	}
> +
>  	/*
>  	 * When current_dr_role is not set, there's no role switching.
>  	 * Only perform GCTL.CoreSoftReset when there's DRD role switching.
>  	 */
> -	if (dwc->current_dr_role && ((DWC3_IP_IS(DWC3) ||
> +	if (dwc->role_switch_reset_quirk ||

Don't override the use of GCTL.CoreSoftReset with this quirk. Not all
controller versions should use GCTL.CoreSoftReset, the new controller
version don't even have it. What version is this vendor using?

I'm concern how this condition is needed...

> +		(dwc->current_dr_role && ((DWC3_IP_IS(DWC3) ||
>  			DWC3_VER_IS_PRIOR(DWC31, 190A)) &&
> -			desired_dr_role != DWC3_GCTL_PRTCAP_OTG)) {
> +			desired_dr_role != DWC3_GCTL_PRTCAP_OTG))) {
>  		reg = dwc3_readl(dwc->regs, DWC3_GCTL);
>  		reg |= DWC3_GCTL_CORESOFTRESET;
>  		dwc3_writel(dwc->regs, DWC3_GCTL, reg);
> @@ -1372,6 +1394,9 @@ static int dwc3_core_init(struct dwc3 *dwc)
>  	if (ret)
>  		goto err_exit_phy;
>  
> +	if (dwc->role_switch_reset_quirk)
> +		dwc3_enable_susphy(dwc, true);
> +

Why do you need to enable susphy here?

>  	dwc3_core_setup_global_control(dwc);
>  	dwc3_core_num_eps(dwc);
>  
> @@ -1635,6 +1660,18 @@ static int dwc3_core_init_mode(struct dwc3 *dwc)
>  		ret = dwc3_drd_init(dwc);
>  		if (ret)
>  			return dev_err_probe(dev, ret, "failed to initialize dual-role\n");
> +
> +		/*
> +		 * If the role switch reset quirk is required the first role
> +		 * switch notification will initialize the core such that we
> +		 * have to shut it down here. Make sure that the __dwc3_set_mode
> +		 * queued by dwc3_drd_init has completed before since it
> +		 * may still try to access MMIO.
> +		 */
> +		if (dwc->role_switch_reset_quirk) {
> +			flush_work(&dwc->drd_work);
> +			dwc3_core_exit(dwc);
> +		}
>  		break;
>  	default:
>  		dev_err(dev, "Unsupported mode of operation %d\n", dwc->dr_mode);
> @@ -2223,6 +2260,22 @@ int dwc3_core_probe(const struct dwc3_probe_data *data)
>  			goto err_put_psy;
>  	}
>  
> +	if (dev->of_node) {
> +		if (of_device_is_compatible(dev->of_node, "apple,t8103-dwc3")) {
> +			if (!IS_ENABLED(CONFIG_USB_ROLE_SWITCH) ||
> +			    !IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)) {
> +				dev_err(dev,
> +				    "Apple DWC3 requires role switch support.\n"
> +				    );
> +				ret = -EINVAL;
> +				goto err_put_psy;
> +			}
> +
> +			dwc->dr_mode = USB_DR_MODE_OTG;
> +			dwc->role_switch_reset_quirk = true;

Put this in your glue driver or device tree.

> +		}
> +	}
> +
>  	ret = reset_control_deassert(dwc->reset);
>  	if (ret)
>  		goto err_put_psy;
> @@ -2391,7 +2444,6 @@ static void dwc3_remove(struct platform_device *pdev)
>  	dwc3_core_remove(platform_get_drvdata(pdev));
>  }
>  
> -#ifdef CONFIG_PM
>  static int dwc3_core_init_for_resume(struct dwc3 *dwc)
>  {
>  	int ret;
> @@ -2418,6 +2470,7 @@ static int dwc3_core_init_for_resume(struct dwc3 *dwc)
>  	return ret;
>  }
>  
> +#ifdef CONFIG_PM
>  static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
>  {
>  	u32 reg;
> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
> index d5b985fa12f4d9ee3f318ea5cce7c1b225cd3623..38f32f2a6193c1b2662ab4f38f4d20cf4b0e198d 100644
> --- a/drivers/usb/dwc3/core.h
> +++ b/drivers/usb/dwc3/core.h
> @@ -1154,6 +1154,7 @@ struct dwc3_scratchpad_array {
>   * @suspended: set to track suspend event due to U3/L2.
>   * @susphy_state: state of DWC3_GUSB2PHYCFG_SUSPHY + DWC3_GUSB3PIPECTL_SUSPHY
>   *		  before PM suspend.
> + * @role_switch_reset_quirk: set to force reinitialization after any role switch
>   * @imod_interval: set the interrupt moderation interval in 250ns
>   *			increments or 0 to disable.
>   * @max_cfg_eps: current max number of IN eps used across all USB configs.
> @@ -1392,6 +1393,8 @@ struct dwc3 {
>  	unsigned		suspended:1;
>  	unsigned		susphy_state:1;
>  
> +	unsigned		role_switch_reset_quirk:1;
> +
>  	u16			imod_interval;
>  
>  	int			max_cfg_eps;
> diff --git a/drivers/usb/dwc3/drd.c b/drivers/usb/dwc3/drd.c
> index 7977860932b142924edd19f859f7c4041d11eda6..65450db91bdea00bb30bfb368f5195ad2fd58da4 100644
> --- a/drivers/usb/dwc3/drd.c
> +++ b/drivers/usb/dwc3/drd.c
> @@ -464,6 +464,9 @@ static int dwc3_usb_role_switch_set(struct usb_role_switch *sw,
>  		break;
>  	}
>  
> +	if (dwc->role_switch_reset_quirk && role == USB_ROLE_NONE)
> +		mode = 0;
> +
>  	dwc3_set_mode(dwc, mode);
>  	return 0;
>  }
> @@ -492,6 +495,10 @@ static enum usb_role dwc3_usb_role_switch_get(struct usb_role_switch *sw)
>  			role = USB_ROLE_DEVICE;
>  		break;
>  	}
> +
> +	if (dwc->role_switch_reset_quirk && !dwc->current_dr_role)
> +		role = USB_ROLE_NONE;

Don't return USB_ROLE_NONE on role_switch get. The USB_ROLE_NONE is the
default role. The role_switch get() should return exactly which role the
controller is currently in, and the driver can figure that out.

> +
>  	spin_unlock_irqrestore(&dwc->lock, flags);
>  	return role;
>  }
> @@ -502,7 +509,9 @@ static int dwc3_setup_role_switch(struct dwc3 *dwc)
>  	u32 mode;
>  
>  	dwc->role_switch_default_mode = usb_get_role_switch_default_mode(dwc->dev);
> -	if (dwc->role_switch_default_mode == USB_DR_MODE_HOST) {
> +	if (dwc->role_switch_reset_quirk) {
> +		mode = 0;
> +	} else if (dwc->role_switch_default_mode == USB_DR_MODE_HOST) {
>  		mode = DWC3_GCTL_PRTCAP_HOST;
>  	} else {
>  		dwc->role_switch_default_mode = USB_DR_MODE_PERIPHERAL;
> diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c
> index 1c513bf8002ec9ec91b41bfd096cbd0da1dd2d2e..f7a71e6f9d80aca632f1f970d900a3de8a76f0a7 100644
> --- a/drivers/usb/dwc3/host.c
> +++ b/drivers/usb/dwc3/host.c
> @@ -223,7 +223,8 @@ void dwc3_host_exit(struct dwc3 *dwc)
>  	if (dwc->sys_wakeup)
>  		device_init_wakeup(&dwc->xhci->dev, false);
>  
> -	dwc3_enable_susphy(dwc, false);
> +	if (!dwc->role_switch_reset_quirk)
> +		dwc3_enable_susphy(dwc, false);
>  	platform_device_unregister(dwc->xhci);
>  	dwc->xhci = NULL;
>  }
> 
> -- 
> 2.34.1
> 
> 

Seems there are experimental logics that may not be needed for the
platform to work properly. We need to figure out what's actually needed.

BR,
Thinh

From kuba at kernel.org  Thu Aug 21 18:18:50 2025
From: kuba at kernel.org (Jakub Kicinski)
Date: Thu, 21 Aug 2025 18:18:50 -0700
Subject: [PATCH v3] phy: ti: gmii-sel: Always write the RGMII ID setting
In-Reply-To: <20250819065622.1019537-1-mwalle@kernel.org>
References: <20250819065622.1019537-1-mwalle@kernel.org>
Message-ID: <20250821181850.6af0ff7f@kernel.org>

On Tue, 19 Aug 2025 08:56:22 +0200 Michael Walle wrote:
> v3:
>  - simplify the logic. Thanks Matthias.
>  - reworded the commit message

This was set to Not Applicable in our patchwork, IDK why.
Could you resend?


From wenbin.yao at oss.qualcomm.com  Thu Aug 21 18:53:30 2025
From: wenbin.yao at oss.qualcomm.com (Wenbin Yao (Consultant))
Date: Fri, 22 Aug 2025 09:53:30 +0800
Subject: [PATCH v2 4/4] phy: qcom: qmp-pcie: Add support for Glymur PCIe
 Gen5x4 PHY
In-Reply-To: <bm3cp2vyw4rpllkwoxoxwrvsjxrtolcroqwx76bkpwmcdvx7ag@b6hvybyouq7m>
References: <20250821-glymur_pcie5-v2-0-cd516784ef20@oss.qualcomm.com>
 <20250821-glymur_pcie5-v2-4-cd516784ef20@oss.qualcomm.com>
 <bm3cp2vyw4rpllkwoxoxwrvsjxrtolcroqwx76bkpwmcdvx7ag@b6hvybyouq7m>
Message-ID: <74bbf915-23cf-46c3-b9f8-48bb43ce9c56@oss.qualcomm.com>

On 8/21/2025 5:57 PM, Dmitry Baryshkov wrote:
> On Thu, Aug 21, 2025 at 02:44:31AM -0700, Wenbin Yao wrote:
>> From: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
>>
>> Add support for Gen5 x4 PCIe QMP PHY found on Glymur platform.
>>
>> Signed-off-by: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
>> Signed-off-by: Wenbin Yao <wenbin.yao at oss.qualcomm.com>
>> ---
>>   drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 32 ++++++++++++++++++++++++++++++++
>>   1 file changed, 32 insertions(+)
>> @@ -5114,6 +5143,9 @@ static const struct of_device_id qmp_pcie_of_match_table[] = {
>>   	}, {
>>   		.compatible = "qcom,x1p42100-qmp-gen4x4-pcie-phy",
>>   		.data = &qmp_v6_gen4x4_pciephy_cfg,
>> +	}, {
>> +		.compatible = "qcom,glymur-qmp-gen5x4-pcie-phy",
>> +		.data = &glymur_qmp_gen5x4_pciephy_cfg,
> Please keep the array sorted. LGTM otherwise.

OK, will fix it.

>
>>   	},
>>   	{ },
>>   };
>>
>> -- 
>> 2.34.1
>>
-- 
With best wishes
Wenbin



From peng.fan at nxp.com  Thu Aug 21 21:05:27 2025
From: peng.fan at nxp.com (Peng Fan)
Date: Fri, 22 Aug 2025 12:05:27 +0800
Subject: [PATCH 0/6] phy: phy-can-transceiver: Support TJA1048/TJA1051
Message-ID: <20250822-can-v1-0-c075f702adea@nxp.com>

TJA1048 is a Dual channel can transceiver with Sleep mode supported.
TJA1051 is a Single Channel can transceiver with Sleep mode supported.

To support them:
patch 1: add binding doc
patch 2: support tja1051
patch 3: To support dual channel,
   - Introduce new flag CAN_TRANSCEIVER_DUAL_CH to indicate the phy
     has two channels.
   - Introduce can_transceiver_priv as a higher level encapsulation for
     phy, mux_state, num_ch.
   - Alloc a phy for each channel
patch 4,5,6: Update dts to use phys

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
---
Peng Fan (6):
      dt-bindings: phy: ti,tcan104x-can: Document NXP TJA1051/1048
      phy: phy-can-transceiver: Add support for NXP TJA1051
      phy: phy-can-transceiver: Add dual channel support for TJA1048
      arm64: dts: imx95-15x15-evk: Use phys to replace xceiver-supply
      arm64: dts: imx8mp-evk: Use phys to replace xceiver-supply
      arm64: dts: imx93-11x11-evk: Use phys to replace xceiver-supply

 .../devicetree/bindings/phy/ti,tcan104x-can.yaml   |  29 ++++-
 arch/arm64/boot/dts/freescale/imx8mp-evk.dts       |  43 +++-----
 arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts  |  17 ++-
 arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts  |  13 +--
 drivers/phy/phy-can-transceiver.c                  | 121 +++++++++++++++------
 5 files changed, 140 insertions(+), 83 deletions(-)
---
base-commit: 5303936d609e09665deda94eaedf26a0e5c3a087
change-id: 20250821-can-c832cb4f0323

Best regards,
-- 
Peng Fan <peng.fan at nxp.com>



From peng.fan at nxp.com  Thu Aug 21 21:05:28 2025
From: peng.fan at nxp.com (Peng Fan)
Date: Fri, 22 Aug 2025 12:05:28 +0800
Subject: [PATCH 1/6] dt-bindings: phy: ti,tcan104x-can: Document NXP
 TJA1051/1048
In-Reply-To: <20250822-can-v1-0-c075f702adea@nxp.com>
References: <20250822-can-v1-0-c075f702adea@nxp.com>
Message-ID: <20250822-can-v1-1-c075f702adea@nxp.com>

The TJA1051 is a high-speed CAN transceiver which is a pin-compatible
alternative for TI TCAN1043 with Sleep mode supported, and has a compatible
programming model, therefore use ti,tcan1043 as fallback compatible.

The TJA1048 is a dual high-speed CAN transceiver with Sleep mode supported.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 .../devicetree/bindings/phy/ti,tcan104x-can.yaml   | 29 +++++++++++++++++++---
 1 file changed, 26 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml b/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
index 4a8c3829d85d3c4a4963750d03567c1c345beb91..de4ab204ec86f91e84eba8f1a6343ed137e5cd71 100644
--- a/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
+++ b/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
@@ -19,18 +19,21 @@ properties:
           - enum:
               - microchip,ata6561
           - const: ti,tcan1042
+      - items:
+          - enum:
+              - nxp,tja1051
+          - const: ti,tcan1043
       - enum:
           - ti,tcan1042
           - ti,tcan1043
+          - nxp,tja1048
           - nxp,tjr1443
 
-  '#phy-cells':
-    const: 0
+  '#phy-cells': true
 
   standby-gpios:
     description:
       gpio node to toggle standby signal on transceiver
-    maxItems: 1
 
   enable-gpios:
     description:
@@ -53,6 +56,26 @@ required:
   - compatible
   - '#phy-cells'
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: nxp,tja1048
+
+    then:
+      properties:
+        '#phy-cells':
+          const: 1
+        standby-gpios:
+          maxItems: 2
+    else:
+      properties:
+        '#phy-cells':
+          const: 0
+        standby-gpios:
+          maxItems: 1
+
 additionalProperties: false
 
 examples:

-- 
2.37.1



From peng.fan at nxp.com  Thu Aug 21 21:05:29 2025
From: peng.fan at nxp.com (Peng Fan)
Date: Fri, 22 Aug 2025 12:05:29 +0800
Subject: [PATCH 2/6] phy: phy-can-transceiver: Add support for NXP TJA1051
In-Reply-To: <20250822-can-v1-0-c075f702adea@nxp.com>
References: <20250822-can-v1-0-c075f702adea@nxp.com>
Message-ID: <20250822-can-v1-2-c075f702adea@nxp.com>

The TJA1051 is a high-speed CAN transceiver which is a pin-compatible
alternative for TI TCAN1043 with Sleep mode supported.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/phy/phy-can-transceiver.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/phy/phy-can-transceiver.c b/drivers/phy/phy-can-transceiver.c
index f59caff4b3d4c267feca4220bf1547b6fad08f95..b49371a1272cd8a25b5e2271586b756103c64f0a 100644
--- a/drivers/phy/phy-can-transceiver.c
+++ b/drivers/phy/phy-can-transceiver.c
@@ -85,6 +85,10 @@ static const struct of_device_id can_transceiver_phy_ids[] = {
 		.compatible = "ti,tcan1043",
 		.data = &tcan1043_drvdata
 	},
+	{
+		.compatible = "nxp,tja1051",
+		.data = &tcan1043_drvdata
+	},
 	{
 		.compatible = "nxp,tjr1443",
 		.data = &tcan1043_drvdata

-- 
2.37.1



From peng.fan at nxp.com  Thu Aug 21 21:05:30 2025
From: peng.fan at nxp.com (Peng Fan)
Date: Fri, 22 Aug 2025 12:05:30 +0800
Subject: [PATCH 3/6] phy: phy-can-transceiver: Add dual channel support for
 TJA1048
In-Reply-To: <20250822-can-v1-0-c075f702adea@nxp.com>
References: <20250822-can-v1-0-c075f702adea@nxp.com>
Message-ID: <20250822-can-v1-3-c075f702adea@nxp.com>

- Introduce new flag CAN_TRANSCEIVER_DUAL_CH to indicate the phy
  has two channels.
- Introduce can_transceiver_priv as a higher level encapsulation for
  phy, mux_state, num_ch.
- Alloc a phy for each channel
- Support TJA1048 which is a dual high-speed CAN transceiver with
  Sleep mode supported.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/phy/phy-can-transceiver.c | 117 +++++++++++++++++++++++++++-----------
 1 file changed, 83 insertions(+), 34 deletions(-)

diff --git a/drivers/phy/phy-can-transceiver.c b/drivers/phy/phy-can-transceiver.c
index b49371a1272cd8a25b5e2271586b756103c64f0a..0e7b23073bfa8eae7200d30dc657a979f6cc9d86 100644
--- a/drivers/phy/phy-can-transceiver.c
+++ b/drivers/phy/phy-can-transceiver.c
@@ -17,13 +17,20 @@ struct can_transceiver_data {
 	u32 flags;
 #define CAN_TRANSCEIVER_STB_PRESENT	BIT(0)
 #define CAN_TRANSCEIVER_EN_PRESENT	BIT(1)
+#define CAN_TRANSCEIVER_DUAL_CH		BIT(2)
 };
 
 struct can_transceiver_phy {
 	struct phy *generic_phy;
 	struct gpio_desc *standby_gpio;
 	struct gpio_desc *enable_gpio;
+	struct can_transceiver_priv *priv;
+};
+
+struct can_transceiver_priv {
+	struct can_transceiver_phy *can_transceiver_phy;
 	struct mux_state *mux_state;
+	int num_ch;
 };
 
 /* Power on function */
@@ -32,8 +39,8 @@ static int can_transceiver_phy_power_on(struct phy *phy)
 	struct can_transceiver_phy *can_transceiver_phy = phy_get_drvdata(phy);
 	int ret;
 
-	if (can_transceiver_phy->mux_state) {
-		ret = mux_state_select(can_transceiver_phy->mux_state);
+	if (can_transceiver_phy->priv->mux_state) {
+		ret = mux_state_select(can_transceiver_phy->priv->mux_state);
 		if (ret) {
 			dev_err(&phy->dev, "Failed to select CAN mux: %d\n", ret);
 			return ret;
@@ -56,8 +63,8 @@ static int can_transceiver_phy_power_off(struct phy *phy)
 		gpiod_set_value_cansleep(can_transceiver_phy->standby_gpio, 1);
 	if (can_transceiver_phy->enable_gpio)
 		gpiod_set_value_cansleep(can_transceiver_phy->enable_gpio, 0);
-	if (can_transceiver_phy->mux_state)
-		mux_state_deselect(can_transceiver_phy->mux_state);
+	if (can_transceiver_phy->priv->mux_state)
+		mux_state_deselect(can_transceiver_phy->priv->mux_state);
 
 	return 0;
 }
@@ -76,6 +83,10 @@ static const struct can_transceiver_data tcan1043_drvdata = {
 	.flags = CAN_TRANSCEIVER_STB_PRESENT | CAN_TRANSCEIVER_EN_PRESENT,
 };
 
+static const struct can_transceiver_data tja1048_drvdata = {
+	.flags = CAN_TRANSCEIVER_STB_PRESENT | CAN_TRANSCEIVER_DUAL_CH,
+};
+
 static const struct of_device_id can_transceiver_phy_ids[] = {
 	{
 		.compatible = "ti,tcan1042",
@@ -85,6 +96,10 @@ static const struct of_device_id can_transceiver_phy_ids[] = {
 		.compatible = "ti,tcan1043",
 		.data = &tcan1043_drvdata
 	},
+	{
+		.compatible = "nxp,tja1048",
+		.data = &tja1048_drvdata
+	},
 	{
 		.compatible = "nxp,tja1051",
 		.data = &tcan1043_drvdata
@@ -107,11 +122,27 @@ devm_mux_state_get_optional(struct device *dev, const char *mux_name)
 	return devm_mux_state_get(dev, mux_name);
 }
 
+static struct phy *can_transceiver_phy_xlate(struct device *dev, const struct of_phandle_args *args)
+{
+	struct can_transceiver_priv *priv = dev_get_drvdata(dev);
+	u32 idx;
+
+	if (priv->num_ch == 1)
+		return priv->can_transceiver_phy[0].generic_phy;
+
+	if (args->args_count != 1)
+		return ERR_PTR(-EINVAL);
+
+	idx = args->args[0];
+
+	return priv->can_transceiver_phy[idx].generic_phy;
+}
+
 static int can_transceiver_phy_probe(struct platform_device *pdev)
 {
 	struct phy_provider *phy_provider;
 	struct device *dev = &pdev->dev;
-	struct can_transceiver_phy *can_transceiver_phy;
+	struct can_transceiver_priv *priv;
 	const struct can_transceiver_data *drvdata;
 	const struct of_device_id *match;
 	struct phy *phy;
@@ -119,52 +150,70 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
 	struct gpio_desc *enable_gpio;
 	struct mux_state *mux_state;
 	u32 max_bitrate = 0;
-	int err;
-
-	can_transceiver_phy = devm_kzalloc(dev, sizeof(struct can_transceiver_phy), GFP_KERNEL);
-	if (!can_transceiver_phy)
-		return -ENOMEM;
+	int num_ch = 1;
+	int err, i;
 
 	match = of_match_node(can_transceiver_phy_ids, pdev->dev.of_node);
 	drvdata = match->data;
 
+	priv = devm_kzalloc(dev, sizeof(struct can_transceiver_priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, priv);
+
+	if (drvdata->flags & CAN_TRANSCEIVER_DUAL_CH)
+		num_ch = 2;
+
+	priv->num_ch = num_ch;
+	priv->can_transceiver_phy = devm_kcalloc(dev, num_ch, sizeof(struct can_transceiver_phy),
+						 GFP_KERNEL);
+	if (!priv->can_transceiver_phy)
+		return -ENOMEM;
+
 	mux_state = devm_mux_state_get_optional(dev, NULL);
 	if (IS_ERR(mux_state))
 		return PTR_ERR(mux_state);
 
-	can_transceiver_phy->mux_state = mux_state;
-
-	phy = devm_phy_create(dev, dev->of_node,
-			      &can_transceiver_phy_ops);
-	if (IS_ERR(phy)) {
-		dev_err(dev, "failed to create can transceiver phy\n");
-		return PTR_ERR(phy);
-	}
+	priv->mux_state = mux_state;
 
 	err = device_property_read_u32(dev, "max-bitrate", &max_bitrate);
 	if ((err != -EINVAL) && !max_bitrate)
 		dev_warn(dev, "Invalid value for transceiver max bitrate. Ignoring bitrate limit\n");
-	phy->attrs.max_link_rate = max_bitrate;
 
-	can_transceiver_phy->generic_phy = phy;
+	for (i = 0; i < num_ch; i++) {
+		phy = devm_phy_create(dev, dev->of_node, &can_transceiver_phy_ops);
+		if (IS_ERR(phy)) {
+			dev_err(dev, "failed to create can transceiver phy\n");
+			return PTR_ERR(phy);
+		}
 
-	if (drvdata->flags & CAN_TRANSCEIVER_STB_PRESENT) {
-		standby_gpio = devm_gpiod_get_optional(dev, "standby", GPIOD_OUT_HIGH);
-		if (IS_ERR(standby_gpio))
-			return PTR_ERR(standby_gpio);
-		can_transceiver_phy->standby_gpio = standby_gpio;
-	}
+		phy->attrs.max_link_rate = max_bitrate;
 
-	if (drvdata->flags & CAN_TRANSCEIVER_EN_PRESENT) {
-		enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW);
-		if (IS_ERR(enable_gpio))
-			return PTR_ERR(enable_gpio);
-		can_transceiver_phy->enable_gpio = enable_gpio;
-	}
+		priv->can_transceiver_phy[i].generic_phy = phy;
+		priv->can_transceiver_phy[i].priv = priv;
+
+		if (drvdata->flags & CAN_TRANSCEIVER_STB_PRESENT) {
+			standby_gpio = devm_gpiod_get_index_optional(dev, "standby", i,
+								     GPIOD_OUT_HIGH);
+			if (IS_ERR(standby_gpio))
+				return PTR_ERR(standby_gpio);
+			priv->can_transceiver_phy[i].standby_gpio = standby_gpio;
+		}
+
+		if (drvdata->flags & CAN_TRANSCEIVER_EN_PRESENT) {
+			enable_gpio = devm_gpiod_get_index_optional(dev, "enable", i,
+								    GPIOD_OUT_LOW);
+			if (IS_ERR(enable_gpio))
+				return PTR_ERR(enable_gpio);
+			priv->can_transceiver_phy[i].enable_gpio = enable_gpio;
+		}
 
-	phy_set_drvdata(can_transceiver_phy->generic_phy, can_transceiver_phy);
+		phy_set_drvdata(priv->can_transceiver_phy[i].generic_phy,
+				&priv->can_transceiver_phy[i]);
+	}
 
-	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+	phy_provider = devm_of_phy_provider_register(dev, can_transceiver_phy_xlate);
 
 	return PTR_ERR_OR_ZERO(phy_provider);
 }

-- 
2.37.1



From peng.fan at nxp.com  Thu Aug 21 21:05:31 2025
From: peng.fan at nxp.com (Peng Fan)
Date: Fri, 22 Aug 2025 12:05:31 +0800
Subject: [PATCH 4/6] arm64: dts: imx95-15x15-evk: Use phys to replace
 xceiver-supply
In-Reply-To: <20250822-can-v1-0-c075f702adea@nxp.com>
References: <20250822-can-v1-0-c075f702adea@nxp.com>
Message-ID: <20250822-can-v1-4-c075f702adea@nxp.com>

The TJA1051T/3 used on i.MX95-15x15-EVK is actually high-speed CAN
transceiver, not a regulator supply. So use phys to reflect the truth.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts b/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
index 46f6e0fbf2b09106e6e726ff8b61522d1359cfa4..f6197ba356d49b97bf7287c3f0f86ef84f89bac9 100644
--- a/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
@@ -89,12 +89,11 @@ reg_audio_switch1: regulator-audio-switch1 {
 		gpio = <&pcal6524 0 GPIO_ACTIVE_LOW>;
 	};
 
-	reg_can2_stby: regulator-can2-stby {
-		compatible = "regulator-fixed";
-		regulator-max-microvolt = <3300000>;
-		regulator-min-microvolt = <3300000>;
-		regulator-name = "can2-stby";
-		gpio = <&pcal6524 14 GPIO_ACTIVE_LOW>;
+	flexcan2_phy: can-phy {
+		compatible = "nxp,tja1051", "ti,tcan1043";
+		#phy-cells = <0>;
+		max-bitrate = <1000000>;
+		standby-gpios = <&pcal6524 14 GPIO_ACTIVE_HIGH>;
 	};
 
 	reg_m2_pwr: regulator-m2-pwr {
@@ -300,7 +299,7 @@ &enetc_port1 {
 &flexcan2 {
 	pinctrl-0 = <&pinctrl_flexcan2>;
 	pinctrl-names = "default";
-	xceiver-supply = <&reg_can2_stby>;
+	phys = <&flexcan2_phy>;
 	status = "okay";
 };
 

-- 
2.37.1



From peng.fan at nxp.com  Thu Aug 21 21:05:32 2025
From: peng.fan at nxp.com (Peng Fan)
Date: Fri, 22 Aug 2025 12:05:32 +0800
Subject: [PATCH 5/6] arm64: dts: imx8mp-evk: Use phys to replace
 xceiver-supply
In-Reply-To: <20250822-can-v1-0-c075f702adea@nxp.com>
References: <20250822-can-v1-0-c075f702adea@nxp.com>
Message-ID: <20250822-can-v1-5-c075f702adea@nxp.com>

The TJA1048 used on i.MX8MP-EVK is actually high-speed CAN
transceiver, not a regulator supply. So use phys to reflect the truth.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8mp-evk.dts | 43 +++++++++-------------------
 1 file changed, 13 insertions(+), 30 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
index c0cc5611048e6a739f13c14bbd2e7b26f2715696..d238d419d87cc7c99d472720c96aade90275cb0f 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
@@ -56,6 +56,16 @@ memory at 40000000 {
 		      <0x1 0x00000000 0 0xc0000000>;
 	};
 
+	flexcan_phy: can-phy {
+		compatible = "nxp,tja1048";
+		#phy-cells = <1>;
+		max-bitrate = <5000000>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_flexcan_phy>;
+		standby-gpios = <&gpio5 5 GPIO_ACTIVE_LOW>,
+				<&gpio4 27 GPIO_ACTIVE_LOW>;
+	};
+
 	native-hdmi-connector {
 		compatible = "hdmi-connector";
 		label = "HDMI OUT";
@@ -103,28 +113,6 @@ reg_audio_pwr: regulator-audio-pwr {
 		enable-active-high;
 	};
 
-	reg_can1_stby: regulator-can1-stby {
-		compatible = "regulator-fixed";
-		regulator-name = "can1-stby";
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_flexcan1_reg>;
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		gpio = <&gpio5 5 GPIO_ACTIVE_HIGH>;
-		enable-active-high;
-	};
-
-	reg_can2_stby: regulator-can2-stby {
-		compatible = "regulator-fixed";
-		regulator-name = "can2-stby";
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_flexcan2_reg>;
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		gpio = <&gpio4 27 GPIO_ACTIVE_HIGH>;
-		enable-active-high;
-	};
-
 	reg_pcie0: regulator-pcie {
 		compatible = "regulator-fixed";
 		pinctrl-names = "default";
@@ -431,14 +419,14 @@ ethphy1: ethernet-phy at 1 {
 &flexcan1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_flexcan1>;
-	xceiver-supply = <&reg_can1_stby>;
+	phys = <&flexcan_phy 0>;
 	status = "okay";
 };
 
 &flexcan2 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_flexcan2>;
-	xceiver-supply = <&reg_can2_stby>;
+	phys = <&flexcan_phy 1>;
 	status = "disabled";/* can2 pin conflict with pdm */
 };
 
@@ -903,14 +891,9 @@ MX8MP_IOMUXC_SAI5_RXD3__CAN2_TX         0x154
 		>;
 	};
 
-	pinctrl_flexcan1_reg: flexcan1reggrp {
+	pinctrl_flexcan_phy: flexcanphygrp {
 		fsl,pins = <
 			MX8MP_IOMUXC_SPDIF_EXT_CLK__GPIO5_IO05  0x154   /* CAN1_STBY */
-		>;
-	};
-
-	pinctrl_flexcan2_reg: flexcan2reggrp {
-		fsl,pins = <
 			MX8MP_IOMUXC_SAI2_MCLK__GPIO4_IO27      0x154   /* CAN2_STBY */
 		>;
 	};

-- 
2.37.1



From peng.fan at nxp.com  Thu Aug 21 21:05:33 2025
From: peng.fan at nxp.com (Peng Fan)
Date: Fri, 22 Aug 2025 12:05:33 +0800
Subject: [PATCH 6/6] arm64: dts: imx93-11x11-evk: Use phys to replace
 xceiver-supply
In-Reply-To: <20250822-can-v1-0-c075f702adea@nxp.com>
References: <20250822-can-v1-0-c075f702adea@nxp.com>
Message-ID: <20250822-can-v1-6-c075f702adea@nxp.com>

The TJA1057 used on i.MX93 EVK is actually high-speed CAN
transceiver, not a regulator supply. So use phys to reflect the truth.

And TJA1057 is compatible with TJA1051, so use nxp,tja1051 compatible
string.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts b/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
index e24e12f04526c3a08c0bdc6134297fb010e6e926..94be59771cd05c93a6569ee08fff71bc11da21c1 100644
--- a/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
@@ -62,6 +62,13 @@ vdevbuffer: vdevbuffer at a4020000 {
 
 	};
 
+	flexcan_phy: can-phy {
+		compatible = "nxp,tja1051", "ti,tcan1043";
+		#phy-cells = <0>;
+		max-bitrate = <5000000>;
+		standby-gpios = <&adp5585 6 GPIO_ACTIVE_HIGH>;
+	};
+
 	reg_vdd_12v: regulator-vdd-12v {
 		compatible = "regulator-fixed";
 		regulator-name = "VDD_12V";
@@ -87,14 +94,6 @@ reg_audio_pwr: regulator-audio-pwr {
 		enable-active-high;
 	};
 
-	reg_can2_standby: regulator-can2-standby {
-		compatible = "regulator-fixed";
-		regulator-name = "can2-stby";
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		gpio = <&adp5585 6 GPIO_ACTIVE_LOW>;
-	};
-
 	reg_m2_pwr: regulator-m2-pwr {
 		compatible = "regulator-fixed";
 		regulator-name = "M.2-power";
@@ -284,7 +283,7 @@ ethphy2: ethernet-phy at 2 {
 &flexcan2 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_flexcan2>;
-	xceiver-supply = <&reg_can2_standby>;
+	phys = <&flexcan_phy>;
 	status = "okay";
 };
 

-- 
2.37.1



From xiangxu.yin at oss.qualcomm.com  Thu Aug 21 23:44:51 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Fri, 22 Aug 2025 14:44:51 +0800
Subject: [PATCH v3 02/14] dt-bindings: phy: Add QMP USB3+DP PHY for QCS615
In-Reply-To: <3lodaz4t72vsxnstfe2msooo3dnwbqy6hxzdshcmyrgb3fbjnv@2afo5atezt24>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-2-a43bd25ec39c@oss.qualcomm.com>
 <3lodaz4t72vsxnstfe2msooo3dnwbqy6hxzdshcmyrgb3fbjnv@2afo5atezt24>
Message-ID: <1cb3803e-5617-41ff-bf3b-95b9f616fbca@oss.qualcomm.com>


On 8/20/2025 6:09 PM, Dmitry Baryshkov wrote:
> On Wed, Aug 20, 2025 at 05:34:44PM +0800, Xiangxu Yin wrote:
>> Add device tree binding documentation for the Qualcomm QMP USB3+DP PHY
>> on QCS615 Platform. This PHY supports both USB3 and DP functionality
>> over USB-C, with PHY mode switching capability. It does not support
>> combo mode.
>>
>> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
>> ---
>>  .../bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml   | 108 +++++++++++++++++++++
>>  1 file changed, 108 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml
>> new file mode 100644
>> index 0000000000000000000000000000000000000000..c2b1fbab2930f0653f4ddb95f7b54d8fe994f92d
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml
>> @@ -0,0 +1,108 @@
>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/phy/qcom,qcs615-qmp-usb3dp-phy.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Qualcomm QMP USB3-DP PHY controller (DP, QCS615)
>> +
>> +maintainers:
>> +  - Vinod Koul <vkoul at kernel.org>
>> +
>> +description:
>> +  The QMP PHY controller supports physical layer functionality for both
>> +  USB3 and DisplayPort over USB-C. While it enables mode switching
>> +  between USB3 and DisplayPort, but does not support combo mode.
>> +
>> +properties:
>> +  compatible:
>> +    enum:
>> +      - qcom,qcs615-qmp-usb3-dp-phy
>> +
>> +  reg:
>> +    maxItems: 1
>> +
>> +  clocks:
>> +    maxItems: 2
>> +
>> +  clock-names:
>> +    items:
>> +      - const: cfg_ahb
>> +      - const: ref
>> +
>> +  resets:
>> +    maxItems: 2
>> +
>> +  reset-names:
>> +    items:
>> +      - const: phy_phy
>> +      - const: dp_phy
>> +
>> +  vdda-phy-supply: true
>> +
>> +  vdda-pll-supply: true
>> +
>> +  "#clock-cells":
>> +    const: 1
>> +    description:
>> +      See include/dt-bindings/phy/phy-qcom-qmp.h
>> +
>> +  "#phy-cells":
>> +    const: 1
>> +    description:
>> +      See include/dt-bindings/phy/phy-qcom-qmp.h
>> +
>> +  qcom,tcsr-reg:
>> +    $ref: /schemas/types.yaml#/definitions/phandle-array
>> +    items:
>> +      - items:
>> +          - description: phandle to TCSR hardware block
>> +          - description: offset of the VLS CLAMP register
>> +      - items:
>> +          - description: phandle to TCSR hardware block
> Why do we need two phandles?

?Thanks for pointing that out. Will update to use a single phandle with multiple register offsets in the next patch.


>
>> +          - description: offset of the DP PHY mode register
> s/DP PHY/PHY/


Ok. Will update in the next version.


>> +    description: Clamp and PHY mode register present in the TCSR
>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +  - clocks
>> +  - clock-names
>> +  - resets
>> +  - reset-names
>> +  - vdda-phy-supply
>> +  - vdda-pll-supply
>> +  - "#clock-cells"
>> +  - "#phy-cells"
>> +  - qcom,tcsr-reg
>> +
>> +additionalProperties: false
>> +
>> +examples:
>> +  - |
>> +    #include <dt-bindings/clock/qcom,qcs615-gcc.h>
>> +    #include <dt-bindings/clock/qcom,rpmh.h>
>> +
>> +    phy at 88e8000 {
>> +      compatible = "qcom,qcs615-qmp-usb3-dp-phy";
>> +      reg = <0x88e8000 0x2000>;
>> +
>> +      clocks = <&gcc GCC_AHB2PHY_WEST_CLK>,
>> +               <&gcc GCC_USB3_SEC_CLKREF_CLK>;
>> +      clock-names = "cfg_ahb",
>> +                    "ref";
>> +
>> +      resets = <&gcc GCC_USB3PHY_PHY_SEC_BCR >,
>> +               <&gcc GCC_USB3_DP_PHY_SEC_BCR>;
>> +      reset-names = "phy_phy",
>> +                    "dp_phy";
>> +
>> +      vdda-phy-supply = <&vreg_l11a>;
>> +      vdda-pll-supply = <&vreg_l5a>;
>> +
>> +      #clock-cells = <1>;
>> +      #phy-cells = <1>;
>> +
>> +      qcom,tcsr-reg = <&tcsr 0xbff0>,
>> +                      <&tcsr 0xb24c>;
>> +    };
>>
>> -- 
>> 2.34.1
>>


From mwalle at kernel.org  Thu Aug 21 23:45:33 2025
From: mwalle at kernel.org (Michael Walle)
Date: Fri, 22 Aug 2025 08:45:33 +0200
Subject: [PATCH v3] phy: ti: gmii-sel: Always write the RGMII ID setting
In-Reply-To: <20250821181850.6af0ff7f@kernel.org>
References: <20250819065622.1019537-1-mwalle@kernel.org>
 <20250821181850.6af0ff7f@kernel.org>
Message-ID: <DC8R5IJ2Q88K.YKUE9X9FZRNK@kernel.org>

Hi,

On Fri Aug 22, 2025 at 3:18 AM CEST, Jakub Kicinski wrote:
> On Tue, 19 Aug 2025 08:56:22 +0200 Michael Walle wrote:
> > v3:
> >  - simplify the logic. Thanks Matthias.
> >  - reworded the commit message
>
> This was set to Not Applicable in our patchwork, IDK why.
> Could you resend?

Won't this patch be picked up by the linux-phy tree?

-michael
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 297 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-phy/attachments/20250822/5da690b6/attachment-0001.sig>

From xiangxu.yin at oss.qualcomm.com  Thu Aug 21 23:48:28 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Fri, 22 Aug 2025 14:48:28 +0800
Subject: [PATCH v3 02/14] dt-bindings: phy: Add QMP USB3+DP PHY for QCS615
In-Reply-To: <tlilctwavwqw6oy46l5fote2pa6f4hdy2im6meo56cjaawba3a@a42bwbbfnsuw>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-2-a43bd25ec39c@oss.qualcomm.com>
 <tlilctwavwqw6oy46l5fote2pa6f4hdy2im6meo56cjaawba3a@a42bwbbfnsuw>
Message-ID: <dd3c9cc4-3b4a-4321-88ab-933909b6da87@oss.qualcomm.com>


On 8/20/2025 7:37 PM, Dmitry Baryshkov wrote:
> On Wed, Aug 20, 2025 at 05:34:44PM +0800, Xiangxu Yin wrote:
>> Add device tree binding documentation for the Qualcomm QMP USB3+DP PHY
>> on QCS615 Platform. This PHY supports both USB3 and DP functionality
>> over USB-C, with PHY mode switching capability. It does not support
>> combo mode.
>>
>> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
>> ---
>>  .../bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml   | 108 +++++++++++++++++++++
>>  1 file changed, 108 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml
>> new file mode 100644
>> index 0000000000000000000000000000000000000000..c2b1fbab2930f0653f4ddb95f7b54d8fe994f92d
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml
>> @@ -0,0 +1,108 @@
>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/phy/qcom,qcs615-qmp-usb3dp-phy.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Qualcomm QMP USB3-DP PHY controller (DP, QCS615)
>> +
>> +maintainers:
>> +  - Vinod Koul <vkoul at kernel.org>
>> +
>> +description:
>> +  The QMP PHY controller supports physical layer functionality for both
>> +  USB3 and DisplayPort over USB-C. While it enables mode switching
>> +  between USB3 and DisplayPort, but does not support combo mode.
>> +
>> +properties:
>> +  compatible:
>> +    enum:
>> +      - qcom,qcs615-qmp-usb3-dp-phy
>> +
>> +  reg:
>> +    maxItems: 1
>> +
>> +  clocks:
>> +    maxItems: 2
> Missing GCC_USB2_SEC_PHY_AUX_CLK and GCC_USB2_SEC_PHY_PIPE_CLK


Ok, will fix in next patch.


>> +
>> +  clock-names:
>> +    items:
>> +      - const: cfg_ahb
>> +      - const: ref
>> +
>> +  resets:
>> +    maxItems: 2
>> +
>> +  reset-names:
>> +    items:
>> +      - const: phy_phy
>> +      - const: dp_phy
>> +
>> +  vdda-phy-supply: true
>> +
>> +  vdda-pll-supply: true
>> +
>> +  "#clock-cells":
>> +    const: 1
>> +    description:
>> +      See include/dt-bindings/phy/phy-qcom-qmp.h
>> +
>> +  "#phy-cells":
>> +    const: 1
>> +    description:
>> +      See include/dt-bindings/phy/phy-qcom-qmp.h
>> +
>> +  qcom,tcsr-reg:
>> +    $ref: /schemas/types.yaml#/definitions/phandle-array
>> +    items:
>> +      - items:
>> +          - description: phandle to TCSR hardware block
>> +          - description: offset of the VLS CLAMP register
>> +      - items:
>> +          - description: phandle to TCSR hardware block
>> +          - description: offset of the DP PHY mode register
>> +    description: Clamp and PHY mode register present in the TCSR
>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +  - clocks
>> +  - clock-names
>> +  - resets
>> +  - reset-names
>> +  - vdda-phy-supply
>> +  - vdda-pll-supply
>> +  - "#clock-cells"
>> +  - "#phy-cells"
>> +  - qcom,tcsr-reg
>> +
>> +additionalProperties: false
>> +
>> +examples:
>> +  - |
>> +    #include <dt-bindings/clock/qcom,qcs615-gcc.h>
>> +    #include <dt-bindings/clock/qcom,rpmh.h>
>> +
>> +    phy at 88e8000 {
>> +      compatible = "qcom,qcs615-qmp-usb3-dp-phy";
>> +      reg = <0x88e8000 0x2000>;
>> +
>> +      clocks = <&gcc GCC_AHB2PHY_WEST_CLK>,
>> +               <&gcc GCC_USB3_SEC_CLKREF_CLK>;
>> +      clock-names = "cfg_ahb",
>> +                    "ref";
>> +
>> +      resets = <&gcc GCC_USB3PHY_PHY_SEC_BCR >,
>> +               <&gcc GCC_USB3_DP_PHY_SEC_BCR>;
>> +      reset-names = "phy_phy",
>> +                    "dp_phy";
>> +
>> +      vdda-phy-supply = <&vreg_l11a>;
>> +      vdda-pll-supply = <&vreg_l5a>;
>> +
>> +      #clock-cells = <1>;
>> +      #phy-cells = <1>;
>> +
>> +      qcom,tcsr-reg = <&tcsr 0xbff0>,
>> +                      <&tcsr 0xb24c>;
>> +    };
>>
>> -- 
>> 2.34.1
>>


From xiangxu.yin at oss.qualcomm.com  Thu Aug 21 23:49:13 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Fri, 22 Aug 2025 14:49:13 +0800
Subject: [PATCH v3 04/14] phy: qcom: qmp-usbc: Add USBC PHY type enum
In-Reply-To: <cueyo7huj2m2yt46sjk3atfktft6y5slhhtslwmi44r7h7lxbn@5zvwxtdmk34t>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-4-a43bd25ec39c@oss.qualcomm.com>
 <cueyo7huj2m2yt46sjk3atfktft6y5slhhtslwmi44r7h7lxbn@5zvwxtdmk34t>
Message-ID: <d21c4c74-a36b-4f01-9c22-44bcec3c20eb@oss.qualcomm.com>


On 8/20/2025 7:34 PM, Dmitry Baryshkov wrote:
> On Wed, Aug 20, 2025 at 05:34:46PM +0800, Xiangxu Yin wrote:
>> Introduce qmp_phy_usbc_type enum and a 'type' field in qmp_phy_cfg to
>> differentiate between USB-only PHYs and USB/DP switchable PHYs.
>>
>> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
>> ---
>>  drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 9 +++++++++
>>  1 file changed, 9 insertions(+)
>>
>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
>> index e484caec2be20121cfe287c507b17af28fb9f211..5afe090b546977a11265bbffa7c355feb8c72dfa 100644
>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
>> @@ -284,6 +284,11 @@ static const struct qmp_phy_init_tbl qcm2290_usb3_pcs_tbl[] = {
>>  	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x88),
>>  };
>>  
>> +enum qmp_phy_usbc_type {
>> +	QMP_PHY_USBC_USB3_ONLY,
>> +	QMP_PHY_USBC_USB3_DP,
> Drop, you can use presense of DP offsets in order to differentiate
> between USB3 and USB3+DP.


Ok, will drop.


>> +};
>> +
>>  struct qmp_usbc_offsets {
>>  	u16 serdes;
>>  	u16 pcs;


From xiangxu.yin at oss.qualcomm.com  Thu Aug 21 23:59:45 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Fri, 22 Aug 2025 14:59:45 +0800
Subject: [PATCH v3 05/14] phy: qcom: qmp-usbc: Add DP-related fields for
 USB/DP switchable PHY
In-Reply-To: <7b6utbnibia767bp55vhvg6ghdavb66ubdpabyguohuwtmz3mp@unvm36jttota>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-5-a43bd25ec39c@oss.qualcomm.com>
 <7b6utbnibia767bp55vhvg6ghdavb66ubdpabyguohuwtmz3mp@unvm36jttota>
Message-ID: <8922ae6e-9be6-49f7-ac84-d4a1dd60421b@oss.qualcomm.com>


On 8/20/2025 7:47 PM, Dmitry Baryshkov wrote:
> On Wed, Aug 20, 2025 at 05:34:47PM +0800, Xiangxu Yin wrote:
>> Extend qmp_usbc_offsets and qmp_phy_cfg with DP-specific fields,
>> including register offsets, init tables, and callback hooks. Also
>> update qmp_usbc struct to track DP-related resources and state.
>> This enables support for USB/DP switchable Type-C PHYs that operate
>> in either mode.
>>
>> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
>> ---
>>  drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 73 ++++++++++++++++++++++++--------
>>  1 file changed, 55 insertions(+), 18 deletions(-)
>>
>>  
>> +	struct regmap *tcsr_map;
>> +	u32 vls_clamp_reg;
>> +	u32 dp_phy_mode_reg;
>> +
>>  	struct mutex phy_mutex;
>>  
>> +	struct phy *usb_phy;
> Should be a part of the previous patch.


Ok, will move usb_phy rename to patch 'Rename USB-specific ops',?

then shall I need drop?the?|Reviewed-by|?tag in that patch since it will change?


>>  	enum phy_mode mode;
>>  	unsigned int usb_init_count;
>>  
>> -	struct phy *phy;
> Similarly.


Ack.


>> -
>> -	struct clk_fixed_rate pipe_clk_fixed;
>> +	struct phy *dp_phy;
>> +	unsigned int dp_aux_cfg;
>> +	struct phy_configure_opts_dp dp_opts;
>> +	unsigned int dp_init_count;
>>  
>>  	struct typec_switch_dev *sw;
>>  	enum typec_orientation orientation;
>> @@ -874,11 +911,11 @@ static int qmp_usbc_typec_switch_set(struct typec_switch_dev *sw,
>>  	qmp->orientation = orientation;
>>  
>>  	if (qmp->usb_init_count) {
>> -		qmp_usbc_usb_power_off(qmp->phy);
>> -		qmp_usbc_com_exit(qmp->phy);
>> +		qmp_usbc_usb_power_off(qmp->usb_phy);
>> +		qmp_usbc_com_exit(qmp->usb_phy);
>>  
>> -		qmp_usbc_com_init(qmp->phy);
>> -		qmp_usbc_usb_power_on(qmp->phy);
>> +		qmp_usbc_com_init(qmp->usb_phy);
>> +		qmp_usbc_usb_power_on(qmp->usb_phy);
> and these.


Ack.


>>  	}
>>  
>>  	mutex_unlock(&qmp->phy_mutex);
>> @@ -1106,14 +1143,14 @@ static int qmp_usbc_probe(struct platform_device *pdev)
>>  	if (ret)
>>  		goto err_node_put;
>>  
>> -	qmp->phy = devm_phy_create(dev, np, &qmp_usbc_usb_phy_ops);
>> -	if (IS_ERR(qmp->phy)) {
>> -		ret = PTR_ERR(qmp->phy);
>> +	qmp->usb_phy = devm_phy_create(dev, np, &qmp_usbc_usb_phy_ops);
>> +	if (IS_ERR(qmp->usb_phy)) {
>> +		ret = PTR_ERR(qmp->usb_phy);
>>  		dev_err(dev, "failed to create PHY: %d\n", ret);
>>  		goto err_node_put;
>>  	}
>>  
>> -	phy_set_drvdata(qmp->phy, qmp);
>> +	phy_set_drvdata(qmp->usb_phy, qmp);
>>  
>>  	of_node_put(np);
>>  
>>
>> -- 
>> 2.34.1
>>


From maudspierings at gocontroll.com  Fri Aug 22 00:20:32 2025
From: maudspierings at gocontroll.com (Maud Spierings)
Date: Fri, 22 Aug 2025 09:20:32 +0200
Subject: [PATCH 2/6] phy: phy-can-transceiver: Add support for NXP TJA1051
In-Reply-To: <20250822-can-v1-2-c075f702adea@nxp.com>
References: <20250822-can-v1-2-c075f702adea@nxp.com>
Message-ID: <060439dd-3df8-4d0b-8957-83b75dc13537@gocontroll.com>

Hi Peng,

> The TJA1051 is a high-speed CAN transceiver which is a pin-compatible
> alternative for TI TCAN1043 with Sleep mode supported.
> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  drivers/phy/phy-can-transceiver.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/phy/phy-can-transceiver.c b/drivers/phy/phy-can-transceiver.c
> index f59caff4b3d4c267feca4220bf1547b6fad08f95..b49371a1272cd8a25b5e2271586b756103c64f0a 100644
> --- a/drivers/phy/phy-can-transceiver.c
> +++ b/drivers/phy/phy-can-transceiver.c
> @@ -85,6 +85,10 @@ static const struct of_device_id can_transceiver_phy_ids[] = {
>  		.compatible = "ti,tcan1043",
>  		.data = &tcan1043_drvdata
>  	},
> +	{
> +		.compatible = "nxp,tja1051",
> +		.data = &tcan1043_drvdata
> +	},
>  	{
>  		.compatible = "nxp,tjr1443",
>  		.data = &tcan1043_drvdata
> 
> -- 
> 2.37.1

Isn't this unnecessary as it has the ti,tcan1043 fallback compatible in 
the bindings? I'm still learning a lot so I might be wrong.

Kind regards,
Maud


From xiangxu.yin at oss.qualcomm.com  Fri Aug 22 00:20:56 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Fri, 22 Aug 2025 15:20:56 +0800
Subject: [PATCH v3 06/14] phy: qcom: qmp-usbc: Add QCS615 DP PHY
 configuration and init data
In-Reply-To: <bx3cumx7ej7taour6zhqufrzjdxuhvlx23ga3vmvokrlekayem@e5rfjbcwle2r>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-6-a43bd25ec39c@oss.qualcomm.com>
 <bx3cumx7ej7taour6zhqufrzjdxuhvlx23ga3vmvokrlekayem@e5rfjbcwle2r>
Message-ID: <1a2c38c6-0d49-4c47-9cc2-014b71e1e81e@oss.qualcomm.com>


On 8/20/2025 7:25 PM, Dmitry Baryshkov wrote:
> On Wed, Aug 20, 2025 at 05:34:48PM +0800, Xiangxu Yin wrote:
>> Introduce QCS615 hardware-specific configuration for DP PHY mode,
>> including register offsets, initialization tables, voltage swing
>> and pre-emphasis settings.
> This will trigger unused warnings. Please squash this into the patch
> adding compat string to the driver.


Ok,

Will squash the compatible string addition into this patch,?

as the following callback functions would also trigger similar unused warnings.


>> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
>> ---
>>  drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 139 +++++++++++++++++++++++++++++++
>>  1 file changed, 139 insertions(+)
>>
>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
>> index 6b0e86ec43ded3d850f68f248a74c39f74ecb5bb..61128d606238321d1b573655b3b987226aa2d594 100644
>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
>> @@ -284,6 +284,86 @@ static const struct qmp_phy_init_tbl qcm2290_usb3_pcs_tbl[] = {
>>  	QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x88),
>>  };
>>  
>> +static const struct qmp_phy_init_tbl qcs615_qmp_dp_serdes_tbl[] = {
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x37),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x00),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x3f),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x0e),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_BG_CTRL, 0x0f),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_BUF_ENABLE, 0x06),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x40),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x08),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x05),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x00),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x00),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x0f),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x02),
>> +};
>> +
>> +static const struct qmp_phy_init_tbl qcs615_qmp_dp_serdes_tbl_rbr[] = {
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x2c),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x69),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x80),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x07),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xbf),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x21),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
>> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0xc6),
>> +};
>> +
>> +static const struct qmp_phy_init_tbl qcs615_qmp_dp_serdes_tbl_hbr[] = {
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x24),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x69),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x80),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x07),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x3f),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x38),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
>> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0xc4),
>> +};
>> +
>> +static const struct qmp_phy_init_tbl qcs615_qmp_dp_serdes_tbl_hbr2[] = {
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x20),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x8c),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x0a),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x7f),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x70),
>> +	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
>> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0xc4),
>> +};
>> +
>> +static const struct qmp_phy_init_tbl qcs615_qmp_dp_tx_tbl[] = {
>> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_TRANSCEIVER_BIAS_EN, 0x1a),
>> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_VMODE_CTRL1, 0x40),
>> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_PRE_STALL_LDO_BOOST_EN, 0x30),
>> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_INTERFACE_SELECT, 0x3d),
>> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_CLKBUF_ENABLE, 0x0f),
>> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RESET_TSYNC_EN, 0x03),
>> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_TRAN_DRVR_EMP_EN, 0x03),
>> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_PARRATE_REC_DETECT_IDLE_EN, 0x00),
>> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_INTERFACE_MODE, 0x00),
>> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_EMP_POST1_LVL, 0x2b),
>> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_DRV_LVL, 0x2f),
>> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_TX_BAND, 0x4),
>> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x12),
>> +	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x12),
>> +};
>> +
>>  enum qmp_phy_usbc_type {
>>  	QMP_PHY_USBC_USB3_ONLY,
>>  	QMP_PHY_USBC_USB3_DP,
>> @@ -449,6 +529,34 @@ static const struct qmp_usbc_offsets qmp_usbc_offsets_v3_qcm2290 = {
>>  	.rx2		= 0x800,
>>  };
>>  
>> +static const struct qmp_usbc_offsets qmp_usbc_usb3dp_offsets_qcs615 = {
>> +	.serdes		= 0x0,
>> +	.pcs		= 0xc00,
>> +	.pcs_misc	= 0xa00,
>> +	.tx		= 0x200,
>> +	.rx		= 0x400,
>> +	.tx2		= 0x600,
>> +	.rx2		= 0x800,
>> +	.dp_serdes	= 0x1c00,
>> +	.dp_txa		= 0x1400,
>> +	.dp_txb		= 0x1800,
>> +	.dp_dp_phy	= 0x1000,
>> +};
>> +
>> +static const u8 qmp_dp_pre_emphasis_hbr2_rbr[4][4] = {
>> +	{0x00, 0x0b, 0x12, 0xff},
>> +	{0x00, 0x0a, 0x12, 0xff},
>> +	{0x00, 0x0c, 0xff, 0xff},
>> +	{0xff, 0xff, 0xff, 0xff}
>> +};
>> +
>> +static const u8 qmp_dp_voltage_swing_hbr2_rbr[4][4] = {
>> +	{0x07, 0x0f, 0x14, 0xff},
>> +	{0x11, 0x1d, 0x1f, 0xff},
>> +	{0x18, 0x1f, 0xff, 0xff},
>> +	{0xff, 0xff, 0xff, 0xff}
>> +};
>> +
>>  static const struct qmp_phy_cfg msm8998_usb3phy_cfg = {
>>  	.offsets		= &qmp_usbc_offsets_v3_qcm2290,
>>  	.type			= QMP_PHY_USBC_USB3_ONLY,
>> @@ -500,6 +608,37 @@ static const struct qmp_phy_cfg sdm660_usb3phy_cfg = {
>>  	.regs			= qmp_v3_usb3phy_regs_layout_qcm2290,
>>  };
>>  
>> +static const struct qmp_phy_cfg qcs615_usb3dp_phy_cfg = {
>> +	.offsets		= &qmp_usbc_usb3dp_offsets_qcs615,
>> +	.type			= QMP_PHY_USBC_USB3_DP,
>> +
>> +	.serdes_tbl		= qcm2290_usb3_serdes_tbl,
>> +	.serdes_tbl_num		= ARRAY_SIZE(qcm2290_usb3_serdes_tbl),
>> +	.tx_tbl			= qcm2290_usb3_tx_tbl,
>> +	.tx_tbl_num		= ARRAY_SIZE(qcm2290_usb3_tx_tbl),
>> +	.rx_tbl			= qcm2290_usb3_rx_tbl,
>> +	.rx_tbl_num		= ARRAY_SIZE(qcm2290_usb3_rx_tbl),
>> +	.pcs_tbl		= qcm2290_usb3_pcs_tbl,
>> +	.pcs_tbl_num		= ARRAY_SIZE(qcm2290_usb3_pcs_tbl),
>> +
>> +	.regs			= qmp_v3_usb3phy_regs_layout_qcm2290,
>> +
>> +	.dp_serdes_tbl		= qcs615_qmp_dp_serdes_tbl,
>> +	.dp_serdes_tbl_num	= ARRAY_SIZE(qcs615_qmp_dp_serdes_tbl),
>> +	.dp_tx_tbl		= qcs615_qmp_dp_tx_tbl,
>> +	.dp_tx_tbl_num		= ARRAY_SIZE(qcs615_qmp_dp_tx_tbl),
>> +
>> +	.serdes_tbl_rbr		= qcs615_qmp_dp_serdes_tbl_rbr,
>> +	.serdes_tbl_rbr_num	= ARRAY_SIZE(qcs615_qmp_dp_serdes_tbl_rbr),
>> +	.serdes_tbl_hbr		= qcs615_qmp_dp_serdes_tbl_hbr,
>> +	.serdes_tbl_hbr_num	= ARRAY_SIZE(qcs615_qmp_dp_serdes_tbl_hbr),
>> +	.serdes_tbl_hbr2	= qcs615_qmp_dp_serdes_tbl_hbr2,
>> +	.serdes_tbl_hbr2_num	= ARRAY_SIZE(qcs615_qmp_dp_serdes_tbl_hbr2),
>> +
>> +	.swing_tbl		= &qmp_dp_voltage_swing_hbr2_rbr,
>> +	.pre_emphasis_tbl	= &qmp_dp_pre_emphasis_hbr2_rbr,
>> +};
>> +
>>  static int qmp_usbc_com_init(struct phy *phy)
>>  {
>>  	struct qmp_usbc *qmp = phy_get_drvdata(phy);
>>
>> -- 
>> 2.34.1
>>


From krzk at kernel.org  Fri Aug 22 00:22:00 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 22 Aug 2025 09:22:00 +0200
Subject: [PATCH RFC 01/22] dt-bindings: usb: snps,dwc3: Allow multiple
 iommus
In-Reply-To: <20250821-atcphy-6-17-v1-1-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
 <20250821-atcphy-6-17-v1-1-172beda182b8@kernel.org>
Message-ID: <20250822-skinny-clay-harrier-64dc58@kuoka>

On Thu, Aug 21, 2025 at 03:38:53PM +0000, Sven Peter wrote:
> Apple's dwc3 variant requires two iommus.
> 
> Signed-off-by: Sven Peter <sven at kernel.org>
> ---
>  Documentation/devicetree/bindings/usb/snps,dwc3.yaml | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
> index 4380bb6fa2f08a475b557e80467abc2861f622e2..6d35dcc605c01977f4fc6fdb6f12976f1cef2b9e 100644
> --- a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
> +++ b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
> @@ -60,7 +60,7 @@ properties:
>    dma-coherent: true
>  
>    iommus:
> -    maxItems: 1
> +    maxItems: 2

Never tested. You anyway need specific constraints.

>  
>    power-domains:
>      description:
> 
> -- 
> 2.34.1
> 
> 


From krzk at kernel.org  Fri Aug 22 00:24:00 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 22 Aug 2025 09:24:00 +0200
Subject: [PATCH RFC 02/22] dt-bindings: usb: Add Apple dwc3
In-Reply-To: <20250821-atcphy-6-17-v1-2-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
 <20250821-atcphy-6-17-v1-2-172beda182b8@kernel.org>
Message-ID: <20250822-banana-ferret-of-opposition-0bcfad@kuoka>

On Thu, Aug 21, 2025 at 03:38:54PM +0000, Sven Peter wrote:
> +
> +  The common content of the node is defined in snps,dwc3.yaml.

Drop sentence, redundant. Schema tells that.

...

> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  iommus:
> +    maxItems: 2
> +
> +  resets:
> +    maxItems: 1
> +
> +  power-domains:
> +    maxItems: 1
> +
> +unevaluatedProperties: false

This goes after required.

> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - iommus
> +  - resets
> +  - power-domains
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/apple-aic.h>
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +
> +    usb at 82280000 {
> +      compatible = "apple,t8103-dwc3", "snps,dwc3";
> +      reg = <0x82280000 0x10000>;
> +      interrupts = <AIC_IRQ 777 IRQ_TYPE_LEVEL_HIGH>;
> +      iommus = <&dwc3_0_dart_0 0>, <&dwc3_0_dart_1 1>;
> +
> +      dr_mode = "otg";
> +      usb-role-switch;
> +      role-switch-default-mode = "host";
> +    };
> diff --git a/MAINTAINERS b/MAINTAINERS
> index fe168477caa45799dfe07de2f54de6d6a1ce0615..0e085cb0762f765958d67be61ae0d3d773503431 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2399,6 +2399,7 @@ F:	Documentation/devicetree/bindings/power/reset/apple,smc-reboot.yaml
>  F:	Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
>  F:	Documentation/devicetree/bindings/spi/apple,spi.yaml
>  F:	Documentation/devicetree/bindings/spmi/apple,spmi.yaml
> +F:	Documentation/devicetree/bindings/usb/apple,dwc3.yaml
>  F:	Documentation/devicetree/bindings/watchdog/apple,wdt.yaml
>  F:	arch/arm64/boot/dts/apple/
>  F:	drivers/bluetooth/hci_bcm4377.c
> 
> -- 
> 2.34.1
> 
> 


From mani at kernel.org  Fri Aug 22 00:43:34 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Fri, 22 Aug 2025 13:13:34 +0530
Subject: [PATCH v10 3/5] arm64: dts: qcom: qcs8300-ride: enable pcie0
 interface
In-Reply-To: <20250811071131.982983-4-ziyue.zhang@oss.qualcomm.com>
References: <20250811071131.982983-1-ziyue.zhang@oss.qualcomm.com>
 <20250811071131.982983-4-ziyue.zhang@oss.qualcomm.com>
Message-ID: <wwpdqg3tqq252emsbhu3lvpq5eefgbzk7bpgr2gu3hekokoqob@76fcww4fm3yg>

On Mon, Aug 11, 2025 at 03:11:29PM GMT, Ziyue Zhang wrote:
> Add configurations in devicetree for PCIe0, board related gpios,
> PMIC regulators, etc for qcs8300-ride board.
> 
> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
> Reviewed-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
> Signed-off-by: Ziyue Zhang <ziyue.zhang at oss.qualcomm.com>
> ---
>  arch/arm64/boot/dts/qcom/qcs8300-ride.dts | 40 +++++++++++++++++++++++
>  1 file changed, 40 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts
> index 8c166ead912c..e8e382db2b99 100644
> --- a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts
> +++ b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts
> @@ -308,6 +308,23 @@ &iris {
>  	status = "okay";
>  };
>  
> +&pcie0 {
> +	perst-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>;
> +	wake-gpios = <&tlmm 0 GPIO_ACTIVE_HIGH>;

Since we have deprecated these properties in host bridge node recently, please
move these properties to PCI bridge node.

- Mani

> +
> +	pinctrl-0 = <&pcie0_default_state>;
> +	pinctrl-names = "default";
> +
> +	status = "okay";
> +};
> +
> +&pcie0_phy {
> +	vdda-phy-supply = <&vreg_l6a>;
> +	vdda-pll-supply = <&vreg_l5a>;
> +
> +	status = "okay";
> +};
> +
>  &qupv3_id_0 {
>  	status = "okay";
>  };
> @@ -348,6 +365,29 @@ ethernet0_mdio: ethernet0-mdio-pins {
>  			bias-pull-up;
>  		};
>  	};
> +
> +	pcie0_default_state: pcie0-default-state {
> +		wake-pins {
> +			pins = "gpio0";
> +			function = "gpio";
> +			drive-strength = <2>;
> +			bias-pull-up;
> +		};
> +
> +		clkreq-pins {
> +			pins = "gpio1";
> +			function = "pcie0_clkreq";
> +			drive-strength = <2>;
> +			bias-pull-up;
> +		};
> +
> +		perst-pins {
> +			pins = "gpio2";
> +			function = "gpio";
> +			drive-strength = <2>;
> +			bias-pull-down;
> +		};
> +	};
>  };
>  
>  &uart7 {
> -- 
> 2.43.0
> 

-- 
????????? ????????


From mani at kernel.org  Fri Aug 22 01:06:23 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Fri, 22 Aug 2025 13:36:23 +0530
Subject: [PATCH v5 1/3] PCI: qcom: Add equalization settings for 8.0 GT/s
 and 32.0 GT/s
In-Reply-To: <20250819071649.1531437-2-ziyue.zhang@oss.qualcomm.com>
References: <20250819071649.1531437-1-ziyue.zhang@oss.qualcomm.com>
 <20250819071649.1531437-2-ziyue.zhang@oss.qualcomm.com>
Message-ID: <z54p5x5u56u7dprrlv3obzhxotjgimbufa2spajoqvnlrevgdd@4dejnkmiegrh>

On Tue, Aug 19, 2025 at 03:16:46PM GMT, Ziyue Zhang wrote:
> Add lane equalization setting for 8.0 GT/s and 32.0 GT/s to enhance link
> stability and avoid AER Correctable Errors reported on some platforms
> (eg. SA8775P).
> 

So this is fixing an issue, right? Then you should add relevant Fixes tag. I
guess the tag here would be the commit that added SA8775p.

> 8.0 GT/s, 16.0 GT/s and 32.0 GT/s require the same equalization setting.
> This setting is programmed into a group of shadow registers, which can be
> switched to configure equalization for different speeds by writing 00b,
> 01b and 10b to `RATE_SHADOW_SEL`.
> 
> Hence program equalization registers in a loop using link speed as index,
> so that equalization setting can be programmed for 8.0 GT/s, 16.0 GT/s
> and 32.0 GT/s.
> 
> Co-developed-by: Qiang Yu <qiang.yu at oss.qualcomm.com>
> Signed-off-by: Qiang Yu <qiang.yu at oss.qualcomm.com>
> Signed-off-by: Ziyue Zhang <ziyue.zhang at oss.qualcomm.com>
> ---
>  drivers/pci/controller/dwc/pcie-designware.h  |  1 -
>  drivers/pci/controller/dwc/pcie-qcom-common.c | 58 +++++++++++--------
>  drivers/pci/controller/dwc/pcie-qcom-common.h |  2 +-
>  drivers/pci/controller/dwc/pcie-qcom-ep.c     |  6 +-
>  drivers/pci/controller/dwc/pcie-qcom.c        |  6 +-
>  5 files changed, 41 insertions(+), 32 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> index b5e7e18138a6..11de844428e5 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -123,7 +123,6 @@
>  #define GEN3_RELATED_OFF_GEN3_EQ_DISABLE	BIT(16)
>  #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_SHIFT	24
>  #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK	GENMASK(25, 24)
> -#define GEN3_RELATED_OFF_RATE_SHADOW_SEL_16_0GT	0x1
>  
>  #define GEN3_EQ_CONTROL_OFF			0x8A8
>  #define GEN3_EQ_CONTROL_OFF_FB_MODE		GENMASK(3, 0)
> diff --git a/drivers/pci/controller/dwc/pcie-qcom-common.c b/drivers/pci/controller/dwc/pcie-qcom-common.c
> index 3aad19b56da8..cb98e66d81d9 100644
> --- a/drivers/pci/controller/dwc/pcie-qcom-common.c
> +++ b/drivers/pci/controller/dwc/pcie-qcom-common.c
> @@ -8,9 +8,11 @@
>  #include "pcie-designware.h"
>  #include "pcie-qcom-common.h"
>  
> -void qcom_pcie_common_set_16gt_equalization(struct dw_pcie *pci)
> +void qcom_pcie_common_set_equalization(struct dw_pcie *pci)
>  {
>  	u32 reg;
> +	u16 speed;
> +	struct device *dev = pci->dev;

Reverse Xmas order please.

>  
>  	/*
>  	 * GEN3_RELATED_OFF register is repurposed to apply equalization
> @@ -19,32 +21,40 @@ void qcom_pcie_common_set_16gt_equalization(struct dw_pcie *pci)
>  	 * determines the data rate for which these equalization settings are
>  	 * applied.
>  	 */
> -	reg = dw_pcie_readl_dbi(pci, GEN3_RELATED_OFF);
> -	reg &= ~GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL;
> -	reg &= ~GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK;
> -	reg |= FIELD_PREP(GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK,
> -			  GEN3_RELATED_OFF_RATE_SHADOW_SEL_16_0GT);
> -	dw_pcie_writel_dbi(pci, GEN3_RELATED_OFF, reg);
>  
> -	reg = dw_pcie_readl_dbi(pci, GEN3_EQ_FB_MODE_DIR_CHANGE_OFF);
> -	reg &= ~(GEN3_EQ_FMDC_T_MIN_PHASE23 |
> -		GEN3_EQ_FMDC_N_EVALS |
> -		GEN3_EQ_FMDC_MAX_PRE_CUSROR_DELTA |
> -		GEN3_EQ_FMDC_MAX_POST_CUSROR_DELTA);
> -	reg |= FIELD_PREP(GEN3_EQ_FMDC_T_MIN_PHASE23, 0x1) |
> -		FIELD_PREP(GEN3_EQ_FMDC_N_EVALS, 0xd) |
> -		FIELD_PREP(GEN3_EQ_FMDC_MAX_PRE_CUSROR_DELTA, 0x5) |
> -		FIELD_PREP(GEN3_EQ_FMDC_MAX_POST_CUSROR_DELTA, 0x5);
> -	dw_pcie_writel_dbi(pci, GEN3_EQ_FB_MODE_DIR_CHANGE_OFF, reg);
> +	for (speed = PCIE_SPEED_8_0GT; speed <= pcie_link_speed[pci->max_link_speed]; ++speed) {
> +		if (speed > PCIE_SPEED_32_0GT) {
> +			dev_warn(dev, "Skipped equalization settings for speeds higher than 32.0 GT/s\n");
> +			break;
> +		}
>  
> -	reg = dw_pcie_readl_dbi(pci, GEN3_EQ_CONTROL_OFF);
> -	reg &= ~(GEN3_EQ_CONTROL_OFF_FB_MODE |
> -		GEN3_EQ_CONTROL_OFF_PHASE23_EXIT_MODE |
> -		GEN3_EQ_CONTROL_OFF_FOM_INC_INITIAL_EVAL |
> -		GEN3_EQ_CONTROL_OFF_PSET_REQ_VEC);
> -	dw_pcie_writel_dbi(pci, GEN3_EQ_CONTROL_OFF, reg);
> +		reg = dw_pcie_readl_dbi(pci, GEN3_RELATED_OFF);
> +		reg &= ~GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL;
> +		reg &= ~GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK;
> +		reg |= FIELD_PREP(GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK,
> +			  speed - PCIE_SPEED_8_0GT);
> +		dw_pcie_writel_dbi(pci, GEN3_RELATED_OFF, reg);
> +
> +		reg = dw_pcie_readl_dbi(pci, GEN3_EQ_FB_MODE_DIR_CHANGE_OFF);
> +		reg &= ~(GEN3_EQ_FMDC_T_MIN_PHASE23 |
> +			GEN3_EQ_FMDC_N_EVALS |
> +			GEN3_EQ_FMDC_MAX_PRE_CUSROR_DELTA |
> +			GEN3_EQ_FMDC_MAX_POST_CUSROR_DELTA);
> +		reg |= FIELD_PREP(GEN3_EQ_FMDC_T_MIN_PHASE23, 0x1) |
> +			FIELD_PREP(GEN3_EQ_FMDC_N_EVALS, 0xd) |
> +			FIELD_PREP(GEN3_EQ_FMDC_MAX_PRE_CUSROR_DELTA, 0x5) |
> +			FIELD_PREP(GEN3_EQ_FMDC_MAX_POST_CUSROR_DELTA, 0x5);
> +		dw_pcie_writel_dbi(pci, GEN3_EQ_FB_MODE_DIR_CHANGE_OFF, reg);
> +
> +		reg = dw_pcie_readl_dbi(pci, GEN3_EQ_CONTROL_OFF);
> +		reg &= ~(GEN3_EQ_CONTROL_OFF_FB_MODE |
> +			GEN3_EQ_CONTROL_OFF_PHASE23_EXIT_MODE |
> +			GEN3_EQ_CONTROL_OFF_FOM_INC_INITIAL_EVAL |
> +			GEN3_EQ_CONTROL_OFF_PSET_REQ_VEC);
> +		dw_pcie_writel_dbi(pci, GEN3_EQ_CONTROL_OFF, reg);
> +	}
>  }
> -EXPORT_SYMBOL_GPL(qcom_pcie_common_set_16gt_equalization);
> +EXPORT_SYMBOL_GPL(qcom_pcie_common_set_equalization);
>  
>  void qcom_pcie_common_set_16gt_lane_margining(struct dw_pcie *pci)
>  {
> diff --git a/drivers/pci/controller/dwc/pcie-qcom-common.h b/drivers/pci/controller/dwc/pcie-qcom-common.h
> index 7d88d29e4766..7f5ca2fd9a72 100644
> --- a/drivers/pci/controller/dwc/pcie-qcom-common.h
> +++ b/drivers/pci/controller/dwc/pcie-qcom-common.h
> @@ -8,7 +8,7 @@
>  
>  struct dw_pcie;
>  
> -void qcom_pcie_common_set_16gt_equalization(struct dw_pcie *pci);
> +void qcom_pcie_common_set_equalization(struct dw_pcie *pci);
>  void qcom_pcie_common_set_16gt_lane_margining(struct dw_pcie *pci);
>  
>  #endif
> diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c
> index 60afb4d0134c..aeb166f68d55 100644
> --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c
> +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c
> @@ -511,10 +511,10 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci)
>  		goto err_disable_resources;
>  	}
>  
> -	if (pcie_link_speed[pci->max_link_speed] == PCIE_SPEED_16_0GT) {
> -		qcom_pcie_common_set_16gt_equalization(pci);
> +	qcom_pcie_common_set_equalization(pci);
> +
> +	if (pcie_link_speed[pci->max_link_speed] == PCIE_SPEED_16_0GT)

This condition has existed even before this patch, but just noticing this
possible issue. So if 'max_link_speed' is > 16 GT/s, we do not need to set lane
margining? We used the same logic to set equalization setting earlier also.

- Mani

-- 
????????? ????????


From neil.armstrong at linaro.org  Fri Aug 22 01:19:49 2025
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Fri, 22 Aug 2025 10:19:49 +0200
Subject: [PATCH v5 3/3] arm64: dts: qcom: lemans: Add PCIe lane
 equalization preset properties
In-Reply-To: <20250819071649.1531437-4-ziyue.zhang@oss.qualcomm.com>
References: <20250819071649.1531437-1-ziyue.zhang@oss.qualcomm.com>
 <20250819071649.1531437-4-ziyue.zhang@oss.qualcomm.com>
Message-ID: <b4456929-cfd8-4e8e-9def-f7ce0a02d240@linaro.org>

On 19/08/2025 09:16, Ziyue Zhang wrote:
> Add PCIe lane equalization preset properties with all values set to 5 for
> 8.0 GT/s and 16.0 GT/s data rates to enhance link stability.
> 
> Co-developed-by: Qiang Yu <qiang.yu at oss.qualcomm.com>
> Signed-off-by: Qiang Yu <qiang.yu at oss.qualcomm.com>
> Signed-off-by: Ziyue Zhang <ziyue.zhang at oss.qualcomm.com>
> Reviewed-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
> Acked-by: Manivannan Sadhasivam <mani at kernel.org>
> ---
>   arch/arm64/boot/dts/qcom/lemans.dtsi | 7 +++++++
>   1 file changed, 7 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/qcom/lemans.dtsi b/arch/arm64/boot/dts/qcom/lemans.dtsi
> index 64f5378c6a47..c7a09c3605a7 100644
> --- a/arch/arm64/boot/dts/qcom/lemans.dtsi
> +++ b/arch/arm64/boot/dts/qcom/lemans.dtsi
> @@ -7657,6 +7657,10 @@ pcie0: pcie at 1c00000 {
>   		phys = <&pcie0_phy>;
>   		phy-names = "pciephy";
>   
> +		eq-presets-8gts = /bits/ 16 <0x5555 0x5555>;
> +		eq-presets-16gts = /bits/ 8 <0x55 0x55>;
> +
> +

Please drop this empty line.

Neil

>   		status = "disabled";
>   
>   		pcieport0: pcie at 0 {
> @@ -7827,6 +7831,9 @@ pcie1: pcie at 1c10000 {
>   		phys = <&pcie1_phy>;
>   		phy-names = "pciephy";
>   
> +		eq-presets-8gts = /bits/ 16 <0x5555 0x5555 0x5555 0x5555>;
> +		eq-presets-16gts = /bits/ 8 <0x55 0x55 0x55 0x55>;
> +
>   		status = "disabled";
>   
>   		pcie at 0 {



From xiangxu.yin at oss.qualcomm.com  Fri Aug 22 01:29:28 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Fri, 22 Aug 2025 16:29:28 +0800
Subject: [PATCH v3 07/14] phy: qcom: qmp-usbc: Move reset and regulator
 config into PHY cfg
In-Reply-To: <ofvzduf5xyip7w6yde2xwsrvv3tdh7ew3yyzeya2qzpqty3j7p@bnetyjowhdn5>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-7-a43bd25ec39c@oss.qualcomm.com>
 <ofvzduf5xyip7w6yde2xwsrvv3tdh7ew3yyzeya2qzpqty3j7p@bnetyjowhdn5>
Message-ID: <6f7c3962-ccfc-4400-a77f-399b06da93e1@oss.qualcomm.com>


On 8/20/2025 7:30 PM, Dmitry Baryshkov wrote:
> On Wed, Aug 20, 2025 at 05:34:49PM +0800, Xiangxu Yin wrote:
>> Refactor reset and regulator configuration to be managed via qmp_phy_cfg
>> instead of hardcoded lists. This enables per-PHY customization and
>> simplifies initialization logic for USB-only and USB/DP switchable PHYs.
> Please split into two patches in order to simplify reviewing.


Ok, will split reset and regulator part.


>> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
>> ---
>>  drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 108 +++++++++++++++----------------
>>  1 file changed, 53 insertions(+), 55 deletions(-)
>>
>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
>> index 61128d606238321d1b573655b3b987226aa2d594..4e797b7e65da0e3a827efa9a179f1c150c1b8b00 100644
>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
>> @@ -421,8 +421,9 @@ struct qmp_phy_cfg {
>>  	int (*configure_dp_phy)(struct qmp_usbc *qmp);
>>  	int (*calibrate_dp_phy)(struct qmp_usbc *qmp);
>>  
>> -	/* regulators to be requested */
>> -	const char * const *vreg_list;
>> +	const char * const *reset_list;
>> +	int num_resets;
>> +	const struct regulator_bulk_data *vreg_list;
>>  	int num_vregs;
>>  
>>  	/* array of registers with different offsets */
>> @@ -453,7 +454,6 @@ struct qmp_usbc {
>>  	struct clk_hw dp_pixel_hw;
>>  	struct clk_bulk_data *clks;
>>  	int num_clks;
>> -	int num_resets;
>>  	struct reset_control_bulk_data *resets;
>>  	struct regulator_bulk_data *vregs;
>>  
>> @@ -514,9 +514,18 @@ static const char * const usb3phy_reset_l[] = {
>>  	"phy_phy", "phy",
>>  };
>>  
>> -/* list of regulators */
>> -static const char * const qmp_phy_vreg_l[] = {
>> -	"vdda-phy", "vdda-pll",
>> +static const char * const usb3dpphy_reset_l[] = {
>> +	"phy_phy", "dp_phy",
>> +};
>> +
>> +static const struct regulator_bulk_data qmp_phy_usb_vreg_l[] = {
>> +	{ .supply = "vdda-phy" },
>> +	{ .supply = "vdda-pll" },
> Please fill in the values for all platforms. It well might be that they
> all share the same current requirements.


I checked previous DP projects and found all platforms configured vdda-phy with 21.8mA and vdda-pll with 36mA.

However, I didn?t find USB load configs in downstream and from SoC related power grids:
QCS615
L12A: VDDA_USB0_SS_1P8/VDDA_USB1_SS_1P8 Ipk:20ma
L5A: VDDA_USB0_SS_0P9/VDDA_USB1_SS_0P9 Ipk:50mA

sm6150
L11A: VDDA_USB0_SS_1P8/VDDA_USB1_SS_1P8 Ipk:20ma
L4A: VDDA_USB0_SS_0P9/VDDA_USB1_SS_0P9 Ipk:50mA

SM6115
L12A: VDDA_USB_SS_DP_1P8 Ipk:13.3mA
L4A: VDDA_USB_SS_DP_CORE Ipk:66.1mA

QCM2290
L13A: VDDA_USB_SS_DP_1P8 Ipk:13.3mA
L12A: VDDA_USB_SS_DP_CORE Ipk:66.1mA

sdm660
LDO10A: VDDA_USB_SS_1P8 Ipk:14mA
LDO1B: VDDA_USB_SS_CORE Ipk:68.6mA

msm8998
L2A: VDDA_USB_SS_1P2 Ipk:14.2mA
L1A: VDDA_USB_SS_CORE Ipk:68.6mA

It seems the USB power requirements vary across platforms, and the 21800 ?A load for vdda-phy exceeds the Ipk range in most cases.
I also tested removing the load settings for USB+DP PHY, and DP still works fine.
So, can we keep the regulator config as original qmp_phy_vreg_l?
static const char * const qmp_phy_vreg_l[] = { "vdda-phy", "vdda-pll"}?


>> +};
>> +
>> +static const struct regulator_bulk_data qmp_phy_usbdp_vreg_l[] = {
>> +	{ .supply = "vdda-phy", .init_load_uA = 21800 },
>> +	{ .supply = "vdda-phy", .init_load_uA = 36000 },
> Typo


Sorry for Typo, will fix in next patch.


>>  };
>>  
>>  static const struct qmp_usbc_offsets qmp_usbc_offsets_v3_qcm2290 = {
>> @@ -569,8 +578,10 @@ static const struct qmp_phy_cfg msm8998_usb3phy_cfg = {
>>  	.rx_tbl_num             = ARRAY_SIZE(msm8998_usb3_rx_tbl),
>>  	.pcs_tbl                = msm8998_usb3_pcs_tbl,
>>  	.pcs_tbl_num            = ARRAY_SIZE(msm8998_usb3_pcs_tbl),
>> -	.vreg_list              = qmp_phy_vreg_l,
>> -	.num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
>> +	.reset_list		= usb3phy_reset_l,
>> +	.num_resets		= ARRAY_SIZE(usb3phy_reset_l),
>> +	.vreg_list              = qmp_phy_usb_vreg_l,
>> +	.num_vregs              = ARRAY_SIZE(qmp_phy_usb_vreg_l),
>>  	.regs                   = qmp_v3_usb3phy_regs_layout,
>>  };
>>  
>> @@ -586,8 +597,10 @@ static const struct qmp_phy_cfg qcm2290_usb3phy_cfg = {
>>  	.rx_tbl_num		= ARRAY_SIZE(qcm2290_usb3_rx_tbl),
>>  	.pcs_tbl		= qcm2290_usb3_pcs_tbl,
>>  	.pcs_tbl_num		= ARRAY_SIZE(qcm2290_usb3_pcs_tbl),
>> -	.vreg_list		= qmp_phy_vreg_l,
>> -	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
>> +	.reset_list		= usb3phy_reset_l,
>> +	.num_resets		= ARRAY_SIZE(usb3phy_reset_l),
>> +	.vreg_list		= qmp_phy_usb_vreg_l,
>> +	.num_vregs		= ARRAY_SIZE(qmp_phy_usb_vreg_l),
>>  	.regs			= qmp_v3_usb3phy_regs_layout_qcm2290,
>>  };
>>  
>> @@ -603,8 +616,10 @@ static const struct qmp_phy_cfg sdm660_usb3phy_cfg = {
>>  	.rx_tbl_num		= ARRAY_SIZE(sdm660_usb3_rx_tbl),
>>  	.pcs_tbl		= qcm2290_usb3_pcs_tbl,
>>  	.pcs_tbl_num		= ARRAY_SIZE(qcm2290_usb3_pcs_tbl),
>> -	.vreg_list		= qmp_phy_vreg_l,
>> -	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
>> +	.reset_list		= usb3phy_reset_l,
>> +	.num_resets		= ARRAY_SIZE(usb3phy_reset_l),
>> +	.vreg_list		= qmp_phy_usb_vreg_l,
>> +	.num_vregs		= ARRAY_SIZE(qmp_phy_usb_vreg_l),
>>  	.regs			= qmp_v3_usb3phy_regs_layout_qcm2290,
>>  };
>>  
>> @@ -637,6 +652,11 @@ static const struct qmp_phy_cfg qcs615_usb3dp_phy_cfg = {
>>  
>>  	.swing_tbl		= &qmp_dp_voltage_swing_hbr2_rbr,
>>  	.pre_emphasis_tbl	= &qmp_dp_pre_emphasis_hbr2_rbr,
>> +
>> +	.reset_list		= usb3dpphy_reset_l,
>> +	.num_resets		= ARRAY_SIZE(usb3dpphy_reset_l),
>> +	.vreg_list		= qmp_phy_usbdp_vreg_l,
>> +	.num_vregs		= ARRAY_SIZE(qmp_phy_usbdp_vreg_l),
>>  };
>>  
>>  static int qmp_usbc_com_init(struct phy *phy)
>> @@ -653,13 +673,13 @@ static int qmp_usbc_com_init(struct phy *phy)
>>  		return ret;
>>  	}
>>  
>> -	ret = reset_control_bulk_assert(qmp->num_resets, qmp->resets);
>> +	ret = reset_control_bulk_assert(cfg->num_resets, qmp->resets);
>>  	if (ret) {
>>  		dev_err(qmp->dev, "reset assert failed\n");
>>  		goto err_disable_regulators;
>>  	}
>>  
>> -	ret = reset_control_bulk_deassert(qmp->num_resets, qmp->resets);
>> +	ret = reset_control_bulk_deassert(cfg->num_resets, qmp->resets);
>>  	if (ret) {
>>  		dev_err(qmp->dev, "reset deassert failed\n");
>>  		goto err_disable_regulators;
>> @@ -682,7 +702,7 @@ static int qmp_usbc_com_init(struct phy *phy)
>>  	return 0;
>>  
>>  err_assert_reset:
>> -	reset_control_bulk_assert(qmp->num_resets, qmp->resets);
>> +	reset_control_bulk_assert(cfg->num_resets, qmp->resets);
>>  err_disable_regulators:
>>  	regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
>>  
>> @@ -694,7 +714,7 @@ static int qmp_usbc_com_exit(struct phy *phy)
>>  	struct qmp_usbc *qmp = phy_get_drvdata(phy);
>>  	const struct qmp_phy_cfg *cfg = qmp->cfg;
>>  
>> -	reset_control_bulk_assert(qmp->num_resets, qmp->resets);
>> +	reset_control_bulk_assert(cfg->num_resets, qmp->resets);
>>  
>>  	clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks);
>>  
>> @@ -921,42 +941,22 @@ static const struct dev_pm_ops qmp_usbc_pm_ops = {
>>  			   qmp_usbc_runtime_resume, NULL)
>>  };
>>  
>> -static int qmp_usbc_vreg_init(struct qmp_usbc *qmp)
>> +static int qmp_usbc_reset_init(struct qmp_usbc *qmp)
>>  {
>>  	const struct qmp_phy_cfg *cfg = qmp->cfg;
>> -	struct device *dev = qmp->dev;
>> -	int num = cfg->num_vregs;
>> -	int i;
>> -
>> -	qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL);
>> -	if (!qmp->vregs)
>> -		return -ENOMEM;
>> -
>> -	for (i = 0; i < num; i++)
>> -		qmp->vregs[i].supply = cfg->vreg_list[i];
>> -
>> -	return devm_regulator_bulk_get(dev, num, qmp->vregs);
>> -}
>> -
>> -static int qmp_usbc_reset_init(struct qmp_usbc *qmp,
>> -			      const char *const *reset_list,
>> -			      int num_resets)
>> -{
>>  	struct device *dev = qmp->dev;
>>  	int i;
>>  	int ret;
>>  
>> -	qmp->resets = devm_kcalloc(dev, num_resets,
>> +	qmp->resets = devm_kcalloc(dev, cfg->num_resets,
>>  				   sizeof(*qmp->resets), GFP_KERNEL);
>>  	if (!qmp->resets)
>>  		return -ENOMEM;
>>  
>> -	for (i = 0; i < num_resets; i++)
>> -		qmp->resets[i].id = reset_list[i];
>> +	for (i = 0; i < cfg->num_resets; i++)
>> +		qmp->resets[i].id = cfg->reset_list[i];
>>  
>> -	qmp->num_resets = num_resets;
>> -
>> -	ret = devm_reset_control_bulk_get_exclusive(dev, num_resets, qmp->resets);
>> +	ret = devm_reset_control_bulk_get_exclusive(dev, cfg->num_resets, qmp->resets);
>>  	if (ret)
>>  		return dev_err_probe(dev, ret, "failed to get resets\n");
>>  
>> @@ -1146,11 +1146,6 @@ static int qmp_usbc_parse_usb_dt_legacy(struct qmp_usbc *qmp, struct device_node
>>  
>>  	qmp->num_clks = ret;
>>  
>> -	ret = qmp_usbc_reset_init(qmp, usb3phy_legacy_reset_l,
>> -				 ARRAY_SIZE(usb3phy_legacy_reset_l));
>> -	if (ret)
>> -		return ret;
>> -
>>  	return 0;
>>  }
>>  
>> @@ -1187,14 +1182,9 @@ static int qmp_usbc_parse_usb_dt(struct qmp_usbc *qmp)
>>  	qmp->pipe_clk = devm_clk_get(dev, "pipe");
>>  	if (IS_ERR(qmp->pipe_clk)) {
>>  		return dev_err_probe(dev, PTR_ERR(qmp->pipe_clk),
>> -				     "failed to get pipe clock\n");
>> +					"failed to get pipe clock\n");
> unrelated


Ack.


>>  	}
>>  
>> -	ret = qmp_usbc_reset_init(qmp, usb3phy_reset_l,
>> -				 ARRAY_SIZE(usb3phy_reset_l));
>> -	if (ret)
>> -		return ret;
>> -
>>  	return 0;
>>  }
>>  
>> @@ -1228,6 +1218,7 @@ static int qmp_usbc_probe(struct platform_device *pdev)
>>  	struct phy_provider *phy_provider;
>>  	struct device_node *np;
>>  	struct qmp_usbc *qmp;
>> +	const struct qmp_phy_cfg *cfg;
>>  	int ret;
>>  
>>  	qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL);
>> @@ -1239,13 +1230,20 @@ static int qmp_usbc_probe(struct platform_device *pdev)
>>  
>>  	qmp->orientation = TYPEC_ORIENTATION_NORMAL;
>>  
>> -	qmp->cfg = of_device_get_match_data(dev);
>> -	if (!qmp->cfg)
>> +	cfg = of_device_get_match_data(dev);
>> +	if (!cfg)
>>  		return -EINVAL;
>>  
>> +	qmp->cfg = cfg;
> Why? This doesn't seem related at all.


I added the?|cfg|?variable to simplify access to?|num_vregs|?and?|vreg_list|?in the following lines,?

avoiding repeated?|qmp->cfg->...|?usage.?

If this is considered unrelated, I?ll remove it in the next version.


>
>> +
>>  	mutex_init(&qmp->phy_mutex);
>>  
>> -	ret = qmp_usbc_vreg_init(qmp);
>> +	ret = qmp_usbc_reset_init(qmp);
>> +	if (ret)
>> +		return ret;
>> +
>> +	ret = devm_regulator_bulk_get_const(qmp->dev, cfg->num_vregs,
>> +					 cfg->vreg_list, &qmp->vregs);
>>  	if (ret)
>>  		return ret;
>>  
>>
>> -- 
>> 2.34.1
>>


From mani at kernel.org  Fri Aug 22 01:40:29 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Fri, 22 Aug 2025 14:10:29 +0530
Subject: [PATCH V3 1/2] phy: qcom-qmp-ufs: Add regulator load voting for
 UFS QMP PHY
In-Reply-To: <20250819222832.8471-2-quic_nitirawa@quicinc.com>
References: <20250819222832.8471-1-quic_nitirawa@quicinc.com>
 <20250819222832.8471-2-quic_nitirawa@quicinc.com>
Message-ID: <iak5s5ligdmq3ru4fkvh5a3si6nxadwouboltxxyce4x7t3l6o@eyhh7khzij7v>

On Wed, Aug 20, 2025 at 03:58:25AM GMT, Nitin Rawat wrote:
> On certain SoCs, power regulators are shared between the QMP UFS PHY
> and other IP blocks. To ensure proper operation, the regulator
> framework must be informed of the UFS PHY's load requirements.
> This is essential because the regulator's operating mode?whether Low
> Power or High Power?depends on the maximum expected load at any given
> time, which the regulator driver needs to manage accordingly.
> 
> To support this, replace devm_regulator_bulk_get() with
> devm_regulator_bulk_get_const() and inline the qmp_ufs_vreg_init()
> function.

Use of 'inline' is confusing. Please reword it to sound like you are just
getting rid of this function in favor of devm_regulator_bulk_get_const().

> additionally replace the array of regulator names with a
> bulk regulator data structure, and utilize the init_load_uA field
> provided by the regulator framework. This ensures that
> regulator_set_load() is automatically invoked before the
> first enable operation.
> 
> Signed-off-by: Nitin Rawat <quic_nitirawa at quicinc.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 29 +++++++------------------
>  1 file changed, 8 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> index 9c69c77d10c8..aaa88ca0ef07 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> @@ -1107,7 +1107,7 @@ struct qmp_phy_cfg {
>  	const struct qmp_phy_cfg_tbls tbls_hs_overlay[NUM_OVERLAY];
> 
>  	/* regulators to be requested */
> -	const char * const *vreg_list;
> +	const struct regulator_bulk_data *vreg_list;
>  	int num_vregs;
> 
>  	/* array of registers with different offsets */
> @@ -1164,9 +1164,10 @@ static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
>  	readl(base + offset);
>  }
> 
> -/* list of regulators */
> -static const char * const qmp_phy_vreg_l[] = {
> -	"vdda-phy", "vdda-pll",
> +/* Default regulator bulk data (no load used) */
> +static const struct regulator_bulk_data qmp_phy_vreg_l[] = {
> +	{ .supply = "vdda-phy" },
> +	{ .supply = "vdda-pll" },
>  };
> 
>  static const struct qmp_ufs_offsets qmp_ufs_offsets = {
> @@ -1890,22 +1891,6 @@ static const struct phy_ops qcom_qmp_ufs_phy_ops = {
>  	.owner		= THIS_MODULE,
>  };
> 
> -static int qmp_ufs_vreg_init(struct qmp_ufs *qmp)
> -{
> -	const struct qmp_phy_cfg *cfg = qmp->cfg;
> -	struct device *dev = qmp->dev;
> -	int num = cfg->num_vregs;
> -	int i;
> -
> -	qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL);
> -	if (!qmp->vregs)
> -		return -ENOMEM;
> -
> -	for (i = 0; i < num; i++)
> -		qmp->vregs[i].supply = cfg->vreg_list[i];
> -
> -	return devm_regulator_bulk_get(dev, num, qmp->vregs);
> -}
> 

Stray new line.

With above changes,

Reviewed-by: Manivannan Sadhasivam <mani at kernel.org>

- Mani

-- 
????????? ????????


From xiangxu.yin at oss.qualcomm.com  Fri Aug 22 01:43:11 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Fri, 22 Aug 2025 16:43:11 +0800
Subject: [PATCH v3 08/14] phy: qcom: qmp-usbc: Add DP PHY configuration
 support for QCS615
In-Reply-To: <su3zkeepxaislh6q5ftqxp6uxsyg7usxmc5hkafw7yn2mgtqeu@wua72odmy7zp>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-8-a43bd25ec39c@oss.qualcomm.com>
 <su3zkeepxaislh6q5ftqxp6uxsyg7usxmc5hkafw7yn2mgtqeu@wua72odmy7zp>
Message-ID: <2e3c1559-7da2-4c6e-bcef-eb1e8dfd4c31@oss.qualcomm.com>


On 8/20/2025 7:16 PM, Dmitry Baryshkov wrote:
> On Wed, Aug 20, 2025 at 05:34:50PM +0800, Xiangxu Yin wrote:
>> Introduce DisplayPort PHY configuration routines for QCS615, including
>> aux channel setup, lane control, voltage swing tuning, clock
>> programming and calibration. These callbacks are registered via
>> qmp_phy_cfg to enable DP mode on USB/DP switchable Type-C PHYs.
>>
>> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
>> ---
>>  drivers/phy/qualcomm/phy-qcom-qmp-dp-phy.h |   1 +
>>  drivers/phy/qualcomm/phy-qcom-qmp-usbc.c   | 251 +++++++++++++++++++++++++++++
>>  2 files changed, 252 insertions(+)
>>
>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy.h b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy.h
>> index 0ebd405bcaf0cac8215550bfc9b226f30cc43a59..59885616405f878885d0837838a0bac1899fb69f 100644
>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy.h
>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy.h
>> @@ -25,6 +25,7 @@
>>  #define QSERDES_DP_PHY_AUX_CFG7				0x03c
>>  #define QSERDES_DP_PHY_AUX_CFG8				0x040
>>  #define QSERDES_DP_PHY_AUX_CFG9				0x044
>> +#define QSERDES_DP_PHY_VCO_DIV				0x068
> This register changes between PHY versions, so you can not declare it here.
>
> Otherwise LGTM.


Ok.

This PHY appears to be QMP_DP_PHY_V2,?but there's no dedicated header for it yet.?

I?ll create?|phy-qcom-qmp-dp-phy-v2.h|?next patch and define?|VCO_DIV|?and shared offsets with V3 will be redefined accordingly.


>
>>  
>>  /* QSERDES COM_BIAS_EN_CLKBUFLR_EN bits */
>>  # define QSERDES_V3_COM_BIAS_EN				0x0001


From mani at kernel.org  Fri Aug 22 01:51:09 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Fri, 22 Aug 2025 14:21:09 +0530
Subject: [PATCH V3 2/2] phy: qcom-qmp-ufs: Add regulator loads for SM8650
 and SM8750
In-Reply-To: <20250819222832.8471-3-quic_nitirawa@quicinc.com>
References: <20250819222832.8471-1-quic_nitirawa@quicinc.com>
 <20250819222832.8471-3-quic_nitirawa@quicinc.com>
Message-ID: <gvfcg5wuzti6ns337onsg6si6sp3walpy3rniouxlxuf5huthm@uay2wzbyq3wt>

On Wed, Aug 20, 2025 at 03:58:26AM GMT, Nitin Rawat wrote:
> Add regulator load voting support for SM8650 and SM8750 platforms by
> introducing dedicated regulator bulk data arrays with their load
> values.
> 
> The load requirements are:
> - SM8650: vdda-phy (205mA), vdda-pll (17.5mA)
> - SM8750: vdda-phy (213mA), vdda-pll (18.3mA)
> 
> This ensures stable operation and proper power management for these
> platforms where regulators are shared between the QMP USB PHY and
> other IP blocks by setting appropriate regulator load currents during PHY
> operations.
> 

So it is fixing stability issues on these platforms. Hence, 'Fixes' tag pointing
to the commits that added these platform support should be added.

> Configurations without specific load requirements will continue to work
> unchanged, as init_load_uA remains zero-initialized when .init_load_uA
> is not provided.
> 
> Signed-off-by: Nitin Rawat <quic_nitirawa at quicinc.com>

Reviewed-by: Manivannan Sadhasivam <mani at kernel.org>

- Mani

> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 19 +++++++++++++++----
>  1 file changed, 15 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> index aaa88ca0ef07..1c3ce0fa6adf 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> @@ -1170,6 +1170,17 @@ static const struct regulator_bulk_data qmp_phy_vreg_l[] = {
>  	{ .supply = "vdda-pll" },
>  };
> 
> +/* Regulator bulk data with load values for specific configurations */
> +static const struct regulator_bulk_data sm8650_ufsphy_vreg_l[] = {
> +	{ .supply = "vdda-phy", .init_load_uA = 205000 },
> +	{ .supply = "vdda-pll", .init_load_uA = 17500 },
> +};
> +
> +static const struct regulator_bulk_data sm8750_ufsphy_vreg_l[] = {
> +	{ .supply = "vdda-phy", .init_load_uA = 213000 },
> +	{ .supply = "vdda-pll", .init_load_uA = 18300 },
> +};
> +
>  static const struct qmp_ufs_offsets qmp_ufs_offsets = {
>  	.serdes		= 0,
>  	.pcs		= 0xc00,
> @@ -1638,8 +1649,8 @@ static const struct qmp_phy_cfg sm8650_ufsphy_cfg = {
>  		.max_gear	= UFS_HS_G5,
>  	},
> 
> -	.vreg_list		= qmp_phy_vreg_l,
> -	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
> +	.vreg_list		= sm8650_ufsphy_vreg_l,
> +	.num_vregs		= ARRAY_SIZE(sm8650_ufsphy_vreg_l),
>  	.regs			= ufsphy_v6_regs_layout,
>  };
> 
> @@ -1676,8 +1687,8 @@ static const struct qmp_phy_cfg sm8750_ufsphy_cfg = {
>  		.max_gear	= UFS_HS_G5,
>  	},
> 
> -	.vreg_list		= qmp_phy_vreg_l,
> -	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
> +	.vreg_list		= sm8750_ufsphy_vreg_l,
> +	.num_vregs		= ARRAY_SIZE(sm8750_ufsphy_vreg_l),
>  	.regs			= ufsphy_v6_regs_layout,
> 
>  };
> --
> 2.48.1
> 

-- 
????????? ????????


From mani at kernel.org  Fri Aug 22 01:53:57 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Fri, 22 Aug 2025 14:23:57 +0530
Subject: [PATCH V3 2/2] phy: qcom-qmp-ufs: Add regulator loads for SM8650
 and SM8750
In-Reply-To: <ger4kizeltjwalfuwu4dpfjiskrv2okgo5c7d6n3pb24yaxgfo@nkcndblyx3il>
References: <20250819222832.8471-1-quic_nitirawa@quicinc.com>
 <20250819222832.8471-3-quic_nitirawa@quicinc.com>
 <ger4kizeltjwalfuwu4dpfjiskrv2okgo5c7d6n3pb24yaxgfo@nkcndblyx3il>
Message-ID: <xir3u3hlmcvfu6uasijz6g2oialoasmuu4bno6ctxpscqcebz6@6kw6xpm5bxbd>

On Wed, Aug 20, 2025 at 03:49:31AM GMT, Dmitry Baryshkov wrote:
> On Wed, Aug 20, 2025 at 03:58:26AM +0530, Nitin Rawat wrote:
> > Add regulator load voting support for SM8650 and SM8750 platforms by
> > introducing dedicated regulator bulk data arrays with their load
> > values.
> > 
> > The load requirements are:
> > - SM8650: vdda-phy (205mA), vdda-pll (17.5mA)
> > - SM8750: vdda-phy (213mA), vdda-pll (18.3mA)
> > 
> > This ensures stable operation and proper power management for these
> > platforms where regulators are shared between the QMP USB PHY and
> > other IP blocks by setting appropriate regulator load currents during PHY
> > operations.
> > 
> > Configurations without specific load requirements will continue to work
> > unchanged, as init_load_uA remains zero-initialized when .init_load_uA
> > is not provided.
> 
> Can we please get configuration for the rest of the platforms?
> 

Only if the rest of the platforms require setting the load... It is not very
clear if the older platforms share the regulators with other IPs or not.

- Mani

> > 
> > Signed-off-by: Nitin Rawat <quic_nitirawa at quicinc.com>
> > ---
> >  drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 19 +++++++++++++++----
> >  1 file changed, 15 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > index aaa88ca0ef07..1c3ce0fa6adf 100644
> > --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > @@ -1170,6 +1170,17 @@ static const struct regulator_bulk_data qmp_phy_vreg_l[] = {
> >  	{ .supply = "vdda-pll" },
> >  };
> > 
> > +/* Regulator bulk data with load values for specific configurations */
> > +static const struct regulator_bulk_data sm8650_ufsphy_vreg_l[] = {
> > +	{ .supply = "vdda-phy", .init_load_uA = 205000 },
> > +	{ .supply = "vdda-pll", .init_load_uA = 17500 },
> > +};
> > +
> > +static const struct regulator_bulk_data sm8750_ufsphy_vreg_l[] = {
> > +	{ .supply = "vdda-phy", .init_load_uA = 213000 },
> > +	{ .supply = "vdda-pll", .init_load_uA = 18300 },
> > +};
> > +
> >  static const struct qmp_ufs_offsets qmp_ufs_offsets = {
> >  	.serdes		= 0,
> >  	.pcs		= 0xc00,
> > @@ -1638,8 +1649,8 @@ static const struct qmp_phy_cfg sm8650_ufsphy_cfg = {
> >  		.max_gear	= UFS_HS_G5,
> >  	},
> > 
> > -	.vreg_list		= qmp_phy_vreg_l,
> > -	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
> > +	.vreg_list		= sm8650_ufsphy_vreg_l,
> > +	.num_vregs		= ARRAY_SIZE(sm8650_ufsphy_vreg_l),
> >  	.regs			= ufsphy_v6_regs_layout,
> >  };
> > 
> > @@ -1676,8 +1687,8 @@ static const struct qmp_phy_cfg sm8750_ufsphy_cfg = {
> >  		.max_gear	= UFS_HS_G5,
> >  	},
> > 
> > -	.vreg_list		= qmp_phy_vreg_l,
> > -	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
> > +	.vreg_list		= sm8750_ufsphy_vreg_l,
> > +	.num_vregs		= ARRAY_SIZE(sm8750_ufsphy_vreg_l),
> >  	.regs			= ufsphy_v6_regs_layout,
> > 
> >  };
> > --
> > 2.48.1
> > 
> 
> -- 
> With best wishes
> Dmitry

-- 
????????? ????????


From dmitry.baryshkov at oss.qualcomm.com  Fri Aug 22 02:05:15 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Fri, 22 Aug 2025 12:05:15 +0300
Subject: [PATCH v3 05/14] phy: qcom: qmp-usbc: Add DP-related fields for
 USB/DP switchable PHY
In-Reply-To: <8922ae6e-9be6-49f7-ac84-d4a1dd60421b@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-5-a43bd25ec39c@oss.qualcomm.com>
 <7b6utbnibia767bp55vhvg6ghdavb66ubdpabyguohuwtmz3mp@unvm36jttota>
 <8922ae6e-9be6-49f7-ac84-d4a1dd60421b@oss.qualcomm.com>
Message-ID: <d4e1f836-afbb-4cc7-a5fd-fa961e3203ec@oss.qualcomm.com>

On 22/08/2025 09:59, Xiangxu Yin wrote:
> 
> On 8/20/2025 7:47 PM, Dmitry Baryshkov wrote:
>> On Wed, Aug 20, 2025 at 05:34:47PM +0800, Xiangxu Yin wrote:
>>> Extend qmp_usbc_offsets and qmp_phy_cfg with DP-specific fields,
>>> including register offsets, init tables, and callback hooks. Also
>>> update qmp_usbc struct to track DP-related resources and state.
>>> This enables support for USB/DP switchable Type-C PHYs that operate
>>> in either mode.
>>>
>>> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
>>> ---
>>>   drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 73 ++++++++++++++++++++++++--------
>>>   1 file changed, 55 insertions(+), 18 deletions(-)
>>>
>>>   
>>> +	struct regmap *tcsr_map;
>>> +	u32 vls_clamp_reg;
>>> +	u32 dp_phy_mode_reg;
>>> +
>>>   	struct mutex phy_mutex;
>>>   
>>> +	struct phy *usb_phy;
>> Should be a part of the previous patch.
> 
> 
> Ok, will move usb_phy rename to patch 'Rename USB-specific ops',
> 
> then shall I need drop?the?|Reviewed-by|?tag in that patch since it will change?

Depends on the amount of changes.

-- 
With best wishes
Dmitry


From dmitry.baryshkov at oss.qualcomm.com  Fri Aug 22 02:15:54 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Fri, 22 Aug 2025 12:15:54 +0300
Subject: [PATCH V3 2/2] phy: qcom-qmp-ufs: Add regulator loads for SM8650
 and SM8750
In-Reply-To: <xir3u3hlmcvfu6uasijz6g2oialoasmuu4bno6ctxpscqcebz6@6kw6xpm5bxbd>
References: <20250819222832.8471-1-quic_nitirawa@quicinc.com>
 <20250819222832.8471-3-quic_nitirawa@quicinc.com>
 <ger4kizeltjwalfuwu4dpfjiskrv2okgo5c7d6n3pb24yaxgfo@nkcndblyx3il>
 <xir3u3hlmcvfu6uasijz6g2oialoasmuu4bno6ctxpscqcebz6@6kw6xpm5bxbd>
Message-ID: <761c97bb-ee90-4ace-acd3-08349831aade@oss.qualcomm.com>

On 22/08/2025 11:53, Manivannan Sadhasivam wrote:
> On Wed, Aug 20, 2025 at 03:49:31AM GMT, Dmitry Baryshkov wrote:
>> On Wed, Aug 20, 2025 at 03:58:26AM +0530, Nitin Rawat wrote:
>>> Add regulator load voting support for SM8650 and SM8750 platforms by
>>> introducing dedicated regulator bulk data arrays with their load
>>> values.
>>>
>>> The load requirements are:
>>> - SM8650: vdda-phy (205mA), vdda-pll (17.5mA)
>>> - SM8750: vdda-phy (213mA), vdda-pll (18.3mA)
>>>
>>> This ensures stable operation and proper power management for these
>>> platforms where regulators are shared between the QMP USB PHY and
>>> other IP blocks by setting appropriate regulator load currents during PHY
>>> operations.
>>>
>>> Configurations without specific load requirements will continue to work
>>> unchanged, as init_load_uA remains zero-initialized when .init_load_uA
>>> is not provided.
>>
>> Can we please get configuration for the rest of the platforms?
>>
> 
> Only if the rest of the platforms require setting the load... It is not very
> clear if the older platforms share the regulators with other IPs or not.

Yes, they are usually shared. USB. PCIe and DSI frequently sit on the 
same voltage rails.


-- 
With best wishes
Dmitry


From dmitry.baryshkov at oss.qualcomm.com  Fri Aug 22 02:19:11 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Fri, 22 Aug 2025 12:19:11 +0300
Subject: [PATCH V3 2/2] phy: qcom-qmp-ufs: Add regulator loads for SM8650
 and SM8750
In-Reply-To: <9a38ec05-f7ab-4241-ba47-0d514b79e808@quicinc.com>
References: <20250819222832.8471-1-quic_nitirawa@quicinc.com>
 <20250819222832.8471-3-quic_nitirawa@quicinc.com>
 <ger4kizeltjwalfuwu4dpfjiskrv2okgo5c7d6n3pb24yaxgfo@nkcndblyx3il>
 <b453b8ff-a460-4ccd-9019-aed746a7d52d@quicinc.com>
 <ukxv7donvkulgci2dwrokuflzxzeyh4kohoyja2vywropntxnb@qepcssbe4wpc>
 <9a38ec05-f7ab-4241-ba47-0d514b79e808@quicinc.com>
Message-ID: <8aa65fdc-d5a1-4a81-bcc1-8d953fa0ffa8@oss.qualcomm.com>

On 21/08/2025 19:02, Nitin Rawat wrote:
> 
> 
> On 8/20/2025 5:24 PM, Dmitry Baryshkov wrote:
>> On Wed, Aug 20, 2025 at 12:07:57PM +0530, Nitin Rawat wrote:
>>>
>>>
>>> On 8/20/2025 6:19 AM, Dmitry Baryshkov wrote:
>>>> On Wed, Aug 20, 2025 at 03:58:26AM +0530, Nitin Rawat wrote:
>>>>> Add regulator load voting support for SM8650 and SM8750 platforms by
>>>>> introducing dedicated regulator bulk data arrays with their load
>>>>> values.
>>>>>
>>>>> The load requirements are:
>>>>> - SM8650: vdda-phy (205mA), vdda-pll (17.5mA)
>>>>> - SM8750: vdda-phy (213mA), vdda-pll (18.3mA)
>>>>>
>>>>> This ensures stable operation and proper power management for these
>>>>> platforms where regulators are shared between the QMP USB PHY and
>>>>> other IP blocks by setting appropriate regulator load currents 
>>>>> during PHY
>>>>> operations.
>>>>>
>>>>> Configurations without specific load requirements will continue to 
>>>>> work
>>>>> unchanged, as init_load_uA remains zero-initialized when .init_load_uA
>>>>> is not provided.
>>>>
>>>> Can we please get configuration for the rest of the platforms?
>>>
>>> Hi Dmitry,
>>>
>>> If you're okay with it, can I merge the configuration for the remaining
>>> platforms in the next patch series after I complete testing on all 
>>> remaining
>>> platforms.
>>
>> You don't need to test, finding MSM8996 or 98 might be troublesome. Just
>> fill in the values from the hardware documentation.
> 
> Hi Dmitry,
> 
> While implementing changes for all remaining platform, I noticed that 
> the "regulator-allow-set-load" property is defined only for SM8750 and 
> SM8850 within the PMIC PHY and PLL device tree nodes which means that 
> even if the UFS PHY driver is updated to vote for this configuration on 
> other platforms, it will have no impact.

If I remember correctly, on other platforms we don't allow setting the 
load exactly because consumers were not voting on the current/power 
requirements.

> 
> Should I still proceed with applying the change across all platform, or 
> limit it to just the SM8750 and SM8850 drivers? What?s your recommendation?

I think, we should proceed, then once all PHYs get those votes we can 
enable load toggling on those platforms too.

> 
> ===========================================================================
> // Device tree:
> vreg_l1j_0p91: ldo1 {
>  ??? regulator-name = "vreg_l1j_0p91";
>  ??? regulator-min-microvolt = <880000>;
>  ??? regulator-max-microvolt = <920000>;
>  ??? regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
>  ??? regulator-allow-set-load;
>  ??? regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM 
> RPMH_REGULATOR_MODE_HPM>;
> };
> 
> ===========================================================================
> drivers/regulator/of_regulator.c
> 
> 
> if (of_property_read_bool(np, "regulator-allow-set-load"))
>  ??????? constraints->valid_ops_mask |= REGULATOR_CHANGE_DRMS;
> 
> ===========================================================================
> //drivers/regulator/core.c
> static int drms_uA_update(struct regulator_dev *rdev)
> {
>  ??? ...
>  ??? if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_DRMS)) {
>  ??????? rdev_dbg(rdev, "DRMS operation not allowed\n");
>  ??????? return 0;
>  ??? }
>  ??? ...
> }
> 
> 
> Regards,
> Nitin
> 
> 
> 
> 
>>
> 


-- 
With best wishes
Dmitry


From devnull+maudspierings.gocontroll.com at kernel.org  Fri Aug 22 02:20:04 2025
From: devnull+maudspierings.gocontroll.com at kernel.org (Maud Spierings via B4 Relay)
Date: Fri, 22 Aug 2025 11:20:04 +0200
Subject: [PATCH 0/2] dt-bindings: phy: ti,tcan104x-can: Document TI
 TCAN1051
Message-ID: <20250822-can_phy3-v1-0-73b3ba1690ee@gocontroll.com>

The Moduline Display mainboard contains 2 TI TCAN1051 CAN transceivers,
properly document these and add them to the devicetree.

Thank Peng Fan for inspiring this patch series.

Signed-off-by: Maud Spierings <maudspierings at gocontroll.com>
---
Maud Spierings (2):
      dt-bindings: phy: ti,tcan104x-can: Document TI TCAN1051
      arm64: dts: freescale: imx8mp-moduline-display-106: Use phys to replace xceiver-supply

 .../devicetree/bindings/phy/ti,tcan104x-can.yaml   |  1 +
 .../imx8mp-tx8p-ml81-moduline-display-106.dts      | 46 +++++++++++-----------
 2 files changed, 23 insertions(+), 24 deletions(-)
---
base-commit: 0f4c93f7eb861acab537dbe94441817a270537bf
change-id: 20250822-can_phy3-542f5144c9e5

Best regards,
-- 
Maud Spierings <maudspierings at gocontroll.com>




From devnull+maudspierings.gocontroll.com at kernel.org  Fri Aug 22 02:20:05 2025
From: devnull+maudspierings.gocontroll.com at kernel.org (Maud Spierings via B4 Relay)
Date: Fri, 22 Aug 2025 11:20:05 +0200
Subject: [PATCH 1/2] dt-bindings: phy: ti,tcan104x-can: Document TI
 TCAN1051
In-Reply-To: <20250822-can_phy3-v1-0-73b3ba1690ee@gocontroll.com>
References: <20250822-can_phy3-v1-0-73b3ba1690ee@gocontroll.com>
Message-ID: <20250822-can_phy3-v1-1-73b3ba1690ee@gocontroll.com>

From: Maud Spierings <maudspierings at gocontroll.com>

TCAN1051-Q1 Automotive Fault Protected CAN Transceiver with CAN FD

It is pretty much identical to the TCAN1042, add the compatible with
fallback on the TCAN1042.

Signed-off-by: Maud Spierings <maudspierings at gocontroll.com>
---
 Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml b/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
index 4a8c3829d85d3c4a4963750d03567c1c345beb91..138923ffedfeeb6a0b391cae863723ec70bf2c88 100644
--- a/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
+++ b/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
@@ -18,6 +18,7 @@ properties:
       - items:
           - enum:
               - microchip,ata6561
+              - ti,tcan1051
           - const: ti,tcan1042
       - enum:
           - ti,tcan1042

-- 
2.50.1




From devnull+maudspierings.gocontroll.com at kernel.org  Fri Aug 22 02:20:06 2025
From: devnull+maudspierings.gocontroll.com at kernel.org (Maud Spierings via B4 Relay)
Date: Fri, 22 Aug 2025 11:20:06 +0200
Subject: [PATCH 2/2] arm64: dts: freescale: imx8mp-moduline-display-106:
 Use phys to replace xceiver-supply
In-Reply-To: <20250822-can_phy3-v1-0-73b3ba1690ee@gocontroll.com>
References: <20250822-can_phy3-v1-0-73b3ba1690ee@gocontroll.com>
Message-ID: <20250822-can_phy3-v1-2-73b3ba1690ee@gocontroll.com>

From: Maud Spierings <maudspierings at gocontroll.com>

Fix the can tranceivers to actually use the new phy description instead
of the regulator tweak.

Signed-off-by: Maud Spierings <maudspierings at gocontroll.com>
---
 .../imx8mp-tx8p-ml81-moduline-display-106.dts      | 46 +++++++++++-----------
 1 file changed, 22 insertions(+), 24 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-tx8p-ml81-moduline-display-106.dts b/arch/arm64/boot/dts/freescale/imx8mp-tx8p-ml81-moduline-display-106.dts
index afd886dd590ff6f125d1d0e91aa71ae0063b5fd1..88ad422c27603b77c1099f2efe61953999c35f77 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-tx8p-ml81-moduline-display-106.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-tx8p-ml81-moduline-display-106.dts
@@ -36,6 +36,24 @@ external-sensor-supply {
 		vout-supply = <&reg_5v0_sensor>;
 	};
 
+	flexcan1_phy: can-phy0 {
+		compatible = "ti,tcan1051", "ti,tcan1042";
+		#phy-cells = <0>;
+		pinctrl-0 = <&pinctrl_flexcan1_stby>;
+		pinctrl-names = "default";
+		max-bitrate = <5000000>;
+		standby-gpios = <&gpio4 3 GPIO_ACTIVE_HIGH>;
+	};
+
+	flexcan2_phy: can-phy1 {
+		compatible = "ti,tcan1051", "ti,tcan1042";
+		#phy-cells = <0>;
+		pinctrl-0 = <&pinctrl_flexcan2_stby>;
+		pinctrl-names = "default";
+		max-bitrate = <5000000>;
+		standby-gpios = <&gpio5 9 GPIO_ACTIVE_HIGH>;
+	};
+
 	reg_1v8_per: regulator-1v8-per {
 		compatible = "regulator-fixed";
 		pinctrl-0 = <&pinctrl_reg_1v8>;
@@ -85,26 +103,6 @@ reg_6v4: regulator-6v4 {
 		regulator-name = "6v4";
 	};
 
-	reg_can1_stby: regulator-can1-stby {
-		compatible = "regulator-fixed";
-		pinctrl-0 = <&pinctrl_flexcan1_reg>;
-		pinctrl-names = "default";
-		regulator-max-microvolt = <3300000>;
-		regulator-min-microvolt = <3300000>;
-		regulator-name = "can1-stby";
-		gpio = <&gpio4 3 GPIO_ACTIVE_LOW>;
-	};
-
-	reg_can2_stby: regulator-can2-stby {
-		compatible = "regulator-fixed";
-		pinctrl-0 = <&pinctrl_flexcan2_reg>;
-		pinctrl-names = "default";
-		regulator-max-microvolt = <3300000>;
-		regulator-min-microvolt = <3300000>;
-		regulator-name = "can2-stby";
-		gpio = <&gpio5 9 GPIO_ACTIVE_LOW>;
-	};
-
 	sound {
 		compatible = "simple-audio-card";
 		simple-audio-card,bitclock-master = <&cpudai>;
@@ -180,16 +178,16 @@ adc at 2 {
 };
 
 &flexcan1 {
+	phys = <&flexcan1_phy>;
 	pinctrl-0 = <&pinctrl_flexcan1>;
 	pinctrl-names = "default";
-	xceiver-supply = <&reg_can1_stby>;
 	status = "okay";
 };
 
 &flexcan2 {
+	phys = <&flexcan2_phy>;
 	pinctrl-0 = <&pinctrl_flexcan2>;
 	pinctrl-names = "default";
-	xceiver-supply = <&reg_can2_stby>;
 	status = "okay";
 };
 
@@ -278,7 +276,7 @@ MX8MP_IOMUXC_SPDIF_TX__CAN1_TX
 		>;
 	};
 
-	pinctrl_flexcan1_reg: flexcan1reggrp {
+	pinctrl_flexcan1_stby: flexcan1stbygrp {
 		fsl,pins = <
 			MX8MP_IOMUXC_SAI1_RXD1__GPIO4_IO03
 				(MX8MP_DSE_X2 | MX8MP_FSEL_FAST | MX8MP_PULL_UP | MX8MP_PULL_ENABLE)
@@ -294,7 +292,7 @@ MX8MP_IOMUXC_UART3_RXD__CAN2_TX
 		>;
 	};
 
-	pinctrl_flexcan2_reg: flexcan2reggrp {
+	pinctrl_flexcan2_stby: flexcan2stbygrp {
 		fsl,pins = <
 			MX8MP_IOMUXC_ECSPI1_SS0__GPIO5_IO09
 				(MX8MP_DSE_X2 | MX8MP_FSEL_FAST | MX8MP_PULL_UP | MX8MP_PULL_ENABLE)

-- 
2.50.1




From quic_nitirawa at quicinc.com  Fri Aug 22 02:23:31 2025
From: quic_nitirawa at quicinc.com (Nitin Rawat)
Date: Fri, 22 Aug 2025 14:53:31 +0530
Subject: [PATCH V3 2/2] phy: qcom-qmp-ufs: Add regulator loads for SM8650
 and SM8750
In-Reply-To: <761c97bb-ee90-4ace-acd3-08349831aade@oss.qualcomm.com>
References: <20250819222832.8471-1-quic_nitirawa@quicinc.com>
 <20250819222832.8471-3-quic_nitirawa@quicinc.com>
 <ger4kizeltjwalfuwu4dpfjiskrv2okgo5c7d6n3pb24yaxgfo@nkcndblyx3il>
 <xir3u3hlmcvfu6uasijz6g2oialoasmuu4bno6ctxpscqcebz6@6kw6xpm5bxbd>
 <761c97bb-ee90-4ace-acd3-08349831aade@oss.qualcomm.com>
Message-ID: <2635ced4-b91f-4c79-ae2a-079f06bbb8a9@quicinc.com>



On 8/22/2025 2:45 PM, Dmitry Baryshkov wrote:
> On 22/08/2025 11:53, Manivannan Sadhasivam wrote:
>> On Wed, Aug 20, 2025 at 03:49:31AM GMT, Dmitry Baryshkov wrote:
>>> On Wed, Aug 20, 2025 at 03:58:26AM +0530, Nitin Rawat wrote:
>>>> Add regulator load voting support for SM8650 and SM8750 platforms by
>>>> introducing dedicated regulator bulk data arrays with their load
>>>> values.
>>>>
>>>> The load requirements are:
>>>> - SM8650: vdda-phy (205mA), vdda-pll (17.5mA)
>>>> - SM8750: vdda-phy (213mA), vdda-pll (18.3mA)
>>>>
>>>> This ensures stable operation and proper power management for these
>>>> platforms where regulators are shared between the QMP USB PHY and
>>>> other IP blocks by setting appropriate regulator load currents 
>>>> during PHY
>>>> operations.
>>>>
>>>> Configurations without specific load requirements will continue to work
>>>> unchanged, as init_load_uA remains zero-initialized when .init_load_uA
>>>> is not provided.
>>>
>>> Can we please get configuration for the rest of the platforms?
>>>
>>
>> Only if the rest of the platforms require setting the load... It is 
>> not very
>> clear if the older platforms share the regulators with other IPs or not.
> 
> Yes, they are usually shared. USB. PCIe and DSI frequently sit on the 
> same voltage rails.

Yes, it?s typically shared across multiple clients.

However, as I mentioned earlier, in the current upstream codebase, the 
"regulator-allow-set-load" property is defined only for SM8750 and 
SM8650 within the PMIC PHY and PLL device tree nodes. This means that 
even if the UFS PHY driver is updated to vote for this configuration on 
other platforms, it will have no effect, as the property is not 
supported there.


> 
> 



From quic_nitirawa at quicinc.com  Fri Aug 22 02:24:52 2025
From: quic_nitirawa at quicinc.com (Nitin Rawat)
Date: Fri, 22 Aug 2025 14:54:52 +0530
Subject: [PATCH V3 2/2] phy: qcom-qmp-ufs: Add regulator loads for SM8650
 and SM8750
In-Reply-To: <8aa65fdc-d5a1-4a81-bcc1-8d953fa0ffa8@oss.qualcomm.com>
References: <20250819222832.8471-1-quic_nitirawa@quicinc.com>
 <20250819222832.8471-3-quic_nitirawa@quicinc.com>
 <ger4kizeltjwalfuwu4dpfjiskrv2okgo5c7d6n3pb24yaxgfo@nkcndblyx3il>
 <b453b8ff-a460-4ccd-9019-aed746a7d52d@quicinc.com>
 <ukxv7donvkulgci2dwrokuflzxzeyh4kohoyja2vywropntxnb@qepcssbe4wpc>
 <9a38ec05-f7ab-4241-ba47-0d514b79e808@quicinc.com>
 <8aa65fdc-d5a1-4a81-bcc1-8d953fa0ffa8@oss.qualcomm.com>
Message-ID: <e42b7bdd-e9a1-47d9-9d97-c4da9e3a553a@quicinc.com>



On 8/22/2025 2:49 PM, Dmitry Baryshkov wrote:
> On 21/08/2025 19:02, Nitin Rawat wrote:
>>
>>
>> On 8/20/2025 5:24 PM, Dmitry Baryshkov wrote:
>>> On Wed, Aug 20, 2025 at 12:07:57PM +0530, Nitin Rawat wrote:
>>>>
>>>>
>>>> On 8/20/2025 6:19 AM, Dmitry Baryshkov wrote:
>>>>> On Wed, Aug 20, 2025 at 03:58:26AM +0530, Nitin Rawat wrote:
>>>>>> Add regulator load voting support for SM8650 and SM8750 platforms by
>>>>>> introducing dedicated regulator bulk data arrays with their load
>>>>>> values.
>>>>>>
>>>>>> The load requirements are:
>>>>>> - SM8650: vdda-phy (205mA), vdda-pll (17.5mA)
>>>>>> - SM8750: vdda-phy (213mA), vdda-pll (18.3mA)
>>>>>>
>>>>>> This ensures stable operation and proper power management for these
>>>>>> platforms where regulators are shared between the QMP USB PHY and
>>>>>> other IP blocks by setting appropriate regulator load currents 
>>>>>> during PHY
>>>>>> operations.
>>>>>>
>>>>>> Configurations without specific load requirements will continue to 
>>>>>> work
>>>>>> unchanged, as init_load_uA remains zero-initialized 
>>>>>> when .init_load_uA
>>>>>> is not provided.
>>>>>
>>>>> Can we please get configuration for the rest of the platforms?
>>>>
>>>> Hi Dmitry,
>>>>
>>>> If you're okay with it, can I merge the configuration for the remaining
>>>> platforms in the next patch series after I complete testing on all 
>>>> remaining
>>>> platforms.
>>>
>>> You don't need to test, finding MSM8996 or 98 might be troublesome. Just
>>> fill in the values from the hardware documentation.
>>
>> Hi Dmitry,
>>
>> While implementing changes for all remaining platform, I noticed that 
>> the "regulator-allow-set-load" property is defined only for SM8750 and 
>> SM8850 within the PMIC PHY and PLL device tree nodes which means that 
>> even if the UFS PHY driver is updated to vote for this configuration 
>> on other platforms, it will have no impact.
> 
> If I remember correctly, on other platforms we don't allow setting the 
> load exactly because consumers were not voting on the current/power 
> requirements.
> 
>>
>> Should I still proceed with applying the change across all platform, 
>> or limit it to just the SM8750 and SM8850 drivers? What?s your 
>> recommendation?
> 
> I think, we should proceed, then once all PHYs get those votes we can 
> enable load toggling on those platforms too.

Sure Dmitry. I'll make the change in next patchset.



> 
>>
>> ===========================================================================
>> // Device tree:
>> vreg_l1j_0p91: ldo1 {
>> ???? regulator-name = "vreg_l1j_0p91";
>> ???? regulator-min-microvolt = <880000>;
>> ???? regulator-max-microvolt = <920000>;
>> ???? regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
>> ???? regulator-allow-set-load;
>> ???? regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM 
>> RPMH_REGULATOR_MODE_HPM>;
>> };
>>
>> ===========================================================================
>> drivers/regulator/of_regulator.c
>>
>>
>> if (of_property_read_bool(np, "regulator-allow-set-load"))
>> ???????? constraints->valid_ops_mask |= REGULATOR_CHANGE_DRMS;
>>
>> ===========================================================================
>> //drivers/regulator/core.c
>> static int drms_uA_update(struct regulator_dev *rdev)
>> {
>> ???? ...
>> ???? if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_DRMS)) {
>> ???????? rdev_dbg(rdev, "DRMS operation not allowed\n");
>> ???????? return 0;
>> ???? }
>> ???? ...
>> }
>>
>>
>> Regards,
>> Nitin
>>
>>
>>
>>
>>>
>>
> 
> 



From pritam.sutar at samsung.com  Fri Aug 22 02:26:32 2025
From: pritam.sutar at samsung.com (Pritam Manohar Sutar)
Date: Fri, 22 Aug 2025 14:56:32 +0530
Subject: [PATCH v6 6/6] phy: exynos5-usbdrd: support SS combo phy for
 ExynosAutov920
In-Reply-To: <202508220553.lm7ExAxG-lkp@intel.com>
References: <20250821073703.2498302-7-pritam.sutar@samsung.com>
	<CGME20250821212909epcas5p3cfcff210863febc2410cf661172be683@epcas5p3.samsung.com>
	<202508220553.lm7ExAxG-lkp@intel.com>
Message-ID: <006f01dc1346$db4edf50$91ec9df0$@samsung.com>

Hi, 

> -----Original Message-----
> From: kernel test robot <lkp at intel.com>
> Sent: 22 August 2025 02:58 AM
> To: Pritam Manohar Sutar <pritam.sutar at samsung.com>; vkoul at kernel.org;
> kishon at kernel.org; robh at kernel.org; krzk+dt at kernel.org;
> conor+dt at kernel.org; alim.akhtar at samsung.com; andre.draszik at linaro.org;
> peter.griffin at linaro.org; kauschluss at disroot.org;
> ivo.ivanov.ivanov1 at gmail.com; igor.belwon at mentallysanemainliners.org;
> johan at kernel.org; m.szyprowski at samsung.com; s.nawrocki at samsung.com
> Cc: oe-kbuild-all at lists.linux.dev; linux-phy at lists.infradead.org;
> devicetree at vger.kernel.org; linux-kernel at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; linux-samsung-soc at vger.kernel.org;
> rosa.pila at samsung.com; dev.tailor at samsung.com;
> faraz.ata at samsung.com; muhammed.ali at samsung.com;
> selvarasu.g at samsung.com
> Subject: Re: [PATCH v6 6/6] phy: exynos5-usbdrd: support SS combo phy for
> ExynosAutov920
> 
> Hi Pritam,
> 
> kernel test robot noticed the following build warnings:
> 
> [auto build test WARNING on robh/for-next] [also build test WARNING on
> krzk/for-next linus/master v6.17-rc2 next-20250821] [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://protect2.fireeye.com/v1/url?k=07116f39-666ac5ae-0710e476-
> 74fe4860001d-17dff89291ad3b5b&q=1&e=45b4f292-bcb1-4614-86a0-
> c790a47fb814&u=https%3A%2F%2Fgithub.com%2Fintel-lab-
> lkp%2Flinux%2Fcommits%2FPritam-Manohar-Sutar%2Fdt-bindings-phy-
> samsung-usb3-drd-phy-add-ExynosAutov920-HS-phy-
> compatible%2F20250821-153122
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git
for-
> next
> patch link:    https://lore.kernel.org/r/20250821073703.2498302-7-
> pritam.sutar%40samsung.com
> patch subject: [PATCH v6 6/6] phy: exynos5-usbdrd: support SS combo phy
> for ExynosAutov920
> config: arc-randconfig-001-20250822 (https://download.01.org/0day-
> ci/archive/20250822/202508220553.lm7ExAxG-lkp at intel.com/config)
> compiler: arc-linux-gcc (GCC) 8.5.0
> reproduce (this is a W=1 build): (https://download.01.org/0day-
> ci/archive/20250822/202508220553.lm7ExAxG-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/202508220553.lm7ExAxG-lkp at intel.
> | com/
> 
> All warnings (new ones prefixed by >>):
> 
>    drivers/phy/samsung/phy-exynos5-usbdrd.c: In function
> 'exynosautov920_usb31drd_cr_write':
> >> drivers/phy/samsung/phy-exynos5-usbdrd.c:2167:17: warning: unused
> >> variable 'dev' [-Wunused-variable]
>      struct device *dev = phy_drd->dev;
>                     ^~~
>    drivers/phy/samsung/phy-exynos5-usbdrd.c: In function
> 'exynosautov920_usb31drd_port_phy_ready':
> >> drivers/phy/samsung/phy-exynos5-usbdrd.c:2137:6: warning: 'reg' is
> >> used uninitialized in this function [-Wuninitialized]
>      reg &= ~(PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK |
>      ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>        PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR);
>        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    during RTL pass: mach
>    drivers/phy/samsung/phy-exynos5-usbdrd.c: In function
> 'exynos5_usbdrd_phy_probe':
>    drivers/phy/samsung/phy-exynos5-usbdrd.c:3056:1: internal compiler
> error: in arc_ifcvt, at config/arc/arc.c:9110
>     }
>     ^
>    Please submit a full bug report,
>    with preprocessed source if appropriate.
>    See <https://gcc.gnu.org/bugs/> for instructions.
> 
> 
> vim +/dev +2167 drivers/phy/samsung/phy-exynos5-usbdrd.c
> 
>   2125
>   2126	static void
>   2127	exynosautov920_usb31drd_port_phy_ready(struct
> exynos5_usbdrd_phy *phy_drd)
>   2128	{
>   2129		struct device *dev = phy_drd->dev;
>   2130		void __iomem *reg_phy = phy_drd->reg_phy;
>   2131		static const unsigned int timeout_us = 20000;
>   2132		static const unsigned int sleep_us = 40;
>   2133		u32 reg;
>   2134		int err;
>   2135
>   2136		/* Clear cr_para_con */
> > 2137		reg &= ~(PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK |
>   2138
> 	PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR);
>   2139		reg |= PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL;
>   2140		writel(reg, reg_phy +
> EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
>   2141		writel(0x0, reg_phy +
> EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON1);
>   2142		writel(0x0, reg_phy +
> EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2);
>   2143
>   2144		exynosautov920_usb31drd_cr_clk(phy_drd, true);
>   2145		exynosautov920_usb31drd_cr_clk(phy_drd, false);
>   2146
>   2147		/*
>   2148		 * The maximum time from phy reset de-assertion to
de-
> assertion of
>   2149		 * tx/rx_ack can be as high as 5ms in fast
simulation mode.
>   2150		 * Time to phy ready is < 20ms
>   2151		 */
>   2152		err = readl_poll_timeout(reg_phy +
>   2153
> 	EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0,
>   2154				reg, !(reg &
> PHY_CR_PARA_CON0_PHY0_CR_PARA_ACK),
>   2155				sleep_us, timeout_us);
>   2156		if (err)
>   2157			dev_err(dev, "timed out waiting for
rx/tx_ack:
> %#.8x\n", reg);
>   2158
>   2159		reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK;
>   2160		writel(reg, reg_phy +
> EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
>   2161	}
>   2162
>   2163	static void
>   2164	exynosautov920_usb31drd_cr_write(struct exynos5_usbdrd_phy
> *phy_drd,
>   2165					 u16 addr, u16 data)
>   2166	{
> > 2167		struct device *dev = phy_drd->dev;
>   2168		void __iomem *reg_phy = phy_drd->reg_phy;
>   2169		u32 cnt = 0;
>   2170		u32 reg;
>   2171
>   2172		/* Pre Clocking */
>   2173		reg = readl(reg_phy +
> EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
>   2174		reg |= PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL;
>   2175		writel(reg, reg_phy +
> EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
>   2176
>   2177		/*
>   2178		 * tx clks must be available prior to assertion of
tx req.
>   2179		 * tx pstate p2 to p0 transition directly is not
permitted.
>   2180		 * tx clk ready must be asserted synchronously on tx
clk prior
>   2181		 * to internal transmit clk alignment sequence in
the phy
>   2182		 * when entering from p2 to p1 to p0.
>   2183		 */
>   2184		do {
>   2185			exynosautov920_usb31drd_cr_clk(phy_drd,
true);
>   2186			exynosautov920_usb31drd_cr_clk(phy_drd,
false);
>   2187			cnt++;
>   2188		} while (cnt < 15);
>   2189
>   2190		reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL;
>   2191		writel(reg, reg_phy +
> EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
>   2192
>   2193		/*
>   2194		 * tx data path is active when tx lane is in p0
state
>   2195		 * and tx data en asserted. enable cr_para_wr_en.
>   2196		 */
>   2197		reg = readl(reg_phy +
> EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2);
>   2198		reg &= ~PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_DATA;
>   2199		reg |=
> FIELD_PREP(PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_DATA, data) |
>   2200			PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_EN;
>   2201		writel(reg, reg_phy +
> EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2);
>   2202
>   2203		/* write addr */
>   2204		reg = readl(reg_phy +
> EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
>   2205		reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR;
>   2206		reg |=
> FIELD_PREP(PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR, addr) |
>   2207			PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK |
>   2208			PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL;
>   2209		writel(reg, reg_phy +
> EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
>   2210
>   2211		/* check cr_para_ack*/
>   2212		cnt = 0;
>   2213		do {
>   2214			/*
>   2215			 * data symbols are captured by phy on
rising edge of
> the
>   2216			 * tx_clk when tx data enabled.
>   2217			 * completion of the write cycle is
acknowledged by
> assertion
>   2218			 * of the cr_para_ack.
>   2219			 */
>   2220			exynosautov920_usb31drd_cr_clk(phy_drd,
true);
>   2221			reg = readl(reg_phy +
> EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
>   2222			if ((reg &
> PHY_CR_PARA_CON0_PHY0_CR_PARA_ACK))
>   2223				break;
>   2224
>   2225			exynosautov920_usb31drd_cr_clk(phy_drd,
false);
>   2226
>   2227			/*
>   2228			 * wait for minimum of 10 cr_para_clk cycles
after phy
> reset
>   2229			 * is negated, before accessing control regs
to allow
> for
>   2230			 * internal resets.
>   2231			 */
>   2232			cnt++;
>   2233		} while (cnt < 10);
>   2234
>   2235		if (cnt < 10)
>   2236			exynosautov920_usb31drd_cr_clk(phy_drd,
false);
>   2237	}
>   2238
> 
> --
> 0-DAY CI Kernel Test Service
> https://protect2.fireeye.com/v1/url?k=96757503-f70edf94-9674fe4c-
> 74fe4860001d-38e3f56dae8e119d&q=1&e=45b4f292-bcb1-4614-86a0-
> c790a47fb814&u=https%3A%2F%2Fgithub.com%2Fintel%2Flkp-tests%2Fwiki

Will post v7 with the fixes for these warnings.

Thank you.

Regards,
Pritam




From pritam.sutar at samsung.com  Fri Aug 22 02:38:39 2025
From: pritam.sutar at samsung.com (Pritam Manohar Sutar)
Date: Fri, 22 Aug 2025 15:08:39 +0530
Subject: [PATCH v7 0/6] initial usbdrd phy support for Exynosautov920 soc
References: <CGME20250822093005epcas5p16df62346568b8c6570cfff7c01da0667@epcas5p1.samsung.com>
Message-ID: <20250822093845.1179395-1-pritam.sutar@samsung.com>

This SoC has a single USB 3.1 DRD combo phy and three USB2.0 only
DRD phy controllers as mentined below

  * Combo phy supports USB3.1 SSP+(10Gbps) protocol and is backwards
    compatible to the USB3.0 SS(5Gbps). 'Add-on USB2.0' phy is added
    to support USB2.0 HS(480Mbps), FS(12Mbps) and LS(1.5Mbps) data rates.
    These two phys are combined to form a combo phy as mentioned below.


   USB30DRD_0 port

 +------------------------------------------------------------+
 |                                                            |
 |                (combo) USB phy controller                  |
 |      +----------------------------------------------+      |
 |      |                  USB HSPHY                   |      |
 |      |  (samsung,exynosautov920-usbdrd-combo-hsphy) |      |
 |      +----------------------------------------------+      |
 |                                                            |
 |    +--------------------------------------------------+    |
 |    |                   USB SSPHY                      |    |
 |    |   (samsung,exynosautov920-usb31drd-combo-ssphy)  |    |
 |    +--------------------------------------------------+-   |
 |                                                            |
 +------------------------------------------------------------+
 |                                                            |
 |                     USBDRD30 Link                          |
 |                       Controller                           |
 +------------------------------------------------------------+

  * USB2.0 phy supports only UTMI+ interface. USB2.0DRD phy
    is very similar to the existing Exynos850 support in this driver.

    USB20DRD_0/1/2 ports

      +---------------------------------------------------+
      |                                                   |
      |                USB PHY controller                 |
      |    +-----------------------------------------+    |
      |    |              USB HSPHY                  |    |
      |    |  (samsung,exynosautov920-usbdrd-phy)    |    |
      |    +-----------------------------------------+    |
      |                                                   |
      +---------------------------------------------------+
      |                                                   |
      |             USBDRD20_* Link                       |
      |                Controller                         |
      |                                                   |
      +---------------------------------------------------+

The "USB20 phy output isolation" is shared across the USB20 phys.
We have to bypass isolation when any one of the USBs is configured
and enable it when all are turned off. The "USB31 phy isolation"
is seperate for USB31 phy.

This patchset only supports device mode and same is verified with
as NCM device

changelog
----------
Changes in v7:
- added fixes for driver build warnings
  link for v6: https://lore.kernel.org/linux-phy/20250821073703.2498302-1-pritam.sutar at samsung.com/

Changes in v6:
- added else part for new supplies in schemas those are only
  supported for exynosautov920.
- addressed comments for driver given in v5.
  link for v5: https://lore.kernel.org/linux-phy/20250805115216.3798121-1-pritam.sutar at samsung.com/

Changes in v5:
- significant changes were added in v4, removed "Reviewed-by" tag.
- addressed comments from v4 patchset.
  - patch (1/6)
    - DTS style is corrected and added required supplies in code/schema.
    - schema block added to resolve below failure during 'dtbs_check'.
      Unevaluated properties are not allowed ('dvdd075-usb-supply', 'vdd18-usb20-supply', 'vdd33-usb20-supply' were unexpected.
  - patch (2/6)
    - removed usage_counter(take this later in subsequent patch-sets)
  - patch (3/6)
    - There are 3 types of the phys in this SoC.
      - one is simmilar with exynos850 as mentioned in patch no.1.
      - second supports only USB3.1 SSP+ and denoted in patch no 5
      - third supports only USB2.0 HS as in patch3.
    - hs phy in combo phy is "NOT" same as phy. (in patch no. 1)
    - These three phys(usbdrd-phy, combo-hsphy, combo-ssphy) are totally
      deferent, "NOT" same, hence added three compatible for three phys.
  - patch (5/6)
    - Since there are two phys in combo phy, explaination is given
      in each patch.
  link for v4: https://lore.kernel.org/linux-phy/20250701120706.2219355-1-pritam.sutar at samsung.com/

Changes in v4:
- addressed comments from v3 patchset
  - removed dts related patches, to be posted in new patchset.
  - added regulator, pmu and power sequences.
  - phy isol is shared across USBs, added usage counter to bypass or
    enable phy isolation.
  - modified schemas with hs and combo phy compatible names
    (used "combo" to denote combo phy) and regulators
- modified code to work with binding and unbinding devices/drivers
- added "Reviewed-by" tag.
  link for v3: https://lore.kernel.org/linux-phy/20250613055613.866909-1-pritam.sutar at samsung.com/

Changes in v3:
- Updated dt-bindings for USB2.0 only.
- Added dt-bindings for combo phy.
- Added implementation for combo phy (SS and HS phy).
- Added added DTS nodes for all the phys
  link for v2: https://lore.kernel.org/linux-phy/20250516102650.2144487-1-pritam.sutar at samsung.com/

Changes in v2:
- Used standard GENMASK() and FIELD_GET() to get the major version
  from controller version register.
  link for v1: https://lore.kernel.org/linux-phy/20250514134813.380807-1-pritam.sutar at samsung.com/

Pritam Manohar Sutar (6):
  dt-bindings: phy: samsung,usb3-drd-phy: add ExynosAutov920 HS phy
    compatible
  phy: exynos5-usbdrd: support HS phy for ExynosAutov920
  dt-bindings: phy: samsung,usb3-drd-phy: add ExynosAutov920 combo hsphy
  phy: exynos5-usbdrd: support HS combo phy for ExynosAutov920
  dt-bindings: phy: samsung,usb3-drd-phy: add ExynosAutov920 combo ssphy
  phy: exynos5-usbdrd: support SS combo phy for ExynosAutov920

 .../bindings/phy/samsung,usb3-drd-phy.yaml    |  50 ++
 drivers/phy/samsung/phy-exynos5-usbdrd.c      | 651 ++++++++++++++++++
 include/linux/soc/samsung/exynos-regs-pmu.h   |   3 +
 3 files changed, 704 insertions(+)

-- 
2.34.1



From pritam.sutar at samsung.com  Fri Aug 22 02:38:40 2025
From: pritam.sutar at samsung.com (Pritam Manohar Sutar)
Date: Fri, 22 Aug 2025 15:08:40 +0530
Subject: [PATCH v7 1/6] dt-bindings: phy: samsung,usb3-drd-phy: add
 ExynosAutov920 HS phy compatible
In-Reply-To: <20250822093845.1179395-1-pritam.sutar@samsung.com>
References: <20250822093845.1179395-1-pritam.sutar@samsung.com>
	<CGME20250822093008epcas5p218f9f9a5381a716b5b8e0c4b23e4b3bf@epcas5p2.samsung.com>
Message-ID: <20250822093845.1179395-2-pritam.sutar@samsung.com>

This SoC has USB2.0 phy and supports only UTMI+ interface. This phy
requires two clocks, named as "phy" and "ref". The required supplies for
this phy are vdd075_usb20(0.75v), vdd18_usb20(1.8v), vdd33_usb20(3.3v).

Add a dedicated compatible string for USB HS phy found in this SoC.

Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
---
 .../bindings/phy/samsung,usb3-drd-phy.yaml    | 24 +++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
index e906403208c0..e238fd0c9f6c 100644
--- a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
@@ -34,6 +34,7 @@ properties:
       - samsung,exynos7870-usbdrd-phy
       - samsung,exynos850-usbdrd-phy
       - samsung,exynos990-usbdrd-phy
+      - samsung,exynosautov920-usbdrd-phy
 
   clocks:
     minItems: 1
@@ -110,6 +111,12 @@ properties:
   vddh-usbdp-supply:
     description: VDDh power supply for the USB DP phy.
 
+  dvdd075-usb20-supply:
+    description: 0.75V power supply for the USB 2.0 phy.
+
+  vdd18-usb20-supply:
+    description: 1.8V power supply for the USB 2.0 phy.
+
 required:
   - compatible
   - clocks
@@ -219,6 +226,7 @@ allOf:
               - samsung,exynos7870-usbdrd-phy
               - samsung,exynos850-usbdrd-phy
               - samsung,exynos990-usbdrd-phy
+              - samsung,exynosautov920-usbdrd-phy
     then:
       properties:
         clocks:
@@ -235,6 +243,22 @@ allOf:
 
         reg-names:
           maxItems: 1
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - samsung,exynosautov920-usbdrd-phy
+    then:
+      required:
+        - dvdd075-usb20-supply
+        - vdd18-usb20-supply
+        - vdd33-usb20-supply
+
+    else:
+      properties:
+        dvdd075-usb20-supply: false
+        vdd18-usb20-supply: false
 
 unevaluatedProperties: false
 
-- 
2.34.1



From pritam.sutar at samsung.com  Fri Aug 22 02:38:41 2025
From: pritam.sutar at samsung.com (Pritam Manohar Sutar)
Date: Fri, 22 Aug 2025 15:08:41 +0530
Subject: [PATCH v7 2/6] phy: exynos5-usbdrd: support HS phy for
 ExynosAutov920
In-Reply-To: <20250822093845.1179395-1-pritam.sutar@samsung.com>
References: <20250822093845.1179395-1-pritam.sutar@samsung.com>
	<CGME20250822093012epcas5p1550eebdc0d2847ebf09945ae46c8335d@epcas5p1.samsung.com>
Message-ID: <20250822093845.1179395-3-pritam.sutar@samsung.com>

Enable UTMI+ phy support for this SoC which is very similar to what
the existing Exynos850 supports.

Add required change in phy driver to support HS phy for this SoC.

Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
---
 drivers/phy/samsung/phy-exynos5-usbdrd.c    | 123 ++++++++++++++++++++
 include/linux/soc/samsung/exynos-regs-pmu.h |   2 +
 2 files changed, 125 insertions(+)

diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
index a88ba95bdc8f..b238d14e2f4a 100644
--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
+++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
@@ -2054,6 +2054,126 @@ static const struct exynos5_usbdrd_phy_drvdata exynos990_usbdrd_phy = {
 	.n_regulators		= ARRAY_SIZE(exynos5_regulator_names),
 };
 
+static int exynosautov920_usbdrd_phy_init(struct phy *phy)
+{
+	struct phy_usb_instance *inst = phy_get_drvdata(phy);
+	struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
+	int ret;
+
+	ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks);
+	if (ret)
+		return ret;
+
+	/* Bypass PHY isol */
+	inst->phy_cfg->phy_isol(inst, false);
+
+	/* UTMI or PIPE3 specific init */
+	inst->phy_cfg->phy_init(phy_drd);
+
+	clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks);
+
+	return 0;
+}
+
+static int exynosautov920_usbdrd_phy_exit(struct phy *phy)
+{
+	struct phy_usb_instance *inst = phy_get_drvdata(phy);
+	struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
+	int ret;
+
+	ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks);
+	if (ret)
+		return ret;
+
+	exynos850_usbdrd_phy_exit(phy);
+
+	/* enable PHY isol */
+	inst->phy_cfg->phy_isol(inst, true);
+
+	clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks);
+
+	return 0;
+}
+
+static int exynosautov920_usbdrd_phy_power_on(struct phy *phy)
+{
+	struct phy_usb_instance *inst = phy_get_drvdata(phy);
+	struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
+	int ret;
+
+	dev_dbg(phy_drd->dev, "Request to power_on usbdrd_phy phy\n");
+
+	ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_core_clks,
+				      phy_drd->core_clks);
+	if (ret)
+		return ret;
+
+	/* Enable supply */
+	ret = regulator_bulk_enable(phy_drd->drv_data->n_regulators,
+				    phy_drd->regulators);
+	if (ret) {
+		dev_err(phy_drd->dev, "Failed to enable PHY regulator(s)\n");
+		goto fail_supply;
+	}
+
+	return 0;
+
+fail_supply:
+	clk_bulk_disable_unprepare(phy_drd->drv_data->n_core_clks,
+				   phy_drd->core_clks);
+
+	return ret;
+}
+
+static int exynosautov920_usbdrd_phy_power_off(struct phy *phy)
+{
+	struct phy_usb_instance *inst = phy_get_drvdata(phy);
+	struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
+
+	dev_dbg(phy_drd->dev, "Request to power_off usbdrd_phy phy\n");
+
+	/* Disable supply */
+	regulator_bulk_disable(phy_drd->drv_data->n_regulators,
+			       phy_drd->regulators);
+
+	clk_bulk_disable_unprepare(phy_drd->drv_data->n_core_clks,
+				   phy_drd->core_clks);
+
+	return 0;
+}
+
+static const char * const exynosautov920_usb20_regulators[] = {
+	"dvdd075-usb20", "vdd18-usb20", "vdd33-usb20",
+};
+
+static const struct phy_ops exynosautov920_usbdrd_phy_ops = {
+	.init		= exynosautov920_usbdrd_phy_init,
+	.exit		= exynosautov920_usbdrd_phy_exit,
+	.power_on       = exynosautov920_usbdrd_phy_power_on,
+	.power_off      = exynosautov920_usbdrd_phy_power_off,
+	.owner		= THIS_MODULE,
+};
+
+static const struct exynos5_usbdrd_phy_config phy_cfg_exynosautov920[] = {
+	{
+		.id		= EXYNOS5_DRDPHY_UTMI,
+		.phy_isol	= exynos5_usbdrd_phy_isol,
+		.phy_init	= exynos850_usbdrd_utmi_init,
+	},
+};
+
+static const struct exynos5_usbdrd_phy_drvdata exynosautov920_usbdrd_phy = {
+	.phy_cfg		= phy_cfg_exynosautov920,
+	.phy_ops		= &exynosautov920_usbdrd_phy_ops,
+	.pmu_offset_usbdrd0_phy	= EXYNOSAUTOV920_PHY_CTRL_USB20,
+	.clk_names		= exynos5_clk_names,
+	.n_clks			= ARRAY_SIZE(exynos5_clk_names),
+	.core_clk_names		= exynos5_core_clk_names,
+	.n_core_clks		= ARRAY_SIZE(exynos5_core_clk_names),
+	.regulator_names	= exynosautov920_usb20_regulators,
+	.n_regulators		= ARRAY_SIZE(exynosautov920_usb20_regulators),
+};
+
 static const struct exynos5_usbdrd_phy_config phy_cfg_gs101[] = {
 	{
 		.id		= EXYNOS5_DRDPHY_UTMI,
@@ -2260,6 +2380,9 @@ static const struct of_device_id exynos5_usbdrd_phy_of_match[] = {
 	}, {
 		.compatible = "samsung,exynos990-usbdrd-phy",
 		.data = &exynos990_usbdrd_phy
+	}, {
+		.compatible = "samsung,exynosautov920-usbdrd-phy",
+		.data = &exynosautov920_usbdrd_phy
 	},
 	{ },
 };
diff --git a/include/linux/soc/samsung/exynos-regs-pmu.h b/include/linux/soc/samsung/exynos-regs-pmu.h
index 71e0c09a49eb..4923f9be3d1f 100644
--- a/include/linux/soc/samsung/exynos-regs-pmu.h
+++ b/include/linux/soc/samsung/exynos-regs-pmu.h
@@ -688,4 +688,6 @@
 #define GS101_GRP2_INTR_BID_UPEND				(0x0208)
 #define GS101_GRP2_INTR_BID_CLEAR				(0x020c)
 
+/* exynosautov920 */
+#define EXYNOSAUTOV920_PHY_CTRL_USB20				(0x0710)
 #endif /* __LINUX_SOC_EXYNOS_REGS_PMU_H */
-- 
2.34.1



From pritam.sutar at samsung.com  Fri Aug 22 02:38:42 2025
From: pritam.sutar at samsung.com (Pritam Manohar Sutar)
Date: Fri, 22 Aug 2025 15:08:42 +0530
Subject: [PATCH v7 3/6] dt-bindings: phy: samsung,usb3-drd-phy: add
 ExynosAutov920 combo hsphy
In-Reply-To: <20250822093845.1179395-1-pritam.sutar@samsung.com>
References: <20250822093845.1179395-1-pritam.sutar@samsung.com>
	<CGME20250822093015epcas5p1f479af38c65a6decc900c37fe37537e5@epcas5p1.samsung.com>
Message-ID: <20250822093845.1179395-4-pritam.sutar@samsung.com>

This phy only supports USB2.0 HS(480Mbps), FS(12Mbps) and
LS(1.5Mbps) data rates. It requires two clocks, named as "phy" and "ref".
The required supplies for this phy, named as vdd075_usb20(0.75v),
vdd18_usb20(1.8v), vdd33_usb20(3.3v).

Add schema for combo hsphy found on this SoC.

Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
---
 .../devicetree/bindings/phy/samsung,usb3-drd-phy.yaml          | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
index e238fd0c9f6c..f0cfca5736b8 100644
--- a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
@@ -34,6 +34,7 @@ properties:
       - samsung,exynos7870-usbdrd-phy
       - samsung,exynos850-usbdrd-phy
       - samsung,exynos990-usbdrd-phy
+      - samsung,exynosautov920-usbdrd-combo-hsphy
       - samsung,exynosautov920-usbdrd-phy
 
   clocks:
@@ -226,6 +227,7 @@ allOf:
               - samsung,exynos7870-usbdrd-phy
               - samsung,exynos850-usbdrd-phy
               - samsung,exynos990-usbdrd-phy
+              - samsung,exynosautov920-usbdrd-combo-hsphy
               - samsung,exynosautov920-usbdrd-phy
     then:
       properties:
@@ -248,6 +250,7 @@ allOf:
         compatible:
           contains:
             enum:
+              - samsung,exynosautov920-usbdrd-combo-hsphy
               - samsung,exynosautov920-usbdrd-phy
     then:
       required:
-- 
2.34.1



From pritam.sutar at samsung.com  Fri Aug 22 02:38:43 2025
From: pritam.sutar at samsung.com (Pritam Manohar Sutar)
Date: Fri, 22 Aug 2025 15:08:43 +0530
Subject: [PATCH v7 4/6] phy: exynos5-usbdrd: support HS combo phy for
 ExynosAutov920
In-Reply-To: <20250822093845.1179395-1-pritam.sutar@samsung.com>
References: <20250822093845.1179395-1-pritam.sutar@samsung.com>
	<CGME20250822093019epcas5p28a21e48b059bc67824e9d7ed96605fbe@epcas5p2.samsung.com>
Message-ID: <20250822093845.1179395-5-pritam.sutar@samsung.com>

Support UTMI+ combo phy for this SoC which is somewhat simmilar to
what the existing Exynos850 support does. The difference is that
some register offsets and bit fields are defferent from Exynos850.

Add required change in phy driver to support combo HS phy for this SoC.

Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
---
 drivers/phy/samsung/phy-exynos5-usbdrd.c | 211 +++++++++++++++++++++++
 1 file changed, 211 insertions(+)

diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
index b238d14e2f4a..32178c5c120d 100644
--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
+++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
@@ -41,6 +41,13 @@
 #define EXYNOS2200_CLKRST_LINK_PCLK_SEL		BIT(1)
 
 #define EXYNOS2200_DRD_UTMI			0x10
+
+/* ExynosAutov920 bits */
+#define UTMICTL_FORCE_UTMI_SUSPEND		BIT(13)
+#define UTMICTL_FORCE_UTMI_SLEEP		BIT(12)
+#define UTMICTL_FORCE_DPPULLDOWN		BIT(9)
+#define UTMICTL_FORCE_DMPULLDOWN		BIT(8)
+
 #define EXYNOS2200_UTMI_FORCE_VBUSVALID		BIT(1)
 #define EXYNOS2200_UTMI_FORCE_BVALID		BIT(0)
 
@@ -250,6 +257,22 @@
 #define EXYNOS850_DRD_HSP_TEST			0x5c
 #define HSP_TEST_SIDDQ				BIT(24)
 
+#define EXYNOSAUTOV920_DRD_HSP_CLKRST		0x100
+#define HSPCLKRST_PHY20_SW_PORTRESET		BIT(3)
+#define HSPCLKRST_PHY20_SW_POR			BIT(1)
+#define HSPCLKRST_PHY20_SW_POR_SEL		BIT(0)
+
+#define EXYNOSAUTOV920_DRD_HSPCTL		0x104
+#define HSPCTRL_VBUSVLDEXTSEL			BIT(13)
+#define HSPCTRL_VBUSVLDEXT			BIT(12)
+#define HSPCTRL_EN_UTMISUSPEND			BIT(9)
+#define HSPCTRL_COMMONONN			BIT(8)
+
+#define EXYNOSAUTOV920_DRD_HSP_TEST		0x10c
+
+#define EXYNOSAUTOV920_DRD_HSPPLLTUNE		0x110
+#define HSPPLLTUNE_FSEL				GENMASK(18, 16)
+
 /* Exynos9 - GS101 */
 #define EXYNOS850_DRD_SECPMACTL			0x48
 #define SECPMACTL_PMA_ROPLL_REF_CLK_SEL		GENMASK(13, 12)
@@ -2054,6 +2077,140 @@ static const struct exynos5_usbdrd_phy_drvdata exynos990_usbdrd_phy = {
 	.n_regulators		= ARRAY_SIZE(exynos5_regulator_names),
 };
 
+static void
+exynosautov920_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd)
+{
+	void __iomem *reg_phy = phy_drd->reg_phy;
+	u32 reg;
+
+	/*
+	 * Disable HWACG (hardware auto clock gating control). This
+	 * forces QACTIVE signal in Q-Channel interface to HIGH level,
+	 * to make sure the PHY clock is not gated by the hardware.
+	 */
+	reg = readl(reg_phy + EXYNOS850_DRD_LINKCTRL);
+	reg |= LINKCTRL_FORCE_QACT;
+	writel(reg, reg_phy + EXYNOS850_DRD_LINKCTRL);
+
+	/* De-assert link reset */
+	reg = readl(reg_phy + EXYNOS2200_DRD_CLKRST);
+	reg &= ~CLKRST_LINK_SW_RST;
+	writel(reg, reg_phy + EXYNOS2200_DRD_CLKRST);
+
+	/* Set PHY POR High */
+	reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSP_CLKRST);
+	reg |= HSPCLKRST_PHY20_SW_POR | HSPCLKRST_PHY20_SW_POR_SEL;
+	writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSP_CLKRST);
+
+	/* Enable UTMI+ */
+	reg = readl(reg_phy + EXYNOS2200_DRD_UTMI);
+	reg &= ~(UTMICTL_FORCE_UTMI_SUSPEND | UTMICTL_FORCE_UTMI_SLEEP |
+		UTMICTL_FORCE_DPPULLDOWN | UTMICTL_FORCE_DMPULLDOWN);
+	writel(reg, reg_phy + EXYNOS2200_DRD_UTMI);
+
+	/* set phy clock & control HS phy */
+	reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSPCTL);
+	reg |= HSPCTRL_EN_UTMISUSPEND | HSPCTRL_COMMONONN;
+	writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSPCTL);
+
+	fsleep(100);
+
+	/* Set VBUS Valid and DP-Pull up control by VBUS pad usage */
+	reg = readl(reg_phy + EXYNOS850_DRD_LINKCTRL);
+	reg |= FIELD_PREP_CONST(LINKCTRL_BUS_FILTER_BYPASS, 0xf);
+	writel(reg, reg_phy + EXYNOS850_DRD_LINKCTRL);
+
+	reg = readl(reg_phy + EXYNOS2200_DRD_UTMI);
+	reg |= EXYNOS2200_UTMI_FORCE_VBUSVALID | EXYNOS2200_UTMI_FORCE_BVALID;
+	writel(reg, reg_phy + EXYNOS2200_DRD_UTMI);
+
+	reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSPCTL);
+	reg |= HSPCTRL_VBUSVLDEXTSEL | HSPCTRL_VBUSVLDEXT;
+	writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSPCTL);
+
+	/* Setting FSEL for refference clock */
+	reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSPPLLTUNE);
+	reg &= ~HSPPLLTUNE_FSEL;
+
+	switch (phy_drd->extrefclk) {
+	case EXYNOS5_FSEL_50MHZ:
+		reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 7);
+		break;
+	case EXYNOS5_FSEL_26MHZ:
+		reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 6);
+		break;
+	case EXYNOS5_FSEL_24MHZ:
+		reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 2);
+		break;
+	case EXYNOS5_FSEL_20MHZ:
+		reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 1);
+		break;
+	case EXYNOS5_FSEL_19MHZ2:
+		reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 0);
+		break;
+	default:
+		dev_warn(phy_drd->dev, "unsupported ref clk: %#.2x\n",
+			 phy_drd->extrefclk);
+		break;
+	}
+	writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSPPLLTUNE);
+
+	/* Enable PHY Power Mode */
+	reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSP_TEST);
+	reg &= ~HSP_TEST_SIDDQ;
+	writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSP_TEST);
+
+	/* before POR low, 10us delay is needed to Finish PHY reset */
+	fsleep(10);
+
+	/* Set PHY POR Low */
+	reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSP_CLKRST);
+	reg |= HSPCLKRST_PHY20_SW_POR_SEL;
+	reg &= ~(HSPCLKRST_PHY20_SW_POR | HSPCLKRST_PHY20_SW_PORTRESET);
+	writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSP_CLKRST);
+
+	/* after POR low and delay 75us, PHYCLOCK is guaranteed. */
+	fsleep(75);
+
+	/* force pipe3 signal for link */
+	reg = readl(reg_phy + EXYNOS850_DRD_LINKCTRL);
+	reg |= LINKCTRL_FORCE_PIPE_EN;
+	reg &= ~LINKCTRL_FORCE_PHYSTATUS;
+	reg |= LINKCTRL_FORCE_RXELECIDLE;
+	writel(reg, reg_phy + EXYNOS850_DRD_LINKCTRL);
+}
+
+static void
+exynosautov920_usbdrd_hsphy_disable(struct exynos5_usbdrd_phy *phy_drd)
+{
+	u32 reg;
+	void __iomem *reg_phy = phy_drd->reg_phy;
+
+	/* set phy clock & control HS phy */
+	reg = readl(reg_phy + EXYNOS2200_DRD_UTMI);
+	reg |= UTMICTL_FORCE_UTMI_SUSPEND | UTMICTL_FORCE_UTMI_SLEEP;
+	reg &= ~(UTMICTL_FORCE_DPPULLDOWN | UTMICTL_FORCE_DMPULLDOWN);
+	writel(reg, reg_phy + EXYNOS2200_DRD_UTMI);
+
+	/* Disable PHY Power Mode */
+	reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSP_TEST);
+	reg |= HSP_TEST_SIDDQ;
+	writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSP_TEST);
+
+	/* clear force q-channel */
+	reg = readl(reg_phy + EXYNOS850_DRD_LINKCTRL);
+	reg &= ~LINKCTRL_FORCE_QACT;
+	writel(reg, reg_phy + EXYNOS850_DRD_LINKCTRL);
+
+	/* link sw reset is need for USB_DP/DM high-z in host mode */
+	reg = readl(reg_phy + EXYNOS2200_DRD_CLKRST);
+	reg |= CLKRST_LINK_SW_RST;
+	writel(reg, reg_phy + EXYNOS2200_DRD_CLKRST);
+	fsleep(10);
+	reg &= ~CLKRST_LINK_SW_RST;
+	writel(reg, reg_phy + EXYNOS2200_DRD_CLKRST);
+}
+
 static int exynosautov920_usbdrd_phy_init(struct phy *phy)
 {
 	struct phy_usb_instance *inst = phy_get_drvdata(phy);
@@ -2095,6 +2252,27 @@ static int exynosautov920_usbdrd_phy_exit(struct phy *phy)
 	return 0;
 }
 
+static int exynosautov920_usbdrd_combo_phy_exit(struct phy *phy)
+{
+	struct phy_usb_instance *inst = phy_get_drvdata(phy);
+	struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
+	int ret = 0;
+
+	ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks);
+	if (ret)
+		return ret;
+
+	if (inst->phy_cfg->id == EXYNOS5_DRDPHY_UTMI)
+		exynosautov920_usbdrd_hsphy_disable(phy_drd);
+
+	/* enable PHY isol */
+	inst->phy_cfg->phy_isol(inst, true);
+
+	clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks);
+
+	return 0;
+}
+
 static int exynosautov920_usbdrd_phy_power_on(struct phy *phy)
 {
 	struct phy_usb_instance *inst = phy_get_drvdata(phy);
@@ -2146,6 +2324,36 @@ static const char * const exynosautov920_usb20_regulators[] = {
 	"dvdd075-usb20", "vdd18-usb20", "vdd33-usb20",
 };
 
+static const struct phy_ops exynosautov920_usbdrd_combo_hsphy_ops = {
+	.init		= exynosautov920_usbdrd_phy_init,
+	.exit		= exynosautov920_usbdrd_combo_phy_exit,
+	.power_on	= exynosautov920_usbdrd_phy_power_on,
+	.power_off	= exynosautov920_usbdrd_phy_power_off,
+	.owner		= THIS_MODULE,
+};
+
+static const struct
+exynos5_usbdrd_phy_config usbdrd_hsphy_cfg_exynosautov920[] = {
+	{
+		.id		= EXYNOS5_DRDPHY_UTMI,
+		.phy_isol	= exynos5_usbdrd_phy_isol,
+		.phy_init	= exynosautov920_usbdrd_utmi_init,
+	},
+};
+
+static const
+struct exynos5_usbdrd_phy_drvdata exynosautov920_usbdrd_combo_hsphy = {
+	.phy_cfg		= usbdrd_hsphy_cfg_exynosautov920,
+	.phy_ops		= &exynosautov920_usbdrd_combo_hsphy_ops,
+	.pmu_offset_usbdrd0_phy	= EXYNOSAUTOV920_PHY_CTRL_USB20,
+	.clk_names		= exynos5_clk_names,
+	.n_clks			= ARRAY_SIZE(exynos5_clk_names),
+	.core_clk_names		= exynos5_core_clk_names,
+	.n_core_clks		= ARRAY_SIZE(exynos5_core_clk_names),
+	.regulator_names	= exynosautov920_usb20_regulators,
+	.n_regulators		= ARRAY_SIZE(exynosautov920_usb20_regulators),
+};
+
 static const struct phy_ops exynosautov920_usbdrd_phy_ops = {
 	.init		= exynosautov920_usbdrd_phy_init,
 	.exit		= exynosautov920_usbdrd_phy_exit,
@@ -2380,6 +2588,9 @@ static const struct of_device_id exynos5_usbdrd_phy_of_match[] = {
 	}, {
 		.compatible = "samsung,exynos990-usbdrd-phy",
 		.data = &exynos990_usbdrd_phy
+	}, {
+		.compatible = "samsung,exynosautov920-usbdrd-combo-hsphy",
+		.data = &exynosautov920_usbdrd_combo_hsphy
 	}, {
 		.compatible = "samsung,exynosautov920-usbdrd-phy",
 		.data = &exynosautov920_usbdrd_phy
-- 
2.34.1



From pritam.sutar at samsung.com  Fri Aug 22 02:38:44 2025
From: pritam.sutar at samsung.com (Pritam Manohar Sutar)
Date: Fri, 22 Aug 2025 15:08:44 +0530
Subject: [PATCH v7 5/6] dt-bindings: phy: samsung,usb3-drd-phy: add
 ExynosAutov920 combo ssphy
In-Reply-To: <20250822093845.1179395-1-pritam.sutar@samsung.com>
References: <20250822093845.1179395-1-pritam.sutar@samsung.com>
	<CGME20250822093022epcas5p42d8c16c851769dab0e1da9d45743ab1f@epcas5p4.samsung.com>
Message-ID: <20250822093845.1179395-6-pritam.sutar@samsung.com>

This phy supports USB3.1 SSP+(10Gbps) protocol and is backwards
compatible to the USB3.0 SS(5Gbps). It requires two clocks, named
"phy" and "ref". The required supplies for USB3.1 are named as
vdd075_usb30(0.75v), vdd18_usb30(1.8v).

Add schemas for combo ssphy found on this SoC.

Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
---
 .../bindings/phy/samsung,usb3-drd-phy.yaml    | 23 +++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
index f0cfca5736b8..96e5bbb2e42c 100644
--- a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
@@ -34,6 +34,7 @@ properties:
       - samsung,exynos7870-usbdrd-phy
       - samsung,exynos850-usbdrd-phy
       - samsung,exynos990-usbdrd-phy
+      - samsung,exynosautov920-usb31drd-combo-ssphy
       - samsung,exynosautov920-usbdrd-combo-hsphy
       - samsung,exynosautov920-usbdrd-phy
 
@@ -118,6 +119,12 @@ properties:
   vdd18-usb20-supply:
     description: 1.8V power supply for the USB 2.0 phy.
 
+  dvdd075-usb30-supply:
+    description: 0.75V power supply for the USB 3.0 phy.
+
+  vdd18-usb30-supply:
+    description: 1.8V power supply for the USB 3.0 phy.
+
 required:
   - compatible
   - clocks
@@ -227,6 +234,7 @@ allOf:
               - samsung,exynos7870-usbdrd-phy
               - samsung,exynos850-usbdrd-phy
               - samsung,exynos990-usbdrd-phy
+              - samsung,exynosautov920-usb31drd-combo-ssphy
               - samsung,exynosautov920-usbdrd-combo-hsphy
               - samsung,exynosautov920-usbdrd-phy
     then:
@@ -262,6 +270,21 @@ allOf:
       properties:
         dvdd075-usb20-supply: false
         vdd18-usb20-supply: false
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - samsung,exynosautov920-usb31drd-combo-ssphy
+    then:
+      required:
+        - dvdd075-usb30-supply
+        - vdd18-usb30-supply
+
+    else:
+      properties:
+        dvdd075-usb30-supply: false
+        vdd18-usb30-supply: false
 
 unevaluatedProperties: false
 
-- 
2.34.1



From pritam.sutar at samsung.com  Fri Aug 22 02:38:45 2025
From: pritam.sutar at samsung.com (Pritam Manohar Sutar)
Date: Fri, 22 Aug 2025 15:08:45 +0530
Subject: [PATCH v7 6/6] phy: exynos5-usbdrd: support SS combo phy for
 ExynosAutov920
In-Reply-To: <20250822093845.1179395-1-pritam.sutar@samsung.com>
References: <20250822093845.1179395-1-pritam.sutar@samsung.com>
	<CGME20250822093026epcas5p24ca84f56e803cbc65b5d21fc539dbd79@epcas5p2.samsung.com>
Message-ID: <20250822093845.1179395-7-pritam.sutar@samsung.com>

Add required change in phy driver to support combo SS phy for this SoC.

Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
---
 drivers/phy/samsung/phy-exynos5-usbdrd.c    | 325 +++++++++++++++++++-
 include/linux/soc/samsung/exynos-regs-pmu.h |   1 +
 2 files changed, 322 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
index 32178c5c120d..038230b1c433 100644
--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
+++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
@@ -273,6 +273,36 @@
 #define EXYNOSAUTOV920_DRD_HSPPLLTUNE		0x110
 #define HSPPLLTUNE_FSEL				GENMASK(18, 16)
 
+/* ExynosAutov920 phy usb31drd port reg */
+#define EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL	0x000
+#define PHY_RST_CTRL_PIPE_LANE0_RESET_N_OVRD_EN	BIT(5)
+#define PHY_RST_CTRL_PIPE_LANE0_RESET_N		BIT(4)
+#define PHY_RST_CTRL_PHY_RESET_OVRD_EN		BIT(1)
+#define PHY_RST_CTRL_PHY_RESET			BIT(0)
+
+#define EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0	0x0004
+#define PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR		GENMASK(31, 16)
+#define PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK		BIT(8)
+#define PHY_CR_PARA_CON0_PHY0_CR_PARA_ACK		BIT(4)
+#define PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL		BIT(0)
+
+#define EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON1	0x0008
+
+#define EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2	0x000c
+#define PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_EN		BIT(0)
+#define PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_DATA		GENMASK(31, 16)
+
+#define EXYNOSAUTOV920_USB31DRD_PHY_CONFIG0	0x100
+#define PHY_CONFIG0_PHY0_PMA_PWR_STABLE		BIT(14)
+#define PHY_CONFIG0_PHY0_PCS_PWR_STABLE		BIT(13)
+#define PHY_CONFIG0_PHY0_ANA_PWR_EN		BIT(1)
+
+#define EXYNOSAUTOV920_USB31DRD_PHY_CONFIG7	0x11c
+#define PHY_CONFIG7_PHY_TEST_POWERDOWN		BIT(24)
+
+#define EXYNOSAUTOV920_USB31DRD_PHY_CONFIG4	0x110
+#define PHY_CONFIG4_PIPE_RX0_SRIS_MODE_EN	BIT(2)
+
 /* Exynos9 - GS101 */
 #define EXYNOS850_DRD_SECPMACTL			0x48
 #define SECPMACTL_PMA_ROPLL_REF_CLK_SEL		GENMASK(13, 12)
@@ -2077,6 +2107,251 @@ static const struct exynos5_usbdrd_phy_drvdata exynos990_usbdrd_phy = {
 	.n_regulators		= ARRAY_SIZE(exynos5_regulator_names),
 };
 
+static void
+exynosautov920_usb31drd_cr_clk(struct exynos5_usbdrd_phy *phy_drd, bool high)
+{
+	void __iomem *reg_phy = phy_drd->reg_phy;
+	u32 reg;
+
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
+	if (high)
+		reg |= PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK;
+	else
+		reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK;
+
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
+	fsleep(1);
+}
+
+static void
+exynosautov920_usb31drd_port_phy_ready(struct exynos5_usbdrd_phy *phy_drd)
+{
+	struct device *dev = phy_drd->dev;
+	void __iomem *reg_phy = phy_drd->reg_phy;
+	static const unsigned int timeout_us = 20000;
+	static const unsigned int sleep_us = 40;
+	u32 reg;
+	int err;
+
+	/* Clear cr_para_con */
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
+	reg &= ~(PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK |
+			PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR);
+	reg |= PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
+	writel(0x0, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON1);
+	writel(0x0, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2);
+
+	exynosautov920_usb31drd_cr_clk(phy_drd, true);
+	exynosautov920_usb31drd_cr_clk(phy_drd, false);
+
+	/*
+	 * The maximum time from phy reset de-assertion to de-assertion of
+	 * tx/rx_ack can be as high as 5ms in fast simulation mode.
+	 * Time to phy ready is < 20ms
+	 */
+	err = readl_poll_timeout(reg_phy +
+				EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0,
+			reg, !(reg & PHY_CR_PARA_CON0_PHY0_CR_PARA_ACK),
+			sleep_us, timeout_us);
+	if (err)
+		dev_err(dev, "timed out waiting for rx/tx_ack: %#.8x\n", reg);
+
+	reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
+}
+
+static void
+exynosautov920_usb31drd_cr_write(struct exynos5_usbdrd_phy *phy_drd,
+				 u16 addr, u16 data)
+{
+	void __iomem *reg_phy = phy_drd->reg_phy;
+	u32 cnt = 0;
+	u32 reg;
+
+	/* Pre Clocking */
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
+	reg |= PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
+
+	/*
+	 * tx clks must be available prior to assertion of tx req.
+	 * tx pstate p2 to p0 transition directly is not permitted.
+	 * tx clk ready must be asserted synchronously on tx clk prior
+	 * to internal transmit clk alignment sequence in the phy
+	 * when entering from p2 to p1 to p0.
+	 */
+	do {
+		exynosautov920_usb31drd_cr_clk(phy_drd, true);
+		exynosautov920_usb31drd_cr_clk(phy_drd, false);
+		cnt++;
+	} while (cnt < 15);
+
+	reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
+
+	/*
+	 * tx data path is active when tx lane is in p0 state
+	 * and tx data en asserted. enable cr_para_wr_en.
+	 */
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2);
+	reg &= ~PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_DATA;
+	reg |= FIELD_PREP(PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_DATA, data) |
+		PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_EN;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2);
+
+	/* write addr */
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
+	reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR;
+	reg |= FIELD_PREP(PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR, addr) |
+		PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK |
+		PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
+
+	/* check cr_para_ack*/
+	cnt = 0;
+	do {
+		/*
+		 * data symbols are captured by phy on rising edge of the
+		 * tx_clk when tx data enabled.
+		 * completion of the write cycle is acknowledged by assertion
+		 * of the cr_para_ack.
+		 */
+		exynosautov920_usb31drd_cr_clk(phy_drd, true);
+		reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0);
+		if ((reg & PHY_CR_PARA_CON0_PHY0_CR_PARA_ACK))
+			break;
+
+		exynosautov920_usb31drd_cr_clk(phy_drd, false);
+
+		/*
+		 * wait for minimum of 10 cr_para_clk cycles after phy reset
+		 * is negated, before accessing control regs to allow for
+		 * internal resets.
+		 */
+		cnt++;
+	} while (cnt < 10);
+
+	if (cnt < 10)
+		exynosautov920_usb31drd_cr_clk(phy_drd, false);
+}
+
+static void
+exynosautov920_usb31drd_phy_reset(struct exynos5_usbdrd_phy *phy_drd, int val)
+{
+	void __iomem *reg_phy = phy_drd->reg_phy;
+	u32 reg;
+
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL);
+	reg &= ~PHY_RST_CTRL_PHY_RESET_OVRD_EN;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL);
+
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL);
+	if (val)
+		reg |= PHY_RST_CTRL_PHY_RESET;
+	else
+		reg &= ~PHY_RST_CTRL_PHY_RESET;
+
+	reg |= PHY_RST_CTRL_PHY_RESET_OVRD_EN;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL);
+}
+
+static void
+exynosautov920_usb31drd_lane0_reset(struct exynos5_usbdrd_phy *phy_drd, int val)
+{
+	void __iomem *reg_phy = phy_drd->reg_phy;
+	u32 reg;
+
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL);
+	reg |= PHY_RST_CTRL_PIPE_LANE0_RESET_N_OVRD_EN;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL);
+
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL);
+	if (val)
+		reg &= ~PHY_RST_CTRL_PIPE_LANE0_RESET_N;
+	else
+		reg |= PHY_RST_CTRL_PIPE_LANE0_RESET_N;
+
+	reg &= ~PHY_RST_CTRL_PIPE_LANE0_RESET_N_OVRD_EN;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL);
+}
+
+static void
+exynosautov920_usb31drd_pipe3_init(struct exynos5_usbdrd_phy *phy_drd)
+{
+	void __iomem *reg_phy = phy_drd->reg_phy;
+	u32 reg;
+
+	/*
+	 * Phy and Pipe Lane reset assert.
+	 * assert reset (phy_reset = 1).
+	 * The lane-ack outputs are asserted during reset (tx_ack = rx_ack = 1)
+	 */
+	exynosautov920_usb31drd_phy_reset(phy_drd, 1);
+	exynosautov920_usb31drd_lane0_reset(phy_drd, 1);
+
+	/*
+	 * ANA Power En, PCS & PMA PWR Stable Set
+	 * ramp-up power suppiles
+	 */
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG0);
+	reg |= PHY_CONFIG0_PHY0_ANA_PWR_EN | PHY_CONFIG0_PHY0_PCS_PWR_STABLE |
+		PHY_CONFIG0_PHY0_PMA_PWR_STABLE;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG0);
+
+	fsleep(10);
+
+	/*
+	 * phy is not functional in test_powerdown mode, test_powerdown to be
+	 * de-asserted for normal operation
+	 */
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG7);
+	reg &= ~PHY_CONFIG7_PHY_TEST_POWERDOWN;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG7);
+
+	/*
+	 * phy reset signal be asserted for minimum 10us after power
+	 * supplies are ramped-up
+	 */
+	fsleep(10);
+
+	/*
+	 * Phy and Pipe Lane reset assert de-assert
+	 */
+	exynosautov920_usb31drd_phy_reset(phy_drd, 0);
+	exynosautov920_usb31drd_lane0_reset(phy_drd, 0);
+
+	/* Pipe_rx0_sris_mode_en  = 1 */
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG4);
+	reg |= PHY_CONFIG4_PIPE_RX0_SRIS_MODE_EN;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG4);
+
+	/*
+	 * wait for lane ack outputs to de-assert (tx_ack = rx_ack = 0)
+	 * Exit from the reset state is indicated by de-assertion of *_ack
+	 */
+	exynosautov920_usb31drd_port_phy_ready(phy_drd);
+
+	/* override values for level settings */
+	exynosautov920_usb31drd_cr_write(phy_drd, 0x22, 0x00F5);
+}
+
+static void
+exynosautov920_usb31drd_ssphy_disable(struct exynos5_usbdrd_phy *phy_drd)
+{
+	void __iomem *reg_phy = phy_drd->reg_phy;
+	u32 reg;
+
+	/* 1. Assert reset (phy_reset = 1) */
+	exynosautov920_usb31drd_lane0_reset(phy_drd, 1);
+	exynosautov920_usb31drd_phy_reset(phy_drd, 1);
+
+	/* phy test power down */
+	reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG7);
+	reg |= PHY_CONFIG7_PHY_TEST_POWERDOWN;
+	writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG7);
+}
+
 static void
 exynosautov920_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd)
 {
@@ -2172,12 +2447,15 @@ exynosautov920_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd)
 	/* after POR low and delay 75us, PHYCLOCK is guaranteed. */
 	fsleep(75);
 
-	/* force pipe3 signal for link */
+	/* Disable forcing pipe interface */
 	reg = readl(reg_phy + EXYNOS850_DRD_LINKCTRL);
-	reg |= LINKCTRL_FORCE_PIPE_EN;
-	reg &= ~LINKCTRL_FORCE_PHYSTATUS;
-	reg |= LINKCTRL_FORCE_RXELECIDLE;
+	reg &= ~LINKCTRL_FORCE_PIPE_EN;
 	writel(reg, reg_phy + EXYNOS850_DRD_LINKCTRL);
+
+	/* Pclk to pipe_clk */
+	reg = readl(reg_phy + EXYNOS2200_DRD_CLKRST);
+	reg |= EXYNOS2200_CLKRST_LINK_PCLK_SEL;
+	writel(reg, reg_phy + EXYNOS2200_DRD_CLKRST);
 }
 
 static void
@@ -2264,6 +2542,8 @@ static int exynosautov920_usbdrd_combo_phy_exit(struct phy *phy)
 
 	if (inst->phy_cfg->id == EXYNOS5_DRDPHY_UTMI)
 		exynosautov920_usbdrd_hsphy_disable(phy_drd);
+	else if (inst->phy_cfg->id == EXYNOS5_DRDPHY_PIPE3)
+		exynosautov920_usb31drd_ssphy_disable(phy_drd);
 
 	/* enable PHY isol */
 	inst->phy_cfg->phy_isol(inst, true);
@@ -2320,10 +2600,44 @@ static int exynosautov920_usbdrd_phy_power_off(struct phy *phy)
 	return 0;
 }
 
+static const char * const exynosautov920_usb30_regulators[] = {
+	"dvdd075-usb30", "vdd18-usb30",
+};
+
 static const char * const exynosautov920_usb20_regulators[] = {
 	"dvdd075-usb20", "vdd18-usb20", "vdd33-usb20",
 };
 
+static const struct
+exynos5_usbdrd_phy_config usb31drd_phy_cfg_exynosautov920[] = {
+	{
+		.id		= EXYNOS5_DRDPHY_PIPE3,
+		.phy_isol	= exynos5_usbdrd_phy_isol,
+		.phy_init	= exynosautov920_usb31drd_pipe3_init,
+	},
+};
+
+static const struct phy_ops exynosautov920_usb31drd_combo_ssphy_ops = {
+	.init		= exynosautov920_usbdrd_phy_init,
+	.exit		= exynosautov920_usbdrd_combo_phy_exit,
+	.power_on	= exynosautov920_usbdrd_phy_power_on,
+	.power_off	= exynosautov920_usbdrd_phy_power_off,
+	.owner		= THIS_MODULE,
+};
+
+static const
+struct exynos5_usbdrd_phy_drvdata exynosautov920_usb31drd_combo_ssphy = {
+	.phy_cfg		= usb31drd_phy_cfg_exynosautov920,
+	.phy_ops		= &exynosautov920_usb31drd_combo_ssphy_ops,
+	.pmu_offset_usbdrd0_phy	= EXYNOSAUTOV920_PHY_CTRL_USB31,
+	.clk_names		= exynos5_clk_names,
+	.n_clks			= ARRAY_SIZE(exynos5_clk_names),
+	.core_clk_names		= exynos5_core_clk_names,
+	.n_core_clks		= ARRAY_SIZE(exynos5_core_clk_names),
+	.regulator_names	= exynosautov920_usb30_regulators,
+	.n_regulators		= ARRAY_SIZE(exynosautov920_usb30_regulators),
+};
+
 static const struct phy_ops exynosautov920_usbdrd_combo_hsphy_ops = {
 	.init		= exynosautov920_usbdrd_phy_init,
 	.exit		= exynosautov920_usbdrd_combo_phy_exit,
@@ -2588,6 +2902,9 @@ static const struct of_device_id exynos5_usbdrd_phy_of_match[] = {
 	}, {
 		.compatible = "samsung,exynos990-usbdrd-phy",
 		.data = &exynos990_usbdrd_phy
+	}, {
+		.compatible = "samsung,exynosautov920-usb31drd-combo-ssphy",
+		.data = &exynosautov920_usb31drd_combo_ssphy
 	}, {
 		.compatible = "samsung,exynosautov920-usbdrd-combo-hsphy",
 		.data = &exynosautov920_usbdrd_combo_hsphy
diff --git a/include/linux/soc/samsung/exynos-regs-pmu.h b/include/linux/soc/samsung/exynos-regs-pmu.h
index 4923f9be3d1f..f96c773b85c9 100644
--- a/include/linux/soc/samsung/exynos-regs-pmu.h
+++ b/include/linux/soc/samsung/exynos-regs-pmu.h
@@ -690,4 +690,5 @@
 
 /* exynosautov920 */
 #define EXYNOSAUTOV920_PHY_CTRL_USB20				(0x0710)
+#define EXYNOSAUTOV920_PHY_CTRL_USB31				(0x0714)
 #endif /* __LINUX_SOC_EXYNOS_REGS_PMU_H */
-- 
2.34.1



From krzk at kernel.org  Fri Aug 22 02:33:51 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 22 Aug 2025 11:33:51 +0200
Subject: [PATCH v2 2/7] dt-bindings: phy: rockchip-inno-csi-dphy: make
 power-domains non-required
In-Reply-To: <20250616-rk3588-csi-dphy-v2-2-7a94f079b712@collabora.com>
References: <20250616-rk3588-csi-dphy-v2-0-7a94f079b712@collabora.com>
 <20250616-rk3588-csi-dphy-v2-2-7a94f079b712@collabora.com>
Message-ID: <20250822-chirpy-capuchin-of-apotheosis-1133fc@kuoka>

On Tue, Aug 19, 2025 at 01:00:36AM +0200, Michael Riesch wrote:
> There are variants of the Rockchip Innosilicon CSI DPHY (e.g., the RK3568
> variant) that are powered on by default as they are part of the ALIVE power
> domain.
> Remove 'power-domains' from the required properties in order to avoid false
> negatives.
> 
> Fixes: 22c8e0a69b7f ("dt-bindings: phy: add compatible for rk356x to rockchip-inno-csi-dphy")
> Cc: stable at kernel.org
> Signed-off-by: Michael Riesch <michael.riesch at collabora.com>
> ---
>  Documentation/devicetree/bindings/phy/rockchip-inno-csi-dphy.yaml | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/phy/rockchip-inno-csi-dphy.yaml b/Documentation/devicetree/bindings/phy/rockchip-inno-csi-dphy.yaml
> index 5ac994b3c0aa..42da616ae2e3 100644
> --- a/Documentation/devicetree/bindings/phy/rockchip-inno-csi-dphy.yaml
> +++ b/Documentation/devicetree/bindings/phy/rockchip-inno-csi-dphy.yaml
> @@ -57,7 +57,6 @@ required:
>    - clocks
>    - clock-names
>    - '#phy-cells'
> -  - power-domains

This could then be restricted per each variant in if:then:.

Best regards,
Krzysztof



From qiang.yu at oss.qualcomm.com  Fri Aug 22 03:05:04 2025
From: qiang.yu at oss.qualcomm.com (Qiang Yu)
Date: Fri, 22 Aug 2025 18:05:04 +0800
Subject: [PATCH v5 1/3] PCI: qcom: Add equalization settings for 8.0 GT/s
 and 32.0 GT/s
In-Reply-To: <z54p5x5u56u7dprrlv3obzhxotjgimbufa2spajoqvnlrevgdd@4dejnkmiegrh>
References: <20250819071649.1531437-1-ziyue.zhang@oss.qualcomm.com>
 <20250819071649.1531437-2-ziyue.zhang@oss.qualcomm.com>
 <z54p5x5u56u7dprrlv3obzhxotjgimbufa2spajoqvnlrevgdd@4dejnkmiegrh>
Message-ID: <b43382fc-a2c3-4c6b-b462-0cabf7a2103d@oss.qualcomm.com>



On 8/22/2025 4:06 PM, Manivannan Sadhasivam wrote:
> On Tue, Aug 19, 2025 at 03:16:46PM GMT, Ziyue Zhang wrote:
>> Add lane equalization setting for 8.0 GT/s and 32.0 GT/s to enhance link
>> stability and avoid AER Correctable Errors reported on some platforms
>> (eg. SA8775P).
>>
> 
> So this is fixing an issue, right? Then you should add relevant Fixes tag. I
> guess the tag here would be the commit that added SA8775p.
> 
>> 8.0 GT/s, 16.0 GT/s and 32.0 GT/s require the same equalization setting.
>> This setting is programmed into a group of shadow registers, which can be
>> switched to configure equalization for different speeds by writing 00b,
>> 01b and 10b to `RATE_SHADOW_SEL`.
>>
>> Hence program equalization registers in a loop using link speed as index,
>> so that equalization setting can be programmed for 8.0 GT/s, 16.0 GT/s
>> and 32.0 GT/s.
>>
>> Co-developed-by: Qiang Yu <qiang.yu at oss.qualcomm.com>
>> Signed-off-by: Qiang Yu <qiang.yu at oss.qualcomm.com>
>> Signed-off-by: Ziyue Zhang <ziyue.zhang at oss.qualcomm.com>
>> ---
>>   drivers/pci/controller/dwc/pcie-designware.h  |  1 -
>>   drivers/pci/controller/dwc/pcie-qcom-common.c | 58 +++++++++++--------
>>   drivers/pci/controller/dwc/pcie-qcom-common.h |  2 +-
>>   drivers/pci/controller/dwc/pcie-qcom-ep.c     |  6 +-
>>   drivers/pci/controller/dwc/pcie-qcom.c        |  6 +-
>>   5 files changed, 41 insertions(+), 32 deletions(-)
>>
>> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
>> index b5e7e18138a6..11de844428e5 100644
>> --- a/drivers/pci/controller/dwc/pcie-designware.h
>> +++ b/drivers/pci/controller/dwc/pcie-designware.h
>> @@ -123,7 +123,6 @@
>>   #define GEN3_RELATED_OFF_GEN3_EQ_DISABLE	BIT(16)
>>   #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_SHIFT	24
>>   #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK	GENMASK(25, 24)
>> -#define GEN3_RELATED_OFF_RATE_SHADOW_SEL_16_0GT	0x1
>>   
>>   #define GEN3_EQ_CONTROL_OFF			0x8A8
>>   #define GEN3_EQ_CONTROL_OFF_FB_MODE		GENMASK(3, 0)
>> diff --git a/drivers/pci/controller/dwc/pcie-qcom-common.c b/drivers/pci/controller/dwc/pcie-qcom-common.c
>> index 3aad19b56da8..cb98e66d81d9 100644
>> --- a/drivers/pci/controller/dwc/pcie-qcom-common.c
>> +++ b/drivers/pci/controller/dwc/pcie-qcom-common.c
>> @@ -8,9 +8,11 @@
>>   #include "pcie-designware.h"
>>   #include "pcie-qcom-common.h"
>>   
>> -void qcom_pcie_common_set_16gt_equalization(struct dw_pcie *pci)
>> +void qcom_pcie_common_set_equalization(struct dw_pcie *pci)
>>   {
>>   	u32 reg;
>> +	u16 speed;
>> +	struct device *dev = pci->dev;
> 
> Reverse Xmas order please.
> 
>>   
>>   	/*
>>   	 * GEN3_RELATED_OFF register is repurposed to apply equalization
>> @@ -19,32 +21,40 @@ void qcom_pcie_common_set_16gt_equalization(struct dw_pcie *pci)
>>   	 * determines the data rate for which these equalization settings are
>>   	 * applied.
>>   	 */
>> -	reg = dw_pcie_readl_dbi(pci, GEN3_RELATED_OFF);
>> -	reg &= ~GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL;
>> -	reg &= ~GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK;
>> -	reg |= FIELD_PREP(GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK,
>> -			  GEN3_RELATED_OFF_RATE_SHADOW_SEL_16_0GT);
>> -	dw_pcie_writel_dbi(pci, GEN3_RELATED_OFF, reg);
>>   
>> -	reg = dw_pcie_readl_dbi(pci, GEN3_EQ_FB_MODE_DIR_CHANGE_OFF);
>> -	reg &= ~(GEN3_EQ_FMDC_T_MIN_PHASE23 |
>> -		GEN3_EQ_FMDC_N_EVALS |
>> -		GEN3_EQ_FMDC_MAX_PRE_CUSROR_DELTA |
>> -		GEN3_EQ_FMDC_MAX_POST_CUSROR_DELTA);
>> -	reg |= FIELD_PREP(GEN3_EQ_FMDC_T_MIN_PHASE23, 0x1) |
>> -		FIELD_PREP(GEN3_EQ_FMDC_N_EVALS, 0xd) |
>> -		FIELD_PREP(GEN3_EQ_FMDC_MAX_PRE_CUSROR_DELTA, 0x5) |
>> -		FIELD_PREP(GEN3_EQ_FMDC_MAX_POST_CUSROR_DELTA, 0x5);
>> -	dw_pcie_writel_dbi(pci, GEN3_EQ_FB_MODE_DIR_CHANGE_OFF, reg);
>> +	for (speed = PCIE_SPEED_8_0GT; speed <= pcie_link_speed[pci->max_link_speed]; ++speed) {
>> +		if (speed > PCIE_SPEED_32_0GT) {
>> +			dev_warn(dev, "Skipped equalization settings for speeds higher than 32.0 GT/s\n");
>> +			break;
>> +		}
>>   
>> -	reg = dw_pcie_readl_dbi(pci, GEN3_EQ_CONTROL_OFF);
>> -	reg &= ~(GEN3_EQ_CONTROL_OFF_FB_MODE |
>> -		GEN3_EQ_CONTROL_OFF_PHASE23_EXIT_MODE |
>> -		GEN3_EQ_CONTROL_OFF_FOM_INC_INITIAL_EVAL |
>> -		GEN3_EQ_CONTROL_OFF_PSET_REQ_VEC);
>> -	dw_pcie_writel_dbi(pci, GEN3_EQ_CONTROL_OFF, reg);
>> +		reg = dw_pcie_readl_dbi(pci, GEN3_RELATED_OFF);
>> +		reg &= ~GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL;
>> +		reg &= ~GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK;
>> +		reg |= FIELD_PREP(GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK,
>> +			  speed - PCIE_SPEED_8_0GT);
>> +		dw_pcie_writel_dbi(pci, GEN3_RELATED_OFF, reg);
>> +
>> +		reg = dw_pcie_readl_dbi(pci, GEN3_EQ_FB_MODE_DIR_CHANGE_OFF);
>> +		reg &= ~(GEN3_EQ_FMDC_T_MIN_PHASE23 |
>> +			GEN3_EQ_FMDC_N_EVALS |
>> +			GEN3_EQ_FMDC_MAX_PRE_CUSROR_DELTA |
>> +			GEN3_EQ_FMDC_MAX_POST_CUSROR_DELTA);
>> +		reg |= FIELD_PREP(GEN3_EQ_FMDC_T_MIN_PHASE23, 0x1) |
>> +			FIELD_PREP(GEN3_EQ_FMDC_N_EVALS, 0xd) |
>> +			FIELD_PREP(GEN3_EQ_FMDC_MAX_PRE_CUSROR_DELTA, 0x5) |
>> +			FIELD_PREP(GEN3_EQ_FMDC_MAX_POST_CUSROR_DELTA, 0x5);
>> +		dw_pcie_writel_dbi(pci, GEN3_EQ_FB_MODE_DIR_CHANGE_OFF, reg);
>> +
>> +		reg = dw_pcie_readl_dbi(pci, GEN3_EQ_CONTROL_OFF);
>> +		reg &= ~(GEN3_EQ_CONTROL_OFF_FB_MODE |
>> +			GEN3_EQ_CONTROL_OFF_PHASE23_EXIT_MODE |
>> +			GEN3_EQ_CONTROL_OFF_FOM_INC_INITIAL_EVAL |
>> +			GEN3_EQ_CONTROL_OFF_PSET_REQ_VEC);
>> +		dw_pcie_writel_dbi(pci, GEN3_EQ_CONTROL_OFF, reg);
>> +	}
>>   }
>> -EXPORT_SYMBOL_GPL(qcom_pcie_common_set_16gt_equalization);
>> +EXPORT_SYMBOL_GPL(qcom_pcie_common_set_equalization);
>>   
>>   void qcom_pcie_common_set_16gt_lane_margining(struct dw_pcie *pci)
>>   {
>> diff --git a/drivers/pci/controller/dwc/pcie-qcom-common.h b/drivers/pci/controller/dwc/pcie-qcom-common.h
>> index 7d88d29e4766..7f5ca2fd9a72 100644
>> --- a/drivers/pci/controller/dwc/pcie-qcom-common.h
>> +++ b/drivers/pci/controller/dwc/pcie-qcom-common.h
>> @@ -8,7 +8,7 @@
>>   
>>   struct dw_pcie;
>>   
>> -void qcom_pcie_common_set_16gt_equalization(struct dw_pcie *pci);
>> +void qcom_pcie_common_set_equalization(struct dw_pcie *pci);
>>   void qcom_pcie_common_set_16gt_lane_margining(struct dw_pcie *pci);
>>   
>>   #endif
>> diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c
>> index 60afb4d0134c..aeb166f68d55 100644
>> --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c
>> +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c
>> @@ -511,10 +511,10 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci)
>>   		goto err_disable_resources;
>>   	}
>>   
>> -	if (pcie_link_speed[pci->max_link_speed] == PCIE_SPEED_16_0GT) {
>> -		qcom_pcie_common_set_16gt_equalization(pci);
>> +	qcom_pcie_common_set_equalization(pci);
>> +
>> +	if (pcie_link_speed[pci->max_link_speed] == PCIE_SPEED_16_0GT)
> 
> This condition has existed even before this patch, but just noticing this
> possible issue. So if 'max_link_speed' is > 16 GT/s, we do not need to set lane
> margining? We used the same logic to set equalization setting earlier also.

Lane margining is supported for 16 GT/s and 32 GT/s. The settings are
dependent on phy design. For a specific phy, they have same settings
for 16 GT/s and 32 GT/s. Perhaps we can get the settings from devicetree
and program them in a loop.

But I'm not sure why we need to program it. It will no affect singal
quality and only required when user wants to collect margining info.

- Qiang Yu

> 
> - Mani
> 



From dmitry.baryshkov at oss.qualcomm.com  Fri Aug 22 03:08:37 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Fri, 22 Aug 2025 13:08:37 +0300
Subject: [PATCH v3 07/14] phy: qcom: qmp-usbc: Move reset and regulator
 config into PHY cfg
In-Reply-To: <6f7c3962-ccfc-4400-a77f-399b06da93e1@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-7-a43bd25ec39c@oss.qualcomm.com>
 <ofvzduf5xyip7w6yde2xwsrvv3tdh7ew3yyzeya2qzpqty3j7p@bnetyjowhdn5>
 <6f7c3962-ccfc-4400-a77f-399b06da93e1@oss.qualcomm.com>
Message-ID: <llrt3xnd5gagovnmyzqebp2da5v67bkxjntfcgc5r5auamspyj@7v5taph3i3c4>

On Fri, Aug 22, 2025 at 04:29:28PM +0800, Xiangxu Yin wrote:
> 
> On 8/20/2025 7:30 PM, Dmitry Baryshkov wrote:
> > On Wed, Aug 20, 2025 at 05:34:49PM +0800, Xiangxu Yin wrote:
> >> Refactor reset and regulator configuration to be managed via qmp_phy_cfg
> >> instead of hardcoded lists. This enables per-PHY customization and
> >> simplifies initialization logic for USB-only and USB/DP switchable PHYs.
> > Please split into two patches in order to simplify reviewing.
> 
> 
> Ok, will split reset and regulator part.
> 
> 
> >> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
> >> ---
> >>  drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 108 +++++++++++++++----------------
> >>  1 file changed, 53 insertions(+), 55 deletions(-)
> >>
> >> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> >> index 61128d606238321d1b573655b3b987226aa2d594..4e797b7e65da0e3a827efa9a179f1c150c1b8b00 100644
> >> --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> >> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> >> @@ -421,8 +421,9 @@ struct qmp_phy_cfg {
> >>  	int (*configure_dp_phy)(struct qmp_usbc *qmp);
> >>  	int (*calibrate_dp_phy)(struct qmp_usbc *qmp);
> >>  
> >> -	/* regulators to be requested */
> >> -	const char * const *vreg_list;
> >> +	const char * const *reset_list;
> >> +	int num_resets;
> >> +	const struct regulator_bulk_data *vreg_list;
> >>  	int num_vregs;
> >>  
> >>  	/* array of registers with different offsets */
> >> @@ -453,7 +454,6 @@ struct qmp_usbc {
> >>  	struct clk_hw dp_pixel_hw;
> >>  	struct clk_bulk_data *clks;
> >>  	int num_clks;
> >> -	int num_resets;
> >>  	struct reset_control_bulk_data *resets;
> >>  	struct regulator_bulk_data *vregs;
> >>  
> >> @@ -514,9 +514,18 @@ static const char * const usb3phy_reset_l[] = {
> >>  	"phy_phy", "phy",
> >>  };
> >>  
> >> -/* list of regulators */
> >> -static const char * const qmp_phy_vreg_l[] = {
> >> -	"vdda-phy", "vdda-pll",
> >> +static const char * const usb3dpphy_reset_l[] = {
> >> +	"phy_phy", "dp_phy",
> >> +};
> >> +
> >> +static const struct regulator_bulk_data qmp_phy_usb_vreg_l[] = {
> >> +	{ .supply = "vdda-phy" },
> >> +	{ .supply = "vdda-pll" },
> > Please fill in the values for all platforms. It well might be that they
> > all share the same current requirements.
> 
> 
> I checked previous DP projects and found all platforms configured vdda-phy with 21.8mA and vdda-pll with 36mA.

No. On SDM660 and MSM8998 DP defines 73.4 mA for 0.9V supply and
12.560 mA for 1.8 V supply.

> 
> However, I didn?t find USB load configs in downstream and from SoC related power grids:

Please check the actual HW documentation for those platforms.

> QCS615
> L12A: VDDA_USB0_SS_1P8/VDDA_USB1_SS_1P8 Ipk:20ma
> L5A: VDDA_USB0_SS_0P9/VDDA_USB1_SS_0P9 Ipk:50mA
> 
> sm6150
> L11A: VDDA_USB0_SS_1P8/VDDA_USB1_SS_1P8 Ipk:20ma
> L4A: VDDA_USB0_SS_0P9/VDDA_USB1_SS_0P9 Ipk:50mA
> 
> SM6115
> L12A: VDDA_USB_SS_DP_1P8 Ipk:13.3mA
> L4A: VDDA_USB_SS_DP_CORE Ipk:66.1mA
> 
> QCM2290
> L13A: VDDA_USB_SS_DP_1P8 Ipk:13.3mA
> L12A: VDDA_USB_SS_DP_CORE Ipk:66.1mA
> 
> sdm660
> LDO10A: VDDA_USB_SS_1P8 Ipk:14mA
> LDO1B: VDDA_USB_SS_CORE Ipk:68.6mA
> 
> msm8998
> L2A: VDDA_USB_SS_1P2 Ipk:14.2mA
> L1A: VDDA_USB_SS_CORE Ipk:68.6mA
> 
> It seems the USB power requirements vary across platforms, and the
> 21800 ?A load for vdda-phy exceeds the Ipk range in most cases.

Ipk being ?

> I also tested removing the load settings for USB+DP PHY, and DP still works fine.

It mostly works either because we don't allow mode switching on older
platforms (yet) or because somebody else has already voted and that vote
keeps the required mode.

As you've started looking on specifying proper current load, please
finish the work.

> So, can we keep the regulator config as original qmp_phy_vreg_l?
> static const char * const qmp_phy_vreg_l[] = { "vdda-phy", "vdda-pll"}?
> 
> 
> >> +};
> >> +
> >> +static const struct regulator_bulk_data qmp_phy_usbdp_vreg_l[] = {
> >> +	{ .supply = "vdda-phy", .init_load_uA = 21800 },
> >> +	{ .supply = "vdda-phy", .init_load_uA = 36000 },
> > Typo
> 
> 
> Sorry for Typo, will fix in next patch.
> 
> 
> >>  };
> >>  
> >>  static const struct qmp_usbc_offsets qmp_usbc_offsets_v3_qcm2290 = {
> >> @@ -569,8 +578,10 @@ static const struct qmp_phy_cfg msm8998_usb3phy_cfg = {
> >>  	.rx_tbl_num             = ARRAY_SIZE(msm8998_usb3_rx_tbl),
> >>  	.pcs_tbl                = msm8998_usb3_pcs_tbl,
> >>  	.pcs_tbl_num            = ARRAY_SIZE(msm8998_usb3_pcs_tbl),
> >> -	.vreg_list              = qmp_phy_vreg_l,
> >> -	.num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
> >> +	.reset_list		= usb3phy_reset_l,
> >> +	.num_resets		= ARRAY_SIZE(usb3phy_reset_l),
> >> +	.vreg_list              = qmp_phy_usb_vreg_l,
> >> +	.num_vregs              = ARRAY_SIZE(qmp_phy_usb_vreg_l),
> >>  	.regs                   = qmp_v3_usb3phy_regs_layout,
> >>  };
> >>  
> >> @@ -586,8 +597,10 @@ static const struct qmp_phy_cfg qcm2290_usb3phy_cfg = {
> >>  	.rx_tbl_num		= ARRAY_SIZE(qcm2290_usb3_rx_tbl),
> >>  	.pcs_tbl		= qcm2290_usb3_pcs_tbl,
> >>  	.pcs_tbl_num		= ARRAY_SIZE(qcm2290_usb3_pcs_tbl),
> >> -	.vreg_list		= qmp_phy_vreg_l,
> >> -	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
> >> +	.reset_list		= usb3phy_reset_l,
> >> +	.num_resets		= ARRAY_SIZE(usb3phy_reset_l),
> >> +	.vreg_list		= qmp_phy_usb_vreg_l,
> >> +	.num_vregs		= ARRAY_SIZE(qmp_phy_usb_vreg_l),
> >>  	.regs			= qmp_v3_usb3phy_regs_layout_qcm2290,
> >>  };
> >>  
> >> @@ -603,8 +616,10 @@ static const struct qmp_phy_cfg sdm660_usb3phy_cfg = {
> >>  	.rx_tbl_num		= ARRAY_SIZE(sdm660_usb3_rx_tbl),
> >>  	.pcs_tbl		= qcm2290_usb3_pcs_tbl,
> >>  	.pcs_tbl_num		= ARRAY_SIZE(qcm2290_usb3_pcs_tbl),
> >> -	.vreg_list		= qmp_phy_vreg_l,
> >> -	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
> >> +	.reset_list		= usb3phy_reset_l,
> >> +	.num_resets		= ARRAY_SIZE(usb3phy_reset_l),
> >> +	.vreg_list		= qmp_phy_usb_vreg_l,
> >> +	.num_vregs		= ARRAY_SIZE(qmp_phy_usb_vreg_l),
> >>  	.regs			= qmp_v3_usb3phy_regs_layout_qcm2290,
> >>  };
> >>  
> >> @@ -637,6 +652,11 @@ static const struct qmp_phy_cfg qcs615_usb3dp_phy_cfg = {
> >>  
> >>  	.swing_tbl		= &qmp_dp_voltage_swing_hbr2_rbr,
> >>  	.pre_emphasis_tbl	= &qmp_dp_pre_emphasis_hbr2_rbr,
> >> +
> >> +	.reset_list		= usb3dpphy_reset_l,
> >> +	.num_resets		= ARRAY_SIZE(usb3dpphy_reset_l),
> >> +	.vreg_list		= qmp_phy_usbdp_vreg_l,
> >> +	.num_vregs		= ARRAY_SIZE(qmp_phy_usbdp_vreg_l),
> >>  };
> >>  
> >>  static int qmp_usbc_com_init(struct phy *phy)
> >> @@ -653,13 +673,13 @@ static int qmp_usbc_com_init(struct phy *phy)
> >>  		return ret;
> >>  	}
> >>  
> >> -	ret = reset_control_bulk_assert(qmp->num_resets, qmp->resets);
> >> +	ret = reset_control_bulk_assert(cfg->num_resets, qmp->resets);
> >>  	if (ret) {
> >>  		dev_err(qmp->dev, "reset assert failed\n");
> >>  		goto err_disable_regulators;
> >>  	}
> >>  
> >> -	ret = reset_control_bulk_deassert(qmp->num_resets, qmp->resets);
> >> +	ret = reset_control_bulk_deassert(cfg->num_resets, qmp->resets);
> >>  	if (ret) {
> >>  		dev_err(qmp->dev, "reset deassert failed\n");
> >>  		goto err_disable_regulators;
> >> @@ -682,7 +702,7 @@ static int qmp_usbc_com_init(struct phy *phy)
> >>  	return 0;
> >>  
> >>  err_assert_reset:
> >> -	reset_control_bulk_assert(qmp->num_resets, qmp->resets);
> >> +	reset_control_bulk_assert(cfg->num_resets, qmp->resets);
> >>  err_disable_regulators:
> >>  	regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
> >>  
> >> @@ -694,7 +714,7 @@ static int qmp_usbc_com_exit(struct phy *phy)
> >>  	struct qmp_usbc *qmp = phy_get_drvdata(phy);
> >>  	const struct qmp_phy_cfg *cfg = qmp->cfg;
> >>  
> >> -	reset_control_bulk_assert(qmp->num_resets, qmp->resets);
> >> +	reset_control_bulk_assert(cfg->num_resets, qmp->resets);
> >>  
> >>  	clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks);
> >>  
> >> @@ -921,42 +941,22 @@ static const struct dev_pm_ops qmp_usbc_pm_ops = {
> >>  			   qmp_usbc_runtime_resume, NULL)
> >>  };
> >>  
> >> -static int qmp_usbc_vreg_init(struct qmp_usbc *qmp)
> >> +static int qmp_usbc_reset_init(struct qmp_usbc *qmp)
> >>  {
> >>  	const struct qmp_phy_cfg *cfg = qmp->cfg;
> >> -	struct device *dev = qmp->dev;
> >> -	int num = cfg->num_vregs;
> >> -	int i;
> >> -
> >> -	qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL);
> >> -	if (!qmp->vregs)
> >> -		return -ENOMEM;
> >> -
> >> -	for (i = 0; i < num; i++)
> >> -		qmp->vregs[i].supply = cfg->vreg_list[i];
> >> -
> >> -	return devm_regulator_bulk_get(dev, num, qmp->vregs);
> >> -}
> >> -
> >> -static int qmp_usbc_reset_init(struct qmp_usbc *qmp,
> >> -			      const char *const *reset_list,
> >> -			      int num_resets)
> >> -{
> >>  	struct device *dev = qmp->dev;
> >>  	int i;
> >>  	int ret;
> >>  
> >> -	qmp->resets = devm_kcalloc(dev, num_resets,
> >> +	qmp->resets = devm_kcalloc(dev, cfg->num_resets,
> >>  				   sizeof(*qmp->resets), GFP_KERNEL);
> >>  	if (!qmp->resets)
> >>  		return -ENOMEM;
> >>  
> >> -	for (i = 0; i < num_resets; i++)
> >> -		qmp->resets[i].id = reset_list[i];
> >> +	for (i = 0; i < cfg->num_resets; i++)
> >> +		qmp->resets[i].id = cfg->reset_list[i];
> >>  
> >> -	qmp->num_resets = num_resets;
> >> -
> >> -	ret = devm_reset_control_bulk_get_exclusive(dev, num_resets, qmp->resets);
> >> +	ret = devm_reset_control_bulk_get_exclusive(dev, cfg->num_resets, qmp->resets);
> >>  	if (ret)
> >>  		return dev_err_probe(dev, ret, "failed to get resets\n");
> >>  
> >> @@ -1146,11 +1146,6 @@ static int qmp_usbc_parse_usb_dt_legacy(struct qmp_usbc *qmp, struct device_node
> >>  
> >>  	qmp->num_clks = ret;
> >>  
> >> -	ret = qmp_usbc_reset_init(qmp, usb3phy_legacy_reset_l,
> >> -				 ARRAY_SIZE(usb3phy_legacy_reset_l));
> >> -	if (ret)
> >> -		return ret;
> >> -
> >>  	return 0;
> >>  }
> >>  
> >> @@ -1187,14 +1182,9 @@ static int qmp_usbc_parse_usb_dt(struct qmp_usbc *qmp)
> >>  	qmp->pipe_clk = devm_clk_get(dev, "pipe");
> >>  	if (IS_ERR(qmp->pipe_clk)) {
> >>  		return dev_err_probe(dev, PTR_ERR(qmp->pipe_clk),
> >> -				     "failed to get pipe clock\n");
> >> +					"failed to get pipe clock\n");
> > unrelated
> 
> 
> Ack.
> 
> 
> >>  	}
> >>  
> >> -	ret = qmp_usbc_reset_init(qmp, usb3phy_reset_l,
> >> -				 ARRAY_SIZE(usb3phy_reset_l));
> >> -	if (ret)
> >> -		return ret;
> >> -
> >>  	return 0;
> >>  }
> >>  
> >> @@ -1228,6 +1218,7 @@ static int qmp_usbc_probe(struct platform_device *pdev)
> >>  	struct phy_provider *phy_provider;
> >>  	struct device_node *np;
> >>  	struct qmp_usbc *qmp;
> >> +	const struct qmp_phy_cfg *cfg;
> >>  	int ret;
> >>  
> >>  	qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL);
> >> @@ -1239,13 +1230,20 @@ static int qmp_usbc_probe(struct platform_device *pdev)
> >>  
> >>  	qmp->orientation = TYPEC_ORIENTATION_NORMAL;
> >>  
> >> -	qmp->cfg = of_device_get_match_data(dev);
> >> -	if (!qmp->cfg)
> >> +	cfg = of_device_get_match_data(dev);
> >> +	if (!cfg)
> >>  		return -EINVAL;
> >>  
> >> +	qmp->cfg = cfg;
> > Why? This doesn't seem related at all.
> 
> 
> I added the?|cfg|?variable to simplify access to?|num_vregs|?and?|vreg_list|?in the following lines,?
> 
> avoiding repeated?|qmp->cfg->...|?usage.?
> 
> If this is considered unrelated, I?ll remove it in the next version.

This all gets clogged in a mixture of regulator and reset changes.
Hopefully it will be more obvious with the patches being split.

> 
> 
> >
> >> +
> >>  	mutex_init(&qmp->phy_mutex);
> >>  
> >> -	ret = qmp_usbc_vreg_init(qmp);
> >> +	ret = qmp_usbc_reset_init(qmp);
> >> +	if (ret)
> >> +		return ret;
> >> +
> >> +	ret = devm_regulator_bulk_get_const(qmp->dev, cfg->num_vregs,
> >> +					 cfg->vreg_list, &qmp->vregs);
> >>  	if (ret)
> >>  		return ret;
> >>  
> >>
> >> -- 
> >> 2.34.1
> >>

-- 
With best wishes
Dmitry


From dmitry.baryshkov at oss.qualcomm.com  Fri Aug 22 03:09:12 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Fri, 22 Aug 2025 13:09:12 +0300
Subject: [PATCH v3 08/14] phy: qcom: qmp-usbc: Add DP PHY configuration
 support for QCS615
In-Reply-To: <2e3c1559-7da2-4c6e-bcef-eb1e8dfd4c31@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-8-a43bd25ec39c@oss.qualcomm.com>
 <su3zkeepxaislh6q5ftqxp6uxsyg7usxmc5hkafw7yn2mgtqeu@wua72odmy7zp>
 <2e3c1559-7da2-4c6e-bcef-eb1e8dfd4c31@oss.qualcomm.com>
Message-ID: <tdmjo5et4ohwg3g5z7wr4dhvvlqbd4z6nfo2hbzpyo77e6okdp@z5f7hlvyovx6>

On Fri, Aug 22, 2025 at 04:43:11PM +0800, Xiangxu Yin wrote:
> 
> On 8/20/2025 7:16 PM, Dmitry Baryshkov wrote:
> > On Wed, Aug 20, 2025 at 05:34:50PM +0800, Xiangxu Yin wrote:
> >> Introduce DisplayPort PHY configuration routines for QCS615, including
> >> aux channel setup, lane control, voltage swing tuning, clock
> >> programming and calibration. These callbacks are registered via
> >> qmp_phy_cfg to enable DP mode on USB/DP switchable Type-C PHYs.
> >>
> >> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
> >> ---
> >>  drivers/phy/qualcomm/phy-qcom-qmp-dp-phy.h |   1 +
> >>  drivers/phy/qualcomm/phy-qcom-qmp-usbc.c   | 251 +++++++++++++++++++++++++++++
> >>  2 files changed, 252 insertions(+)
> >>
> >> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy.h b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy.h
> >> index 0ebd405bcaf0cac8215550bfc9b226f30cc43a59..59885616405f878885d0837838a0bac1899fb69f 100644
> >> --- a/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy.h
> >> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy.h
> >> @@ -25,6 +25,7 @@
> >>  #define QSERDES_DP_PHY_AUX_CFG7				0x03c
> >>  #define QSERDES_DP_PHY_AUX_CFG8				0x040
> >>  #define QSERDES_DP_PHY_AUX_CFG9				0x044
> >> +#define QSERDES_DP_PHY_VCO_DIV				0x068
> > This register changes between PHY versions, so you can not declare it here.
> >
> > Otherwise LGTM.
> 
> 
> Ok.
> 
> This PHY appears to be QMP_DP_PHY_V2,?but there's no dedicated header for it yet.?
> 
> I?ll create?|phy-qcom-qmp-dp-phy-v2.h|?next patch and define?|VCO_DIV|?and shared offsets with V3 will be redefined accordingly.

Nice! Thanks.

> 
> 
> >
> >>  
> >>  /* QSERDES COM_BIAS_EN_CLKBUFLR_EN bits */
> >>  # define QSERDES_V3_COM_BIAS_EN				0x0001

-- 
With best wishes
Dmitry


From mani at kernel.org  Fri Aug 22 03:56:01 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Fri, 22 Aug 2025 16:26:01 +0530
Subject: [PATCH V3 2/2] phy: qcom-qmp-ufs: Add regulator loads for SM8650
 and SM8750
In-Reply-To: <2635ced4-b91f-4c79-ae2a-079f06bbb8a9@quicinc.com>
References: <20250819222832.8471-1-quic_nitirawa@quicinc.com>
 <20250819222832.8471-3-quic_nitirawa@quicinc.com>
 <ger4kizeltjwalfuwu4dpfjiskrv2okgo5c7d6n3pb24yaxgfo@nkcndblyx3il>
 <xir3u3hlmcvfu6uasijz6g2oialoasmuu4bno6ctxpscqcebz6@6kw6xpm5bxbd>
 <761c97bb-ee90-4ace-acd3-08349831aade@oss.qualcomm.com>
 <2635ced4-b91f-4c79-ae2a-079f06bbb8a9@quicinc.com>
Message-ID: <pp3hr3kssytyfuuesdfrzdo6hm6e3tjlahla53mlmydetsgxdy@wmxwkatf7lvr>

On Fri, Aug 22, 2025 at 02:53:31PM GMT, Nitin Rawat wrote:
> 
> 
> On 8/22/2025 2:45 PM, Dmitry Baryshkov wrote:
> > On 22/08/2025 11:53, Manivannan Sadhasivam wrote:
> > > On Wed, Aug 20, 2025 at 03:49:31AM GMT, Dmitry Baryshkov wrote:
> > > > On Wed, Aug 20, 2025 at 03:58:26AM +0530, Nitin Rawat wrote:
> > > > > Add regulator load voting support for SM8650 and SM8750 platforms by
> > > > > introducing dedicated regulator bulk data arrays with their load
> > > > > values.
> > > > > 
> > > > > The load requirements are:
> > > > > - SM8650: vdda-phy (205mA), vdda-pll (17.5mA)
> > > > > - SM8750: vdda-phy (213mA), vdda-pll (18.3mA)
> > > > > 
> > > > > This ensures stable operation and proper power management for these
> > > > > platforms where regulators are shared between the QMP USB PHY and
> > > > > other IP blocks by setting appropriate regulator load
> > > > > currents during PHY
> > > > > operations.
> > > > > 
> > > > > Configurations without specific load requirements will continue to work
> > > > > unchanged, as init_load_uA remains zero-initialized when .init_load_uA
> > > > > is not provided.
> > > > 
> > > > Can we please get configuration for the rest of the platforms?
> > > > 
> > > 
> > > Only if the rest of the platforms require setting the load... It is
> > > not very
> > > clear if the older platforms share the regulators with other IPs or not.
> > 
> > Yes, they are usually shared. USB. PCIe and DSI frequently sit on the
> > same voltage rails.
> 
> Yes, it?s typically shared across multiple clients.
> 
> However, as I mentioned earlier, in the current upstream codebase, the
> "regulator-allow-set-load" property is defined only for SM8750 and SM8650
> within the PMIC PHY and PLL device tree nodes. This means that even if the
> UFS PHY driver is updated to vote for this configuration on other platforms,
> it will have no effect, as the property is not supported there.
> 

Which means:

1. Those platforms are still prone to this stability issue.
2. Only UFS is setting the regulator constraint, but not other drivers sharing
the same regulator.

IMO, both cases are bad. At leat, you can update the UFS driver to set the load
now and later on add the DTS property as a follow-up series for those platforms.

- Mani

-- 
????????? ????????


From dmitry.baryshkov at oss.qualcomm.com  Fri Aug 22 03:57:07 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Fri, 22 Aug 2025 13:57:07 +0300
Subject: [PATCH RFC 1/3] dt-bindings: phy: qcom,sc8280xp-qmp-usb43dp-phy:
 Document default phy mode
In-Reply-To: <20250821-topic-x1e80100-hdmi-v1-1-f14ad9430e88@linaro.org>
References: <20250821-topic-x1e80100-hdmi-v1-0-f14ad9430e88@linaro.org>
 <20250821-topic-x1e80100-hdmi-v1-1-f14ad9430e88@linaro.org>
Message-ID: <yc7ceoq3bn3lkxdwkrk64ecubej64vblpwlwzyj5cuep2wmjui@nln2t2yicu7o>

On Thu, Aug 21, 2025 at 03:53:26PM +0200, Neil Armstrong wrote:
> The QMP USB3/DP Combo PHY hosts an USB3 phy and a DP PHY on top
> of a combo glue to route either lanes to the 4 shared physical lanes.
> 
> The routing of the lanes can be:
> - 2 DP + 2 USB3
> - 4 DP
> - 2 USB3
> 
> And the layout of the lanes can be swpped depending of an
> eventual USB-C connector orientation.
> 
> Nevertheless those QMP Comby PHY can be statically used to
> drive a DisplayPort connector, DP->HDMI bridge, USB3 A Connector...
> 
> But if a 4lanes DP->HDMI bridge is directly connected to the
> QMP Comby PHY lanes, in the default routing 2 or the 4 lanes would
> probbaly be USB3, making the DP->HDMI bridge non functional.
> 
> Add a property to hint in which layout mode the QMP Comby PHY
> should be as startup.
> 
> Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
> ---
>  .../bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml         | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml
> index c8bc512df08b5694c8599f475de78679a4438449..129475a1d9527733e43ded5a38aad766f9810fe7 100644
> --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml
> +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml
> @@ -76,6 +76,19 @@ properties:
>    mode-switch: true
>    orientation-switch: true
>  
> +  qcom,combo-initial-mode:
> +    description:
> +      Describe the initial mode of the Combo PHY configuration.
> +      The Combo PHY is a wrapper on top of a DP PHY and an USB3 PHY,
> +      sharing the same SuperSpeed lanes with either DisplayPort over
> +      the 4 lanes (dp), USB3 on a pair of lanes (usb3) or both
> +      technologies in a 2+2 configuration (usb3+dp) as default.

SPecifying this as an initial mode means that it can be switched later.
Should we generalize this and desribe it as bus-type (from
video-interfaces.yaml) and allow it to be present only if there is no
mode-switch property?


> +    default: usb3+dp
> +    enum:
> +      - usb3+dp
> +      - usb3
> +      - dp
> +
>    ports:
>      $ref: /schemas/graph.yaml#/properties/ports
>      properties:
> 
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry


From dmitry.baryshkov at oss.qualcomm.com  Fri Aug 22 04:01:30 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Fri, 22 Aug 2025 14:01:30 +0300
Subject: [PATCH RFC 3/3] arm64: dts: qcom: x1e78100-lenovo-thinkpad-t14s:
 add HDMI nodes
In-Reply-To: <20250821-topic-x1e80100-hdmi-v1-3-f14ad9430e88@linaro.org>
References: <20250821-topic-x1e80100-hdmi-v1-0-f14ad9430e88@linaro.org>
 <20250821-topic-x1e80100-hdmi-v1-3-f14ad9430e88@linaro.org>
Message-ID: <as7pbmhfgsg3ht3s5lu25pfjjamaxyonuohkuohono3kr2mxii@posspuko4vwa>

On Thu, Aug 21, 2025 at 03:53:28PM +0200, Neil Armstrong wrote:
> The Thinkpad T14s embeds a transparent 4lanes DP->HDMI transceiver
> connected to the third QMP Combo PHY 4 lanes.
> 
> Add all the data routing, disable mode switching and specify the
> QMP Combo PHY should be in DP-Only mode to route the 4 lanes to
> the underlying DP phy.
> 
> Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
> ---
>  .../dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi    | 44 ++++++++++++++++++++++
>  1 file changed, 44 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi
> index 4cf61c2a34e31233b1adc93332bcabef22de3f86..5b62b8c3123633360f249e3ecdc8ea23f44e8e09 100644
> --- a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi
> +++ b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi
> @@ -62,6 +62,20 @@ switch-lid {
>  		};
>  	};
>  
> +
> +	hdmi-connector {
> +		compatible = "hdmi-connector";
> +		type = "a";
> +		pinctrl-0 = <&hdmi_hpd_default>;
> +		pinctrl-names = "default";

If this is a DP HPD signal, it should be a part of the DP device.

> +
> +		port {
> +			hdmi_con: endpoint {
> +				remote-endpoint = <&usb_1_ss2_qmpphy_out>;

Please describe the transparent bridge too. It can be covered by the
simple-bridge.yaml / simple-bridge.c


> +			};
> +		};
> +	};
> +
>  	pmic-glink {
>  		compatible = "qcom,x1e80100-pmic-glink",
>  			     "qcom,sm8550-pmic-glink",
> @@ -1007,6 +1021,14 @@ &mdss_dp1_out {
>  	link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>;
>  };
>  
> +&mdss_dp2 {
> +	status = "okay";
> +};
> +
> +&mdss_dp2_out {
> +	data-lanes = <0 1 2 3>;
> +};
> +
>  &mdss_dp3 {
>  	/delete-property/ #sound-dai-cells;
>  
> @@ -1263,6 +1285,12 @@ &tlmm {
>  			       <72 2>, /* Secure EC I2C connection (?) */
>  			       <238 1>; /* UFS Reset */
>  
> +	hdmi_hpd_default: hdmi-hpd-default-state {
> +		pins = "gpio126";
> +		function = "usb2_dp";
> +		bias-disable;
> +	};
> +
>  	eusb3_reset_n: eusb3-reset-n-state {
>  		pins = "gpio6";
>  		function = "gpio";
> @@ -1486,6 +1514,22 @@ &usb_1_ss0_qmpphy_out {
>  	remote-endpoint = <&retimer_ss0_ss_in>;
>  };
>  
> +&usb_1_ss2_qmpphy {
> +	vdda-phy-supply = <&vreg_l2j_1p2>;
> +	vdda-pll-supply = <&vreg_l2d_0p9>;
> +
> +	qcom,combo-initial-mode = "dp";
> +
> +	/delete-property/ mode-switch;
> +	/delete-property/ orientation-switch;
> +
> +	status = "okay";
> +};
> +
> +&usb_1_ss2_qmpphy_out {
> +	remote-endpoint = <&hdmi_con>;
> +};
> +
>  &usb_1_ss1_hsphy {
>  	vdd-supply = <&vreg_l3j_0p8>;
>  	vdda12-supply = <&vreg_l2j_1p2>;
> 
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry


From neil.armstrong at linaro.org  Fri Aug 22 04:02:21 2025
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Fri, 22 Aug 2025 13:02:21 +0200
Subject: [PATCH RFC 1/3] dt-bindings: phy: qcom,sc8280xp-qmp-usb43dp-phy:
 Document default phy mode
In-Reply-To: <yc7ceoq3bn3lkxdwkrk64ecubej64vblpwlwzyj5cuep2wmjui@nln2t2yicu7o>
References: <20250821-topic-x1e80100-hdmi-v1-0-f14ad9430e88@linaro.org>
 <20250821-topic-x1e80100-hdmi-v1-1-f14ad9430e88@linaro.org>
 <yc7ceoq3bn3lkxdwkrk64ecubej64vblpwlwzyj5cuep2wmjui@nln2t2yicu7o>
Message-ID: <018751b8-8b9c-4966-94e2-f3ec8625f87d@linaro.org>

On 22/08/2025 12:57, Dmitry Baryshkov wrote:
> On Thu, Aug 21, 2025 at 03:53:26PM +0200, Neil Armstrong wrote:
>> The QMP USB3/DP Combo PHY hosts an USB3 phy and a DP PHY on top
>> of a combo glue to route either lanes to the 4 shared physical lanes.
>>
>> The routing of the lanes can be:
>> - 2 DP + 2 USB3
>> - 4 DP
>> - 2 USB3
>>
>> And the layout of the lanes can be swpped depending of an
>> eventual USB-C connector orientation.
>>
>> Nevertheless those QMP Comby PHY can be statically used to
>> drive a DisplayPort connector, DP->HDMI bridge, USB3 A Connector...
>>
>> But if a 4lanes DP->HDMI bridge is directly connected to the
>> QMP Comby PHY lanes, in the default routing 2 or the 4 lanes would
>> probbaly be USB3, making the DP->HDMI bridge non functional.
>>
>> Add a property to hint in which layout mode the QMP Comby PHY
>> should be as startup.
>>
>> Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
>> ---
>>   .../bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml         | 13 +++++++++++++
>>   1 file changed, 13 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml
>> index c8bc512df08b5694c8599f475de78679a4438449..129475a1d9527733e43ded5a38aad766f9810fe7 100644
>> --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml
>> +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml
>> @@ -76,6 +76,19 @@ properties:
>>     mode-switch: true
>>     orientation-switch: true
>>   
>> +  qcom,combo-initial-mode:
>> +    description:
>> +      Describe the initial mode of the Combo PHY configuration.
>> +      The Combo PHY is a wrapper on top of a DP PHY and an USB3 PHY,
>> +      sharing the same SuperSpeed lanes with either DisplayPort over
>> +      the 4 lanes (dp), USB3 on a pair of lanes (usb3) or both
>> +      technologies in a 2+2 configuration (usb3+dp) as default.
> 
> SPecifying this as an initial mode means that it can be switched later.
> Should we generalize this and desribe it as bus-type (from
> video-interfaces.yaml) and allow it to be present only if there is no
> mode-switch property?

I was not sure about that, and yes we should do that instead but I'm not
sure about how.

bus-type sounds great, but the numbering doesn't match so I was thinking instead
something like phy-type with a string or use the numbers from include/dt-bindings/phy/phy.h

The thing is, do we want to keep the dual dp+usb3 as static ? I think it's very possible
a board would connect the combo phy to an USB3 A connector and a 2lanes DisplayPort connector.

Neil

> 
> 
>> +    default: usb3+dp
>> +    enum:
>> +      - usb3+dp
>> +      - usb3
>> +      - dp
>> +
>>     ports:
>>       $ref: /schemas/graph.yaml#/properties/ports
>>       properties:
>>
>> -- 
>> 2.34.1
>>
> 



From neil.armstrong at linaro.org  Fri Aug 22 04:02:56 2025
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Fri, 22 Aug 2025 13:02:56 +0200
Subject: [PATCH RFC 3/3] arm64: dts: qcom: x1e78100-lenovo-thinkpad-t14s:
 add HDMI nodes
In-Reply-To: <as7pbmhfgsg3ht3s5lu25pfjjamaxyonuohkuohono3kr2mxii@posspuko4vwa>
References: <20250821-topic-x1e80100-hdmi-v1-0-f14ad9430e88@linaro.org>
 <20250821-topic-x1e80100-hdmi-v1-3-f14ad9430e88@linaro.org>
 <as7pbmhfgsg3ht3s5lu25pfjjamaxyonuohkuohono3kr2mxii@posspuko4vwa>
Message-ID: <431de5f8-2dca-4ec0-9b94-fcc12480e8c9@linaro.org>

On 22/08/2025 13:01, Dmitry Baryshkov wrote:
> On Thu, Aug 21, 2025 at 03:53:28PM +0200, Neil Armstrong wrote:
>> The Thinkpad T14s embeds a transparent 4lanes DP->HDMI transceiver
>> connected to the third QMP Combo PHY 4 lanes.
>>
>> Add all the data routing, disable mode switching and specify the
>> QMP Combo PHY should be in DP-Only mode to route the 4 lanes to
>> the underlying DP phy.
>>
>> Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
>> ---
>>   .../dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi    | 44 ++++++++++++++++++++++
>>   1 file changed, 44 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi
>> index 4cf61c2a34e31233b1adc93332bcabef22de3f86..5b62b8c3123633360f249e3ecdc8ea23f44e8e09 100644
>> --- a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi
>> +++ b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi
>> @@ -62,6 +62,20 @@ switch-lid {
>>   		};
>>   	};
>>   
>> +
>> +	hdmi-connector {
>> +		compatible = "hdmi-connector";
>> +		type = "a";
>> +		pinctrl-0 = <&hdmi_hpd_default>;
>> +		pinctrl-names = "default";
> 
> If this is a DP HPD signal, it should be a part of the DP device.
> 
>> +
>> +		port {
>> +			hdmi_con: endpoint {
>> +				remote-endpoint = <&usb_1_ss2_qmpphy_out>;
> 
> Please describe the transparent bridge too. It can be covered by the
> simple-bridge.yaml / simple-bridge.c

Ack, indeed it could take the pinctrl thing.

Neil

> 
> 
>> +			};
>> +		};
>> +	};
>> +
>>   	pmic-glink {
>>   		compatible = "qcom,x1e80100-pmic-glink",
>>   			     "qcom,sm8550-pmic-glink",
>> @@ -1007,6 +1021,14 @@ &mdss_dp1_out {
>>   	link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>;
>>   };
>>   
>> +&mdss_dp2 {
>> +	status = "okay";
>> +};
>> +
>> +&mdss_dp2_out {
>> +	data-lanes = <0 1 2 3>;
>> +};
>> +
>>   &mdss_dp3 {
>>   	/delete-property/ #sound-dai-cells;
>>   
>> @@ -1263,6 +1285,12 @@ &tlmm {
>>   			       <72 2>, /* Secure EC I2C connection (?) */
>>   			       <238 1>; /* UFS Reset */
>>   
>> +	hdmi_hpd_default: hdmi-hpd-default-state {
>> +		pins = "gpio126";
>> +		function = "usb2_dp";
>> +		bias-disable;
>> +	};
>> +
>>   	eusb3_reset_n: eusb3-reset-n-state {
>>   		pins = "gpio6";
>>   		function = "gpio";
>> @@ -1486,6 +1514,22 @@ &usb_1_ss0_qmpphy_out {
>>   	remote-endpoint = <&retimer_ss0_ss_in>;
>>   };
>>   
>> +&usb_1_ss2_qmpphy {
>> +	vdda-phy-supply = <&vreg_l2j_1p2>;
>> +	vdda-pll-supply = <&vreg_l2d_0p9>;
>> +
>> +	qcom,combo-initial-mode = "dp";
>> +
>> +	/delete-property/ mode-switch;
>> +	/delete-property/ orientation-switch;
>> +
>> +	status = "okay";
>> +};
>> +
>> +&usb_1_ss2_qmpphy_out {
>> +	remote-endpoint = <&hdmi_con>;
>> +};
>> +
>>   &usb_1_ss1_hsphy {
>>   	vdd-supply = <&vreg_l3j_0p8>;
>>   	vdda12-supply = <&vreg_l2j_1p2>;
>>
>> -- 
>> 2.34.1
>>
> 



From quic_nitirawa at quicinc.com  Fri Aug 22 04:39:14 2025
From: quic_nitirawa at quicinc.com (Nitin Rawat)
Date: Fri, 22 Aug 2025 17:09:14 +0530
Subject: [PATCH V3 2/2] phy: qcom-qmp-ufs: Add regulator loads for SM8650
 and SM8750
In-Reply-To: <pp3hr3kssytyfuuesdfrzdo6hm6e3tjlahla53mlmydetsgxdy@wmxwkatf7lvr>
References: <20250819222832.8471-1-quic_nitirawa@quicinc.com>
 <20250819222832.8471-3-quic_nitirawa@quicinc.com>
 <ger4kizeltjwalfuwu4dpfjiskrv2okgo5c7d6n3pb24yaxgfo@nkcndblyx3il>
 <xir3u3hlmcvfu6uasijz6g2oialoasmuu4bno6ctxpscqcebz6@6kw6xpm5bxbd>
 <761c97bb-ee90-4ace-acd3-08349831aade@oss.qualcomm.com>
 <2635ced4-b91f-4c79-ae2a-079f06bbb8a9@quicinc.com>
 <pp3hr3kssytyfuuesdfrzdo6hm6e3tjlahla53mlmydetsgxdy@wmxwkatf7lvr>
Message-ID: <61070746-431d-4adf-9e68-7ae9646a44c9@quicinc.com>



On 8/22/2025 4:26 PM, Manivannan Sadhasivam wrote:
> On Fri, Aug 22, 2025 at 02:53:31PM GMT, Nitin Rawat wrote:
>>
>>
>> On 8/22/2025 2:45 PM, Dmitry Baryshkov wrote:
>>> On 22/08/2025 11:53, Manivannan Sadhasivam wrote:
>>>> On Wed, Aug 20, 2025 at 03:49:31AM GMT, Dmitry Baryshkov wrote:
>>>>> On Wed, Aug 20, 2025 at 03:58:26AM +0530, Nitin Rawat wrote:
>>>>>> Add regulator load voting support for SM8650 and SM8750 platforms by
>>>>>> introducing dedicated regulator bulk data arrays with their load
>>>>>> values.
>>>>>>
>>>>>> The load requirements are:
>>>>>> - SM8650: vdda-phy (205mA), vdda-pll (17.5mA)
>>>>>> - SM8750: vdda-phy (213mA), vdda-pll (18.3mA)
>>>>>>
>>>>>> This ensures stable operation and proper power management for these
>>>>>> platforms where regulators are shared between the QMP USB PHY and
>>>>>> other IP blocks by setting appropriate regulator load
>>>>>> currents during PHY
>>>>>> operations.
>>>>>>
>>>>>> Configurations without specific load requirements will continue to work
>>>>>> unchanged, as init_load_uA remains zero-initialized when .init_load_uA
>>>>>> is not provided.
>>>>>
>>>>> Can we please get configuration for the rest of the platforms?
>>>>>
>>>>
>>>> Only if the rest of the platforms require setting the load... It is
>>>> not very
>>>> clear if the older platforms share the regulators with other IPs or not.
>>>
>>> Yes, they are usually shared. USB. PCIe and DSI frequently sit on the
>>> same voltage rails.
>>
>> Yes, it?s typically shared across multiple clients.
>>
>> However, as I mentioned earlier, in the current upstream codebase, the
>> "regulator-allow-set-load" property is defined only for SM8750 and SM8650
>> within the PMIC PHY and PLL device tree nodes. This means that even if the
>> UFS PHY driver is updated to vote for this configuration on other platforms,
>> it will have no effect, as the property is not supported there.
>>
> 
> Which means:
> 
> 1. Those platforms are still prone to this stability issue.
> 2. Only UFS is setting the regulator constraint, but not other drivers sharing
> the same regulator.

You understanding is correct.

> 
> IMO, both cases are bad. At leat, you can update the UFS driver to set the load
> now and later on add the DTS property as a follow-up series for those platforms.


sure will take care of this.>
> - Mani



> 



From dmitry.baryshkov at oss.qualcomm.com  Fri Aug 22 04:39:47 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Fri, 22 Aug 2025 14:39:47 +0300
Subject: [PATCH RFC 1/3] dt-bindings: phy: qcom,sc8280xp-qmp-usb43dp-phy:
 Document default phy mode
In-Reply-To: <018751b8-8b9c-4966-94e2-f3ec8625f87d@linaro.org>
References: <20250821-topic-x1e80100-hdmi-v1-0-f14ad9430e88@linaro.org>
 <20250821-topic-x1e80100-hdmi-v1-1-f14ad9430e88@linaro.org>
 <yc7ceoq3bn3lkxdwkrk64ecubej64vblpwlwzyj5cuep2wmjui@nln2t2yicu7o>
 <018751b8-8b9c-4966-94e2-f3ec8625f87d@linaro.org>
Message-ID: <kxevo35c7tsbjeu4b7ep3f4eld5t4ohy35x4igaki6n7uvteev@ifotwczstsn3>

On Fri, Aug 22, 2025 at 01:02:21PM +0200, Neil Armstrong wrote:
> On 22/08/2025 12:57, Dmitry Baryshkov wrote:
> > On Thu, Aug 21, 2025 at 03:53:26PM +0200, Neil Armstrong wrote:
> > > The QMP USB3/DP Combo PHY hosts an USB3 phy and a DP PHY on top
> > > of a combo glue to route either lanes to the 4 shared physical lanes.
> > > 
> > > The routing of the lanes can be:
> > > - 2 DP + 2 USB3
> > > - 4 DP
> > > - 2 USB3
> > > 
> > > And the layout of the lanes can be swpped depending of an
> > > eventual USB-C connector orientation.
> > > 
> > > Nevertheless those QMP Comby PHY can be statically used to
> > > drive a DisplayPort connector, DP->HDMI bridge, USB3 A Connector...
> > > 
> > > But if a 4lanes DP->HDMI bridge is directly connected to the
> > > QMP Comby PHY lanes, in the default routing 2 or the 4 lanes would
> > > probbaly be USB3, making the DP->HDMI bridge non functional.
> > > 
> > > Add a property to hint in which layout mode the QMP Comby PHY
> > > should be as startup.
> > > 
> > > Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
> > > ---
> > >   .../bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml         | 13 +++++++++++++
> > >   1 file changed, 13 insertions(+)
> > > 
> > > diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml
> > > index c8bc512df08b5694c8599f475de78679a4438449..129475a1d9527733e43ded5a38aad766f9810fe7 100644
> > > --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml
> > > +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml
> > > @@ -76,6 +76,19 @@ properties:
> > >     mode-switch: true
> > >     orientation-switch: true
> > > +  qcom,combo-initial-mode:
> > > +    description:
> > > +      Describe the initial mode of the Combo PHY configuration.
> > > +      The Combo PHY is a wrapper on top of a DP PHY and an USB3 PHY,
> > > +      sharing the same SuperSpeed lanes with either DisplayPort over
> > > +      the 4 lanes (dp), USB3 on a pair of lanes (usb3) or both
> > > +      technologies in a 2+2 configuration (usb3+dp) as default.
> > 
> > SPecifying this as an initial mode means that it can be switched later.
> > Should we generalize this and desribe it as bus-type (from
> > video-interfaces.yaml) and allow it to be present only if there is no
> > mode-switch property?
> 
> I was not sure about that, and yes we should do that instead but I'm not
> sure about how.
> 
> bus-type sounds great, but the numbering doesn't match so I was thinking instead
> something like phy-type with a string or use the numbers from include/dt-bindings/phy/phy.h

Well... we can add more entries there and map them in the driver.

> 
> The thing is, do we want to keep the dual dp+usb3 as static ? I think it's very possible
> a board would connect the combo phy to an USB3 A connector and a 2lanes DisplayPort connector.

I'm not sure I follow the question. Could you please explain what you've
meant here?


-- 
With best wishes
Dmitry


From dmitry.baryshkov at oss.qualcomm.com  Fri Aug 22 04:40:38 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Fri, 22 Aug 2025 14:40:38 +0300
Subject: [PATCH RFC 3/3] arm64: dts: qcom: x1e78100-lenovo-thinkpad-t14s:
 add HDMI nodes
In-Reply-To: <431de5f8-2dca-4ec0-9b94-fcc12480e8c9@linaro.org>
References: <20250821-topic-x1e80100-hdmi-v1-0-f14ad9430e88@linaro.org>
 <20250821-topic-x1e80100-hdmi-v1-3-f14ad9430e88@linaro.org>
 <as7pbmhfgsg3ht3s5lu25pfjjamaxyonuohkuohono3kr2mxii@posspuko4vwa>
 <431de5f8-2dca-4ec0-9b94-fcc12480e8c9@linaro.org>
Message-ID: <k6n4ojdhsr2sjxoyrvo7qdoajdxbrjuuxfuhw76wrmpegdyayo@arumyjto7kpp>

On Fri, Aug 22, 2025 at 01:02:56PM +0200, Neil Armstrong wrote:
> On 22/08/2025 13:01, Dmitry Baryshkov wrote:
> > On Thu, Aug 21, 2025 at 03:53:28PM +0200, Neil Armstrong wrote:
> > > The Thinkpad T14s embeds a transparent 4lanes DP->HDMI transceiver
> > > connected to the third QMP Combo PHY 4 lanes.
> > > 
> > > Add all the data routing, disable mode switching and specify the
> > > QMP Combo PHY should be in DP-Only mode to route the 4 lanes to
> > > the underlying DP phy.
> > > 
> > > Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
> > > ---
> > >   .../dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi    | 44 ++++++++++++++++++++++
> > >   1 file changed, 44 insertions(+)
> > > 
> > > diff --git a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi
> > > index 4cf61c2a34e31233b1adc93332bcabef22de3f86..5b62b8c3123633360f249e3ecdc8ea23f44e8e09 100644
> > > --- a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi
> > > +++ b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi
> > > @@ -62,6 +62,20 @@ switch-lid {
> > >   		};
> > >   	};
> > > +
> > > +	hdmi-connector {
> > > +		compatible = "hdmi-connector";
> > > +		type = "a";
> > > +		pinctrl-0 = <&hdmi_hpd_default>;
> > > +		pinctrl-names = "default";
> > 
> > If this is a DP HPD signal, it should be a part of the DP device.
> > 
> > > +
> > > +		port {
> > > +			hdmi_con: endpoint {
> > > +				remote-endpoint = <&usb_1_ss2_qmpphy_out>;
> > 
> > Please describe the transparent bridge too. It can be covered by the
> > simple-bridge.yaml / simple-bridge.c
> 
> Ack, indeed it could take the pinctrl thing.

Pinctrl, enables, etc.

But from my POV the HPD pin should be a part of the DP controller
itself.

> 
> Neil
> 
> > 
> > 
> > > +			};
> > > +		};
> > > +	};
> > > +
> > >   	pmic-glink {
> > >   		compatible = "qcom,x1e80100-pmic-glink",
> > >   			     "qcom,sm8550-pmic-glink",
> > > @@ -1007,6 +1021,14 @@ &mdss_dp1_out {
> > >   	link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>;
> > >   };
> > > +&mdss_dp2 {
> > > +	status = "okay";
> > > +};
> > > +
> > > +&mdss_dp2_out {
> > > +	data-lanes = <0 1 2 3>;
> > > +};
> > > +
> > >   &mdss_dp3 {
> > >   	/delete-property/ #sound-dai-cells;
> > > @@ -1263,6 +1285,12 @@ &tlmm {
> > >   			       <72 2>, /* Secure EC I2C connection (?) */
> > >   			       <238 1>; /* UFS Reset */
> > > +	hdmi_hpd_default: hdmi-hpd-default-state {
> > > +		pins = "gpio126";
> > > +		function = "usb2_dp";
> > > +		bias-disable;
> > > +	};
> > > +
> > >   	eusb3_reset_n: eusb3-reset-n-state {
> > >   		pins = "gpio6";
> > >   		function = "gpio";
> > > @@ -1486,6 +1514,22 @@ &usb_1_ss0_qmpphy_out {
> > >   	remote-endpoint = <&retimer_ss0_ss_in>;
> > >   };
> > > +&usb_1_ss2_qmpphy {
> > > +	vdda-phy-supply = <&vreg_l2j_1p2>;
> > > +	vdda-pll-supply = <&vreg_l2d_0p9>;
> > > +
> > > +	qcom,combo-initial-mode = "dp";
> > > +
> > > +	/delete-property/ mode-switch;
> > > +	/delete-property/ orientation-switch;
> > > +
> > > +	status = "okay";
> > > +};
> > > +
> > > +&usb_1_ss2_qmpphy_out {
> > > +	remote-endpoint = <&hdmi_con>;
> > > +};
> > > +
> > >   &usb_1_ss1_hsphy {
> > >   	vdd-supply = <&vreg_l3j_0p8>;
> > >   	vdda12-supply = <&vreg_l2j_1p2>;
> > > 
> > > -- 
> > > 2.34.1
> > > 
> > 
> 

-- 
With best wishes
Dmitry


From stephan.gerhold at linaro.org  Fri Aug 22 04:45:38 2025
From: stephan.gerhold at linaro.org (Stephan Gerhold)
Date: Fri, 22 Aug 2025 13:45:38 +0200
Subject: [PATCH RFC 3/3] arm64: dts: qcom: x1e78100-lenovo-thinkpad-t14s:
 add HDMI nodes
In-Reply-To: <as7pbmhfgsg3ht3s5lu25pfjjamaxyonuohkuohono3kr2mxii@posspuko4vwa>
References: <20250821-topic-x1e80100-hdmi-v1-0-f14ad9430e88@linaro.org>
 <20250821-topic-x1e80100-hdmi-v1-3-f14ad9430e88@linaro.org>
 <as7pbmhfgsg3ht3s5lu25pfjjamaxyonuohkuohono3kr2mxii@posspuko4vwa>
Message-ID: <aKhYYjUuOQ7H1aPm@linaro.org>

On Fri, Aug 22, 2025 at 02:01:30PM +0300, Dmitry Baryshkov wrote:
> On Thu, Aug 21, 2025 at 03:53:28PM +0200, Neil Armstrong wrote:
> > The Thinkpad T14s embeds a transparent 4lanes DP->HDMI transceiver
> > connected to the third QMP Combo PHY 4 lanes.
> > 
> > Add all the data routing, disable mode switching and specify the
> > QMP Combo PHY should be in DP-Only mode to route the 4 lanes to
> > the underlying DP phy.
> > 
> > Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
> > ---
> >  .../dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi    | 44 ++++++++++++++++++++++
> >  1 file changed, 44 insertions(+)
> > 
> > diff --git a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi
> > index 4cf61c2a34e31233b1adc93332bcabef22de3f86..5b62b8c3123633360f249e3ecdc8ea23f44e8e09 100644
> > --- a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi
> > +++ b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi
> > @@ -62,6 +62,20 @@ switch-lid {
> >  		};
> >  	};
> >  
> > +
> > +	hdmi-connector {
> > +		compatible = "hdmi-connector";
> > +		type = "a";
> > +		pinctrl-0 = <&hdmi_hpd_default>;
> > +		pinctrl-names = "default";
> [...]
> > +
> > +		port {
> > +			hdmi_con: endpoint {
> > +				remote-endpoint = <&usb_1_ss2_qmpphy_out>;
> 
> Please describe the transparent bridge too. It can be covered by the
> simple-bridge.yaml / simple-bridge.c
> 

I think this isn't the case here(?), but how are we going to handle
devices where we don't know which bridge chip is used? I've seen at
least 3 or 4 different chips already across all X1E laptops and we don't
have schematics for most of them.

Thanks,
Stephan


From dmitry.baryshkov at oss.qualcomm.com  Fri Aug 22 04:57:24 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Fri, 22 Aug 2025 14:57:24 +0300
Subject: [PATCH RFC 3/3] arm64: dts: qcom: x1e78100-lenovo-thinkpad-t14s:
 add HDMI nodes
In-Reply-To: <aKhYYjUuOQ7H1aPm@linaro.org>
References: <20250821-topic-x1e80100-hdmi-v1-0-f14ad9430e88@linaro.org>
 <20250821-topic-x1e80100-hdmi-v1-3-f14ad9430e88@linaro.org>
 <as7pbmhfgsg3ht3s5lu25pfjjamaxyonuohkuohono3kr2mxii@posspuko4vwa>
 <aKhYYjUuOQ7H1aPm@linaro.org>
Message-ID: <26j2trl7lypmqzjnw6kwgqz32eqcags34qpgaua7zbwxd4lbgx@n54gemj42xbd>

On Fri, Aug 22, 2025 at 01:45:38PM +0200, Stephan Gerhold wrote:
> On Fri, Aug 22, 2025 at 02:01:30PM +0300, Dmitry Baryshkov wrote:
> > On Thu, Aug 21, 2025 at 03:53:28PM +0200, Neil Armstrong wrote:
> > > The Thinkpad T14s embeds a transparent 4lanes DP->HDMI transceiver
> > > connected to the third QMP Combo PHY 4 lanes.
> > > 
> > > Add all the data routing, disable mode switching and specify the
> > > QMP Combo PHY should be in DP-Only mode to route the 4 lanes to
> > > the underlying DP phy.
> > > 
> > > Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
> > > ---
> > >  .../dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi    | 44 ++++++++++++++++++++++
> > >  1 file changed, 44 insertions(+)
> > > 
> > > diff --git a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi
> > > index 4cf61c2a34e31233b1adc93332bcabef22de3f86..5b62b8c3123633360f249e3ecdc8ea23f44e8e09 100644
> > > --- a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi
> > > +++ b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi
> > > @@ -62,6 +62,20 @@ switch-lid {
> > >  		};
> > >  	};
> > >  
> > > +
> > > +	hdmi-connector {
> > > +		compatible = "hdmi-connector";
> > > +		type = "a";
> > > +		pinctrl-0 = <&hdmi_hpd_default>;
> > > +		pinctrl-names = "default";
> > [...]
> > > +
> > > +		port {
> > > +			hdmi_con: endpoint {
> > > +				remote-endpoint = <&usb_1_ss2_qmpphy_out>;
> > 
> > Please describe the transparent bridge too. It can be covered by the
> > simple-bridge.yaml / simple-bridge.c
> > 
> 
> I think this isn't the case here(?), but how are we going to handle
> devices where we don't know which bridge chip is used? I've seen at
> least 3 or 4 different chips already across all X1E laptops and we don't
> have schematics for most of them.

Open the case, inspect the board, identify the chip. Everything is as
usual.

-- 
With best wishes
Dmitry


From stephan.gerhold at linaro.org  Fri Aug 22 05:20:11 2025
From: stephan.gerhold at linaro.org (Stephan Gerhold)
Date: Fri, 22 Aug 2025 14:20:11 +0200
Subject: [PATCH RFC 3/3] arm64: dts: qcom: x1e78100-lenovo-thinkpad-t14s:
 add HDMI nodes
In-Reply-To: <26j2trl7lypmqzjnw6kwgqz32eqcags34qpgaua7zbwxd4lbgx@n54gemj42xbd>
References: <20250821-topic-x1e80100-hdmi-v1-0-f14ad9430e88@linaro.org>
 <20250821-topic-x1e80100-hdmi-v1-3-f14ad9430e88@linaro.org>
 <as7pbmhfgsg3ht3s5lu25pfjjamaxyonuohkuohono3kr2mxii@posspuko4vwa>
 <aKhYYjUuOQ7H1aPm@linaro.org>
 <26j2trl7lypmqzjnw6kwgqz32eqcags34qpgaua7zbwxd4lbgx@n54gemj42xbd>
Message-ID: <aKhge2ngLwj4uhmC@linaro.org>

On Fri, Aug 22, 2025 at 02:57:24PM +0300, Dmitry Baryshkov wrote:
> On Fri, Aug 22, 2025 at 01:45:38PM +0200, Stephan Gerhold wrote:
> > On Fri, Aug 22, 2025 at 02:01:30PM +0300, Dmitry Baryshkov wrote:
> > > On Thu, Aug 21, 2025 at 03:53:28PM +0200, Neil Armstrong wrote:
> > > > The Thinkpad T14s embeds a transparent 4lanes DP->HDMI transceiver
> > > > connected to the third QMP Combo PHY 4 lanes.
> > > > 
> > > > Add all the data routing, disable mode switching and specify the
> > > > QMP Combo PHY should be in DP-Only mode to route the 4 lanes to
> > > > the underlying DP phy.
> > > > 
> > > > Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
> > > > ---
> > > >  .../dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi    | 44 ++++++++++++++++++++++
> > > >  1 file changed, 44 insertions(+)
> > > > 
> > > > diff --git a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi
> > > > index 4cf61c2a34e31233b1adc93332bcabef22de3f86..5b62b8c3123633360f249e3ecdc8ea23f44e8e09 100644
> > > > --- a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi
> > > > +++ b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi
> > > > @@ -62,6 +62,20 @@ switch-lid {
> > > >  		};
> > > >  	};
> > > >  
> > > > +
> > > > +	hdmi-connector {
> > > > +		compatible = "hdmi-connector";
> > > > +		type = "a";
> > > > +		pinctrl-0 = <&hdmi_hpd_default>;
> > > > +		pinctrl-names = "default";
> > > [...]
> > > > +
> > > > +		port {
> > > > +			hdmi_con: endpoint {
> > > > +				remote-endpoint = <&usb_1_ss2_qmpphy_out>;
> > > 
> > > Please describe the transparent bridge too. It can be covered by the
> > > simple-bridge.yaml / simple-bridge.c
> > > 
> > 
> > I think this isn't the case here(?), but how are we going to handle
> > devices where we don't know which bridge chip is used? I've seen at
> > least 3 or 4 different chips already across all X1E laptops and we don't
> > have schematics for most of them.
> 
> Open the case, inspect the board, identify the chip. Everything is as
> usual.
> 

The chip might not have any visible identifier. :-) But I guess there is
no point theorizing about such potential issues now. We'll see. I agree
it would be cleaner to have the bridges modelled.

Thanks,
Stephan


From kuba at kernel.org  Fri Aug 22 07:01:48 2025
From: kuba at kernel.org (Jakub Kicinski)
Date: Fri, 22 Aug 2025 07:01:48 -0700
Subject: [PATCH v3] phy: ti: gmii-sel: Always write the RGMII ID setting
In-Reply-To: <DC8R5IJ2Q88K.YKUE9X9FZRNK@kernel.org>
References: <20250819065622.1019537-1-mwalle@kernel.org>
	<20250821181850.6af0ff7f@kernel.org>
	<DC8R5IJ2Q88K.YKUE9X9FZRNK@kernel.org>
Message-ID: <20250822070148.2e23c3f6@kernel.org>

On Fri, 22 Aug 2025 08:45:33 +0200 Michael Walle wrote:
> On Fri Aug 22, 2025 at 3:18 AM CEST, Jakub Kicinski wrote:
> > On Tue, 19 Aug 2025 08:56:22 +0200 Michael Walle wrote:  
> > > v3:
> > >  - simplify the logic. Thanks Matthias.
> > >  - reworded the commit message  
> >
> > This was set to Not Applicable in our patchwork, IDK why.
> > Could you resend?  
> 
> Won't this patch be picked up by the linux-phy tree?

Ah, poops, you're right! Let me adjust our filters..


From robh at kernel.org  Fri Aug 22 07:22:30 2025
From: robh at kernel.org (Rob Herring)
Date: Fri, 22 Aug 2025 09:22:30 -0500
Subject: [PATCH v3 02/14] dt-bindings: phy: Add QMP USB3+DP PHY for QCS615
In-Reply-To: <20250820-add-displayport-support-for-qcs615-platform-v3-2-a43bd25ec39c@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-2-a43bd25ec39c@oss.qualcomm.com>
Message-ID: <20250822142230.GA3591699-robh@kernel.org>

On Wed, Aug 20, 2025 at 05:34:44PM +0800, Xiangxu Yin wrote:
> Add device tree binding documentation for the Qualcomm QMP USB3+DP PHY
> on QCS615 Platform. This PHY supports both USB3 and DP functionality
> over USB-C, with PHY mode switching capability. It does not support
> combo mode.
> 
> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
> ---
>  .../bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml   | 108 +++++++++++++++++++++
>  1 file changed, 108 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml
> new file mode 100644
> index 0000000000000000000000000000000000000000..c2b1fbab2930f0653f4ddb95f7b54d8fe994f92d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml
> @@ -0,0 +1,108 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/phy/qcom,qcs615-qmp-usb3dp-phy.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Qualcomm QMP USB3-DP PHY controller (DP, QCS615)
> +
> +maintainers:
> +  - Vinod Koul <vkoul at kernel.org>

No, this should be someone who has the h/w.

> +
> +description:
> +  The QMP PHY controller supports physical layer functionality for both
> +  USB3 and DisplayPort over USB-C. While it enables mode switching
> +  between USB3 and DisplayPort, but does not support combo mode.

Wrap at 80 chars.

> +
> +properties:
> +  compatible:
> +    enum:
> +      - qcom,qcs615-qmp-usb3-dp-phy
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 2
> +
> +  clock-names:
> +    items:
> +      - const: cfg_ahb
> +      - const: ref
> +
> +  resets:
> +    maxItems: 2
> +
> +  reset-names:
> +    items:
> +      - const: phy_phy

phy_phy?

> +      - const: dp_phy
> +
> +  vdda-phy-supply: true
> +
> +  vdda-pll-supply: true
> +
> +  "#clock-cells":
> +    const: 1
> +    description:
> +      See include/dt-bindings/phy/phy-qcom-qmp.h
> +
> +  "#phy-cells":
> +    const: 1
> +    description:
> +      See include/dt-bindings/phy/phy-qcom-qmp.h
> +
> +  qcom,tcsr-reg:
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    items:
> +      - items:
> +          - description: phandle to TCSR hardware block
> +          - description: offset of the VLS CLAMP register
> +      - items:
> +          - description: phandle to TCSR hardware block
> +          - description: offset of the DP PHY mode register
> +    description: Clamp and PHY mode register present in the TCSR
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - clock-names
> +  - resets
> +  - reset-names
> +  - vdda-phy-supply
> +  - vdda-pll-supply
> +  - "#clock-cells"
> +  - "#phy-cells"
> +  - qcom,tcsr-reg
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/qcom,qcs615-gcc.h>
> +    #include <dt-bindings/clock/qcom,rpmh.h>
> +
> +    phy at 88e8000 {
> +      compatible = "qcom,qcs615-qmp-usb3-dp-phy";
> +      reg = <0x88e8000 0x2000>;
> +
> +      clocks = <&gcc GCC_AHB2PHY_WEST_CLK>,
> +               <&gcc GCC_USB3_SEC_CLKREF_CLK>;
> +      clock-names = "cfg_ahb",
> +                    "ref";
> +
> +      resets = <&gcc GCC_USB3PHY_PHY_SEC_BCR >,
> +               <&gcc GCC_USB3_DP_PHY_SEC_BCR>;
> +      reset-names = "phy_phy",
> +                    "dp_phy";
> +
> +      vdda-phy-supply = <&vreg_l11a>;
> +      vdda-pll-supply = <&vreg_l5a>;
> +
> +      #clock-cells = <1>;
> +      #phy-cells = <1>;
> +
> +      qcom,tcsr-reg = <&tcsr 0xbff0>,
> +                      <&tcsr 0xb24c>;
> +    };
> 
> -- 
> 2.34.1
> 


From heiko at sntech.de  Fri Aug 22 08:06:56 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 22 Aug 2025 17:06:56 +0200
Subject: (subset) [PATCH v5 0/6] Support RK3528 variant of Rockchip naneng-combphy
In-Reply-To: <20250728102947.38984-2-ziyao@disroot.org>
References: <20250728102947.38984-2-ziyao@disroot.org>
Message-ID: <175587519618.3220879.13156903990488376391.b4-ty@sntech.de>


On Mon, 28 Jul 2025 10:29:42 +0000, Yao Zi wrote:
> Rockchip RK3528 ships a naneng-combphy that operates in either PCIe or
> USB 3.0 mode. It has a similar control logic to previous generations of
> naneng-combphy but an apparently different register layout.
> 
> This series prepares phy-rockchip-naneng-combphy.c for variants with a
> different register layout and add RK3528 support.
> 
> [...]

Applied, thanks!

[6/6] arm64: dts: rockchip: Add naneng-combphy for RK3528
      commit: 70bb21cbc8c704c664b5d3ea417f3e35376fc229

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From robh at kernel.org  Fri Aug 22 09:18:28 2025
From: robh at kernel.org (Rob Herring)
Date: Fri, 22 Aug 2025 11:18:28 -0500
Subject: [PATCH 03/11] dt-bindings: phy: renesas: Document Renesas RZ/G3E
 USB3.0 PHY
In-Reply-To: <TY3PR01MB113467039A598C0EDC284AE198632A@TY3PR01MB11346.jpnprd01.prod.outlook.com>
References: <20250820171812.402519-1-biju.das.jz@bp.renesas.com>
 <20250820171812.402519-4-biju.das.jz@bp.renesas.com>
 <20250820-primer-shaded-66da9fa4bcae@spud>
 <20250820-commodity-curator-1f580789885b@spud>
 <TY3PR01MB113467039A598C0EDC284AE198632A@TY3PR01MB11346.jpnprd01.prod.outlook.com>
Message-ID: <20250822161828.GA3905962-robh@kernel.org>

On Thu, Aug 21, 2025 at 07:18:59AM +0000, Biju Das wrote:
> Hi Conor,
> 
> Thanks for the feedback.
> 
> > -----Original Message-----
> > From: Conor Dooley <conor at kernel.org>
> > Sent: 20 August 2025 21:13
> > Subject: Re: [PATCH 03/11] dt-bindings: phy: renesas: Document Renesas RZ/G3E USB3.0 PHY
> > 
> > On Wed, Aug 20, 2025 at 09:10:07PM +0100, Conor Dooley wrote:
> > > Acked-by: Conor Dooley <conor.dooley at microchip.com>
> > 
> > Now that I look again, same applies here with the different filename and compatible. Copypaste mistake?
> > Or why does the compatible not match the filename?
> > 
> 
> r9a09g047 is SoC part number which also known as RZ/G3E SoC.
> 
> I just followed the convention used in [1] and [2].
> Please let me know, should I change rzg3e-usb3-phy.yaml.yaml-> r9a09g047-usb3-phy.yaml ?

I think it is fine as-is.

Rob


From conor at kernel.org  Fri Aug 22 09:52:16 2025
From: conor at kernel.org (Conor Dooley)
Date: Fri, 22 Aug 2025 17:52:16 +0100
Subject: [PATCH 1/2] dt-bindings: phy: ti,tcan104x-can: Document TI
 TCAN1051
In-Reply-To: <20250822-can_phy3-v1-1-73b3ba1690ee@gocontroll.com>
References: <20250822-can_phy3-v1-0-73b3ba1690ee@gocontroll.com>
 <20250822-can_phy3-v1-1-73b3ba1690ee@gocontroll.com>
Message-ID: <20250822-gout-denture-688eeb65b6e0@spud>

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/20250822/cf2bf4da/attachment-0001.sig>

From conor at kernel.org  Fri Aug 22 09:55:22 2025
From: conor at kernel.org (Conor Dooley)
Date: Fri, 22 Aug 2025 17:55:22 +0100
Subject: [PATCH 1/6] dt-bindings: phy: ti,tcan104x-can: Document NXP
 TJA1051/1048
In-Reply-To: <20250822-can-v1-1-c075f702adea@nxp.com>
References: <20250822-can-v1-0-c075f702adea@nxp.com>
 <20250822-can-v1-1-c075f702adea@nxp.com>
Message-ID: <20250822-crop-ungreased-6494d68e388e@spud>

On Fri, Aug 22, 2025 at 12:05:28PM +0800, Peng Fan wrote:
> The TJA1051 is a high-speed CAN transceiver which is a pin-compatible
> alternative for TI TCAN1043 with Sleep mode supported, and has a compatible
> programming model, therefore use ti,tcan1043 as fallback compatible.
> 
> The TJA1048 is a dual high-speed CAN transceiver with Sleep mode supported.
> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  .../devicetree/bindings/phy/ti,tcan104x-can.yaml   | 29 +++++++++++++++++++---
>  1 file changed, 26 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml b/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
> index 4a8c3829d85d3c4a4963750d03567c1c345beb91..de4ab204ec86f91e84eba8f1a6343ed137e5cd71 100644
> --- a/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
> +++ b/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
> @@ -19,18 +19,21 @@ properties:
>            - enum:
>                - microchip,ata6561
>            - const: ti,tcan1042
> +      - items:
> +          - enum:
> +              - nxp,tja1051
> +          - const: ti,tcan1043
>        - enum:
>            - ti,tcan1042
>            - ti,tcan1043
> +          - nxp,tja1048
>            - nxp,tjr1443
>  
> -  '#phy-cells':
> -    const: 0
> +  '#phy-cells': true
>  
>    standby-gpios:
>      description:
>        gpio node to toggle standby signal on transceiver
> -    maxItems: 1

Please put the outtermost constraints here and narrow it down in the
else.

>  
>    enable-gpios:
>      description:
> @@ -53,6 +56,26 @@ required:
>    - compatible
>    - '#phy-cells'
>  
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: nxp,tja1048
> +
> +    then:
> +      properties:
> +        '#phy-cells':
> +          const: 1
> +        standby-gpios:
> +          maxItems: 2
> +    else:
> +      properties:
> +        '#phy-cells':
> +          const: 0
> +        standby-gpios:
> +          maxItems: 1
> +
>  additionalProperties: false
>  
>  examples:
> 
> -- 
> 2.37.1
> 
-------------- 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/20250822/b83e4bcc/attachment-0001.sig>

From dmitry.baryshkov at oss.qualcomm.com  Fri Aug 22 11:20:01 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Fri, 22 Aug 2025 21:20:01 +0300
Subject: [PATCH v3 02/14] dt-bindings: phy: Add QMP USB3+DP PHY for QCS615
In-Reply-To: <20250822142230.GA3591699-robh@kernel.org>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-2-a43bd25ec39c@oss.qualcomm.com>
 <20250822142230.GA3591699-robh@kernel.org>
Message-ID: <vbzqtpsjkxd5qhth4k2exo2dsnfmfn5km5i5z74wun7jc5j7nb@n7dqdw3t235v>

On Fri, Aug 22, 2025 at 09:22:30AM -0500, Rob Herring wrote:
> On Wed, Aug 20, 2025 at 05:34:44PM +0800, Xiangxu Yin wrote:
> > Add device tree binding documentation for the Qualcomm QMP USB3+DP PHY
> > on QCS615 Platform. This PHY supports both USB3 and DP functionality
> > over USB-C, with PHY mode switching capability. It does not support
> > combo mode.
> > 
> > Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
> > ---
> >  .../bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml   | 108 +++++++++++++++++++++
> >  1 file changed, 108 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml
> > new file mode 100644
> > index 0000000000000000000000000000000000000000..c2b1fbab2930f0653f4ddb95f7b54d8fe994f92d
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml

> > +
> > +  resets:
> > +    maxItems: 2
> > +
> > +  reset-names:
> > +    items:
> > +      - const: phy_phy
> 
> phy_phy?

Yes, see other Qualcomm USB PHYs. And unfortunately we can not use just
'phy' here. Once this lands I plan to push corresponding changes for
several other USBC PHYs (described in qcom,msm8998-qmp-usb3-phy.yaml)
and those will have both "phy" and "phy_phy" resets.

> 
> > +      - const: dp_phy
> > +

-- 
With best wishes
Dmitry


From robh at kernel.org  Fri Aug 22 13:15:22 2025
From: robh at kernel.org (Rob Herring (Arm))
Date: Fri, 22 Aug 2025 15:15:22 -0500
Subject: [PATCH v3 01/31] dt-bindings: media: add DW MIPI CSI-2 Host
 support
In-Reply-To: <20250821-95_cam-v3-1-c9286fbb34b9@nxp.com>
References: <20250821-95_cam-v3-0-c9286fbb34b9@nxp.com>
 <20250821-95_cam-v3-1-c9286fbb34b9@nxp.com>
Message-ID: <175589372183.282948.13173863715963070537.robh@kernel.org>


On Thu, 21 Aug 2025 16:15:36 -0400, Frank Li wrote:
> From: Eugen Hristev <eugen.hristev at linaro.org>
> 
> Add bindings for Synopsys DesignWare MIPI CSI-2 host, which used at i.MX93
> and i.MX95 platform.
> 
> Signed-off-by: Luis Oliveira <lolivei at synopsys.com>
> Signed-off-by: Eugen Hristev <eugen.hristev at linaro.org>
> Signed-off-by: Frank Li <Frank.Li at nxp.com>
> ---
> Change in v3
> - drop remote-endpoint: true
> - drop clock-lanes
> 
> Change in v2
> - remove Eugen Hristev <eugen.hristev at microchip.com> from mantainer.
> - update ugen Hristev's s-o-b tag to align original author's email address
> - remove single snps,dw-mipi-csi2-v150 compatible string
> - move additionalProperties after required
> ---
>  .../bindings/media/snps,dw-mipi-csi2-v150.yaml     | 151 +++++++++++++++++++++
>  MAINTAINERS                                        |   1 +
>  2 files changed, 152 insertions(+)
> 

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



From robh at kernel.org  Fri Aug 22 14:20:43 2025
From: robh at kernel.org (Rob Herring)
Date: Fri, 22 Aug 2025 16:20:43 -0500
Subject: [PATCH v4 1/6] dt-bindings: phy: qcom,sc8280xp-qmp-usb43dp:
 Reference usb-switch.yaml to allow mode-switch
In-Reply-To: <20250807-topic-4ln_dp_respin-v4-1-43272d6eca92@oss.qualcomm.com>
References: <20250807-topic-4ln_dp_respin-v4-0-43272d6eca92@oss.qualcomm.com>
 <20250807-topic-4ln_dp_respin-v4-1-43272d6eca92@oss.qualcomm.com>
Message-ID: <20250822212043.GA475528-robh@kernel.org>

On Thu, Aug 07, 2025 at 06:33:19PM +0200, Konrad Dybcio wrote:
> From: Neil Armstrong <neil.armstrong at linaro.org>
> 
> The QMP USB3/DP Combo PHY can work in 3 modes:
> - DisplayPort Only
> - USB3 Only
> - USB3 + DisplayPort Combo mode
> 
> In order to switch between those modes, the PHY needs to receive
> Type-C events, allow marking to the phy with the mode-switch
> property in order to allow the PHY to Type-C events.
> 
> Reference usb-switch.yaml as a simpler way to allow the mode-switch
> property instead of duplicating the property definition.
> 
> Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
> Reviewed-by: Krzysztof Kozlowski <krzk at kernel.org>
> Signed-off-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
> ---
>  .../devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml     | 7 +++----
>  1 file changed, 3 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml
> index 38ce04c35d945d0d8d319191c241920810ee9005..c8bc512df08b5694c8599f475de78679a4438449 100644
> --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml
> +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml
> @@ -73,10 +73,8 @@ properties:
>      description:
>        See include/dt-bindings/phy/phy-qcom-qmp.h
>  
> -  orientation-switch:
> -    description:
> -      Flag the PHY as possible handler of USB Type-C orientation switching
> -    type: boolean
> +  mode-switch: true
> +  orientation-switch: true
>  
>    ports:
>      $ref: /schemas/graph.yaml#/properties/ports
> @@ -106,6 +104,7 @@ required:
>    - "#phy-cells"
>  
>  allOf:
> +  - $ref: /schemas/usb/usb-switch.yaml#

As reported already in this thread, this adds a crap load of warnings as 
it makes ports or port required. Sigh. Can QCom folks pay more attention 
to this please. Every cycle the number goes up though that's often 
temporary because there's no coordination of taking .dts files after 
bindings. But generally, progress on QCom warnings has stalled.

Here's the top (bottom?) platforms in arm64. The first number is 
total warnings. The 2nd number is unique warnings (to remove inflated 
numbers due to lots of boards per SoC).

mediatek:785:166
hisilicon:133:112
qcom:362:104
broadcom:286:104
marvell:558:80
apm:78:58
rockchip:128:57
nvidia:199:53
sprd:30:29
xilinx:94:22

Congrats on 3rd place. There's a bunch of pending Mediatek fixes, so I 
expect you all will move up to 2nd soon. 

All this data is updated daily. There's some scripts to get and process 
the logs here[1].

Rob

[1] https://gitlab.com/robherring/ci-jobs.git


From sophon at radxa.com  Fri Aug 22 23:22:56 2025
From: sophon at radxa.com (Xilin Wu)
Date: Sat, 23 Aug 2025 14:22:56 +0800
Subject: [PATCH RFC 1/3] dt-bindings: phy: qcom,sc8280xp-qmp-usb43dp-phy:
 Document default phy mode
In-Reply-To: <018751b8-8b9c-4966-94e2-f3ec8625f87d@linaro.org>
References: <20250821-topic-x1e80100-hdmi-v1-0-f14ad9430e88@linaro.org>
 <20250821-topic-x1e80100-hdmi-v1-1-f14ad9430e88@linaro.org>
 <yc7ceoq3bn3lkxdwkrk64ecubej64vblpwlwzyj5cuep2wmjui@nln2t2yicu7o>
 <018751b8-8b9c-4966-94e2-f3ec8625f87d@linaro.org>
Message-ID: <8A7C126C22789C9B+f30def47-302a-45ee-8f76-64ef277f773f@radxa.com>

On 2025/8/22 19:02:21, Neil Armstrong wrote:
> On 22/08/2025 12:57, Dmitry Baryshkov wrote:
>> On Thu, Aug 21, 2025 at 03:53:26PM +0200, Neil Armstrong wrote:
>>> The QMP USB3/DP Combo PHY hosts an USB3 phy and a DP PHY on top
>>> of a combo glue to route either lanes to the 4 shared physical lanes.
>>>
>>> The routing of the lanes can be:
>>> - 2 DP + 2 USB3
>>> - 4 DP
>>> - 2 USB3
>>>
>>> And the layout of the lanes can be swpped depending of an
>>> eventual USB-C connector orientation.
>>>
>>> Nevertheless those QMP Comby PHY can be statically used to
>>> drive a DisplayPort connector, DP->HDMI bridge, USB3 A Connector...
>>>
>>> But if a 4lanes DP->HDMI bridge is directly connected to the
>>> QMP Comby PHY lanes, in the default routing 2 or the 4 lanes would
>>> probbaly be USB3, making the DP->HDMI bridge non functional.
>>>
>>> Add a property to hint in which layout mode the QMP Comby PHY
>>> should be as startup.
>>>
>>> Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
>>> ---
>>> ? .../bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml???????? | 13 ++ 
>>> +++++++++++
>>> ? 1 file changed, 13 insertions(+)
>>>
>>> diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp- 
>>> usb43dp-phy.yaml b/Documentation/devicetree/bindings/phy/ 
>>> qcom,sc8280xp-qmp-usb43dp-phy.yaml
>>> index 
>>> c8bc512df08b5694c8599f475de78679a4438449..129475a1d9527733e43ded5a38aad766f9810fe7 100644
>>> --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp- 
>>> usb43dp-phy.yaml
>>> +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp- 
>>> usb43dp-phy.yaml
>>> @@ -76,6 +76,19 @@ properties:
>>> ??? mode-switch: true
>>> ??? orientation-switch: true
>>> +? qcom,combo-initial-mode:
>>> +??? description:
>>> +????? Describe the initial mode of the Combo PHY configuration.
>>> +????? The Combo PHY is a wrapper on top of a DP PHY and an USB3 PHY,
>>> +????? sharing the same SuperSpeed lanes with either DisplayPort over
>>> +????? the 4 lanes (dp), USB3 on a pair of lanes (usb3) or both
>>> +????? technologies in a 2+2 configuration (usb3+dp) as default.
>>
>> SPecifying this as an initial mode means that it can be switched later.
>> Should we generalize this and desribe it as bus-type (from
>> video-interfaces.yaml) and allow it to be present only if there is no
>> mode-switch property?
> 
> I was not sure about that, and yes we should do that instead but I'm not
> sure about how.
> 
> bus-type sounds great, but the numbering doesn't match so I was thinking 
> instead
> something like phy-type with a string or use the numbers from include/ 
> dt-bindings/phy/phy.h
> 
> The thing is, do we want to keep the dual dp+usb3 as static ? I think 
> it's very possible
> a board would connect the combo phy to an USB3 A connector and a 2lanes 
> DisplayPort connector.

Yes, our board (Radxa Dragon Q6A) is using such design, but with usb3 
and dp lanes swapped. [1] I think this patch series could be extended to 
handle such configuration.

Currently I just change the default orientation to reverse in 
qmp_combo_probe. [2] It works flawlessly. But of course, it's not an 
upstreamable solution :)

FWIW, Rockchip usbdp phy binding [3] has a property called 
`rockchip,dp-lane-mux` to support such configuration.

[1] 
https://dl.radxa.com/q6a/hw/RADXA%20Dragon%20Q6A%20V1.20%20Schematic%2020250621.pdf

[2] 
https://github.com/strongtz/linux-next/commit/928cd166ce81aca7f8e051c72eccbd84ad896d98

[3] 
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/Documentation/devicetree/bindings/phy/phy-rockchip-usbdp.yaml#n53

> 
> Neil
> 
>>
>>
>>> +??? default: usb3+dp
>>> +??? enum:
>>> +????? - usb3+dp
>>> +????? - usb3
>>> +????? - dp
>>> +
>>> ??? ports:
>>> ????? $ref: /schemas/graph.yaml#/properties/ports
>>> ????? properties:
>>>
>>> -- 
>>> 2.34.1
>>>
>>
> 


-- 
Best regards,
Xilin Wu <sophon at radxa.com>


From sven at kernel.org  Sat Aug 23 02:32:23 2025
From: sven at kernel.org (Sven Peter)
Date: Sat, 23 Aug 2025 11:32:23 +0200
Subject: [PATCH RFC 07/22] usb: dwc3: apple: Adjust vendor-specific
 registers during init
In-Reply-To: <20250821221832.zsn4rk7nomsbgytx@synopsys.com>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
 <20250821-atcphy-6-17-v1-7-172beda182b8@kernel.org>
 <20250821221832.zsn4rk7nomsbgytx@synopsys.com>
Message-ID: <0289f92d-0d18-43d2-b98a-da8bb08e9342@kernel.org>

Hi Thinh,

On 22.08.25 00:18, Thinh Nguyen wrote:
> For this patch, however, I'd prefer these vendor-specific settings to be
> in their own glue driver. I can only imagine more changes will be
> introduced in the future with this vendor. See if we can use the new
> glue interface in glue.h (some call this the new "flatten" model) when
> creating a glue driver.

Nice, thanks! Hints like that are exactly what I was hoping for when
I sent this RFC.

When I originally started working on this I tried to use the 
parent/child model but didn't really get anywhere. This flattened model 
looks very useful though.

I think I can even move some of logic from the previous commits to 
dwc3-apple.c if I extend the glue a little bit. I'll see how that works 
out and maybe do that for the next version then.

Thanks,

Sven



From sven at kernel.org  Sat Aug 23 04:42:09 2025
From: sven at kernel.org (Sven Peter)
Date: Sat, 23 Aug 2025 13:42:09 +0200
Subject: [PATCH RFC 05/22] usb: dwc3: apple: Do not use host-vbus-glitches
 workaround
In-Reply-To: <20250821222842.fqrxjp56czc7ubok@synopsys.com>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
 <20250821-atcphy-6-17-v1-5-172beda182b8@kernel.org>
 <20250821222842.fqrxjp56czc7ubok@synopsys.com>
Message-ID: <c052860b-c239-43a6-b05d-c8495bc1c731@kernel.org>

On 22.08.25 00:28, Thinh Nguyen wrote:
> On Thu, Aug 21, 2025, Sven Peter wrote:
>> From: Janne Grunau <j at jannau.net>

[...]

>>   	/*
>>   	 * Some platforms need to power off all Root hub ports immediately after DWC3 set to host
>>   	 * mode to avoid VBUS glitch happen when xhci get reset later.
>> +	 * On Apple platforms we must not touch any MMIO yet because dwc3
>> +	 * will not work correctly before its PHY has been initialized.
> 
> This doesn't make sense, the phy should've been initialized by this
> point. We already access MMIO before this. Even your [PATCH RFC 7/22]
> attempts to access MMIO before this, yet accessing here causes problem.
> Do we know when the phy get initialized then?

You're absolutely right, this doesn't make any sense!

dwc3_power_off_all_roothub_ports uses ioremap which will map the XHCI 
region as Device-nGnRE. That just doesn't work on these machines and 
actually explains the SErrors.
Resources on these machines generally have the IORESOURCE_MEM_NONPOSTED 
flag set (via the nonposted-mmio dt property) and then use ioremap_np to 
map them using Device-nGnRnE.


Best,


Sven



From dmitry.baryshkov at oss.qualcomm.com  Sat Aug 23 07:02:43 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Sat, 23 Aug 2025 17:02:43 +0300
Subject: [PATCH RFC 1/3] dt-bindings: phy: qcom,sc8280xp-qmp-usb43dp-phy:
 Document default phy mode
In-Reply-To: <8A7C126C22789C9B+f30def47-302a-45ee-8f76-64ef277f773f@radxa.com>
References: <20250821-topic-x1e80100-hdmi-v1-0-f14ad9430e88@linaro.org>
 <20250821-topic-x1e80100-hdmi-v1-1-f14ad9430e88@linaro.org>
 <yc7ceoq3bn3lkxdwkrk64ecubej64vblpwlwzyj5cuep2wmjui@nln2t2yicu7o>
 <018751b8-8b9c-4966-94e2-f3ec8625f87d@linaro.org>
 <8A7C126C22789C9B+f30def47-302a-45ee-8f76-64ef277f773f@radxa.com>
Message-ID: <k736p6h6dzy5ywepcgcr64llusqkrrsknf5h4o2e6zcpcyqpz5@7k7kmhumzcw5>

On Sat, Aug 23, 2025 at 02:22:56PM +0800, Xilin Wu wrote:
> On 2025/8/22 19:02:21, Neil Armstrong wrote:
> > On 22/08/2025 12:57, Dmitry Baryshkov wrote:
> > > On Thu, Aug 21, 2025 at 03:53:26PM +0200, Neil Armstrong wrote:
> > > > The QMP USB3/DP Combo PHY hosts an USB3 phy and a DP PHY on top
> > > > of a combo glue to route either lanes to the 4 shared physical lanes.
> > > > 
> > > > The routing of the lanes can be:
> > > > - 2 DP + 2 USB3
> > > > - 4 DP
> > > > - 2 USB3
> > > > 
> > > > And the layout of the lanes can be swpped depending of an
> > > > eventual USB-C connector orientation.
> > > > 
> > > > Nevertheless those QMP Comby PHY can be statically used to
> > > > drive a DisplayPort connector, DP->HDMI bridge, USB3 A Connector...
> > > > 
> > > > But if a 4lanes DP->HDMI bridge is directly connected to the
> > > > QMP Comby PHY lanes, in the default routing 2 or the 4 lanes would
> > > > probbaly be USB3, making the DP->HDMI bridge non functional.
> > > > 
> > > > Add a property to hint in which layout mode the QMP Comby PHY
> > > > should be as startup.
> > > > 
> > > > Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
> > > > ---
> > > > ? .../bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml???????? |
> > > > 13 ++ +++++++++++
> > > > ? 1 file changed, 13 insertions(+)
> > > > 
> > > > diff --git
> > > > a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-
> > > > usb43dp-phy.yaml b/Documentation/devicetree/bindings/phy/
> > > > qcom,sc8280xp-qmp-usb43dp-phy.yaml
> > > > index c8bc512df08b5694c8599f475de78679a4438449..129475a1d9527733e43ded5a38aad766f9810fe7
> > > > 100644
> > > > --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-
> > > > usb43dp-phy.yaml
> > > > +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-
> > > > usb43dp-phy.yaml
> > > > @@ -76,6 +76,19 @@ properties:
> > > > ??? mode-switch: true
> > > > ??? orientation-switch: true
> > > > +? qcom,combo-initial-mode:
> > > > +??? description:
> > > > +????? Describe the initial mode of the Combo PHY configuration.
> > > > +????? The Combo PHY is a wrapper on top of a DP PHY and an USB3 PHY,
> > > > +????? sharing the same SuperSpeed lanes with either DisplayPort over
> > > > +????? the 4 lanes (dp), USB3 on a pair of lanes (usb3) or both
> > > > +????? technologies in a 2+2 configuration (usb3+dp) as default.
> > > 
> > > SPecifying this as an initial mode means that it can be switched later.
> > > Should we generalize this and desribe it as bus-type (from
> > > video-interfaces.yaml) and allow it to be present only if there is no
> > > mode-switch property?
> > 
> > I was not sure about that, and yes we should do that instead but I'm not
> > sure about how.
> > 
> > bus-type sounds great, but the numbering doesn't match so I was thinking
> > instead
> > something like phy-type with a string or use the numbers from include/
> > dt-bindings/phy/phy.h
> > 
> > The thing is, do we want to keep the dual dp+usb3 as static ? I think
> > it's very possible
> > a board would connect the combo phy to an USB3 A connector and a 2lanes
> > DisplayPort connector.
> 
> Yes, our board (Radxa Dragon Q6A) is using such design, but with usb3 and dp
> lanes swapped. [1] I think this patch series could be extended to handle
> such configuration.
> 
> Currently I just change the default orientation to reverse in
> qmp_combo_probe. [2] It works flawlessly. But of course, it's not an
> upstreamable solution :)

I thought about using data-lanes in the QMP PHY, but then I realised
that there is no way to use that property to correctly describe all
these variants. So, I think it should be the bus-type of some kind.

> 
> FWIW, Rockchip usbdp phy binding [3] has a property called
> `rockchip,dp-lane-mux` to support such configuration.
> 
> [1] https://dl.radxa.com/q6a/hw/RADXA%20Dragon%20Q6A%20V1.20%20Schematic%2020250621.pdf
> 
> [2] https://github.com/strongtz/linux-next/commit/928cd166ce81aca7f8e051c72eccbd84ad896d98
> 
> [3] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/Documentation/devicetree/bindings/phy/phy-rockchip-usbdp.yaml#n53
> 
> > 
> > Neil
> > 
> > > 
> > > 
> > > > +??? default: usb3+dp
> > > > +??? enum:
> > > > +????? - usb3+dp
> > > > +????? - usb3
> > > > +????? - dp
> > > > +
> > > > ??? ports:
> > > > ????? $ref: /schemas/graph.yaml#/properties/ports
> > > > ????? properties:
> > > > 
> > > > -- 
> > > > 2.34.1
> > > > 
> > > 
> > 
> 
> 
> -- 
> Best regards,
> Xilin Wu <sophon at radxa.com>

-- 
With best wishes
Dmitry


From me at adomerle.pw  Sat Aug 23 23:25:56 2025
From: me at adomerle.pw (Arseniy Velikanov)
Date: Sun, 24 Aug 2025 10:25:56 +0400
Subject: [PATCH v1 1/2] dt-bindings: phy: mtk-tphy: add property for
 software role switch
In-Reply-To: <20250815-important-warm-dove-03dde5@kuoka>
References: <20250814234825.810-1-me@adomerle.pw>
 <20250815-important-warm-dove-03dde5@kuoka>
Message-ID: <ce4f990c-c336-4aa4-93b0-7b9f4d9663b4@adomerle.pw>

On 15.08.2025 10:28, Krzysztof Kozlowski wrote:
> On Fri, Aug 15, 2025 at 03:48:24AM +0400, Arseniy Velikanov wrote:
>> Add a boolean property to enable software control of the PHY mode
>> switching.
>>
>> Signed-off-by: Arseniy Velikanov <me at adomerle.pw>
>> ---
>>   Documentation/devicetree/bindings/phy/mediatek,tphy.yaml | 6 ++++++
>>   1 file changed, 6 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
>> index b2218c151939..a90890d4a86f 100644
>> --- a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
>> +++ b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
>> @@ -255,6 +255,12 @@ patternProperties:
>>             use the property "mediatek,syscon-type" for newer SoCs that support it.
>>           type: boolean
>>   
>> +      mediatek,software-role-switch:
> 
> No, bindings do not describe software.
Sorry, I didn't quite understand you.

With this property the driver changes phy mode manually using debug regs 
instead of configuring hardware mode switching (because it's broken on 
some platforms). So every time the role in usb-role-switch changes, it 
has to switch phy mode. That's what I mean by "software".

I can rename this property to `mediatek,force-mode-switch` if that's a 
issue.

> 
> Also, never tested.
> 
> Best regards,
> Krzysztof

-- 
Kind regards,
Arseniy.


From krzk at kernel.org  Sun Aug 24 01:18:16 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sun, 24 Aug 2025 10:18:16 +0200
Subject: [PATCH v1 1/2] dt-bindings: phy: mtk-tphy: add property for
 software role switch
In-Reply-To: <ce4f990c-c336-4aa4-93b0-7b9f4d9663b4@adomerle.pw>
References: <20250814234825.810-1-me@adomerle.pw>
 <20250815-important-warm-dove-03dde5@kuoka>
 <ce4f990c-c336-4aa4-93b0-7b9f4d9663b4@adomerle.pw>
Message-ID: <df9a09a5-15eb-4760-b312-d54e4e57283c@kernel.org>

On 24/08/2025 08:25, Arseniy Velikanov wrote:
> On 15.08.2025 10:28, Krzysztof Kozlowski wrote:
>> On Fri, Aug 15, 2025 at 03:48:24AM +0400, Arseniy Velikanov wrote:
>>> Add a boolean property to enable software control of the PHY mode
>>> switching.
>>>
>>> Signed-off-by: Arseniy Velikanov <me at adomerle.pw>
>>> ---
>>>   Documentation/devicetree/bindings/phy/mediatek,tphy.yaml | 6 ++++++
>>>   1 file changed, 6 insertions(+)
>>>
>>> diff --git a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
>>> index b2218c151939..a90890d4a86f 100644
>>> --- a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
>>> +++ b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
>>> @@ -255,6 +255,12 @@ patternProperties:
>>>             use the property "mediatek,syscon-type" for newer SoCs that support it.
>>>           type: boolean
>>>   
>>> +      mediatek,software-role-switch:
>>
>> No, bindings do not describe software.
> Sorry, I didn't quite understand you.
> 
> With this property the driver changes phy mode manually using debug regs 


Here is the problem:     ^^^^^^^^, driver.

> instead of configuring hardware mode switching (because it's broken on 
> some platforms). So every time the role in usb-role-switch changes, it 
> has to switch phy mode. That's what I mean by "software".
> 
> I can rename this property to `mediatek,force-mode-switch` if that's a 
> issue.


Describe the hardware problem, characteristic, wiring or whatever else,
but not the drivers and not software.

force-media-switch is the same uninformative and same underlying
instruction for the driver.

Best regards,
Krzysztof


From krzk at kernel.org  Sun Aug 24 01:31:59 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sun, 24 Aug 2025 10:31:59 +0200
Subject: [PATCH RFC 01/22] dt-bindings: usb: snps,dwc3: Allow multiple
 iommus
In-Reply-To: <20250822-skinny-clay-harrier-64dc58@kuoka>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
 <20250821-atcphy-6-17-v1-1-172beda182b8@kernel.org>
 <20250822-skinny-clay-harrier-64dc58@kuoka>
Message-ID: <e4c730d2-6ee1-46d7-850b-8ebbe0a1bfcd@kernel.org>

On 22/08/2025 09:22, Krzysztof Kozlowski wrote:
> On Thu, Aug 21, 2025 at 03:38:53PM +0000, Sven Peter wrote:
>> Apple's dwc3 variant requires two iommus.
>>
>> Signed-off-by: Sven Peter <sven at kernel.org>
>> ---
>>  Documentation/devicetree/bindings/usb/snps,dwc3.yaml | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
>> index 4380bb6fa2f08a475b557e80467abc2861f622e2..6d35dcc605c01977f4fc6fdb6f12976f1cef2b9e 100644
>> --- a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
>> +++ b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
>> @@ -60,7 +60,7 @@ properties:
>>    dma-coherent: true
>>  
>>    iommus:
>> -    maxItems: 1
>> +    maxItems: 2
> 
> Never tested. You anyway need specific constraints.
I realized that's pretty vague, so clarifying: you changed all bindings
to have two iommus and that's unexpected. All other devices have only
one IOMMU mapping here, so they need to stay like that. If these IOMMUs
differ, you should also list them, but probably that's not the case here.

Best regards,
Krzysztof


From krzk at kernel.org  Sun Aug 24 01:46:13 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sun, 24 Aug 2025 10:46:13 +0200
Subject: [PATCH v7 1/6] dt-bindings: phy: samsung,usb3-drd-phy: add
 ExynosAutov920 HS phy compatible
In-Reply-To: <20250822093845.1179395-2-pritam.sutar@samsung.com>
References: <20250822093845.1179395-1-pritam.sutar@samsung.com>
 <CGME20250822093008epcas5p218f9f9a5381a716b5b8e0c4b23e4b3bf@epcas5p2.samsung.com>
 <20250822093845.1179395-2-pritam.sutar@samsung.com>
Message-ID: <20250824-mustang-of-glorious-sufficiency-b55bf4@kuoka>

On Fri, Aug 22, 2025 at 03:08:40PM +0530, Pritam Manohar Sutar wrote:
>          reg-names:
>            maxItems: 1
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - samsung,exynosautov920-usbdrd-phy
> +    then:
> +      required:
> +        - dvdd075-usb20-supply
> +        - vdd18-usb20-supply
> +        - vdd33-usb20-supply

These if:then:else soon will become unmanageable, but I guess we can
worry and fix it later.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From krzk at kernel.org  Sun Aug 24 01:47:14 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sun, 24 Aug 2025 10:47:14 +0200
Subject: [PATCH v7 3/6] dt-bindings: phy: samsung,usb3-drd-phy: add
 ExynosAutov920 combo hsphy
In-Reply-To: <20250822093845.1179395-4-pritam.sutar@samsung.com>
References: <20250822093845.1179395-1-pritam.sutar@samsung.com>
 <CGME20250822093015epcas5p1f479af38c65a6decc900c37fe37537e5@epcas5p1.samsung.com>
 <20250822093845.1179395-4-pritam.sutar@samsung.com>
Message-ID: <20250824-hopping-asp-of-painting-fbbfc2@kuoka>

On Fri, Aug 22, 2025 at 03:08:42PM +0530, Pritam Manohar Sutar wrote:
> This phy only supports USB2.0 HS(480Mbps), FS(12Mbps) and
> LS(1.5Mbps) data rates. It requires two clocks, named as "phy" and "ref".
> The required supplies for this phy, named as vdd075_usb20(0.75v),
> vdd18_usb20(1.8v), vdd33_usb20(3.3v).
> 
> Add schema for combo hsphy found on this SoC.
> 
> Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
> ---
>  .../devicetree/bindings/phy/samsung,usb3-drd-phy.yaml          | 3 +++
>  1 file changed, 3 insertions(+)

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From krzk at kernel.org  Sun Aug 24 01:55:52 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sun, 24 Aug 2025 10:55:52 +0200
Subject: [PATCH v7 5/6] dt-bindings: phy: samsung,usb3-drd-phy: add
 ExynosAutov920 combo ssphy
In-Reply-To: <20250822093845.1179395-6-pritam.sutar@samsung.com>
References: <20250822093845.1179395-1-pritam.sutar@samsung.com>
 <CGME20250822093022epcas5p42d8c16c851769dab0e1da9d45743ab1f@epcas5p4.samsung.com>
 <20250822093845.1179395-6-pritam.sutar@samsung.com>
Message-ID: <20250824-rough-fresh-orangutan-eecb2f@kuoka>

On Fri, Aug 22, 2025 at 03:08:44PM +0530, Pritam Manohar Sutar wrote:
> This phy supports USB3.1 SSP+(10Gbps) protocol and is backwards
> compatible to the USB3.0 SS(5Gbps). It requires two clocks, named
> "phy" and "ref". The required supplies for USB3.1 are named as
> vdd075_usb30(0.75v), vdd18_usb30(1.8v).

Please do not describe the schema, but hardware. This sentence does not
help me in my question further.

> 
> Add schemas for combo ssphy found on this SoC.
> 
> Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
> ---
>  .../bindings/phy/samsung,usb3-drd-phy.yaml    | 23 +++++++++++++++++++
>  1 file changed, 23 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
> index f0cfca5736b8..96e5bbb2e42c 100644
> --- a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
> +++ b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
> @@ -34,6 +34,7 @@ properties:
>        - samsung,exynos7870-usbdrd-phy
>        - samsung,exynos850-usbdrd-phy
>        - samsung,exynos990-usbdrd-phy
> +      - samsung,exynosautov920-usb31drd-combo-ssphy
>        - samsung,exynosautov920-usbdrd-combo-hsphy
>        - samsung,exynosautov920-usbdrd-phy
>  
> @@ -118,6 +119,12 @@ properties:
>    vdd18-usb20-supply:
>      description: 1.8V power supply for the USB 2.0 phy.
>  
> +  dvdd075-usb30-supply:
> +    description: 0.75V power supply for the USB 3.0 phy.
> +
> +  vdd18-usb30-supply:
> +    description: 1.8V power supply for the USB 3.0 phy.
> +
>  required:
>    - compatible
>    - clocks
> @@ -227,6 +234,7 @@ allOf:
>                - samsung,exynos7870-usbdrd-phy
>                - samsung,exynos850-usbdrd-phy
>                - samsung,exynos990-usbdrd-phy
> +              - samsung,exynosautov920-usb31drd-combo-ssphy
>                - samsung,exynosautov920-usbdrd-combo-hsphy
>                - samsung,exynosautov920-usbdrd-phy
>      then:
> @@ -262,6 +270,21 @@ allOf:
>        properties:
>          dvdd075-usb20-supply: false
>          vdd18-usb20-supply: false
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - samsung,exynosautov920-usb31drd-combo-ssphy
> +    then:
> +      required:
> +        - dvdd075-usb30-supply
> +        - vdd18-usb30-supply

Why are you adding usb20 and usb30 suffixes to the supplies? These are
separate devices, so they do not have both variants at the same time.

>From this device point of view, the supply is called dvdd075 or vdd18.
If you open device datasheet (not SoC datasheet), that's how it will be
called, most likely.

Best regards,
Krzysztof



From j at jannau.net  Sun Aug 24 06:18:41 2025
From: j at jannau.net (Janne Grunau)
Date: Sun, 24 Aug 2025 15:18:41 +0200
Subject: [PATCH RFC 04/22] usb: dwc3: apple: Reset dwc3 during role
 switches
In-Reply-To: <20250821232547.qzplkafogsacnbti@synopsys.com>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
 <20250821-atcphy-6-17-v1-4-172beda182b8@kernel.org>
 <20250821232547.qzplkafogsacnbti@synopsys.com>
Message-ID: <20250824131841.GG1270980@robin.jannau.net>

On Thu, Aug 21, 2025 at 11:25:51PM +0000, Thinh Nguyen wrote:
> On Thu, Aug 21, 2025, Sven Peter wrote:
> > As mad as it sounds, the dwc3 controller present on the Apple M1 must be
> > reset and reinitialized whenever a device is unplugged from the root
> > port or when the PHY mode is changed.
> > 
> > This is required for at least the following reasons:
> > 
> >   - The USB2 D+/D- lines are connected through a stateful eUSB2 repeater
> >     which in turn is controlled by a variant of the TI TPS6598x USB PD
> >     chip. When the USB PD controller detects a hotplug event it resets
> >     the eUSB2 repeater. Afterwards, no new device is recognized before
> >     the DWC3 core and PHY are reset as well because the eUSB2 repeater
> >     and the PHY/dwc3 block disagree about the current state.
> > 
> >   - It's possible to completely break the dwc3 controller by switching
> >     it to device mode and unplugging the cable at just the wrong time.
> >     If this happens dwc3 behaves as if no device is connected.
> >     CORESOFTRESET will also never clear after it has been set. The only
> >     workaround is to trigger a hard reset of the entire dwc3 core with
> >     its external reset line.
> > 
> >   - Whenever the PHY mode is changed (to e.g. transition to DisplayPort
> >     alternate mode or USB4) dwc3 has to be shutdown and reinitialized.
> >     Otherwise the Type-C port will not be usable until the entire SoC
> >     has been reset.
> > 
> > All of this can be easily worked around by respecting transitions to
> > USB_ROLE_NONE and making sure the external reset line is asserted when
> > switching roles. We additionally have to ensure that the PHY is
> > suspended during init.
> > 
> > Signed-off-by: Sven Peter <sven at kernel.org>
> > ---
> >  drivers/usb/dwc3/core.c | 61 +++++++++++++++++++++++++++++++++++++++++++++----
> >  drivers/usb/dwc3/core.h |  3 +++
> >  drivers/usb/dwc3/drd.c  | 11 ++++++++-
> >  drivers/usb/dwc3/host.c |  3 ++-
> >  4 files changed, 72 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> > index 8002c23a5a02acb8f3e87b2662a53998a4cf4f5c..26aa507a738f001409a97ef563c6561433a1cac5 100644
> > --- a/drivers/usb/dwc3/core.c
> > +++ b/drivers/usb/dwc3/core.c

...

> >  	/*
> >  	 * When current_dr_role is not set, there's no role switching.
> >  	 * Only perform GCTL.CoreSoftReset when there's DRD role switching.
> >  	 */
> > -	if (dwc->current_dr_role && ((DWC3_IP_IS(DWC3) ||
> > +	if (dwc->role_switch_reset_quirk ||
> 
> Don't override the use of GCTL.CoreSoftReset with this quirk. Not all
> controller versions should use GCTL.CoreSoftReset, the new controller
> version don't even have it. What version is this vendor using?

It reports DWC31, revision 190A and the unlisted version_types
0x736f3035 (M1), 0x736f3039 (M1 Pro/Max/Ultra) and 0x736f3130 (M2, M2
Pro/Max/Ultra).

> I'm concern how this condition is needed...
> 
> > +		(dwc->current_dr_role && ((DWC3_IP_IS(DWC3) ||
> >  			DWC3_VER_IS_PRIOR(DWC31, 190A)) &&
> > -			desired_dr_role != DWC3_GCTL_PRTCAP_OTG)) {
> > +			desired_dr_role != DWC3_GCTL_PRTCAP_OTG))) {
> >  		reg = dwc3_readl(dwc->regs, DWC3_GCTL);
> >  		reg |= DWC3_GCTL_CORESOFTRESET;
> >  		dwc3_writel(dwc->regs, DWC3_GCTL, reg);

Janne


From sven at kernel.org  Sun Aug 24 08:24:06 2025
From: sven at kernel.org (Sven Peter)
Date: Sun, 24 Aug 2025 17:24:06 +0200
Subject: [PATCH RFC 04/22] usb: dwc3: apple: Reset dwc3 during role
 switches
In-Reply-To: <20250821232547.qzplkafogsacnbti@synopsys.com>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
 <20250821-atcphy-6-17-v1-4-172beda182b8@kernel.org>
 <20250821232547.qzplkafogsacnbti@synopsys.com>
Message-ID: <bc4fa511-5dc5-4844-8206-eb55783647e8@kernel.org>

On 22.08.25 01:25, Thinh Nguyen wrote:
> On Thu, Aug 21, 2025, Sven Peter wrote:
>> As mad as it sounds, the dwc3 controller present on the Apple M1 must be
>> reset and reinitialized whenever a device is unplugged from the root
>> port or when the PHY mode is changed.
>>
>> This is required for at least the following reasons:
>>
>>    - The USB2 D+/D- lines are connected through a stateful eUSB2 repeater
>>      which in turn is controlled by a variant of the TI TPS6598x USB PD
>>      chip. When the USB PD controller detects a hotplug event it resets
>>      the eUSB2 repeater. Afterwards, no new device is recognized before
>>      the DWC3 core and PHY are reset as well because the eUSB2 repeater
>>      and the PHY/dwc3 block disagree about the current state.
>>
>>    - It's possible to completely break the dwc3 controller by switching
>>      it to device mode and unplugging the cable at just the wrong time.
>>      If this happens dwc3 behaves as if no device is connected.
>>      CORESOFTRESET will also never clear after it has been set. The only
>>      workaround is to trigger a hard reset of the entire dwc3 core with
>>      its external reset line.
>>
>>    - Whenever the PHY mode is changed (to e.g. transition to DisplayPort
>>      alternate mode or USB4) dwc3 has to be shutdown and reinitialized.
>>      Otherwise the Type-C port will not be usable until the entire SoC
>>      has been reset.
>>
>> All of this can be easily worked around by respecting transitions to
>> USB_ROLE_NONE and making sure the external reset line is asserted when
>> switching roles. We additionally have to ensure that the PHY is
>> suspended during init.
>>
>> Signed-off-by: Sven Peter <sven at kernel.org>
>> ---
>>   drivers/usb/dwc3/core.c | 61 +++++++++++++++++++++++++++++++++++++++++++++---


[...]

> 
>> +			dwc3_core_exit(dwc);
>> +		}
>> +
>> +		if (desired_dr_role) {
>> +			ret = dwc3_core_init_for_resume(dwc);
> 
> The dwc3_core_init_for_resume() is for PM, reusing this with its
> current name is confusing.

Ack, I was going to clean this up later and wanted to get feedback on 
this entire approach first. Won't be used anymore when moving to a 
glue.h based approach anyway.

> 
>> +			if (ret) {
>> +				dev_err(dwc->dev,
>> +				    "failed to reinitialize core\n");
>> +				goto out;
>> +			}
>> +		} else {
>> +			goto out;
>> +		}
>> +	}
>> +
>>   	/*
>>   	 * When current_dr_role is not set, there's no role switching.
>>   	 * Only perform GCTL.CoreSoftReset when there's DRD role switching.
>>   	 */
>> -	if (dwc->current_dr_role && ((DWC3_IP_IS(DWC3) ||
>> +	if (dwc->role_switch_reset_quirk ||
> 
> Don't override the use of GCTL.CoreSoftReset with this quirk. Not all
> controller versions should use GCTL.CoreSoftReset, the new controller
> version don't even have it. What version is this vendor using?
> 
> I'm concern how this condition is needed...

This is actually a leftover from the first attempts at making this work. 
I didn't know about the external reset line back then and had to 
soft-reset it here because it would not see new devices otherwise IIRC.
Since we're going through a hard-reset now anyway this can be dropped
and this entire commit will disappear in favor of a glue.h based driver 
anyway.

> 
>> +		(dwc->current_dr_role && ((DWC3_IP_IS(DWC3) ||
>>   			DWC3_VER_IS_PRIOR(DWC31, 190A)) &&
>> -			desired_dr_role != DWC3_GCTL_PRTCAP_OTG)) {
>> +			desired_dr_role != DWC3_GCTL_PRTCAP_OTG))) {
>>   		reg = dwc3_readl(dwc->regs, DWC3_GCTL);
>>   		reg |= DWC3_GCTL_CORESOFTRESET;
>>   		dwc3_writel(dwc->regs, DWC3_GCTL, reg);
>> @@ -1372,6 +1394,9 @@ static int dwc3_core_init(struct dwc3 *dwc)
>>   	if (ret)
>>   		goto err_exit_phy;
>>   
>> +	if (dwc->role_switch_reset_quirk)
>> +		dwc3_enable_susphy(dwc, true);
>> +
> 
> Why do you need to enable susphy here?

The only place we actually need it is when we shut down the Type-C PHY 
due some what I assume is some hardware quirk, i.e. just before 
dwc3_core_exit.

The PHY will otherwise not be able to acquire some hardware lock (which 
they call PIPEHANDLER lock in debug strings) to switch from e.g. USB3 
PHY to a dummy PHY for USB2 only. It then can't shut down cleanly 
anymore and will get stuck in a weird state where the port refuses to 
work until I reset everything.
Originally it was added because we just undid some commit where susphy 
handling was made unconditional IIRC.

I'll move this to the glue driver with a comment explaining why it's 
required.


> 
>>   	dwc3_core_setup_global_control(dwc);

[...]

>> +	if (dev->of_node) {
>> +		if (of_device_is_compatible(dev->of_node, "apple,t8103-dwc3")) {
>> +			if (!IS_ENABLED(CONFIG_USB_ROLE_SWITCH) ||
>> +			    !IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)) {
>> +				dev_err(dev,
>> +				    "Apple DWC3 requires role switch support.\n"
>> +				    );
>> +				ret = -EINVAL;
>> +				goto err_put_psy;
>> +			}
>> +
>> +			dwc->dr_mode = USB_DR_MODE_OTG;
>> +			dwc->role_switch_reset_quirk = true;
> 
> Put this in your glue driver or device tree.

Ack.

> 
>> +		}
>> +	}

[...]

>> +
>> +	if (dwc->role_switch_reset_quirk && !dwc->current_dr_role)
>> +		role = USB_ROLE_NONE;
> 
> Don't return USB_ROLE_NONE on role_switch get. The USB_ROLE_NONE is the
> default role. The role_switch get() should return exactly which role the
> controller is currently in, and the driver can figure that out.

Ack, will also happen from inside the glue driver now.




Sven



From sven at kernel.org  Sun Aug 24 08:30:45 2025
From: sven at kernel.org (Sven Peter)
Date: Sun, 24 Aug 2025 17:30:45 +0200
Subject: [PATCH RFC 02/22] dt-bindings: usb: Add Apple dwc3
In-Reply-To: <20250822-banana-ferret-of-opposition-0bcfad@kuoka>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
 <20250821-atcphy-6-17-v1-2-172beda182b8@kernel.org>
 <20250822-banana-ferret-of-opposition-0bcfad@kuoka>
Message-ID: <8e6b19e1-e1fc-40fd-bf5c-e36180aefd19@kernel.org>

On 22.08.25 09:24, Krzysztof Kozlowski wrote:
> On Thu, Aug 21, 2025 at 03:38:54PM +0000, Sven Peter wrote:
>> +
>> +  The common content of the node is defined in snps,dwc3.yaml.
> 
> Drop sentence, redundant. Schema tells that.

Ok, will drop it.

> 
> ...
> 

[..]

>> +
>> +unevaluatedProperties: false
> 
> This goes after required.

Ack, moved after required.



Thanks,


Sven



From sven at kernel.org  Sun Aug 24 08:33:42 2025
From: sven at kernel.org (Sven Peter)
Date: Sun, 24 Aug 2025 17:33:42 +0200
Subject: [PATCH RFC 03/22] dt-bindings: phy: Add Apple Type-C PHY
In-Reply-To: <CAL_JsqL=y2OT4YrzT8z0O0T2hpM5X1k2pFEb8XjBRPoNMdO5kw@mail.gmail.com>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
 <20250821-atcphy-6-17-v1-3-172beda182b8@kernel.org>
 <20250821163320.GE1270980@robin.jannau.net>
 <CAL_JsqL=y2OT4YrzT8z0O0T2hpM5X1k2pFEb8XjBRPoNMdO5kw@mail.gmail.com>
Message-ID: <96409a43-b3f7-4b9e-a1e8-fd0ac6503cd9@kernel.org>

On 22.08.25 01:00, Rob Herring wrote:
> On Thu, Aug 21, 2025 at 11:33?AM Janne Grunau <j at jannau.net> wrote:
>>
>> On Thu, Aug 21, 2025 at 03:38:55PM +0000, Sven Peter wrote:

[...]

>>> +
>>> +properties:
>>> +  compatible:
>>> +    enum:
>>> +      - apple,t6000-atcphy
>>> +      - apple,t6000-atcphy-dp-only # PHY hardwired to DP-to-HDMI converter on M2 Pro MacBook
>>
>> The comment is misleading, "t6000-atcphy-dp-only" would be for M1
>> Pro/Max Macbooks. M2 Pro/Max Macbooks use the same design so the
>> corresponding "apple,t6020-atcphy-dp-only" compatible is missing.
>> I'm not sure this is the correct design though as the HW block is
>> identical to "apple,t6000-atcphy".
>> I think it might be better to have either the DRM KMS driver or a
>> custom DP->HDMI drm_bridge switch the mode to DP-only.
>> Or atcphy could initialize itself to DP-only based on the available
>> ports.
> 
> Doesn't sound like this should be a different compatible. There's a
> 'phy-mode' property or you can define the mode in the 'phys' cells for
> the DP controller.

Okay, makes sense. I'll drop the compatible.

I've only found "intel,phy-mode" inside bindings/phy but we can figure 
this out later once we actually get to upstreaming what's required for 
DisplayPort and mostly focus on USB3 for this series.


Thanks


Sven




From peng.fan at nxp.com  Mon Aug 25 00:01:57 2025
From: peng.fan at nxp.com (Peng Fan)
Date: Mon, 25 Aug 2025 07:01:57 +0000
Subject: [PATCH 2/6] phy: phy-can-transceiver: Add support for NXP TJA1051
In-Reply-To: <060439dd-3df8-4d0b-8957-83b75dc13537@gocontroll.com>
References: <20250822-can-v1-2-c075f702adea@nxp.com>
 <060439dd-3df8-4d0b-8957-83b75dc13537@gocontroll.com>
Message-ID: <PAXPR04MB8459009CF8AC91D3F71060E8883EA@PAXPR04MB8459.eurprd04.prod.outlook.com>

> Subject: Re: [PATCH 2/6] phy: phy-can-transceiver: Add support for
> NXP TJA1051
> 
> Hi Peng,
> 
> > The TJA1051 is a high-speed CAN transceiver which is a pin-
> compatible
> > alternative for TI TCAN1043 with Sleep mode supported.
> >
> > Signed-off-by: Peng Fan <peng.fan at nxp.com>
> > ---
> >  drivers/phy/phy-can-transceiver.c | 4 ++++
> >  1 file changed, 4 insertions(+)
> >
> > diff --git a/drivers/phy/phy-can-transceiver.c
> > b/drivers/phy/phy-can-transceiver.c
> > index
> >
> f59caff4b3d4c267feca4220bf1547b6fad08f95..b49371a1272cd8a25b
> 5e2271586b
> > 756103c64f0a 100644
> > --- a/drivers/phy/phy-can-transceiver.c
> > +++ b/drivers/phy/phy-can-transceiver.c
> > @@ -85,6 +85,10 @@ static const struct of_device_id
> can_transceiver_phy_ids[] = {
> >  		.compatible = "ti,tcan1043",
> >  		.data = &tcan1043_drvdata
> >  	},
> > +	{
> > +		.compatible = "nxp,tja1051",
> > +		.data = &tcan1043_drvdata
> > +	},
> >  	{
> >  		.compatible = "nxp,tjr1443",
> >  		.data = &tcan1043_drvdata
> >
> > --
> > 2.37.1
> 
> Isn't this unnecessary as it has the ti,tcan1043 fallback compatible in
> the bindings? I'm still learning a lot so I might be wrong.

Oops. This patch is not needed and should be dropped.

Thanks,
Peng.

> 
> Kind regards,
> Maud

From nicolas.frattaroli at collabora.com  Mon Aug 25 00:48:05 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 25 Aug 2025 09:48:05 +0200
Subject: [PATCH v2 19/20] clk: sp7021: switch to FIELD_PREP_WM16 macro
In-Reply-To: <175340605069.3513.18204498860033427106@lazor>
References: <20250623-byeword-update-v2-0-cf1fc08a2e1f@collabora.com>
 <20250623-byeword-update-v2-19-cf1fc08a2e1f@collabora.com>
 <175340605069.3513.18204498860033427106@lazor>
Message-ID: <2795210.mvXUDI8C0e@workhorse>

On Friday, 25 July 2025 03:14:10 Central European Summer Time Stephen Boyd wrote:
> Quoting Nicolas Frattaroli (2025-06-23 09:05:47)
> > The sp7021 clock driver has its own shifted high word mask macro,
> > similar to the ones many Rockchip drivers have.
> > 
> > Remove it, and replace instances of it with hw_bitfield.h's
> > FIELD_PREP_WM16 macro, which does the same thing except in a common
> > macro that also does compile-time error checking.
> > 
> > This was compile-tested with 32-bit ARM with Clang, no runtime tests
> > were performed as I lack the hardware. However, I verified that fix
> > commit 5c667d5a5a3e ("clk: sp7021: Adjust width of _m in HWM_FIELD_PREP()")
> > is not regressed. No warning is produced.
> 
> Does it generate the same code before and after?
> 

Yes, the generated machine code is exactly the same, at least with
clang, and I'll assume it'll be the same for gcc.

Kind regards,
Nicolas Frattaroli




From mani at kernel.org  Mon Aug 25 01:10:37 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Mon, 25 Aug 2025 13:40:37 +0530
Subject: [PATCH 3/3] dts: describe x1e80100 ufs
In-Reply-To: <bc001360-1cfe-4886-a023-367a8edc21c5@quicinc.com>
References: <20250814005904.39173-1-harrison.vanderbyl@gmail.com>
 <20250814005904.39173-4-harrison.vanderbyl@gmail.com>
 <bc001360-1cfe-4886-a023-367a8edc21c5@quicinc.com>
Message-ID: <cp33qzgnc5i6e3nratfk7p6rhblltmem6nokk3wls3dtpattvt@cb2rbhbbe4vx>

On Thu, Aug 14, 2025 at 12:50:17PM GMT, Nitin Rawat wrote:
> 
> 
> On 8/14/2025 6:29 AM, Harrison Vanderbyl wrote:
> > Describe device tree entry for x1e80100 ufs device
> > Signed-off-by: Harrison Vanderbyl <harrison.vanderbyl at gmail.com>
> > ---
> >   arch/arm64/boot/dts/qcom/x1e80100.dtsi | 91 ++++++++++++++++++++++++++
> >   1 file changed, 91 insertions(+)
> > 
> > diff --git a/arch/arm64/boot/dts/qcom/x1e80100.dtsi b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
> > index a9a7bb676c6f..effa776e3dd0 100644
> > --- a/arch/arm64/boot/dts/qcom/x1e80100.dtsi
> > +++ b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
> > @@ -2819,6 +2819,97 @@ tsens3: thermal-sensor at c274000 {
> >   			#thermal-sensor-cells = <1>;
> >   		};
> > +
> > +		ufs_mem_hc: ufs at 1d84000 {
> > +			compatible = "qcom,x1e80100-ufshc",
> > +			"qcom,ufshc", "jedec,ufs-2.0";

This controller is UFS 3.0 based. Also, JEDEC has two specs for UFS:

1. UFSHCI (Host controllers found in SoCs)
2. UFS (UFS devices)

And this compatible 'jedec,ufs-2.0' is mostly for UFS devices, not Host
controllers. So using we should be using 'jedec,ufshc-3.0' here and in other
bindings.

krzk: Is it OK to change the compatible for all bindings and dts? Atleast linux
is not making use of this compatible, but I'm not sure about other DT users.

> > +			reg = <0 0x01d84000 0 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-gpios = <&tlmm 238 GPIO_ACTIVE_LOW>;
> > +			reset-names = "rst";
> > +
> > +			power-domains = <&gcc GCC_UFS_PHY_GDSC>;
> > +
> > +			iommus = <&apps_smmu 0x1a0 0x0>;
> > +
> > +			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";
> > +
> > +			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>;
> > +
> > +			freq-table-hz = <100000000 403000000>,
> > +					<0 0>,
> > +					<0 0>,
> > +					<100000000 403000000>,
> > +					<100000000 403000000>,
> > +					<0 0>,
> > +					<0 0>,
> > +					<0 0>;
> > +
> Please use OPP table instead of freq-table-hz.
> 
> 
> > +			interconnects = <&aggre1_noc MASTER_UFS_MEM QCOM_ICC_TAG_ALWAYS
> > +					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
> > +					<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
> > +					 &config_noc SLAVE_UFS_MEM_CFG QCOM_ICC_TAG_ALWAYS>;
> 
> For Config Path, use QCOM_ICC_TAG_ACTIVE_ONLY.
> 
> YOu can refer to ICC discussion link for SM8750 - https://lore.kernel.org/linux-devicetree/354f8710-a5ec-47b5-bcfa-bff75ac3ca71 at oss.qualcomm.com/
> 

Nitin, question for you: Is this controller cache coherent as like its ancerstor
sm8550?

- Mani

-- 
????????? ????????


From luyulin at eswincomputing.com  Mon Aug 25 01:19:44 2025
From: luyulin at eswincomputing.com (luyulin at eswincomputing.com)
Date: Mon, 25 Aug 2025 16:19:44 +0800 (GMT+08:00)
Subject: [PATCH v2 1/3] dt-bindings: ata: eswin: Document for
 EIC7700 SoC ahci
In-Reply-To: <CAL_JsqKFotNLZZXwiy7S6K8qXLdGRAnsa-1zvZRDQBE39Gf5kg@mail.gmail.com>
References: <20250819134722.220-1-luyulin@eswincomputing.com>
 <20250819135413.386-1-luyulin@eswincomputing.com>
 <CAL_JsqKFotNLZZXwiy7S6K8qXLdGRAnsa-1zvZRDQBE39Gf5kg@mail.gmail.com>
Message-ID: <2cc9f2ff.6a2.198e04fd36e.Coremail.luyulin@eswincomputing.com>

Hi, Rob
Thank you very much for your professional response and suggestions.
Among the suggestions you mentioned, 
one point is not entirely clear, and I would like to seek your advice on it.
> 
> On Tue, Aug 19, 2025 at 8:54?AM Yulin Lu <luyulin at eswincomputing.com> wrote:
> >
> > From: luyulin <luyulin at eswincomputing.com>
> 
> Please fix your name.
> 
> >
> > Add document for the SATA AHCI controller on the EIC7700 SoC platform,
> > including descriptions of its hardware configurations.
> >
> > Signed-off-by: luyulin <luyulin at eswincomputing.com>
> 
> And here.
> 
> > ---
> >  .../bindings/ata/eswin,eic7700-ahci.yaml      | 92 +++++++++++++++++++
> >  1 file changed, 92 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/ata/eswin,eic7700-ahci.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/ata/eswin,eic7700-ahci.yaml b/Documentation/devicetree/bindings/ata/eswin,eic7700-ahci.yaml
> > new file mode 100644
> > index 000000000000..9ef58c9c2f28
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/ata/eswin,eic7700-ahci.yaml
> > @@ -0,0 +1,92 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/ata/eswin,eic7700-ahci.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Eswin EIC7700 SoC SATA Controller
> > +
> > +maintainers:
> > +  - Yulin Lu <luyulin at eswincomputing.com>
> > +  - Huan He <hehuan1 at eswincomputing.com>
> > +
> > +description:
> > +  This document defines device tree bindings for the Synopsys DWC
> > +  implementation of the AHCI SATA controller found in Eswin's
> > +  Eic7700 SoC platform.
> > +
> > +select:
> > +  properties:
> > +    compatible:
> > +      const: eswin,eic7700-ahci
> > +  required:
> > +    - compatible
> > +
> > +allOf:
> > +  - $ref: snps,dwc-ahci-common.yaml#
> > +
> > +properties:
> > +  compatible:
> > +    items:
> > +      - const: eswin,eic7700-ahci
> > +      - const: snps,dwc-ahci
> > +
> > +  reg:
> > +    maxItems: 1
> 
> Drop. snps,dwc-ahci-common.yaml already defines this.
> 
> > +
> > +  interrupts:
> > +    maxItems: 1
> 
> Drop. snps,dwc-ahci-common.yaml already defines this.
> 
> > +
> > +  ports-implemented:
> > +    const: 1
> 
> Really, your firmware should initialize the DWC specific register that
> sets this and is discoverable via a standard AHCI register.
> 
Yes, I initialized the relevant registers during the uboot stage,
and they worked correctly after entering the Linux system.
However, after unloading and then reloading the ko driver,
a reset operation causes these registers to be initialized to 0,
leading to initialization errors when reloading the ko driver.
If I want to implement it this way, I need to modify the ahci_dwc.c driver
and add program handling tailored to our SoC design.

I searched the kernel for "snps,dwc-ahci" and found that
in manufacturers' dts files, such as rk3588-base.dtsi, dra7-l4.dtsi,
exynos5250.dtsi, etc., all include the ports-implemented field in their sata nodes. 
only the sata node in amd-seattle-soc.dtsi lacks the ports-implemented field
and does not have reset resources.
Additionally, in the YAML files under the?/Documentation/ata?directory that
integrate the DWC AHCI controller, the?ports-implemented?field has been implemented,
as seen in examples such as?rockchip,dwc-ahci.yaml?and?baikal,bt1-ahci.yaml.

Therefore, I have questions I would like to confirm with you:
1. In your previous feedback, were you suggesting that I remove the?ports-implemented?field?
And what is the reason for doing so?
Based on your professional advice and considering our SoC design, do you think
it is acceptable to retain the?ports-implemented?field in the dts instead of
removing it and modifying the?ahci_dwc.c?driver?
2. I noticed that in the arch/ directory, chips like dra7-l4.dtsi and
exynos5250.dtsi integrate the DWC AHCI controller and include corresponding
hardware resource designs such as clocks and resets.
Why do they not have independent yaml files implemented in the kernel?

Best regards,
Yulin Lu

From nicolas.frattaroli at collabora.com  Mon Aug 25 01:28:20 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 25 Aug 2025 10:28:20 +0200
Subject: [PATCH v3 00/20] BYEWORD_UPDATE: unifying (most) HIWORD_UPDATE
 macros
Message-ID: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>

This series was spawned by [1], where I was asked to move every instance
of HIWORD_UPDATE et al that I could find to a common macro in the same
series that I am introducing said common macro.

The first patch of the series introduces a new header file,
hw_bitfield.h, which contains two new macros: FIELD_PREP_WM16 and
FIELD_PREP_WM16_CONST. The latter can be used in initializers.

I've cheekily added the hw_bitfield.h header to the BITMAP API section
of the MAINTAINERS file.

This macro definition checks that the mask fits, and that the value fits
in the mask. Like FIELD_PREP, it also shifts the value up to the mask,
so turning off a bit does not require using the mask as a value. Masks
are also required to be contiguous, like with FIELD_PREP.

For each definition of such a macro, the driver(s) that used it were
evaluated for three different treatments:
 - full conversion to the new macro, for cases where replacing the
   implementation of the old macro wouldn't have worked, or where the
   conversion was trivial. These are the most complex patches in this
   series, as they sometimes have to pull apart definitions of masks
   and values due to the new semantics, which require a contiguous
   mask and shift the value for us.
 - replacing the implementation of the old macro with an instance of the
   new macro, done where I felt it made the patch much easier to review
   because I didn't want to drop a big diff on people.
 - skipping conversion entirely, usually because the mask is
   non-constant and it's not trivial to make it constant. Sometimes an
   added complication is that said non-constant mask is either used in a
   path where runtime overhead may not be desirable, or in an
   initializer.

Left out of conversion:
 - drivers/mmc/host/sdhci-of-arasan.c: mask is non-constant.
 - drivers/phy/rockchip/phy-rockchip-inno-csidphy.c: mask is
   non-constant likely by way of runtime pointer dereferencing, even if
   struct and members are made const.
 - drivers/clk/rockchip/clk.h: way too many clock drivers use non-const
   masks in the context of an initializer.

I will not be addressing these 3 remaining users in this series, as
implementing a runtime checked version on top of this and verifying that
it doesn't cause undue overhead just for 3 stragglers is a bit outside
the scope of wanting to get my RK3576 PWM series unblocked. Please have
mercy.

In total, I count 19 different occurrences of such a macro fixed out of
22 I found. The vast majority of these patches have either undergone
static testing to ensure the values end up the same during development,
or have been verified to not break the device the driver is for at
runtime. Only a handful are just compile-tested, and the individual
patches remark which ones those are.

This took a lot of manual work as this wasn't really something that
could be automated: code had to be refactored to ensure masks were
contiguous, made sense to how the hardware actually works and to human
readers, were constant, and that the code uses unshifted values.

Please note that I will not be resending the whole series again for
purely subjective cosmetic changes. This series touches a lot of
subsystems, which means many clashing tastes. You've had a week's notice
to get any low-effort naming nitpicks out of the way after v1. If you as
a maintainer are unhappy with a commit prefix or such, then you have my
express permission to modify it while applying the patch, so that I
don't need to bombard everyone else's inboxes again.

https://lore.kernel.org/all/aD8hB-qJ4Qm6IFuS at yury/ [1]

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
Changes in v3:
- Rebased onto next-20250825
- Link to v2: https://lore.kernel.org/r/20250623-byeword-update-v2-0-cf1fc08a2e1f at collabora.com

Changes in v2:
- rebase onto next-20250623. This involved solving two conflicts in
  pcie-dw-rockchip.
- move new macros to a new hw_bitfield.h, and rename them to
  FIELD_PREP_WM16*. All patches in the series have been updated to use
  the new names.
- hw_bitfield.h: fix macro param re-use in FIELD_PREP_WM16. I don't know
  if there's any way to do the same in FIELD_PREP_WM16_CONST, but the
  bitfield.h FIELD_PREP functions don't do it for either, so I'm already
  strictly better anyway.
- hw_bitfield.h: remove whitespace after cast operators.
- change newly introduced U literal suffixes to UL, as they are more
  commonly used in the kernel.
- pcie-dw-rockchip: remove the legacy mode flag, as it's unused.
- Link to v1: https://lore.kernel.org/r/20250612-byeword-update-v1-0-f4afb8f6313f at collabora.com

---
Nicolas Frattaroli (20):
      bitmap: introduce hardware-specific bitfield operations
      mmc: dw_mmc-rockchip: switch to FIELD_PREP_WM16 macro
      soc: rockchip: grf: switch to FIELD_PREP_WM16_CONST macro
      media: synopsys: hdmirx: replace macros with bitfield variants
      drm/rockchip: lvds: switch to FIELD_PREP_WM16 macro
      phy: rockchip-emmc: switch to FIELD_PREP_WM16 macro
      drm/rockchip: dsi: switch to FIELD_PREP_WM16* macros
      drm/rockchip: vop2: switch to FIELD_PREP_WM16 macro
      phy: rockchip-samsung-dcphy: switch to FIELD_PREP_WM16 macro
      drm/rockchip: dw_hdmi_qp: switch to FIELD_PREP_WM16 macro
      drm/rockchip: inno-hdmi: switch to FIELD_PREP_WM16 macro
      phy: rockchip-usb: switch to FIELD_PREP_WM16 macro
      drm/rockchip: dw_hdmi: switch to FIELD_PREP_WM16* macros
      ASoC: rockchip: i2s-tdm: switch to FIELD_PREP_WM16_CONST macro
      net: stmmac: dwmac-rk: switch to FIELD_PREP_WM16 macro
      PCI: rockchip: Switch to FIELD_PREP_WM16* macros
      PCI: dw-rockchip: Switch to FIELD_PREP_WM16 macro
      PM / devfreq: rockchip-dfi: switch to FIELD_PREP_WM16 macro
      clk: sp7021: switch to FIELD_PREP_WM16 macro
      phy: rockchip-pcie: switch to FIELD_PREP_WM16 macro

 MAINTAINERS                                        |   1 +
 drivers/clk/clk-sp7021.c                           |  22 ++--
 drivers/devfreq/event/rockchip-dfi.c               |  27 ++--
 drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c    | 142 ++++++++++-----------
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c        |  80 ++++++------
 drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c     |  68 +++++-----
 drivers/gpu/drm/rockchip/inno_hdmi.c               |  11 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h       |   1 -
 drivers/gpu/drm/rockchip/rockchip_lvds.h           |  21 +--
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c       |  15 ++-
 .../media/platform/synopsys/hdmirx/snps_hdmirx.h   |   6 +-
 drivers/mmc/host/dw_mmc-rockchip.c                 |   9 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c     |   3 +-
 drivers/pci/controller/dwc/pcie-dw-rockchip.c      |  42 +++---
 drivers/pci/controller/pcie-rockchip.h             |  35 ++---
 drivers/phy/rockchip/phy-rockchip-emmc.c           |   3 +-
 drivers/phy/rockchip/phy-rockchip-pcie.c           |  70 +++-------
 drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c  |  11 +-
 drivers/phy/rockchip/phy-rockchip-usb.c            |  51 +++-----
 drivers/soc/rockchip/grf.c                         |  35 +++--
 include/linux/hw_bitfield.h                        |  62 +++++++++
 sound/soc/rockchip/rockchip_i2s_tdm.h              |   4 +-
 22 files changed, 366 insertions(+), 353 deletions(-)
---
base-commit: 0c5416a62c0e4df1b3f79b5c74c03cd48df51357
change-id: 20250610-byeword-update-445c0eea771d

Best regards,
-- 
Nicolas Frattaroli <nicolas.frattaroli at collabora.com>



From nicolas.frattaroli at collabora.com  Mon Aug 25 01:28:22 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 25 Aug 2025 10:28:22 +0200
Subject: [PATCH v3 02/20] mmc: dw_mmc-rockchip: switch to FIELD_PREP_WM16
 macro
In-Reply-To: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
Message-ID: <20250825-byeword-update-v3-2-947b841cdb29@collabora.com>

The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
drivers that use constant masks.

Switch to the new FIELD_PREP_WM16 macro in hw_bitfield.h, which has
error checking. Instead of redefining the driver's HIWORD_UPDATE macro
in this case, replace the two only instances of it with the new macro,
as I could test that they result in an equivalent value.

Acked-by: Ulf Hansson <ulf.hansson at linaro.org>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/mmc/host/dw_mmc-rockchip.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c
index d2aec6cf9773dcb057d1bf3785ace586a7955f12..82dd906bb002cb8327691ac1ef4818561c9ac7e6 100644
--- a/drivers/mmc/host/dw_mmc-rockchip.c
+++ b/drivers/mmc/host/dw_mmc-rockchip.c
@@ -6,6 +6,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/hw_bitfield.h>
 #include <linux/mmc/host.h>
 #include <linux/of_address.h>
 #include <linux/mmc/slot-gpio.h>
@@ -24,8 +25,6 @@
 #define ROCKCHIP_MMC_DELAYNUM_OFFSET	2
 #define ROCKCHIP_MMC_DELAYNUM_MASK	(0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC	60
-#define HIWORD_UPDATE(val, mask, shift) \
-		((val) << (shift) | (mask) << ((shift) + 16))
 
 static const unsigned int freqs[] = { 100000, 200000, 300000, 400000 };
 
@@ -148,9 +147,11 @@ static int rockchip_mmc_set_internal_phase(struct dw_mci *host, bool sample, int
 	raw_value |= nineties;
 
 	if (sample)
-		mci_writel(host, TIMING_CON1, HIWORD_UPDATE(raw_value, 0x07ff, 1));
+		mci_writel(host, TIMING_CON1,
+			   FIELD_PREP_WM16(GENMASK(11, 1), raw_value));
 	else
-		mci_writel(host, TIMING_CON0, HIWORD_UPDATE(raw_value, 0x07ff, 1));
+		mci_writel(host, TIMING_CON0,
+			   FIELD_PREP_WM16(GENMASK(11, 1), raw_value));
 
 	dev_dbg(host->dev, "set %s_phase(%d) delay_nums=%u actual_degrees=%d\n",
 		sample ? "sample" : "drv", degrees, delay_num,

-- 
2.51.0



From nicolas.frattaroli at collabora.com  Mon Aug 25 01:28:21 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 25 Aug 2025 10:28:21 +0200
Subject: [PATCH v3 01/20] bitmap: introduce hardware-specific bitfield
 operations
In-Reply-To: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
Message-ID: <20250825-byeword-update-v3-1-947b841cdb29@collabora.com>

Hardware of various vendors, but very notably Rockchip, often uses
32-bit registers where the upper 16-bit half of the register is a
write-enable mask for the lower half.

This type of hardware setup allows for more granular concurrent register
write access.

Over the years, many drivers have hand-rolled their own version of this
macro, usually without any checks, often called something like
HIWORD_UPDATE or FIELD_PREP_HIWORD, commonly with slightly different
semantics between them.

Clearly there is a demand for such a macro, and thus the demand should
be satisfied in a common header file. As this is a convention that spans
across multiple vendors, and similar conventions may also have
cross-vendor adoption, it's best if it lives in a vendor-agnostic header
file that can be expanded over time.

Add hw_bitfield.h with two macros: FIELD_PREP_WM16, and
FIELD_PREP_WM16_CONST. The latter is a version that can be used in
initializers, like FIELD_PREP_CONST.

Suggested-by: Yury Norov [NVIDIA] <yury.norov at gmail.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 MAINTAINERS                 |  1 +
 include/linux/hw_bitfield.h | 62 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index d4bddc462c079f85ee35e685527c93dd1620f890..75a266a78a13721372a92b9ae45b9ae56e301347 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4281,6 +4281,7 @@ F:	include/linux/bits.h
 F:	include/linux/cpumask.h
 F:	include/linux/cpumask_types.h
 F:	include/linux/find.h
+F:	include/linux/hw_bitfield.h
 F:	include/linux/nodemask.h
 F:	include/linux/nodemask_types.h
 F:	include/uapi/linux/bits.h
diff --git a/include/linux/hw_bitfield.h b/include/linux/hw_bitfield.h
new file mode 100644
index 0000000000000000000000000000000000000000..df202e167ce487122e4440962eacb2e44817ad9f
--- /dev/null
+++ b/include/linux/hw_bitfield.h
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2025, Collabora Ltd.
+ */
+
+#ifndef _LINUX_HW_BITFIELD_H
+#define _LINUX_HW_BITFIELD_H
+
+#include <linux/bitfield.h>
+#include <linux/build_bug.h>
+#include <linux/limits.h>
+
+/**
+ * FIELD_PREP_WM16() - prepare a bitfield element with a mask in the upper half
+ * @_mask: shifted mask defining the field's length and position
+ * @_val:  value to put in the field
+ *
+ * FIELD_PREP_WM16() masks and shifts up the value, as well as bitwise ORs the
+ * result with the mask shifted up by 16.
+ *
+ * This is useful for a common design of hardware registers where the upper
+ * 16-bit half of a 32-bit register is used as a write-enable mask. In such a
+ * register, a bit in the lower half is only updated if the corresponding bit
+ * in the upper half is high.
+ */
+#define FIELD_PREP_WM16(_mask, _val)					     \
+	({								     \
+		typeof(_val) __val = _val;				     \
+		typeof(_mask) __mask = _mask;				     \
+		__BF_FIELD_CHECK(__mask, ((u16)0U), __val,		     \
+				 "HWORD_UPDATE: ");			     \
+		(((typeof(__mask))(__val) << __bf_shf(__mask)) & (__mask)) | \
+		((__mask) << 16);					     \
+	})
+
+/**
+ * FIELD_PREP_WM16_CONST() - prepare a constant bitfield element with a mask in
+ *                           the upper half
+ * @_mask: shifted mask defining the field's length and position
+ * @_val:  value to put in the field
+ *
+ * FIELD_PREP_WM16_CONST() masks and shifts up the value, as well as bitwise ORs
+ * the result with the mask shifted up by 16.
+ *
+ * This is useful for a common design of hardware registers where the upper
+ * 16-bit half of a 32-bit register is used as a write-enable mask. In such a
+ * register, a bit in the lower half is only updated if the corresponding bit
+ * in the upper half is high.
+ *
+ * Unlike FIELD_PREP_WM16(), this is a constant expression and can therefore
+ * be used in initializers. Error checking is less comfortable for this
+ * version.
+ */
+#define FIELD_PREP_WM16_CONST(_mask, _val)				 \
+	(								 \
+		FIELD_PREP_CONST(_mask, _val) |				 \
+		(BUILD_BUG_ON_ZERO(const_true((u64)(_mask) > U16_MAX)) + \
+		 ((_mask) << 16))					 \
+	)
+
+
+#endif /* _LINUX_HW_BITFIELD_H */

-- 
2.51.0



From nicolas.frattaroli at collabora.com  Mon Aug 25 01:28:23 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 25 Aug 2025 10:28:23 +0200
Subject: [PATCH v3 03/20] soc: rockchip: grf: switch to
 FIELD_PREP_WM16_CONST macro
In-Reply-To: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
Message-ID: <20250825-byeword-update-v3-3-947b841cdb29@collabora.com>

The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
drivers that use constant masks.

Switch the rockchip grf driver to the FIELD_PREP_WM16_CONST macro, which
brings with it more error checking while still being able to be used in
initializers.

All HIWORD_UPDATE instances and its definition are removed from the
driver, as the conversion here is obvious, and static_asserts were used
during development to make sure the ones greater than one bit in width
were really equivalent.

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/soc/rockchip/grf.c | 35 +++++++++++++++++------------------
 1 file changed, 17 insertions(+), 18 deletions(-)

diff --git a/drivers/soc/rockchip/grf.c b/drivers/soc/rockchip/grf.c
index 1eab4bb0eacffe19a8f0af0b71bdaa5c0b506629..344870da7675fcde38ef1d7d9dcf243fcb9711e4 100644
--- a/drivers/soc/rockchip/grf.c
+++ b/drivers/soc/rockchip/grf.c
@@ -6,13 +6,12 @@
  */
 
 #include <linux/err.h>
+#include <linux/hw_bitfield.h>
 #include <linux/mfd/syscon.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 
-#define HIWORD_UPDATE(val, mask, shift) \
-		((val) << (shift) | (mask) << ((shift) + 16))
 
 struct rockchip_grf_value {
 	const char *desc;
@@ -32,7 +31,7 @@ static const struct rockchip_grf_value rk3036_defaults[] __initconst = {
 	 * Disable auto jtag/sdmmc switching that causes issues with the
 	 * clock-framework and the mmc controllers making them unreliable.
 	 */
-	{ "jtag switching", RK3036_GRF_SOC_CON0, HIWORD_UPDATE(0, 1, 11) },
+	{ "jtag switching", RK3036_GRF_SOC_CON0, FIELD_PREP_WM16_CONST(BIT(11), 0) },
 };
 
 static const struct rockchip_grf_info rk3036_grf __initconst = {
@@ -44,8 +43,8 @@ static const struct rockchip_grf_info rk3036_grf __initconst = {
 #define RK3128_GRF_SOC_CON1		0x144
 
 static const struct rockchip_grf_value rk3128_defaults[] __initconst = {
-	{ "jtag switching", RK3128_GRF_SOC_CON0, HIWORD_UPDATE(0, 1, 8) },
-	{ "vpu main clock", RK3128_GRF_SOC_CON1, HIWORD_UPDATE(0, 1, 10) },
+	{ "jtag switching", RK3128_GRF_SOC_CON0, FIELD_PREP_WM16_CONST(BIT(8), 0) },
+	{ "vpu main clock", RK3128_GRF_SOC_CON1, FIELD_PREP_WM16_CONST(BIT(10), 0) },
 };
 
 static const struct rockchip_grf_info rk3128_grf __initconst = {
@@ -56,7 +55,7 @@ static const struct rockchip_grf_info rk3128_grf __initconst = {
 #define RK3228_GRF_SOC_CON6		0x418
 
 static const struct rockchip_grf_value rk3228_defaults[] __initconst = {
-	{ "jtag switching", RK3228_GRF_SOC_CON6, HIWORD_UPDATE(0, 1, 8) },
+	{ "jtag switching", RK3228_GRF_SOC_CON6, FIELD_PREP_WM16_CONST(BIT(8), 0) },
 };
 
 static const struct rockchip_grf_info rk3228_grf __initconst = {
@@ -68,8 +67,8 @@ static const struct rockchip_grf_info rk3228_grf __initconst = {
 #define RK3288_GRF_SOC_CON2		0x24c
 
 static const struct rockchip_grf_value rk3288_defaults[] __initconst = {
-	{ "jtag switching", RK3288_GRF_SOC_CON0, HIWORD_UPDATE(0, 1, 12) },
-	{ "pwm select", RK3288_GRF_SOC_CON2, HIWORD_UPDATE(1, 1, 0) },
+	{ "jtag switching", RK3288_GRF_SOC_CON0, FIELD_PREP_WM16_CONST(BIT(12), 0) },
+	{ "pwm select", RK3288_GRF_SOC_CON2, FIELD_PREP_WM16_CONST(BIT(0), 1) },
 };
 
 static const struct rockchip_grf_info rk3288_grf __initconst = {
@@ -80,7 +79,7 @@ static const struct rockchip_grf_info rk3288_grf __initconst = {
 #define RK3328_GRF_SOC_CON4		0x410
 
 static const struct rockchip_grf_value rk3328_defaults[] __initconst = {
-	{ "jtag switching", RK3328_GRF_SOC_CON4, HIWORD_UPDATE(0, 1, 12) },
+	{ "jtag switching", RK3328_GRF_SOC_CON4, FIELD_PREP_WM16_CONST(BIT(12), 0) },
 };
 
 static const struct rockchip_grf_info rk3328_grf __initconst = {
@@ -91,7 +90,7 @@ static const struct rockchip_grf_info rk3328_grf __initconst = {
 #define RK3368_GRF_SOC_CON15		0x43c
 
 static const struct rockchip_grf_value rk3368_defaults[] __initconst = {
-	{ "jtag switching", RK3368_GRF_SOC_CON15, HIWORD_UPDATE(0, 1, 13) },
+	{ "jtag switching", RK3368_GRF_SOC_CON15, FIELD_PREP_WM16_CONST(BIT(13), 0) },
 };
 
 static const struct rockchip_grf_info rk3368_grf __initconst = {
@@ -102,7 +101,7 @@ static const struct rockchip_grf_info rk3368_grf __initconst = {
 #define RK3399_GRF_SOC_CON7		0xe21c
 
 static const struct rockchip_grf_value rk3399_defaults[] __initconst = {
-	{ "jtag switching", RK3399_GRF_SOC_CON7, HIWORD_UPDATE(0, 1, 12) },
+	{ "jtag switching", RK3399_GRF_SOC_CON7, FIELD_PREP_WM16_CONST(BIT(12), 0) },
 };
 
 static const struct rockchip_grf_info rk3399_grf __initconst = {
@@ -113,9 +112,9 @@ static const struct rockchip_grf_info rk3399_grf __initconst = {
 #define RK3566_GRF_USB3OTG0_CON1	0x0104
 
 static const struct rockchip_grf_value rk3566_defaults[] __initconst = {
-	{ "usb3otg port switch", RK3566_GRF_USB3OTG0_CON1, HIWORD_UPDATE(0, 1, 12) },
-	{ "usb3otg clock switch", RK3566_GRF_USB3OTG0_CON1, HIWORD_UPDATE(1, 1, 7) },
-	{ "usb3otg disable usb3", RK3566_GRF_USB3OTG0_CON1, HIWORD_UPDATE(1, 1, 0) },
+	{ "usb3otg port switch", RK3566_GRF_USB3OTG0_CON1, FIELD_PREP_WM16_CONST(BIT(12), 0) },
+	{ "usb3otg clock switch", RK3566_GRF_USB3OTG0_CON1, FIELD_PREP_WM16_CONST(BIT(7), 1) },
+	{ "usb3otg disable usb3", RK3566_GRF_USB3OTG0_CON1, FIELD_PREP_WM16_CONST(BIT(0), 1) },
 };
 
 static const struct rockchip_grf_info rk3566_pipegrf __initconst = {
@@ -126,8 +125,8 @@ static const struct rockchip_grf_info rk3566_pipegrf __initconst = {
 #define RK3576_SYSGRF_SOC_CON1		0x0004
 
 static const struct rockchip_grf_value rk3576_defaults_sys_grf[] __initconst = {
-	{ "i3c0 weakpull", RK3576_SYSGRF_SOC_CON1, HIWORD_UPDATE(3, 3, 6) },
-	{ "i3c1 weakpull", RK3576_SYSGRF_SOC_CON1, HIWORD_UPDATE(3, 3, 8) },
+	{ "i3c0 weakpull", RK3576_SYSGRF_SOC_CON1, FIELD_PREP_WM16_CONST(GENMASK(7, 6), 3) },
+	{ "i3c1 weakpull", RK3576_SYSGRF_SOC_CON1, FIELD_PREP_WM16_CONST(GENMASK(9, 8), 3) },
 };
 
 static const struct rockchip_grf_info rk3576_sysgrf __initconst = {
@@ -138,7 +137,7 @@ static const struct rockchip_grf_info rk3576_sysgrf __initconst = {
 #define RK3576_IOCGRF_MISC_CON		0x04F0
 
 static const struct rockchip_grf_value rk3576_defaults_ioc_grf[] __initconst = {
-	{ "jtag switching", RK3576_IOCGRF_MISC_CON, HIWORD_UPDATE(0, 1, 1) },
+	{ "jtag switching", RK3576_IOCGRF_MISC_CON, FIELD_PREP_WM16_CONST(BIT(1), 0) },
 };
 
 static const struct rockchip_grf_info rk3576_iocgrf __initconst = {
@@ -149,7 +148,7 @@ static const struct rockchip_grf_info rk3576_iocgrf __initconst = {
 #define RK3588_GRF_SOC_CON6		0x0318
 
 static const struct rockchip_grf_value rk3588_defaults[] __initconst = {
-	{ "jtag switching", RK3588_GRF_SOC_CON6, HIWORD_UPDATE(0, 1, 14) },
+	{ "jtag switching", RK3588_GRF_SOC_CON6, FIELD_PREP_WM16_CONST(BIT(14), 0) },
 };
 
 static const struct rockchip_grf_info rk3588_sysgrf __initconst = {

-- 
2.51.0



From nicolas.frattaroli at collabora.com  Mon Aug 25 01:28:24 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 25 Aug 2025 10:28:24 +0200
Subject: [PATCH v3 04/20] media: synopsys: hdmirx: replace macros with
 bitfield variants
In-Reply-To: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
Message-ID: <20250825-byeword-update-v3-4-947b841cdb29@collabora.com>

The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
drivers that use constant masks.

Replace the UPDATE macro with bitfield.h's FIELD_PREP, to give us
additional error checking.

Also, replace the HIWORD_UPDATE macro at the same time with the new
FIELD_PREP_WM16 macro in hw_bitfield.h, which also gives us additional
error checking.

The UPDATE/HIWORD_UPDATE macros are left as wrappers around the
replacement macros, in order to not rock the boat too much, and keep the
changes easy to review.

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/media/platform/synopsys/hdmirx/snps_hdmirx.h | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.h b/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.h
index 220ab99ca61152b36b0a08b398ddefdb985709a5..b26668a98aafd1682b8342cc11f84666a13f07a3 100644
--- a/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.h
+++ b/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.h
@@ -8,10 +8,12 @@
 #ifndef DW_HDMIRX_H
 #define DW_HDMIRX_H
 
+#include <linux/bitfield.h>
 #include <linux/bitops.h>
+#include <linux/hw_bitfield.h>
 
-#define UPDATE(x, h, l)		(((x) << (l)) & GENMASK((h), (l)))
-#define HIWORD_UPDATE(v, h, l)	(((v) << (l)) | (GENMASK((h), (l)) << 16))
+#define UPDATE(x, h, l)		(FIELD_PREP(GENMASK((h), (l)), (x)))
+#define HIWORD_UPDATE(v, h, l)	(FIELD_PREP_WM16(GENMASK((h), (l)), (v)))
 
 /* SYS_GRF */
 #define SYS_GRF_SOC_CON1			0x0304

-- 
2.51.0



From nicolas.frattaroli at collabora.com  Mon Aug 25 01:28:25 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 25 Aug 2025 10:28:25 +0200
Subject: [PATCH v3 05/20] drm/rockchip: lvds: switch to FIELD_PREP_WM16
 macro
In-Reply-To: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
Message-ID: <20250825-byeword-update-v3-5-947b841cdb29@collabora.com>

The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
drivers that use constant masks.

Remove rockchip_lvds.h's own HIWORD_UPDATE macro, and replace all
instances of it with hw_bitfield.h's FIELD_PREP_WM16 macro, which gives
us more error checking.

For the slightly-less-trivial case of the 2-bit width instance, the
results were checked during development to match all possible input
values (0 to 3, inclusive).

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/gpu/drm/rockchip/rockchip_lvds.h | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_lvds.h b/drivers/gpu/drm/rockchip/rockchip_lvds.h
index ca83d7b6bea733588849d3ff379cf8540405462b..2d92447d819bed18adc99f84664c93c639c86a19 100644
--- a/drivers/gpu/drm/rockchip/rockchip_lvds.h
+++ b/drivers/gpu/drm/rockchip/rockchip_lvds.h
@@ -9,6 +9,9 @@
 #ifndef _ROCKCHIP_LVDS_
 #define _ROCKCHIP_LVDS_
 
+#include <linux/bits.h>
+#include <linux/hw_bitfield.h>
+
 #define RK3288_LVDS_CH0_REG0			0x00
 #define RK3288_LVDS_CH0_REG0_LVDS_EN		BIT(7)
 #define RK3288_LVDS_CH0_REG0_TTL_EN		BIT(6)
@@ -106,18 +109,16 @@
 #define LVDS_VESA_18				2
 #define LVDS_JEIDA_18				3
 
-#define HIWORD_UPDATE(v, h, l)  ((GENMASK(h, l) << 16) | ((v) << (l)))
-
 #define PX30_LVDS_GRF_PD_VO_CON0		0x434
-#define   PX30_LVDS_TIE_CLKS(val)		HIWORD_UPDATE(val,  8,  8)
-#define   PX30_LVDS_INVERT_CLKS(val)		HIWORD_UPDATE(val,  9,  9)
-#define   PX30_LVDS_INVERT_DCLK(val)		HIWORD_UPDATE(val,  5,  5)
+#define   PX30_LVDS_TIE_CLKS(val)		FIELD_PREP_WM16(BIT(8), (val))
+#define   PX30_LVDS_INVERT_CLKS(val)		FIELD_PREP_WM16(BIT(9), (val))
+#define   PX30_LVDS_INVERT_DCLK(val)		FIELD_PREP_WM16(BIT(5), (val))
 
 #define PX30_LVDS_GRF_PD_VO_CON1		0x438
-#define   PX30_LVDS_FORMAT(val)			HIWORD_UPDATE(val, 14, 13)
-#define   PX30_LVDS_MODE_EN(val)		HIWORD_UPDATE(val, 12, 12)
-#define   PX30_LVDS_MSBSEL(val)			HIWORD_UPDATE(val, 11, 11)
-#define   PX30_LVDS_P2S_EN(val)			HIWORD_UPDATE(val,  6,  6)
-#define   PX30_LVDS_VOP_SEL(val)		HIWORD_UPDATE(val,  1,  1)
+#define   PX30_LVDS_FORMAT(val)			FIELD_PREP_WM16(GENMASK(14, 13), (val))
+#define   PX30_LVDS_MODE_EN(val)		FIELD_PREP_WM16(BIT(12), (val))
+#define   PX30_LVDS_MSBSEL(val)			FIELD_PREP_WM16(BIT(11), (val))
+#define   PX30_LVDS_P2S_EN(val)			FIELD_PREP_WM16(BIT(6), (val))
+#define   PX30_LVDS_VOP_SEL(val)		FIELD_PREP_WM16(BIT(1), (val))
 
 #endif /* _ROCKCHIP_LVDS_ */

-- 
2.51.0



From nicolas.frattaroli at collabora.com  Mon Aug 25 01:28:26 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 25 Aug 2025 10:28:26 +0200
Subject: [PATCH v3 06/20] phy: rockchip-emmc: switch to FIELD_PREP_WM16
 macro
In-Reply-To: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
Message-ID: <20250825-byeword-update-v3-6-947b841cdb29@collabora.com>

The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
drivers that use constant masks.

Replace the implementation of the rockchip eMMC PHY driver's
HIWORD_UPDATE macro with hw_bitfield.h's FIELD_PREP_WM16. This makes the
change more easily reviewable.

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-emmc.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-emmc.c b/drivers/phy/rockchip/phy-rockchip-emmc.c
index 20023f6eb9944eaab505101d57e806476ecfac71..5187983c58e5e9bc56e65c208122a3be7be00427 100644
--- a/drivers/phy/rockchip/phy-rockchip-emmc.c
+++ b/drivers/phy/rockchip/phy-rockchip-emmc.c
@@ -8,6 +8,7 @@
 
 #include <linux/clk.h>
 #include <linux/delay.h>
+#include <linux/hw_bitfield.h>
 #include <linux/mfd/syscon.h>
 #include <linux/module.h>
 #include <linux/of.h>
@@ -21,7 +22,7 @@
  * only if BIT(x + 16) set to 1 the BIT(x) can be written.
  */
 #define HIWORD_UPDATE(val, mask, shift) \
-		((val) << (shift) | (mask) << ((shift) + 16))
+		(FIELD_PREP_WM16((mask) << (shift), (val)))
 
 /* Register definition */
 #define GRF_EMMCPHY_CON0		0x0

-- 
2.51.0



From nicolas.frattaroli at collabora.com  Mon Aug 25 01:28:27 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 25 Aug 2025 10:28:27 +0200
Subject: [PATCH v3 07/20] drm/rockchip: dsi: switch to FIELD_PREP_WM16*
 macros
In-Reply-To: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
Message-ID: <20250825-byeword-update-v3-7-947b841cdb29@collabora.com>

The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
drivers that use constant masks.

Remove this driver's HIWORD_UPDATE macro, and replace instances of it
with either FIELD_PREP_WM16 or FIELD_PREP_WM16_CONST, depending on
whether they're in an initializer. This gives us better error checking,
which already saved me some trouble during this refactor.

The driver's HIWORD_UPDATE macro doesn't shift up the value, but expects
a pre-shifted value. Meanwhile, FIELD_PREP_WM16 and
FIELD_PREP_WM16_CONST will shift the value for us, based on the given
mask. So a few things that used to be a HIWORD_UPDATE(VERY_LONG_FOO,
VERY_LONG_FOO) are now a somewhat more pleasant
FIELD_PREP_WM16(VERY_LONG_FOO, 1).

There are some non-trivial refactors here. A few literals needed a UL
suffix added to stop them from unintentionally overflowing as a signed
long. To make sure all of these cases are caught, and not just the ones
where the FIELD_PREP_WM16* macros use such a value as a mask, just mark
every literal that's used as a mask as unsigned.

Non-contiguous masks also have to be split into multiple
FIELD_PREP_WM16* instances, as the macro's checks and shifting logic
rely on contiguous masks.

This is compile-tested only.

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 142 ++++++++++++------------
 1 file changed, 68 insertions(+), 74 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
index 3398160ad75e4a9629082bc47491eab473caecc0..5523911b990d93aa5b8a28acb8ffa01298c4a3b7 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
@@ -7,6 +7,7 @@
  */
 
 #include <linux/clk.h>
+#include <linux/hw_bitfield.h>
 #include <linux/iopoll.h>
 #include <linux/math64.h>
 #include <linux/mfd/syscon.h>
@@ -148,7 +149,7 @@
 #define DW_MIPI_NEEDS_GRF_CLK		BIT(1)
 
 #define PX30_GRF_PD_VO_CON1		0x0438
-#define PX30_DSI_FORCETXSTOPMODE	(0xf << 7)
+#define PX30_DSI_FORCETXSTOPMODE	(0xfUL << 7)
 #define PX30_DSI_FORCERXMODE		BIT(6)
 #define PX30_DSI_TURNDISABLE		BIT(5)
 #define PX30_DSI_LCDC_SEL		BIT(0)
@@ -167,16 +168,16 @@
 #define RK3399_DSI1_LCDC_SEL		BIT(4)
 
 #define RK3399_GRF_SOC_CON22		0x6258
-#define RK3399_DSI0_TURNREQUEST		(0xf << 12)
-#define RK3399_DSI0_TURNDISABLE		(0xf << 8)
-#define RK3399_DSI0_FORCETXSTOPMODE	(0xf << 4)
-#define RK3399_DSI0_FORCERXMODE		(0xf << 0)
+#define RK3399_DSI0_TURNREQUEST		(0xfUL << 12)
+#define RK3399_DSI0_TURNDISABLE		(0xfUL << 8)
+#define RK3399_DSI0_FORCETXSTOPMODE	(0xfUL << 4)
+#define RK3399_DSI0_FORCERXMODE		(0xfUL << 0)
 
 #define RK3399_GRF_SOC_CON23		0x625c
-#define RK3399_DSI1_TURNDISABLE		(0xf << 12)
-#define RK3399_DSI1_FORCETXSTOPMODE	(0xf << 8)
-#define RK3399_DSI1_FORCERXMODE		(0xf << 4)
-#define RK3399_DSI1_ENABLE		(0xf << 0)
+#define RK3399_DSI1_TURNDISABLE		(0xfUL << 12)
+#define RK3399_DSI1_FORCETXSTOPMODE	(0xfUL << 8)
+#define RK3399_DSI1_FORCERXMODE		(0xfUL << 4)
+#define RK3399_DSI1_ENABLE		(0xfUL << 0)
 
 #define RK3399_GRF_SOC_CON24		0x6260
 #define RK3399_TXRX_MASTERSLAVEZ	BIT(7)
@@ -186,8 +187,8 @@
 #define RK3399_TXRX_TURNREQUEST		GENMASK(3, 0)
 
 #define RK3568_GRF_VO_CON2		0x0368
-#define RK3568_DSI0_SKEWCALHS		(0x1f << 11)
-#define RK3568_DSI0_FORCETXSTOPMODE	(0xf << 4)
+#define RK3568_DSI0_SKEWCALHS		(0x1fUL << 11)
+#define RK3568_DSI0_FORCETXSTOPMODE	(0xfUL << 4)
 #define RK3568_DSI0_TURNDISABLE		BIT(2)
 #define RK3568_DSI0_FORCERXMODE		BIT(0)
 
@@ -197,18 +198,16 @@
  * come from. Name GRF_VO_CON3 is assumed.
  */
 #define RK3568_GRF_VO_CON3		0x36c
-#define RK3568_DSI1_SKEWCALHS		(0x1f << 11)
-#define RK3568_DSI1_FORCETXSTOPMODE	(0xf << 4)
+#define RK3568_DSI1_SKEWCALHS		(0x1fUL << 11)
+#define RK3568_DSI1_FORCETXSTOPMODE	(0xfUL << 4)
 #define RK3568_DSI1_TURNDISABLE		BIT(2)
 #define RK3568_DSI1_FORCERXMODE		BIT(0)
 
 #define RV1126_GRF_DSIPHY_CON		0x10220
-#define RV1126_DSI_FORCETXSTOPMODE	(0xf << 4)
+#define RV1126_DSI_FORCETXSTOPMODE	(0xfUL << 4)
 #define RV1126_DSI_TURNDISABLE		BIT(2)
 #define RV1126_DSI_FORCERXMODE		BIT(0)
 
-#define HIWORD_UPDATE(val, mask)	(val | (mask) << 16)
-
 enum {
 	DW_DSI_USAGE_IDLE,
 	DW_DSI_USAGE_DSI,
@@ -1484,14 +1483,13 @@ static const struct rockchip_dw_dsi_chip_data px30_chip_data[] = {
 	{
 		.reg = 0xff450000,
 		.lcdsel_grf_reg = PX30_GRF_PD_VO_CON1,
-		.lcdsel_big = HIWORD_UPDATE(0, PX30_DSI_LCDC_SEL),
-		.lcdsel_lit = HIWORD_UPDATE(PX30_DSI_LCDC_SEL,
-					    PX30_DSI_LCDC_SEL),
+		.lcdsel_big = FIELD_PREP_WM16_CONST(PX30_DSI_LCDC_SEL, 0),
+		.lcdsel_lit = FIELD_PREP_WM16_CONST(PX30_DSI_LCDC_SEL, 1),
 
 		.lanecfg1_grf_reg = PX30_GRF_PD_VO_CON1,
-		.lanecfg1 = HIWORD_UPDATE(0, PX30_DSI_TURNDISABLE |
-					     PX30_DSI_FORCERXMODE |
-					     PX30_DSI_FORCETXSTOPMODE),
+		.lanecfg1 = FIELD_PREP_WM16_CONST((PX30_DSI_TURNDISABLE |
+						PX30_DSI_FORCERXMODE |
+						PX30_DSI_FORCETXSTOPMODE), 0),
 
 		.max_data_lanes = 4,
 	},
@@ -1502,9 +1500,9 @@ static const struct rockchip_dw_dsi_chip_data rk3128_chip_data[] = {
 	{
 		.reg = 0x10110000,
 		.lanecfg1_grf_reg = RK3128_GRF_LVDS_CON0,
-		.lanecfg1 = HIWORD_UPDATE(0, RK3128_DSI_TURNDISABLE |
-					     RK3128_DSI_FORCERXMODE |
-					     RK3128_DSI_FORCETXSTOPMODE),
+		.lanecfg1 = FIELD_PREP_WM16_CONST((RK3128_DSI_TURNDISABLE |
+						RK3128_DSI_FORCERXMODE |
+						RK3128_DSI_FORCETXSTOPMODE), 0),
 		.max_data_lanes = 4,
 	},
 	{ /* sentinel */ }
@@ -1514,16 +1512,16 @@ static const struct rockchip_dw_dsi_chip_data rk3288_chip_data[] = {
 	{
 		.reg = 0xff960000,
 		.lcdsel_grf_reg = RK3288_GRF_SOC_CON6,
-		.lcdsel_big = HIWORD_UPDATE(0, RK3288_DSI0_LCDC_SEL),
-		.lcdsel_lit = HIWORD_UPDATE(RK3288_DSI0_LCDC_SEL, RK3288_DSI0_LCDC_SEL),
+		.lcdsel_big = FIELD_PREP_WM16_CONST(RK3288_DSI0_LCDC_SEL, 0),
+		.lcdsel_lit = FIELD_PREP_WM16_CONST(RK3288_DSI0_LCDC_SEL, 1),
 
 		.max_data_lanes = 4,
 	},
 	{
 		.reg = 0xff964000,
 		.lcdsel_grf_reg = RK3288_GRF_SOC_CON6,
-		.lcdsel_big = HIWORD_UPDATE(0, RK3288_DSI1_LCDC_SEL),
-		.lcdsel_lit = HIWORD_UPDATE(RK3288_DSI1_LCDC_SEL, RK3288_DSI1_LCDC_SEL),
+		.lcdsel_big = FIELD_PREP_WM16_CONST(RK3288_DSI1_LCDC_SEL, 0),
+		.lcdsel_lit = FIELD_PREP_WM16_CONST(RK3288_DSI1_LCDC_SEL, 1),
 
 		.max_data_lanes = 4,
 	},
@@ -1539,13 +1537,13 @@ static int rk3399_dphy_tx1rx1_init(struct phy *phy)
 	 * Assume ISP0 is supplied by the RX0 dphy.
 	 */
 	regmap_write(dsi->grf_regmap, RK3399_GRF_SOC_CON24,
-		     HIWORD_UPDATE(0, RK3399_TXRX_SRC_SEL_ISP0));
+		     FIELD_PREP_WM16(RK3399_TXRX_SRC_SEL_ISP0, 0));
 	regmap_write(dsi->grf_regmap, RK3399_GRF_SOC_CON24,
-		     HIWORD_UPDATE(0, RK3399_TXRX_MASTERSLAVEZ));
+		     FIELD_PREP_WM16(RK3399_TXRX_MASTERSLAVEZ, 0));
 	regmap_write(dsi->grf_regmap, RK3399_GRF_SOC_CON24,
-		     HIWORD_UPDATE(0, RK3399_TXRX_BASEDIR));
+		     FIELD_PREP_WM16(RK3399_TXRX_BASEDIR, 0));
 	regmap_write(dsi->grf_regmap, RK3399_GRF_SOC_CON23,
-		     HIWORD_UPDATE(0, RK3399_DSI1_ENABLE));
+		     FIELD_PREP_WM16(RK3399_DSI1_ENABLE, 0));
 
 	return 0;
 }
@@ -1559,21 +1557,20 @@ static int rk3399_dphy_tx1rx1_power_on(struct phy *phy)
 	usleep_range(100, 150);
 
 	regmap_write(dsi->grf_regmap, RK3399_GRF_SOC_CON24,
-		     HIWORD_UPDATE(0, RK3399_TXRX_MASTERSLAVEZ));
+		     FIELD_PREP_WM16(RK3399_TXRX_MASTERSLAVEZ, 0));
 	regmap_write(dsi->grf_regmap, RK3399_GRF_SOC_CON24,
-		     HIWORD_UPDATE(RK3399_TXRX_BASEDIR, RK3399_TXRX_BASEDIR));
+		     FIELD_PREP_WM16(RK3399_TXRX_BASEDIR, 1));
 
 	regmap_write(dsi->grf_regmap, RK3399_GRF_SOC_CON23,
-		     HIWORD_UPDATE(0, RK3399_DSI1_FORCERXMODE));
+		     FIELD_PREP_WM16(RK3399_DSI1_FORCERXMODE, 0));
 	regmap_write(dsi->grf_regmap, RK3399_GRF_SOC_CON23,
-		     HIWORD_UPDATE(0, RK3399_DSI1_FORCETXSTOPMODE));
+		     FIELD_PREP_WM16(RK3399_DSI1_FORCETXSTOPMODE, 0));
 
 	/* Disable lane turn around, which is ignored in receive mode */
 	regmap_write(dsi->grf_regmap, RK3399_GRF_SOC_CON24,
-		     HIWORD_UPDATE(0, RK3399_TXRX_TURNREQUEST));
+		     FIELD_PREP_WM16(RK3399_TXRX_TURNREQUEST, 0));
 	regmap_write(dsi->grf_regmap, RK3399_GRF_SOC_CON23,
-		     HIWORD_UPDATE(RK3399_DSI1_TURNDISABLE,
-				   RK3399_DSI1_TURNDISABLE));
+		     FIELD_PREP_WM16(RK3399_DSI1_TURNDISABLE, 0xf));
 	usleep_range(100, 150);
 
 	dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLK | PHY_UNTESTCLR);
@@ -1581,8 +1578,8 @@ static int rk3399_dphy_tx1rx1_power_on(struct phy *phy)
 
 	/* Enable dphy lanes */
 	regmap_write(dsi->grf_regmap, RK3399_GRF_SOC_CON23,
-		     HIWORD_UPDATE(GENMASK(dsi->dphy_config.lanes - 1, 0),
-				   RK3399_DSI1_ENABLE));
+		     FIELD_PREP_WM16(RK3399_DSI1_ENABLE,
+				  GENMASK(dsi->dphy_config.lanes - 1, 0)));
 
 	usleep_range(100, 150);
 
@@ -1594,7 +1591,7 @@ static int rk3399_dphy_tx1rx1_power_off(struct phy *phy)
 	struct dw_mipi_dsi_rockchip *dsi = phy_get_drvdata(phy);
 
 	regmap_write(dsi->grf_regmap, RK3399_GRF_SOC_CON23,
-		     HIWORD_UPDATE(0, RK3399_DSI1_ENABLE));
+		     FIELD_PREP_WM16(RK3399_DSI1_ENABLE, 0));
 
 	return 0;
 }
@@ -1603,15 +1600,14 @@ static const struct rockchip_dw_dsi_chip_data rk3399_chip_data[] = {
 	{
 		.reg = 0xff960000,
 		.lcdsel_grf_reg = RK3399_GRF_SOC_CON20,
-		.lcdsel_big = HIWORD_UPDATE(0, RK3399_DSI0_LCDC_SEL),
-		.lcdsel_lit = HIWORD_UPDATE(RK3399_DSI0_LCDC_SEL,
-					    RK3399_DSI0_LCDC_SEL),
+		.lcdsel_big = FIELD_PREP_WM16_CONST(RK3399_DSI0_LCDC_SEL, 0),
+		.lcdsel_lit = FIELD_PREP_WM16_CONST(RK3399_DSI0_LCDC_SEL, 1),
 
 		.lanecfg1_grf_reg = RK3399_GRF_SOC_CON22,
-		.lanecfg1 = HIWORD_UPDATE(0, RK3399_DSI0_TURNREQUEST |
-					     RK3399_DSI0_TURNDISABLE |
-					     RK3399_DSI0_FORCETXSTOPMODE |
-					     RK3399_DSI0_FORCERXMODE),
+		.lanecfg1 = FIELD_PREP_WM16_CONST((RK3399_DSI0_TURNREQUEST |
+						RK3399_DSI0_TURNDISABLE |
+						RK3399_DSI0_FORCETXSTOPMODE |
+						RK3399_DSI0_FORCERXMODE), 0),
 
 		.flags = DW_MIPI_NEEDS_PHY_CFG_CLK | DW_MIPI_NEEDS_GRF_CLK,
 		.max_data_lanes = 4,
@@ -1619,25 +1615,23 @@ static const struct rockchip_dw_dsi_chip_data rk3399_chip_data[] = {
 	{
 		.reg = 0xff968000,
 		.lcdsel_grf_reg = RK3399_GRF_SOC_CON20,
-		.lcdsel_big = HIWORD_UPDATE(0, RK3399_DSI1_LCDC_SEL),
-		.lcdsel_lit = HIWORD_UPDATE(RK3399_DSI1_LCDC_SEL,
-					    RK3399_DSI1_LCDC_SEL),
+		.lcdsel_big = FIELD_PREP_WM16_CONST(RK3399_DSI1_LCDC_SEL, 0),
+		.lcdsel_lit = FIELD_PREP_WM16_CONST(RK3399_DSI1_LCDC_SEL, 1),
+
 
 		.lanecfg1_grf_reg = RK3399_GRF_SOC_CON23,
-		.lanecfg1 = HIWORD_UPDATE(0, RK3399_DSI1_TURNDISABLE |
-					     RK3399_DSI1_FORCETXSTOPMODE |
-					     RK3399_DSI1_FORCERXMODE |
-					     RK3399_DSI1_ENABLE),
+		.lanecfg1 = FIELD_PREP_WM16_CONST((RK3399_DSI1_TURNDISABLE |
+						RK3399_DSI1_FORCETXSTOPMODE |
+						RK3399_DSI1_FORCERXMODE |
+						RK3399_DSI1_ENABLE), 0),
 
 		.lanecfg2_grf_reg = RK3399_GRF_SOC_CON24,
-		.lanecfg2 = HIWORD_UPDATE(RK3399_TXRX_MASTERSLAVEZ |
-					  RK3399_TXRX_ENABLECLK,
-					  RK3399_TXRX_MASTERSLAVEZ |
-					  RK3399_TXRX_ENABLECLK |
-					  RK3399_TXRX_BASEDIR),
+		.lanecfg2 = (FIELD_PREP_WM16_CONST(RK3399_TXRX_MASTERSLAVEZ, 1) |
+			     FIELD_PREP_WM16_CONST(RK3399_TXRX_ENABLECLK, 1) |
+			     FIELD_PREP_WM16_CONST(RK3399_TXRX_BASEDIR, 0)),
 
 		.enable_grf_reg = RK3399_GRF_SOC_CON23,
-		.enable = HIWORD_UPDATE(RK3399_DSI1_ENABLE, RK3399_DSI1_ENABLE),
+		.enable = FIELD_PREP_WM16_CONST(RK3399_DSI1_ENABLE, RK3399_DSI1_ENABLE),
 
 		.flags = DW_MIPI_NEEDS_PHY_CFG_CLK | DW_MIPI_NEEDS_GRF_CLK,
 		.max_data_lanes = 4,
@@ -1653,19 +1647,19 @@ static const struct rockchip_dw_dsi_chip_data rk3568_chip_data[] = {
 	{
 		.reg = 0xfe060000,
 		.lanecfg1_grf_reg = RK3568_GRF_VO_CON2,
-		.lanecfg1 = HIWORD_UPDATE(0, RK3568_DSI0_SKEWCALHS |
-					  RK3568_DSI0_FORCETXSTOPMODE |
-					  RK3568_DSI0_TURNDISABLE |
-					  RK3568_DSI0_FORCERXMODE),
+		.lanecfg1 = (FIELD_PREP_WM16_CONST(RK3568_DSI0_SKEWCALHS, 0) |
+			     FIELD_PREP_WM16_CONST(RK3568_DSI0_FORCETXSTOPMODE, 0) |
+			     FIELD_PREP_WM16_CONST(RK3568_DSI0_TURNDISABLE, 0) |
+			     FIELD_PREP_WM16_CONST(RK3568_DSI0_FORCERXMODE, 0)),
 		.max_data_lanes = 4,
 	},
 	{
 		.reg = 0xfe070000,
 		.lanecfg1_grf_reg = RK3568_GRF_VO_CON3,
-		.lanecfg1 = HIWORD_UPDATE(0, RK3568_DSI1_SKEWCALHS |
-					  RK3568_DSI1_FORCETXSTOPMODE |
-					  RK3568_DSI1_TURNDISABLE |
-					  RK3568_DSI1_FORCERXMODE),
+		.lanecfg1 = (FIELD_PREP_WM16_CONST(RK3568_DSI1_SKEWCALHS, 0) |
+			     FIELD_PREP_WM16_CONST(RK3568_DSI1_FORCETXSTOPMODE, 0) |
+			     FIELD_PREP_WM16_CONST(RK3568_DSI1_TURNDISABLE, 0) |
+			     FIELD_PREP_WM16_CONST(RK3568_DSI1_FORCERXMODE, 0)),
 		.max_data_lanes = 4,
 	},
 	{ /* sentinel */ }
@@ -1675,9 +1669,9 @@ static const struct rockchip_dw_dsi_chip_data rv1126_chip_data[] = {
 	{
 		.reg = 0xffb30000,
 		.lanecfg1_grf_reg = RV1126_GRF_DSIPHY_CON,
-		.lanecfg1 = HIWORD_UPDATE(0, RV1126_DSI_TURNDISABLE |
-					     RV1126_DSI_FORCERXMODE |
-					     RV1126_DSI_FORCETXSTOPMODE),
+		.lanecfg1 = (FIELD_PREP_WM16_CONST(RV1126_DSI_TURNDISABLE, 0) |
+			     FIELD_PREP_WM16_CONST(RV1126_DSI_FORCERXMODE, 0) |
+			     FIELD_PREP_WM16_CONST(RV1126_DSI_FORCETXSTOPMODE, 0)),
 		.max_data_lanes = 4,
 	},
 	{ /* sentinel */ }

-- 
2.51.0



From nicolas.frattaroli at collabora.com  Mon Aug 25 01:28:28 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 25 Aug 2025 10:28:28 +0200
Subject: [PATCH v3 08/20] drm/rockchip: vop2: switch to FIELD_PREP_WM16
 macro
In-Reply-To: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
Message-ID: <20250825-byeword-update-v3-8-947b841cdb29@collabora.com>

The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
drivers that use constant masks.

Remove VOP2's HIWORD_UPDATE macro from the vop2 header file, and replace
all instances in rockchip_vop2_reg.c (the only user of this particular
HIWORD_UPDATE definition) with equivalent FIELD_PREP_WM16 instances. This
gives us better error checking.

Reviewed-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
Tested-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  1 -
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 15 +++++++++------
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index fa5c56f16047e3493e82fbedaced221459696dcc..9124191899baca764e4e362f86bbc2bb1f319577 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -33,7 +33,6 @@
 #define WIN_FEATURE_AFBDC		BIT(0)
 #define WIN_FEATURE_CLUSTER		BIT(1)
 
-#define HIWORD_UPDATE(v, h, l)  ((GENMASK(h, l) << 16) | ((v) << (l)))
 /*
  *  the delay number of a window in different mode.
  */
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
index 45c5e39878133163ee05c25a6a99004313f5ed19..38c49030c7ab6416c4af6b5c7be7b241e3c9db18 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
@@ -7,6 +7,7 @@
 #include <linux/bitfield.h>
 #include <linux/kernel.h>
 #include <linux/component.h>
+#include <linux/hw_bitfield.h>
 #include <linux/mod_devicetable.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
@@ -1695,8 +1696,9 @@ static unsigned long rk3588_set_intf_mux(struct vop2_video_port *vp, int id, u32
 		die |= RK3588_SYS_DSP_INFACE_EN_HDMI0 |
 			    FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX, vp->id);
 		val = rk3588_get_hdmi_pol(polflags);
-		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 1, 1));
-		regmap_write(vop2->vo1_grf, RK3588_GRF_VO1_CON0, HIWORD_UPDATE(val, 6, 5));
+		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, FIELD_PREP_WM16(BIT(1), 1));
+		regmap_write(vop2->vo1_grf, RK3588_GRF_VO1_CON0,
+			     FIELD_PREP_WM16(GENMASK(6, 5), val));
 		break;
 	case ROCKCHIP_VOP2_EP_HDMI1:
 		div &= ~RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV;
@@ -1707,8 +1709,9 @@ static unsigned long rk3588_set_intf_mux(struct vop2_video_port *vp, int id, u32
 		die |= RK3588_SYS_DSP_INFACE_EN_HDMI1 |
 			    FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX, vp->id);
 		val = rk3588_get_hdmi_pol(polflags);
-		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 4, 4));
-		regmap_write(vop2->vo1_grf, RK3588_GRF_VO1_CON0, HIWORD_UPDATE(val, 8, 7));
+		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, FIELD_PREP_WM16(BIT(4), 1));
+		regmap_write(vop2->vo1_grf, RK3588_GRF_VO1_CON0,
+			     FIELD_PREP_WM16(GENMASK(8, 7), val));
 		break;
 	case ROCKCHIP_VOP2_EP_EDP0:
 		div &= ~RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV;
@@ -1718,7 +1721,7 @@ static unsigned long rk3588_set_intf_mux(struct vop2_video_port *vp, int id, u32
 		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX;
 		die |= RK3588_SYS_DSP_INFACE_EN_EDP0 |
 			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX, vp->id);
-		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 0, 0));
+		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, FIELD_PREP_WM16(BIT(0), 1));
 		break;
 	case ROCKCHIP_VOP2_EP_EDP1:
 		div &= ~RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV;
@@ -1728,7 +1731,7 @@ static unsigned long rk3588_set_intf_mux(struct vop2_video_port *vp, int id, u32
 		die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX;
 		die |= RK3588_SYS_DSP_INFACE_EN_EDP1 |
 			   FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX, vp->id);
-		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 3, 3));
+		regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, FIELD_PREP_WM16(BIT(3), 1));
 		break;
 	case ROCKCHIP_VOP2_EP_MIPI0:
 		div &= ~RK3588_DSP_IF_MIPI0_PCLK_DIV;

-- 
2.51.0



From nicolas.frattaroli at collabora.com  Mon Aug 25 01:28:29 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 25 Aug 2025 10:28:29 +0200
Subject: [PATCH v3 09/20] phy: rockchip-samsung-dcphy: switch to
 FIELD_PREP_WM16 macro
In-Reply-To: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
Message-ID: <20250825-byeword-update-v3-9-947b841cdb29@collabora.com>

The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
drivers that use constant masks.

phy-rockchip-samsung-dcphy is actually an exemplary example, where the
similarities to FIELD_PREP were spotted and the driver local macro has
the same semantics as the new FIELD_PREP_WM16 hw_bitfield.h macro.

Still, get rid of FIELD_PREP_HIWORD now that a shared implementation
exists, replacing the two instances of it with FIELD_PREP_WM16. This
gives us slightly better error checking; the value is now checked to fit
in 16 bits.

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c b/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c
index 28a052e17366516d5a99988bec9a52e3f0f09101..4508a314727232473e90fd1649ec0f2829b65c49 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c
@@ -8,6 +8,7 @@
 #include <dt-bindings/phy/phy.h>
 #include <linux/bitfield.h>
 #include <linux/clk.h>
+#include <linux/hw_bitfield.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/mfd/syscon.h>
@@ -20,12 +21,6 @@
 #include <linux/regmap.h>
 #include <linux/reset.h>
 
-#define FIELD_PREP_HIWORD(_mask, _val)		\
-	(					\
-		FIELD_PREP((_mask), (_val)) |	\
-		((_mask) << 16)			\
-	)
-
 #define BIAS_CON0		0x0000
 #define I_RES_CNTL_MASK		GENMASK(6, 4)
 #define I_RES_CNTL(x)		FIELD_PREP(I_RES_CNTL_MASK, x)
@@ -252,8 +247,8 @@
 
 /* MIPI_CDPHY_GRF registers */
 #define MIPI_DCPHY_GRF_CON0		0x0000
-#define S_CPHY_MODE			FIELD_PREP_HIWORD(BIT(3), 1)
-#define M_CPHY_MODE			FIELD_PREP_HIWORD(BIT(0), 1)
+#define S_CPHY_MODE			FIELD_PREP_WM16(BIT(3), 1)
+#define M_CPHY_MODE			FIELD_PREP_WM16(BIT(0), 1)
 
 enum hs_drv_res_ohm {
 	STRENGTH_30_OHM = 0x8,

-- 
2.51.0



From nicolas.frattaroli at collabora.com  Mon Aug 25 01:28:30 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 25 Aug 2025 10:28:30 +0200
Subject: [PATCH v3 10/20] drm/rockchip: dw_hdmi_qp: switch to
 FIELD_PREP_WM16 macro
In-Reply-To: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
Message-ID: <20250825-byeword-update-v3-10-947b841cdb29@collabora.com>

The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
drivers that use constant masks.

Replace this driver's HIWORD_UPDATE with the FIELD_PREP_WM16 macro from
hw_bitfield.h. While at it, disambiguate the GRF write to SOC_CON7 by
splitting the definition into the individual bitflags. This is done
because FIELD_PREP_WM16 shifts the value for us according to the mask,
so writing the mask to itself to enable two bits is no longer something
that can be done. It should also not be done anyway because it hides the
true meaning of those two individual bit flags.

HDMI output with this patch has been tested on both RK3588 and RK3576.
On the former, with both present HDMI connectors.

Reviewed-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
Tested-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 68 +++++++++++++-------------
 1 file changed, 33 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
index 7d531b6f4c098c6c548788dad487ce4613a2f32b..ed6e8f036f4b3d76425725c130394cedf039acd0 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
@@ -9,6 +9,7 @@
 
 #include <linux/clk.h>
 #include <linux/gpio/consumer.h>
+#include <linux/hw_bitfield.h>
 #include <linux/mfd/syscon.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
@@ -66,7 +67,8 @@
 #define RK3588_HDMI1_HPD_INT_MSK	BIT(15)
 #define RK3588_HDMI1_HPD_INT_CLR	BIT(14)
 #define RK3588_GRF_SOC_CON7		0x031c
-#define RK3588_SET_HPD_PATH_MASK	GENMASK(13, 12)
+#define RK3588_HPD_HDMI0_IO_EN_MASK	BIT(12)
+#define RK3588_HPD_HDMI1_IO_EN_MASK	BIT(13)
 #define RK3588_GRF_SOC_STATUS1		0x0384
 #define RK3588_HDMI0_LEVEL_INT		BIT(16)
 #define RK3588_HDMI1_LEVEL_INT		BIT(24)
@@ -80,7 +82,6 @@
 #define RK3588_HDMI0_GRANT_SEL		BIT(10)
 #define RK3588_HDMI1_GRANT_SEL		BIT(12)
 
-#define HIWORD_UPDATE(val, mask)	((val) | (mask) << 16)
 #define HOTPLUG_DEBOUNCE_MS		150
 #define MAX_HDMI_PORT_NUM		2
 
@@ -185,11 +186,11 @@ static void dw_hdmi_qp_rk3588_setup_hpd(struct dw_hdmi_qp *dw_hdmi, void *data)
 	u32 val;
 
 	if (hdmi->port_id)
-		val = HIWORD_UPDATE(RK3588_HDMI1_HPD_INT_CLR,
-				    RK3588_HDMI1_HPD_INT_CLR | RK3588_HDMI1_HPD_INT_MSK);
+		val = (FIELD_PREP_WM16(RK3588_HDMI1_HPD_INT_CLR, 1) |
+		       FIELD_PREP_WM16(RK3588_HDMI1_HPD_INT_MSK, 0));
 	else
-		val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_CLR,
-				    RK3588_HDMI0_HPD_INT_CLR | RK3588_HDMI0_HPD_INT_MSK);
+		val = (FIELD_PREP_WM16(RK3588_HDMI0_HPD_INT_CLR, 1) |
+		       FIELD_PREP_WM16(RK3588_HDMI0_HPD_INT_MSK, 0));
 
 	regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
 }
@@ -218,8 +219,8 @@ static void dw_hdmi_qp_rk3576_setup_hpd(struct dw_hdmi_qp *dw_hdmi, void *data)
 	struct rockchip_hdmi_qp *hdmi = (struct rockchip_hdmi_qp *)data;
 	u32 val;
 
-	val = HIWORD_UPDATE(RK3576_HDMI_HPD_INT_CLR,
-			    RK3576_HDMI_HPD_INT_CLR | RK3576_HDMI_HPD_INT_MSK);
+	val = (FIELD_PREP_WM16(RK3576_HDMI_HPD_INT_CLR, 1) |
+	       FIELD_PREP_WM16(RK3576_HDMI_HPD_INT_MSK, 0));
 
 	regmap_write(hdmi->regmap, RK3576_IOC_MISC_CON0, val);
 	regmap_write(hdmi->regmap, 0xa404, 0xffff0102);
@@ -254,7 +255,7 @@ static irqreturn_t dw_hdmi_qp_rk3576_hardirq(int irq, void *dev_id)
 
 	regmap_read(hdmi->regmap, RK3576_IOC_HDMI_HPD_STATUS, &intr_stat);
 	if (intr_stat) {
-		val = HIWORD_UPDATE(RK3576_HDMI_HPD_INT_MSK, RK3576_HDMI_HPD_INT_MSK);
+		val = FIELD_PREP_WM16(RK3576_HDMI_HPD_INT_MSK, 1);
 
 		regmap_write(hdmi->regmap, RK3576_IOC_MISC_CON0, val);
 		return IRQ_WAKE_THREAD;
@@ -273,12 +274,12 @@ static irqreturn_t dw_hdmi_qp_rk3576_irq(int irq, void *dev_id)
 	if (!intr_stat)
 		return IRQ_NONE;
 
-	val = HIWORD_UPDATE(RK3576_HDMI_HPD_INT_CLR, RK3576_HDMI_HPD_INT_CLR);
+	val = FIELD_PREP_WM16(RK3576_HDMI_HPD_INT_CLR, 1);
 	regmap_write(hdmi->regmap, RK3576_IOC_MISC_CON0, val);
 	mod_delayed_work(system_wq, &hdmi->hpd_work,
 			 msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
 
-	val = HIWORD_UPDATE(0, RK3576_HDMI_HPD_INT_MSK);
+	val = FIELD_PREP_WM16(RK3576_HDMI_HPD_INT_MSK, 0);
 	regmap_write(hdmi->regmap, RK3576_IOC_MISC_CON0, val);
 
 	return IRQ_HANDLED;
@@ -293,11 +294,9 @@ static irqreturn_t dw_hdmi_qp_rk3588_hardirq(int irq, void *dev_id)
 
 	if (intr_stat) {
 		if (hdmi->port_id)
-			val = HIWORD_UPDATE(RK3588_HDMI1_HPD_INT_MSK,
-					    RK3588_HDMI1_HPD_INT_MSK);
+			val = FIELD_PREP_WM16(RK3588_HDMI1_HPD_INT_MSK, 1);
 		else
-			val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_MSK,
-					    RK3588_HDMI0_HPD_INT_MSK);
+			val = FIELD_PREP_WM16(RK3588_HDMI0_HPD_INT_MSK, 1);
 		regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
 		return IRQ_WAKE_THREAD;
 	}
@@ -315,20 +314,18 @@ static irqreturn_t dw_hdmi_qp_rk3588_irq(int irq, void *dev_id)
 		return IRQ_NONE;
 
 	if (hdmi->port_id)
-		val = HIWORD_UPDATE(RK3588_HDMI1_HPD_INT_CLR,
-				    RK3588_HDMI1_HPD_INT_CLR);
+		val = FIELD_PREP_WM16(RK3588_HDMI1_HPD_INT_CLR, 1);
 	else
-		val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_CLR,
-				    RK3588_HDMI0_HPD_INT_CLR);
+		val = FIELD_PREP_WM16(RK3588_HDMI0_HPD_INT_CLR, 1);
 	regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
 
 	mod_delayed_work(system_wq, &hdmi->hpd_work,
 			 msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
 
 	if (hdmi->port_id)
-		val |= HIWORD_UPDATE(0, RK3588_HDMI1_HPD_INT_MSK);
+		val |= FIELD_PREP_WM16(RK3588_HDMI1_HPD_INT_MSK, 0);
 	else
-		val |= HIWORD_UPDATE(0, RK3588_HDMI0_HPD_INT_MSK);
+		val |= FIELD_PREP_WM16(RK3588_HDMI0_HPD_INT_MSK, 0);
 	regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
 
 	return IRQ_HANDLED;
@@ -338,14 +335,14 @@ static void dw_hdmi_qp_rk3576_io_init(struct rockchip_hdmi_qp *hdmi)
 {
 	u32 val;
 
-	val = HIWORD_UPDATE(RK3576_SCLIN_MASK, RK3576_SCLIN_MASK) |
-	      HIWORD_UPDATE(RK3576_SDAIN_MASK, RK3576_SDAIN_MASK) |
-	      HIWORD_UPDATE(RK3576_HDMI_GRANT_SEL, RK3576_HDMI_GRANT_SEL) |
-	      HIWORD_UPDATE(RK3576_I2S_SEL_MASK, RK3576_I2S_SEL_MASK);
+	val = FIELD_PREP_WM16(RK3576_SCLIN_MASK, 1) |
+	      FIELD_PREP_WM16(RK3576_SDAIN_MASK, 1) |
+	      FIELD_PREP_WM16(RK3576_HDMI_GRANT_SEL, 1) |
+	      FIELD_PREP_WM16(RK3576_I2S_SEL_MASK, 1);
 
 	regmap_write(hdmi->vo_regmap, RK3576_VO0_GRF_SOC_CON14, val);
 
-	val = HIWORD_UPDATE(0, RK3576_HDMI_HPD_INT_MSK);
+	val = FIELD_PREP_WM16(RK3576_HDMI_HPD_INT_MSK, 0);
 	regmap_write(hdmi->regmap, RK3576_IOC_MISC_CON0, val);
 }
 
@@ -353,27 +350,28 @@ static void dw_hdmi_qp_rk3588_io_init(struct rockchip_hdmi_qp *hdmi)
 {
 	u32 val;
 
-	val = HIWORD_UPDATE(RK3588_SCLIN_MASK, RK3588_SCLIN_MASK) |
-	      HIWORD_UPDATE(RK3588_SDAIN_MASK, RK3588_SDAIN_MASK) |
-	      HIWORD_UPDATE(RK3588_MODE_MASK, RK3588_MODE_MASK) |
-	      HIWORD_UPDATE(RK3588_I2S_SEL_MASK, RK3588_I2S_SEL_MASK);
+	val = FIELD_PREP_WM16(RK3588_SCLIN_MASK, 1) |
+	      FIELD_PREP_WM16(RK3588_SDAIN_MASK, 1) |
+	      FIELD_PREP_WM16(RK3588_MODE_MASK, 1) |
+	      FIELD_PREP_WM16(RK3588_I2S_SEL_MASK, 1);
 	regmap_write(hdmi->vo_regmap,
 		     hdmi->port_id ? RK3588_GRF_VO1_CON6 : RK3588_GRF_VO1_CON3,
 		     val);
 
-	val = HIWORD_UPDATE(RK3588_SET_HPD_PATH_MASK, RK3588_SET_HPD_PATH_MASK);
+	val = FIELD_PREP_WM16(RK3588_HPD_HDMI0_IO_EN_MASK, 1) |
+	      FIELD_PREP_WM16(RK3588_HPD_HDMI1_IO_EN_MASK, 1);
 	regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON7, val);
 
 	if (hdmi->port_id)
-		val = HIWORD_UPDATE(RK3588_HDMI1_GRANT_SEL, RK3588_HDMI1_GRANT_SEL);
+		val = FIELD_PREP_WM16(RK3588_HDMI1_GRANT_SEL, 1);
 	else
-		val = HIWORD_UPDATE(RK3588_HDMI0_GRANT_SEL, RK3588_HDMI0_GRANT_SEL);
+		val = FIELD_PREP_WM16(RK3588_HDMI0_GRANT_SEL, 1);
 	regmap_write(hdmi->vo_regmap, RK3588_GRF_VO1_CON9, val);
 
 	if (hdmi->port_id)
-		val = HIWORD_UPDATE(RK3588_HDMI1_HPD_INT_MSK, RK3588_HDMI1_HPD_INT_MSK);
+		val = FIELD_PREP_WM16(RK3588_HDMI1_HPD_INT_MSK, 1);
 	else
-		val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_MSK, RK3588_HDMI0_HPD_INT_MSK);
+		val = FIELD_PREP_WM16(RK3588_HDMI0_HPD_INT_MSK, 1);
 	regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val);
 }
 

-- 
2.51.0



From nicolas.frattaroli at collabora.com  Mon Aug 25 01:28:31 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 25 Aug 2025 10:28:31 +0200
Subject: [PATCH v3 11/20] drm/rockchip: inno-hdmi: switch to
 FIELD_PREP_WM16 macro
In-Reply-To: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
Message-ID: <20250825-byeword-update-v3-11-947b841cdb29@collabora.com>

The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
drivers that use constant masks.

The inno-hdmi driver's own HIWORD_UPDATE macro is instantiated only
twice. Remove it, and replace its uses with FIELD_PREP_WM16. Since
FIELD_PREP_WM16 shifts the value for us, we replace using the mask as
the value by simply using 1 instead.

With the new FIELD_PREP_WM16 macro, we gain better error checking and a
central shared definition.

This has been compile-tested only as I lack hardware this old, but the
change is trivial enough that I am fairly certain it's equivalent.

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/gpu/drm/rockchip/inno_hdmi.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 1ab3ad4bde9ea7305021186ea221d2ff9057fdbb..f24827dc1421cf5e0c1be63a80da23d645cf3f24 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -10,6 +10,7 @@
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/hdmi.h>
+#include <linux/hw_bitfield.h>
 #include <linux/mfd/syscon.h>
 #include <linux/mod_devicetable.h>
 #include <linux/module.h>
@@ -382,8 +383,6 @@ enum {
 #define HDMI_CEC_BUSFREETIME_H		0xdd
 #define HDMI_CEC_LOGICADDR		0xde
 
-#define HIWORD_UPDATE(val, mask)	((val) | (mask) << 16)
-
 #define RK3036_GRF_SOC_CON2	0x148
 #define RK3036_HDMI_PHSYNC	BIT(4)
 #define RK3036_HDMI_PVSYNC	BIT(5)
@@ -756,10 +755,10 @@ static int inno_hdmi_config_video_timing(struct inno_hdmi *hdmi,
 	int value, psync;
 
 	if (hdmi->variant->dev_type == RK3036_HDMI) {
-		psync = mode->flags & DRM_MODE_FLAG_PHSYNC ? RK3036_HDMI_PHSYNC : 0;
-		value = HIWORD_UPDATE(psync, RK3036_HDMI_PHSYNC);
-		psync = mode->flags & DRM_MODE_FLAG_PVSYNC ? RK3036_HDMI_PVSYNC : 0;
-		value |= HIWORD_UPDATE(psync, RK3036_HDMI_PVSYNC);
+		psync = mode->flags & DRM_MODE_FLAG_PHSYNC ? 1 : 0;
+		value = FIELD_PREP_WM16(RK3036_HDMI_PHSYNC, psync);
+		psync = mode->flags & DRM_MODE_FLAG_PVSYNC ? 1 : 0;
+		value |= FIELD_PREP_WM16(RK3036_HDMI_PVSYNC, psync);
 		regmap_write(hdmi->grf, RK3036_GRF_SOC_CON2, value);
 	}
 

-- 
2.51.0



From nicolas.frattaroli at collabora.com  Mon Aug 25 01:28:32 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 25 Aug 2025 10:28:32 +0200
Subject: [PATCH v3 12/20] phy: rockchip-usb: switch to FIELD_PREP_WM16
 macro
In-Reply-To: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
Message-ID: <20250825-byeword-update-v3-12-947b841cdb29@collabora.com>

The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
drivers that use constant masks.

Remove this driver's HIWORD_UPDATE macro, and replace all instances of
it with (hopefully) equivalent FIELD_PREP_WM16 instances. To do this, a
few of the defines are being adjusted, as FIELD_PREP_WM16 shifts up the
value for us. This gets rid of the icky update(mask, mask) shenanigans.

The benefit of using FIELD_PREP_WM16 is that it does more checking of
the input, hopefully catching errors. In practice, a shared definition
makes code more readable than several different flavours of the same
macro, and the shifted value helps as well.

I do not have the hardware that uses this particular driver, so it's
compile-tested only as far as my own testing goes.

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-usb.c | 51 +++++++++++++--------------------
 1 file changed, 20 insertions(+), 31 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-usb.c b/drivers/phy/rockchip/phy-rockchip-usb.c
index 666a896c8f0a08443228914a039b95974e15ba58..c3c30df29c3ea1a25f7b6100afac36506ec83601 100644
--- a/drivers/phy/rockchip/phy-rockchip-usb.c
+++ b/drivers/phy/rockchip/phy-rockchip-usb.c
@@ -8,6 +8,7 @@
 
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
+#include <linux/hw_bitfield.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -24,9 +25,6 @@
 
 static int enable_usb_uart;
 
-#define HIWORD_UPDATE(val, mask) \
-		((val) | (mask) << 16)
-
 #define UOC_CON0					0x00
 #define UOC_CON0_SIDDQ					BIT(13)
 #define UOC_CON0_DISABLE				BIT(4)
@@ -38,10 +36,10 @@ static int enable_usb_uart;
 #define UOC_CON3					0x0c
 /* bits present on rk3188 and rk3288 phys */
 #define UOC_CON3_UTMI_TERMSEL_FULLSPEED			BIT(5)
-#define UOC_CON3_UTMI_XCVRSEELCT_FSTRANSC		(1 << 3)
-#define UOC_CON3_UTMI_XCVRSEELCT_MASK			(3 << 3)
-#define UOC_CON3_UTMI_OPMODE_NODRIVING			(1 << 1)
-#define UOC_CON3_UTMI_OPMODE_MASK			(3 << 1)
+#define UOC_CON3_UTMI_XCVRSEELCT_FSTRANSC		1UL
+#define UOC_CON3_UTMI_XCVRSEELCT_MASK			GENMASK(4, 3)
+#define UOC_CON3_UTMI_OPMODE_NODRIVING			1UL
+#define UOC_CON3_UTMI_OPMODE_MASK			GENMASK(2, 1)
 #define UOC_CON3_UTMI_SUSPENDN				BIT(0)
 
 struct rockchip_usb_phys {
@@ -79,7 +77,7 @@ struct rockchip_usb_phy {
 static int rockchip_usb_phy_power(struct rockchip_usb_phy *phy,
 					   bool siddq)
 {
-	u32 val = HIWORD_UPDATE(siddq ? UOC_CON0_SIDDQ : 0, UOC_CON0_SIDDQ);
+	u32 val = FIELD_PREP_WM16(UOC_CON0_SIDDQ, siddq);
 
 	return regmap_write(phy->base->reg_base, phy->reg_offset, val);
 }
@@ -332,29 +330,24 @@ static int __init rockchip_init_usb_uart_common(struct regmap *grf,
 	 * but were not present in the original code.
 	 * Also disable the analog phy components to save power.
 	 */
-	val = HIWORD_UPDATE(UOC_CON0_COMMON_ON_N
-				| UOC_CON0_DISABLE
-				| UOC_CON0_SIDDQ,
-			    UOC_CON0_COMMON_ON_N
-				| UOC_CON0_DISABLE
-				| UOC_CON0_SIDDQ);
+	val = FIELD_PREP_WM16(UOC_CON0_COMMON_ON_N, 1) |
+	      FIELD_PREP_WM16(UOC_CON0_DISABLE, 1) |
+	      FIELD_PREP_WM16(UOC_CON0_SIDDQ, 1);
 	ret = regmap_write(grf, regoffs + UOC_CON0, val);
 	if (ret)
 		return ret;
 
-	val = HIWORD_UPDATE(UOC_CON2_SOFT_CON_SEL,
-			    UOC_CON2_SOFT_CON_SEL);
+	val = FIELD_PREP_WM16(UOC_CON2_SOFT_CON_SEL, 1);
 	ret = regmap_write(grf, regoffs + UOC_CON2, val);
 	if (ret)
 		return ret;
 
-	val = HIWORD_UPDATE(UOC_CON3_UTMI_OPMODE_NODRIVING
-				| UOC_CON3_UTMI_XCVRSEELCT_FSTRANSC
-				| UOC_CON3_UTMI_TERMSEL_FULLSPEED,
-			    UOC_CON3_UTMI_SUSPENDN
-				| UOC_CON3_UTMI_OPMODE_MASK
-				| UOC_CON3_UTMI_XCVRSEELCT_MASK
-				| UOC_CON3_UTMI_TERMSEL_FULLSPEED);
+	val = FIELD_PREP_WM16(UOC_CON3_UTMI_SUSPENDN, 0) |
+	      FIELD_PREP_WM16(UOC_CON3_UTMI_OPMODE_MASK,
+			   UOC_CON3_UTMI_OPMODE_NODRIVING) |
+	      FIELD_PREP_WM16(UOC_CON3_UTMI_XCVRSEELCT_MASK,
+			   UOC_CON3_UTMI_XCVRSEELCT_FSTRANSC) |
+	      FIELD_PREP_WM16(UOC_CON3_UTMI_TERMSEL_FULLSPEED, 1);
 	ret = regmap_write(grf, UOC_CON3, val);
 	if (ret)
 		return ret;
@@ -380,10 +373,8 @@ static int __init rk3188_init_usb_uart(struct regmap *grf,
 	if (ret)
 		return ret;
 
-	val = HIWORD_UPDATE(RK3188_UOC0_CON0_BYPASSSEL
-				| RK3188_UOC0_CON0_BYPASSDMEN,
-			    RK3188_UOC0_CON0_BYPASSSEL
-				| RK3188_UOC0_CON0_BYPASSDMEN);
+	val = FIELD_PREP_WM16(RK3188_UOC0_CON0_BYPASSSEL, 1) |
+	      FIELD_PREP_WM16(RK3188_UOC0_CON0_BYPASSDMEN, 1);
 	ret = regmap_write(grf, RK3188_UOC0_CON0, val);
 	if (ret)
 		return ret;
@@ -430,10 +421,8 @@ static int __init rk3288_init_usb_uart(struct regmap *grf,
 	if (ret)
 		return ret;
 
-	val = HIWORD_UPDATE(RK3288_UOC0_CON3_BYPASSSEL
-				| RK3288_UOC0_CON3_BYPASSDMEN,
-			    RK3288_UOC0_CON3_BYPASSSEL
-				| RK3288_UOC0_CON3_BYPASSDMEN);
+	val = FIELD_PREP_WM16(RK3288_UOC0_CON3_BYPASSSEL, 1) |
+	      FIELD_PREP_WM16(RK3288_UOC0_CON3_BYPASSDMEN, 1);
 	ret = regmap_write(grf, RK3288_UOC0_CON3, val);
 	if (ret)
 		return ret;

-- 
2.51.0



From nicolas.frattaroli at collabora.com  Mon Aug 25 01:28:33 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 25 Aug 2025 10:28:33 +0200
Subject: [PATCH v3 13/20] drm/rockchip: dw_hdmi: switch to FIELD_PREP_WM16*
 macros
In-Reply-To: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
Message-ID: <20250825-byeword-update-v3-13-947b841cdb29@collabora.com>

The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
drivers that use constant masks.

Remove this driver's very own HIWORD_UPDATE macro, and replace all
instances of it with equivalent instantiations of FIELD_PREP_WM16 or
FIELD_PREP_WM16_CONST, depending on whether it's in an initializer.

This gives us better error checking, and a centrally agreed upon
signature for this macro, to ease in code comprehension.

Because FIELD_PREP_WM16/FIELD_PREP_WM16_CONST shifts the value to the
mask (like FIELD_PREP et al do), a lot of macro instantiations get
easier to read.

This was tested on an RK3568 ODROID M1, as well as an RK3399 ROCKPro64.

Reviewed-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
Tested-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 80 +++++++++++++----------------
 1 file changed, 36 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index acb59b25d928946a604fb35706a523a76067163b..7b613997bb501bb2ee88c386b5ee1cbbfcae1c9d 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -4,6 +4,7 @@
  */
 
 #include <linux/clk.h>
+#include <linux/hw_bitfield.h>
 #include <linux/mfd/syscon.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
@@ -54,8 +55,6 @@
 #define RK3568_HDMI_SDAIN_MSK		BIT(15)
 #define RK3568_HDMI_SCLIN_MSK		BIT(14)
 
-#define HIWORD_UPDATE(val, mask)	(val | (mask) << 16)
-
 /**
  * struct rockchip_hdmi_chip_data - splite the grf setting of kind of chips
  * @lcdsel_grf_reg: grf register offset of lcdc select
@@ -355,17 +354,14 @@ static void dw_hdmi_rk3228_setup_hpd(struct dw_hdmi *dw_hdmi, void *data)
 
 	dw_hdmi_phy_setup_hpd(dw_hdmi, data);
 
-	regmap_write(hdmi->regmap,
-		RK3228_GRF_SOC_CON6,
-		HIWORD_UPDATE(RK3228_HDMI_HPD_VSEL | RK3228_HDMI_SDA_VSEL |
-			      RK3228_HDMI_SCL_VSEL,
-			      RK3228_HDMI_HPD_VSEL | RK3228_HDMI_SDA_VSEL |
-			      RK3228_HDMI_SCL_VSEL));
-
-	regmap_write(hdmi->regmap,
-		RK3228_GRF_SOC_CON2,
-		HIWORD_UPDATE(RK3228_HDMI_SDAIN_MSK | RK3228_HDMI_SCLIN_MSK,
-			      RK3228_HDMI_SDAIN_MSK | RK3228_HDMI_SCLIN_MSK));
+	regmap_write(hdmi->regmap, RK3228_GRF_SOC_CON6,
+		     FIELD_PREP_WM16(RK3228_HDMI_HPD_VSEL, 1) |
+		     FIELD_PREP_WM16(RK3228_HDMI_SDA_VSEL, 1) |
+		     FIELD_PREP_WM16(RK3228_HDMI_SCL_VSEL, 1));
+
+	regmap_write(hdmi->regmap, RK3228_GRF_SOC_CON2,
+		     FIELD_PREP_WM16(RK3228_HDMI_SDAIN_MSK, 1) |
+		     FIELD_PREP_WM16(RK3328_HDMI_SCLIN_MSK, 1));
 }
 
 static enum drm_connector_status
@@ -377,15 +373,13 @@ dw_hdmi_rk3328_read_hpd(struct dw_hdmi *dw_hdmi, void *data)
 	status = dw_hdmi_phy_read_hpd(dw_hdmi, data);
 
 	if (status == connector_status_connected)
-		regmap_write(hdmi->regmap,
-			RK3328_GRF_SOC_CON4,
-			HIWORD_UPDATE(RK3328_HDMI_SDA_5V | RK3328_HDMI_SCL_5V,
-				      RK3328_HDMI_SDA_5V | RK3328_HDMI_SCL_5V));
+		regmap_write(hdmi->regmap, RK3328_GRF_SOC_CON4,
+			     FIELD_PREP_WM16(RK3328_HDMI_SDA_5V, 1) |
+			     FIELD_PREP_WM16(RK3328_HDMI_SCL_5V, 1));
 	else
-		regmap_write(hdmi->regmap,
-			RK3328_GRF_SOC_CON4,
-			HIWORD_UPDATE(0, RK3328_HDMI_SDA_5V |
-					 RK3328_HDMI_SCL_5V));
+		regmap_write(hdmi->regmap, RK3328_GRF_SOC_CON4,
+			     FIELD_PREP_WM16(RK3328_HDMI_SDA_5V, 0) |
+			     FIELD_PREP_WM16(RK3328_HDMI_SCL_5V, 0));
 	return status;
 }
 
@@ -396,21 +390,21 @@ static void dw_hdmi_rk3328_setup_hpd(struct dw_hdmi *dw_hdmi, void *data)
 	dw_hdmi_phy_setup_hpd(dw_hdmi, data);
 
 	/* Enable and map pins to 3V grf-controlled io-voltage */
-	regmap_write(hdmi->regmap,
-		RK3328_GRF_SOC_CON4,
-		HIWORD_UPDATE(0, RK3328_HDMI_HPD_SARADC | RK3328_HDMI_CEC_5V |
-				 RK3328_HDMI_SDA_5V | RK3328_HDMI_SCL_5V |
-				 RK3328_HDMI_HPD_5V));
-	regmap_write(hdmi->regmap,
-		RK3328_GRF_SOC_CON3,
-		HIWORD_UPDATE(0, RK3328_HDMI_SDA5V_GRF | RK3328_HDMI_SCL5V_GRF |
-				 RK3328_HDMI_HPD5V_GRF |
-				 RK3328_HDMI_CEC5V_GRF));
-	regmap_write(hdmi->regmap,
-		RK3328_GRF_SOC_CON2,
-		HIWORD_UPDATE(RK3328_HDMI_SDAIN_MSK | RK3328_HDMI_SCLIN_MSK,
-			      RK3328_HDMI_SDAIN_MSK | RK3328_HDMI_SCLIN_MSK |
-			      RK3328_HDMI_HPD_IOE));
+	regmap_write(hdmi->regmap, RK3328_GRF_SOC_CON4,
+		     FIELD_PREP_WM16(RK3328_HDMI_HPD_SARADC, 0) |
+		     FIELD_PREP_WM16(RK3328_HDMI_CEC_5V, 0) |
+		     FIELD_PREP_WM16(RK3328_HDMI_SDA_5V, 0) |
+		     FIELD_PREP_WM16(RK3328_HDMI_SCL_5V, 0) |
+		     FIELD_PREP_WM16(RK3328_HDMI_HPD_5V, 0));
+	regmap_write(hdmi->regmap, RK3328_GRF_SOC_CON3,
+		     FIELD_PREP_WM16(RK3328_HDMI_SDA5V_GRF, 0) |
+		     FIELD_PREP_WM16(RK3328_HDMI_SCL5V_GRF, 0) |
+		     FIELD_PREP_WM16(RK3328_HDMI_HPD5V_GRF, 0) |
+		     FIELD_PREP_WM16(RK3328_HDMI_CEC5V_GRF, 0));
+	regmap_write(hdmi->regmap, RK3328_GRF_SOC_CON2,
+		     FIELD_PREP_WM16(RK3328_HDMI_SDAIN_MSK, 1) |
+		     FIELD_PREP_WM16(RK3328_HDMI_SCLIN_MSK, 1) |
+		     FIELD_PREP_WM16(RK3328_HDMI_HPD_IOE, 0));
 
 	dw_hdmi_rk3328_read_hpd(dw_hdmi, data);
 }
@@ -438,8 +432,8 @@ static const struct dw_hdmi_plat_data rk3228_hdmi_drv_data = {
 
 static struct rockchip_hdmi_chip_data rk3288_chip_data = {
 	.lcdsel_grf_reg = RK3288_GRF_SOC_CON6,
-	.lcdsel_big = HIWORD_UPDATE(0, RK3288_HDMI_LCDC_SEL),
-	.lcdsel_lit = HIWORD_UPDATE(RK3288_HDMI_LCDC_SEL, RK3288_HDMI_LCDC_SEL),
+	.lcdsel_big = FIELD_PREP_WM16_CONST(RK3288_HDMI_LCDC_SEL, 0),
+	.lcdsel_lit = FIELD_PREP_WM16_CONST(RK3288_HDMI_LCDC_SEL, 1),
 	.max_tmds_clock = 340000,
 };
 
@@ -475,8 +469,8 @@ static const struct dw_hdmi_plat_data rk3328_hdmi_drv_data = {
 
 static struct rockchip_hdmi_chip_data rk3399_chip_data = {
 	.lcdsel_grf_reg = RK3399_GRF_SOC_CON20,
-	.lcdsel_big = HIWORD_UPDATE(0, RK3399_HDMI_LCDC_SEL),
-	.lcdsel_lit = HIWORD_UPDATE(RK3399_HDMI_LCDC_SEL, RK3399_HDMI_LCDC_SEL),
+	.lcdsel_big = FIELD_PREP_WM16_CONST(RK3399_HDMI_LCDC_SEL, 0),
+	.lcdsel_lit = FIELD_PREP_WM16_CONST(RK3399_HDMI_LCDC_SEL, 1),
 	.max_tmds_clock = 594000,
 };
 
@@ -589,10 +583,8 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
 
 	if (hdmi->chip_data == &rk3568_chip_data) {
 		regmap_write(hdmi->regmap, RK3568_GRF_VO_CON1,
-			     HIWORD_UPDATE(RK3568_HDMI_SDAIN_MSK |
-					   RK3568_HDMI_SCLIN_MSK,
-					   RK3568_HDMI_SDAIN_MSK |
-					   RK3568_HDMI_SCLIN_MSK));
+			     FIELD_PREP_WM16(RK3568_HDMI_SDAIN_MSK, 1) |
+			     FIELD_PREP_WM16(RK3568_HDMI_SCLIN_MSK, 1));
 	}
 
 	drm_encoder_helper_add(encoder, &dw_hdmi_rockchip_encoder_helper_funcs);

-- 
2.51.0



From nicolas.frattaroli at collabora.com  Mon Aug 25 01:28:34 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 25 Aug 2025 10:28:34 +0200
Subject: [PATCH v3 14/20] ASoC: rockchip: i2s-tdm: switch to
 FIELD_PREP_WM16_CONST macro
In-Reply-To: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
Message-ID: <20250825-byeword-update-v3-14-947b841cdb29@collabora.com>

The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
drivers that use constant masks.

Replace the implementation of this driver's HIWORD_UPDATE macro with an
instance of FIELD_PREP_WM16_CONST. The const variant is chosen here
because some of the header defines are then used in initializers.

This gives us some compile-time error checking, while keeping the diff
very small and easy to review.

Acked-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 sound/soc/rockchip/rockchip_i2s_tdm.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.h b/sound/soc/rockchip/rockchip_i2s_tdm.h
index 0aa1c6da1e2c0ebb70473b1bcd1f6e0c1fb90df3..0171e05ee886cdd35f8202db20a313f226958918 100644
--- a/sound/soc/rockchip/rockchip_i2s_tdm.h
+++ b/sound/soc/rockchip/rockchip_i2s_tdm.h
@@ -10,6 +10,8 @@
 #ifndef _ROCKCHIP_I2S_TDM_H
 #define _ROCKCHIP_I2S_TDM_H
 
+#include <linux/hw_bitfield.h>
+
 /*
  * TXCR
  * transmit operation control register
@@ -285,7 +287,7 @@ enum {
 #define I2S_TDM_RXCR	(0x0034)
 #define I2S_CLKDIV	(0x0038)
 
-#define HIWORD_UPDATE(v, h, l)	(((v) << (l)) | (GENMASK((h), (l)) << 16))
+#define HIWORD_UPDATE(v, h, l)	(FIELD_PREP_WM16_CONST(GENMASK((h), (l)), (v)))
 
 /* PX30 GRF CONFIGS */
 #define PX30_I2S0_CLK_IN_SRC_FROM_TX		HIWORD_UPDATE(1, 13, 12)

-- 
2.51.0



From nicolas.frattaroli at collabora.com  Mon Aug 25 01:28:35 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 25 Aug 2025 10:28:35 +0200
Subject: [PATCH v3 15/20] net: stmmac: dwmac-rk: switch to FIELD_PREP_WM16
 macro
In-Reply-To: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
Message-ID: <20250825-byeword-update-v3-15-947b841cdb29@collabora.com>

The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
drivers that use constant masks.

Like many other Rockchip drivers, dwmac-rk has its own HIWORD_UPDATE
macro. Its semantics allow us to redefine it as a wrapper to the shared
hw_bitfield.h FIELD_PREP_WM16 macros though.

Replace the implementation of this driver's very own HIWORD_UPDATE macro
with an instance of FIELD_PREP_WM16 from hw_bitfield.h. This keeps the
diff easily reviewable, while giving us more compile-time error
checking.

The related GRF_BIT macro is left alone for now; any attempt to rework
the code to not use its own solution here would likely end up harder to
review and less pretty for the time being.

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index 9fc41207cc459313e575a2b00236b82611ad9603..c500194de3cc303f68fdd8a2466a81a63d4601d8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -8,6 +8,7 @@
  */
 
 #include <linux/stmmac.h>
+#include <linux/hw_bitfield.h>
 #include <linux/bitops.h>
 #include <linux/clk.h>
 #include <linux/phy.h>
@@ -149,7 +150,7 @@ static int rk_set_clk_mac_speed(struct rk_priv_data *bsp_priv,
 }
 
 #define HIWORD_UPDATE(val, mask, shift) \
-		((val) << (shift) | (mask) << ((shift) + 16))
+		(FIELD_PREP_WM16((mask) << (shift), (val)))
 
 #define GRF_BIT(nr)	(BIT(nr) | BIT(nr+16))
 #define GRF_CLR_BIT(nr)	(BIT(nr+16))

-- 
2.51.0



From nicolas.frattaroli at collabora.com  Mon Aug 25 01:28:36 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 25 Aug 2025 10:28:36 +0200
Subject: [PATCH v3 16/20] PCI: rockchip: Switch to FIELD_PREP_WM16* macros
In-Reply-To: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
Message-ID: <20250825-byeword-update-v3-16-947b841cdb29@collabora.com>

The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
drivers that use constant masks.

The Rockchip PCI driver, like many other Rockchip drivers, has its very
own definition of HIWORD_UPDATE.

Remove it, and replace its usage with either FIELD_PREP_WM16, or two new
header local macros for setting/clearing a bit with the high mask, which
use FIELD_PREP_WM16_CONST internally. In the process, ENCODE_LANES
needed to be adjusted, as FIELD_PREP_WM16* shifts the value for us.

That this is equivalent was verified by first making all FIELD_PREP_WM16
instances FIELD_PREP_WM16_CONST, then doing a static_assert() comparing
it to the old macro (and for those with parameters, static_asserting for
the full range of possible values with the old encode macro).

What we get out of this is compile time error checking to make sure the
value actually fits in the mask, and that the mask fits in the register,
and also generally less icky code that writes shifted values when it
actually just meant to set and clear a handful of bits.

Acked-by: Bjorn Helgaas <bhelgaas at google.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/pci/controller/pcie-rockchip.h | 35 +++++++++++++++++-----------------
 1 file changed, 18 insertions(+), 17 deletions(-)

diff --git a/drivers/pci/controller/pcie-rockchip.h b/drivers/pci/controller/pcie-rockchip.h
index 72a2c045f6fe95cb43f01a2841a5ca0f597c85d4..3e82a69b9c006e52d134278651c5a420a1f195c2 100644
--- a/drivers/pci/controller/pcie-rockchip.h
+++ b/drivers/pci/controller/pcie-rockchip.h
@@ -12,6 +12,7 @@
 #define _PCIE_ROCKCHIP_H
 
 #include <linux/clk.h>
+#include <linux/hw_bitfield.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/pci-ecam.h>
@@ -21,10 +22,10 @@
  * The upper 16 bits of PCIE_CLIENT_CONFIG are a write mask for the lower 16
  * bits.  This allows atomic updates of the register without locking.
  */
-#define HIWORD_UPDATE(mask, val)	(((mask) << 16) | (val))
-#define HIWORD_UPDATE_BIT(val)		HIWORD_UPDATE(val, val)
+#define HWORD_SET_BIT(val)		(FIELD_PREP_WM16_CONST((val), 1))
+#define HWORD_CLR_BIT(val)		(FIELD_PREP_WM16_CONST((val), 0))
 
-#define ENCODE_LANES(x)			((((x) >> 1) & 3) << 4)
+#define ENCODE_LANES(x)			((((x) >> 1) & 3))
 #define MAX_LANE_NUM			4
 #define MAX_REGION_LIMIT		32
 #define MIN_EP_APERTURE			28
@@ -32,21 +33,21 @@
 
 #define PCIE_CLIENT_BASE		0x0
 #define PCIE_CLIENT_CONFIG		(PCIE_CLIENT_BASE + 0x00)
-#define   PCIE_CLIENT_CONF_ENABLE	  HIWORD_UPDATE_BIT(0x0001)
-#define   PCIE_CLIENT_CONF_DISABLE       HIWORD_UPDATE(0x0001, 0)
-#define   PCIE_CLIENT_LINK_TRAIN_ENABLE	  HIWORD_UPDATE_BIT(0x0002)
-#define   PCIE_CLIENT_LINK_TRAIN_DISABLE  HIWORD_UPDATE(0x0002, 0)
-#define   PCIE_CLIENT_ARI_ENABLE	  HIWORD_UPDATE_BIT(0x0008)
-#define   PCIE_CLIENT_CONF_LANE_NUM(x)	  HIWORD_UPDATE(0x0030, ENCODE_LANES(x))
-#define   PCIE_CLIENT_MODE_RC		  HIWORD_UPDATE_BIT(0x0040)
-#define   PCIE_CLIENT_MODE_EP            HIWORD_UPDATE(0x0040, 0)
-#define   PCIE_CLIENT_GEN_SEL_1		  HIWORD_UPDATE(0x0080, 0)
-#define   PCIE_CLIENT_GEN_SEL_2		  HIWORD_UPDATE_BIT(0x0080)
+#define   PCIE_CLIENT_CONF_ENABLE		HWORD_SET_BIT(0x0001)
+#define   PCIE_CLIENT_CONF_DISABLE		HWORD_CLR_BIT(0x0001)
+#define   PCIE_CLIENT_LINK_TRAIN_ENABLE		HWORD_SET_BIT(0x0002)
+#define   PCIE_CLIENT_LINK_TRAIN_DISABLE	HWORD_CLR_BIT(0x0002)
+#define   PCIE_CLIENT_ARI_ENABLE		HWORD_SET_BIT(0x0008)
+#define   PCIE_CLIENT_CONF_LANE_NUM(x)		FIELD_PREP_WM16(0x0030, ENCODE_LANES(x))
+#define   PCIE_CLIENT_MODE_RC			HWORD_SET_BIT(0x0040)
+#define   PCIE_CLIENT_MODE_EP			HWORD_CLR_BIT(0x0040)
+#define   PCIE_CLIENT_GEN_SEL_1			HWORD_CLR_BIT(0x0080)
+#define   PCIE_CLIENT_GEN_SEL_2			HWORD_SET_BIT(0x0080)
 #define PCIE_CLIENT_LEGACY_INT_CTRL	(PCIE_CLIENT_BASE + 0x0c)
-#define   PCIE_CLIENT_INT_IN_ASSERT		HIWORD_UPDATE_BIT(0x0002)
-#define   PCIE_CLIENT_INT_IN_DEASSERT		HIWORD_UPDATE(0x0002, 0)
-#define   PCIE_CLIENT_INT_PEND_ST_PEND		HIWORD_UPDATE_BIT(0x0001)
-#define   PCIE_CLIENT_INT_PEND_ST_NORMAL	HIWORD_UPDATE(0x0001, 0)
+#define   PCIE_CLIENT_INT_IN_ASSERT		HWORD_SET_BIT(0x0002)
+#define   PCIE_CLIENT_INT_IN_DEASSERT		HWORD_CLR_BIT(0x0002)
+#define   PCIE_CLIENT_INT_PEND_ST_PEND		HWORD_SET_BIT(0x0001)
+#define   PCIE_CLIENT_INT_PEND_ST_NORMAL	HWORD_CLR_BIT(0x0001)
 #define PCIE_CLIENT_SIDE_BAND_STATUS	(PCIE_CLIENT_BASE + 0x20)
 #define   PCIE_CLIENT_PHY_ST			BIT(12)
 #define PCIE_CLIENT_DEBUG_OUT_0		(PCIE_CLIENT_BASE + 0x3c)

-- 
2.51.0



From nicolas.frattaroli at collabora.com  Mon Aug 25 01:28:37 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 25 Aug 2025 10:28:37 +0200
Subject: [PATCH v3 17/20] PCI: dw-rockchip: Switch to FIELD_PREP_WM16 macro
In-Reply-To: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
Message-ID: <20250825-byeword-update-v3-17-947b841cdb29@collabora.com>

The era of hand-rolled HIWORD_UPDATE macros is over.

Like many other Rockchip drivers, pcie-dw-rockchip brings with it its
very own flavour of HIWORD_UPDATE. It's occasionally used without a
constant mask, which complicates matters. HIWORD_UPDATE_BIT is a
confusingly named addition, as it doesn't update the bit, it actually
sets all bits in the value to 1. HIWORD_DISABLE_BIT is similarly
confusing; it disables several bits at once by using the value as a mask
and the inverse of value as the value, and the "disabling only these"
effect comes from the hardware actually using the mask. The more obvious
approach would've been HIWORD_UPDATE(val, 0) in my opinion.

This is part of the motivation why this patch uses hw_bitfield.h's
FIELD_PREP_WM16 instead, where possible. FIELD_PREP_WM16 requires a
constant bit mask, which isn't possible where the irq number is used to
generate a bit mask. For that purpose, we replace it with a more robust
macro than what was there but that should also bring close to zero
runtime overhead: we actually mask the IRQ number to make sure we're not
writing garbage.

For the remaining bits, there also are some caveats. For starters, the
PCIE_CLIENT_ENABLE_LTSSM and PCIE_CLIENT_DISABLE_LTSSM were named in a
manner that isn't quite truthful to what they do. Their modification
actually spans not just the LTSSM bit but also another bit, flipping
only the LTSSM one, but keeping the other (which according to the TRM
has a reset value of 0) always enabled. This other bit is reserved as of
the IP version RK3588 uses at least, and I have my doubts as to whether
it was meant to be set, and whether it was meant to be set in that code
path. Either way, it's confusing.

Replace it with just writing either 1 or 0 to the LTSSM bit, using the
new FIELD_PREP_WM16 macro from hw_bitfield.h, which grants us the
benefit of better compile-time error checking.

The change of no longer setting the reserved bit doesn't appear to
change the behaviour on RK3568 in RC mode, where it's not marked as
reserved.

PCIE_CLIENT_RC_MODE/PCIE_CLIENT_EP_MODE was another field that wasn't
super clear on what the bit field modification actually is. As far as I
can tell, switching to RC mode doesn't actually write the correct value
to the field if any of its bits have been set previously, as it only
updates one bit of a 4 bit field.

Replace it by actually writing the full values to the field, using the
new FIELD_PREP_WM16 macro, which grants us the benefit of better
compile-time error checking.

This patch was tested on RK3588 (PCIe3 x4 controller), RK3576 (PCIe2 x1
controller) and RK3568 (PCIe x2 controller), all in RC mode.

Acked-by: Bjorn Helgaas <bhelgaas at google.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/pci/controller/dwc/pcie-dw-rockchip.c | 42 +++++++++++++++++----------
 1 file changed, 26 insertions(+), 16 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
index c045353fa4930724c71ffc33d52bd03789b6e048..3e2752c7dd096ecb5c22f475ed17bea6d261f3fa 100644
--- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
+++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
@@ -11,6 +11,7 @@
 #include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/gpio/consumer.h>
+#include <linux/hw_bitfield.h>
 #include <linux/irqchip/chained_irq.h>
 #include <linux/irqdomain.h>
 #include <linux/mfd/syscon.h>
@@ -29,18 +30,18 @@
  * The upper 16 bits of PCIE_CLIENT_CONFIG are a write
  * mask for the lower 16 bits.
  */
-#define HIWORD_UPDATE(mask, val) (((mask) << 16) | (val))
-#define HIWORD_UPDATE_BIT(val)	HIWORD_UPDATE(val, val)
-#define HIWORD_DISABLE_BIT(val)	HIWORD_UPDATE(val, ~val)
 
 #define to_rockchip_pcie(x) dev_get_drvdata((x)->dev)
 
 /* General Control Register */
 #define PCIE_CLIENT_GENERAL_CON		0x0
-#define  PCIE_CLIENT_RC_MODE		HIWORD_UPDATE_BIT(0x40)
-#define  PCIE_CLIENT_EP_MODE		HIWORD_UPDATE(0xf0, 0x0)
-#define  PCIE_CLIENT_ENABLE_LTSSM	HIWORD_UPDATE_BIT(0xc)
-#define  PCIE_CLIENT_DISABLE_LTSSM	HIWORD_UPDATE(0x0c, 0x8)
+#define  PCIE_CLIENT_MODE_MASK		GENMASK(7, 4)
+#define  PCIE_CLIENT_MODE_EP		0x0UL
+#define  PCIE_CLIENT_MODE_RC		0x4UL
+#define  PCIE_CLIENT_SET_MODE(x)	FIELD_PREP_WM16(PCIE_CLIENT_MODE_MASK, (x))
+#define  PCIE_CLIENT_LD_RQ_RST_GRT	FIELD_PREP_WM16(BIT(3), 1)
+#define  PCIE_CLIENT_ENABLE_LTSSM	FIELD_PREP_WM16(BIT(2), 1)
+#define  PCIE_CLIENT_DISABLE_LTSSM	FIELD_PREP_WM16(BIT(2), 0)
 
 /* Interrupt Status Register Related to Legacy Interrupt */
 #define PCIE_CLIENT_INTR_STATUS_LEGACY	0x8
@@ -52,6 +53,11 @@
 
 /* Interrupt Mask Register Related to Legacy Interrupt */
 #define PCIE_CLIENT_INTR_MASK_LEGACY	0x1c
+#define  PCIE_INTR_MASK			GENMASK(7, 0)
+#define  PCIE_INTR_CLAMP(_x)		((BIT((_x)) & PCIE_INTR_MASK))
+#define  PCIE_INTR_LEGACY_MASK(x)	(PCIE_INTR_CLAMP((x)) | \
+					 (PCIE_INTR_CLAMP((x)) << 16))
+#define  PCIE_INTR_LEGACY_UNMASK(x)	(PCIE_INTR_CLAMP((x)) << 16)
 
 /* Interrupt Mask Register Related to Miscellaneous Operation */
 #define PCIE_CLIENT_INTR_MASK_MISC	0x24
@@ -116,14 +122,14 @@ static void rockchip_pcie_intx_handler(struct irq_desc *desc)
 static void rockchip_intx_mask(struct irq_data *data)
 {
 	rockchip_pcie_writel_apb(irq_data_get_irq_chip_data(data),
-				 HIWORD_UPDATE_BIT(BIT(data->hwirq)),
+				 PCIE_INTR_LEGACY_MASK(data->hwirq),
 				 PCIE_CLIENT_INTR_MASK_LEGACY);
 };
 
 static void rockchip_intx_unmask(struct irq_data *data)
 {
 	rockchip_pcie_writel_apb(irq_data_get_irq_chip_data(data),
-				 HIWORD_DISABLE_BIT(BIT(data->hwirq)),
+				 PCIE_INTR_LEGACY_UNMASK(data->hwirq),
 				 PCIE_CLIENT_INTR_MASK_LEGACY);
 };
 
@@ -487,7 +493,7 @@ static irqreturn_t rockchip_pcie_ep_sys_irq_thread(int irq, void *arg)
 		dev_dbg(dev, "hot reset or link-down reset\n");
 		dw_pcie_ep_linkdown(&pci->ep);
 		/* Stop delaying link training. */
-		val = HIWORD_UPDATE_BIT(PCIE_LTSSM_APP_DLY2_DONE);
+		val = FIELD_PREP_WM16(PCIE_LTSSM_APP_DLY2_DONE, 1);
 		rockchip_pcie_writel_apb(rockchip, val,
 					 PCIE_CLIENT_HOT_RESET_CTRL);
 	}
@@ -526,10 +532,11 @@ static int rockchip_pcie_configure_rc(struct platform_device *pdev,
 	}
 
 	/* LTSSM enable control mode */
-	val = HIWORD_UPDATE_BIT(PCIE_LTSSM_ENABLE_ENHANCE);
+	val = FIELD_PREP_WM16(PCIE_LTSSM_ENABLE_ENHANCE, 1);
 	rockchip_pcie_writel_apb(rockchip, val, PCIE_CLIENT_HOT_RESET_CTRL);
 
-	rockchip_pcie_writel_apb(rockchip, PCIE_CLIENT_RC_MODE,
+	rockchip_pcie_writel_apb(rockchip,
+				 PCIE_CLIENT_SET_MODE(PCIE_CLIENT_MODE_RC),
 				 PCIE_CLIENT_GENERAL_CON);
 
 	pp = &rockchip->pci.pp;
@@ -543,7 +550,7 @@ static int rockchip_pcie_configure_rc(struct platform_device *pdev,
 	}
 
 	/* unmask DLL up/down indicator */
-	val = HIWORD_UPDATE(PCIE_RDLH_LINK_UP_CHGED, 0);
+	val = FIELD_PREP_WM16(PCIE_RDLH_LINK_UP_CHGED, 0);
 	rockchip_pcie_writel_apb(rockchip, val, PCIE_CLIENT_INTR_MASK_MISC);
 
 	return ret;
@@ -575,10 +582,12 @@ static int rockchip_pcie_configure_ep(struct platform_device *pdev,
 	 * LTSSM enable control mode, and automatically delay link training on
 	 * hot reset/link-down reset.
 	 */
-	val = HIWORD_UPDATE_BIT(PCIE_LTSSM_ENABLE_ENHANCE | PCIE_LTSSM_APP_DLY2_EN);
+	val = FIELD_PREP_WM16(PCIE_LTSSM_ENABLE_ENHANCE, 1) |
+	      FIELD_PREP_WM16(PCIE_LTSSM_APP_DLY2_EN, 1);
 	rockchip_pcie_writel_apb(rockchip, val, PCIE_CLIENT_HOT_RESET_CTRL);
 
-	rockchip_pcie_writel_apb(rockchip, PCIE_CLIENT_EP_MODE,
+	rockchip_pcie_writel_apb(rockchip,
+				 PCIE_CLIENT_SET_MODE(PCIE_CLIENT_MODE_EP),
 				 PCIE_CLIENT_GENERAL_CON);
 
 	rockchip->pci.ep.ops = &rockchip_pcie_ep_ops;
@@ -602,7 +611,8 @@ static int rockchip_pcie_configure_ep(struct platform_device *pdev,
 	pci_epc_init_notify(rockchip->pci.ep.epc);
 
 	/* unmask DLL up/down indicator and hot reset/link-down reset */
-	val = HIWORD_UPDATE(PCIE_RDLH_LINK_UP_CHGED | PCIE_LINK_REQ_RST_NOT_INT, 0);
+	val = FIELD_PREP_WM16(PCIE_RDLH_LINK_UP_CHGED, 0) |
+	      FIELD_PREP_WM16(PCIE_LINK_REQ_RST_NOT_INT, 0);
 	rockchip_pcie_writel_apb(rockchip, val, PCIE_CLIENT_INTR_MASK_MISC);
 
 	return ret;

-- 
2.51.0



From nicolas.frattaroli at collabora.com  Mon Aug 25 01:28:38 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 25 Aug 2025 10:28:38 +0200
Subject: [PATCH v3 18/20] PM / devfreq: rockchip-dfi: switch to
 FIELD_PREP_WM16 macro
In-Reply-To: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
Message-ID: <20250825-byeword-update-v3-18-947b841cdb29@collabora.com>

The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
drivers that use constant masks.

Like many other Rockchip drivers, rockchip-dfi brings with it its own
HIWORD_UPDATE macro. This variant doesn't shift the value (and like the
others, doesn't do any checking).

Remove it, and replace instances of it with hw_bitfield.h's
FIELD_PREP_WM16.  Since FIELD_PREP_WM16 requires contiguous masks and
shifts the value for us, some reshuffling of definitions needs to
happen.

This gives us better compile-time error checking, and in my opinion,
nicer code.

Tested on an RK3568 ODROID-M1 board, and an RK3588 ROCK 5B board.

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/devfreq/event/rockchip-dfi.c | 27 +++++++++++++--------------
 1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/drivers/devfreq/event/rockchip-dfi.c b/drivers/devfreq/event/rockchip-dfi.c
index 0470d7c175f4f6bb3955e36c713f4c55538d1a87..19fc23dedb0af0dfe88dd418f6817a1b0bed10f2 100644
--- a/drivers/devfreq/event/rockchip-dfi.c
+++ b/drivers/devfreq/event/rockchip-dfi.c
@@ -20,6 +20,7 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/bitfield.h>
+#include <linux/hw_bitfield.h>
 #include <linux/bits.h>
 #include <linux/perf_event.h>
 
@@ -30,8 +31,6 @@
 
 #define DMC_MAX_CHANNELS	4
 
-#define HIWORD_UPDATE(val, mask)	((val) | (mask) << 16)
-
 /* DDRMON_CTRL */
 #define DDRMON_CTRL	0x04
 #define DDRMON_CTRL_DDR4		BIT(5)
@@ -40,9 +39,6 @@
 #define DDRMON_CTRL_LPDDR23		BIT(2)
 #define DDRMON_CTRL_SOFTWARE_EN		BIT(1)
 #define DDRMON_CTRL_TIMER_CNT_EN	BIT(0)
-#define DDRMON_CTRL_DDR_TYPE_MASK	(DDRMON_CTRL_DDR4 | \
-					 DDRMON_CTRL_LPDDR4 | \
-					 DDRMON_CTRL_LPDDR23)
 
 #define DDRMON_CH0_WR_NUM		0x20
 #define DDRMON_CH0_RD_NUM		0x24
@@ -142,29 +138,32 @@ static int rockchip_dfi_enable(struct rockchip_dfi *dfi)
 			continue;
 
 		/* clear DDRMON_CTRL setting */
-		writel_relaxed(HIWORD_UPDATE(0, DDRMON_CTRL_TIMER_CNT_EN |
-			       DDRMON_CTRL_SOFTWARE_EN | DDRMON_CTRL_HARDWARE_EN),
+		writel_relaxed(FIELD_PREP_WM16(DDRMON_CTRL_TIMER_CNT_EN, 0) |
+			       FIELD_PREP_WM16(DDRMON_CTRL_SOFTWARE_EN, 0) |
+			       FIELD_PREP_WM16(DDRMON_CTRL_HARDWARE_EN, 0),
 			       dfi_regs + i * dfi->ddrmon_stride + DDRMON_CTRL);
 
 		/* set ddr type to dfi */
 		switch (dfi->ddr_type) {
 		case ROCKCHIP_DDRTYPE_LPDDR2:
 		case ROCKCHIP_DDRTYPE_LPDDR3:
-			ctrl = DDRMON_CTRL_LPDDR23;
+			ctrl = FIELD_PREP_WM16(DDRMON_CTRL_LPDDR23, 1) |
+			       FIELD_PREP_WM16(DDRMON_CTRL_LPDDR4, 0);
 			break;
 		case ROCKCHIP_DDRTYPE_LPDDR4:
 		case ROCKCHIP_DDRTYPE_LPDDR4X:
-			ctrl = DDRMON_CTRL_LPDDR4;
+			ctrl = FIELD_PREP_WM16(DDRMON_CTRL_LPDDR23, 0) |
+			       FIELD_PREP_WM16(DDRMON_CTRL_LPDDR4, 1);
 			break;
 		default:
 			break;
 		}
 
-		writel_relaxed(HIWORD_UPDATE(ctrl, DDRMON_CTRL_DDR_TYPE_MASK),
-			       dfi_regs + i * dfi->ddrmon_stride + DDRMON_CTRL);
+		writel_relaxed(ctrl, dfi_regs + i * dfi->ddrmon_stride +
+			       DDRMON_CTRL);
 
 		/* enable count, use software mode */
-		writel_relaxed(HIWORD_UPDATE(DDRMON_CTRL_SOFTWARE_EN, DDRMON_CTRL_SOFTWARE_EN),
+		writel_relaxed(FIELD_PREP_WM16(DDRMON_CTRL_SOFTWARE_EN, 1),
 			       dfi_regs + i * dfi->ddrmon_stride + DDRMON_CTRL);
 
 		if (dfi->ddrmon_ctrl_single)
@@ -194,8 +193,8 @@ static void rockchip_dfi_disable(struct rockchip_dfi *dfi)
 		if (!(dfi->channel_mask & BIT(i)))
 			continue;
 
-		writel_relaxed(HIWORD_UPDATE(0, DDRMON_CTRL_SOFTWARE_EN),
-			      dfi_regs + i * dfi->ddrmon_stride + DDRMON_CTRL);
+		writel_relaxed(FIELD_PREP_WM16(DDRMON_CTRL_SOFTWARE_EN, 0),
+			       dfi_regs + i * dfi->ddrmon_stride + DDRMON_CTRL);
 
 		if (dfi->ddrmon_ctrl_single)
 			break;

-- 
2.51.0



From nicolas.frattaroli at collabora.com  Mon Aug 25 01:28:39 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 25 Aug 2025 10:28:39 +0200
Subject: [PATCH v3 19/20] clk: sp7021: switch to FIELD_PREP_WM16 macro
In-Reply-To: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
Message-ID: <20250825-byeword-update-v3-19-947b841cdb29@collabora.com>

The sp7021 clock driver has its own shifted high word mask macro,
similar to the ones many Rockchip drivers have.

Remove it, and replace instances of it with hw_bitfield.h's
FIELD_PREP_WM16 macro, which does the same thing except in a common
macro that also does compile-time error checking.

This was compile-tested with 32-bit ARM with Clang, no runtime tests
were performed as I lack the hardware. However, I verified that fix
commit 5c667d5a5a3e ("clk: sp7021: Adjust width of _m in HWM_FIELD_PREP()")
is not regressed. No warning is produced.

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/clk/clk-sp7021.c | 22 ++++++++--------------
 1 file changed, 8 insertions(+), 14 deletions(-)

diff --git a/drivers/clk/clk-sp7021.c b/drivers/clk/clk-sp7021.c
index 95d66191df4bdb3609128ea097be896ef3a1038a..e902ba75e00656688441b938938f3fc4afc46974 100644
--- a/drivers/clk/clk-sp7021.c
+++ b/drivers/clk/clk-sp7021.c
@@ -7,6 +7,7 @@
 #include <linux/clk-provider.h>
 #include <linux/of.h>
 #include <linux/bitfield.h>
+#include <linux/hw_bitfield.h>
 #include <linux/slab.h>
 #include <linux/io.h>
 #include <linux/err.h>
@@ -38,13 +39,6 @@ enum {
 #define MASK_DIVN	GENMASK(7, 0)
 #define MASK_DIVM	GENMASK(14, 8)
 
-/* HIWORD_MASK FIELD_PREP */
-#define HWM_FIELD_PREP(mask, value)		\
-({						\
-	u64 _m = mask;				\
-	(_m << 16) | FIELD_PREP(_m, value);	\
-})
-
 struct sp_pll {
 	struct clk_hw hw;
 	void __iomem *reg;
@@ -313,15 +307,15 @@ static int plltv_set_rate(struct sp_pll *clk)
 	u32 r0, r1, r2;
 
 	r0  = BIT(clk->bp_bit + 16);
-	r0 |= HWM_FIELD_PREP(MASK_SEL_FRA, clk->p[SEL_FRA]);
-	r0 |= HWM_FIELD_PREP(MASK_SDM_MOD, clk->p[SDM_MOD]);
-	r0 |= HWM_FIELD_PREP(MASK_PH_SEL, clk->p[PH_SEL]);
-	r0 |= HWM_FIELD_PREP(MASK_NFRA, clk->p[NFRA]);
+	r0 |= FIELD_PREP_WM16(MASK_SEL_FRA, clk->p[SEL_FRA]);
+	r0 |= FIELD_PREP_WM16(MASK_SDM_MOD, clk->p[SDM_MOD]);
+	r0 |= FIELD_PREP_WM16(MASK_PH_SEL, clk->p[PH_SEL]);
+	r0 |= FIELD_PREP_WM16(MASK_NFRA, clk->p[NFRA]);
 
-	r1  = HWM_FIELD_PREP(MASK_DIVR, clk->p[DIVR]);
+	r1  = FIELD_PREP_WM16(MASK_DIVR, clk->p[DIVR]);
 
-	r2  = HWM_FIELD_PREP(MASK_DIVN, clk->p[DIVN] - 1);
-	r2 |= HWM_FIELD_PREP(MASK_DIVM, clk->p[DIVM] - 1);
+	r2  = FIELD_PREP_WM16(MASK_DIVN, clk->p[DIVN] - 1);
+	r2 |= FIELD_PREP_WM16(MASK_DIVM, clk->p[DIVM] - 1);
 
 	spin_lock_irqsave(&clk->lock, flags);
 	writel(r0, clk->reg);

-- 
2.51.0



From nicolas.frattaroli at collabora.com  Mon Aug 25 01:28:40 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 25 Aug 2025 10:28:40 +0200
Subject: [PATCH v3 20/20] phy: rockchip-pcie: switch to FIELD_PREP_WM16
 macro
In-Reply-To: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
Message-ID: <20250825-byeword-update-v3-20-947b841cdb29@collabora.com>

The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
drivers that use constant masks.

The Rockchip PCIe PHY driver, used on the RK3399, has its own definition
of HIWORD_UPDATE.

Remove it, and replace instances of it with hw_bitfield.h's
FIELD_PREP_WM16. To achieve this, some mask defines are reshuffled, as
FIELD_PREP_WM16 uses the mask as both the mask of bits to write and to
derive the shift amount from in order to shift the value.

In order to ensure that the mask is always a constant, the inst->index
shift is performed after the FIELD_PREP_WM16, as this is a runtime
value.

>From this, we gain compile-time error checking, and in my humble opinion
nicer code, as well as a single definition of this macro across the
entire codebase to aid in code comprehension.

Tested on a RK3399 ROCKPro64, where PCIe still works as expected when
accessing an NVMe drive.

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/phy/rockchip/phy-rockchip-pcie.c | 70 +++++++++-----------------------
 1 file changed, 20 insertions(+), 50 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-pcie.c b/drivers/phy/rockchip/phy-rockchip-pcie.c
index 4e2dfd01adf2ff09da5129579171e6ac44ca89e5..126306c014546d3f4d8c630c1eed6d339c49800b 100644
--- a/drivers/phy/rockchip/phy-rockchip-pcie.c
+++ b/drivers/phy/rockchip/phy-rockchip-pcie.c
@@ -8,6 +8,7 @@
 
 #include <linux/clk.h>
 #include <linux/delay.h>
+#include <linux/hw_bitfield.h>
 #include <linux/io.h>
 #include <linux/mfd/syscon.h>
 #include <linux/module.h>
@@ -18,22 +19,13 @@
 #include <linux/regmap.h>
 #include <linux/reset.h>
 
-/*
- * The higher 16-bit of this register is used for write protection
- * only if BIT(x + 16) set to 1 the BIT(x) can be written.
- */
-#define HIWORD_UPDATE(val, mask, shift) \
-		((val) << (shift) | (mask) << ((shift) + 16))
 
 #define PHY_MAX_LANE_NUM      4
-#define PHY_CFG_DATA_SHIFT    7
-#define PHY_CFG_ADDR_SHIFT    1
-#define PHY_CFG_DATA_MASK     0xf
-#define PHY_CFG_ADDR_MASK     0x3f
+#define PHY_CFG_DATA_MASK     GENMASK(10, 7)
+#define PHY_CFG_ADDR_MASK     GENMASK(6, 1)
 #define PHY_CFG_WR_ENABLE     1
 #define PHY_CFG_WR_DISABLE    0
-#define PHY_CFG_WR_SHIFT      0
-#define PHY_CFG_WR_MASK       1
+#define PHY_CFG_WR_MASK       BIT(0)
 #define PHY_CFG_PLL_LOCK      0x10
 #define PHY_CFG_CLK_TEST      0x10
 #define PHY_CFG_CLK_SCC       0x12
@@ -48,11 +40,7 @@
 #define PHY_LANE_RX_DET_SHIFT 11
 #define PHY_LANE_RX_DET_TH    0x1
 #define PHY_LANE_IDLE_OFF     0x1
-#define PHY_LANE_IDLE_MASK    0x1
-#define PHY_LANE_IDLE_A_SHIFT 3
-#define PHY_LANE_IDLE_B_SHIFT 4
-#define PHY_LANE_IDLE_C_SHIFT 5
-#define PHY_LANE_IDLE_D_SHIFT 6
+#define PHY_LANE_IDLE_MASK    BIT(3)
 
 struct rockchip_pcie_data {
 	unsigned int pcie_conf;
@@ -99,22 +87,14 @@ static inline void phy_wr_cfg(struct rockchip_pcie_phy *rk_phy,
 			      u32 addr, u32 data)
 {
 	regmap_write(rk_phy->reg_base, rk_phy->phy_data->pcie_conf,
-		     HIWORD_UPDATE(data,
-				   PHY_CFG_DATA_MASK,
-				   PHY_CFG_DATA_SHIFT) |
-		     HIWORD_UPDATE(addr,
-				   PHY_CFG_ADDR_MASK,
-				   PHY_CFG_ADDR_SHIFT));
+		     FIELD_PREP_WM16(PHY_CFG_DATA_MASK, data) |
+		     FIELD_PREP_WM16(PHY_CFG_ADDR_MASK, addr));
 	udelay(1);
 	regmap_write(rk_phy->reg_base, rk_phy->phy_data->pcie_conf,
-		     HIWORD_UPDATE(PHY_CFG_WR_ENABLE,
-				   PHY_CFG_WR_MASK,
-				   PHY_CFG_WR_SHIFT));
+		     FIELD_PREP_WM16(PHY_CFG_WR_MASK, PHY_CFG_WR_ENABLE));
 	udelay(1);
 	regmap_write(rk_phy->reg_base, rk_phy->phy_data->pcie_conf,
-		     HIWORD_UPDATE(PHY_CFG_WR_DISABLE,
-				   PHY_CFG_WR_MASK,
-				   PHY_CFG_WR_SHIFT));
+		     FIELD_PREP_WM16(PHY_CFG_WR_MASK, PHY_CFG_WR_DISABLE));
 }
 
 static int rockchip_pcie_phy_power_off(struct phy *phy)
@@ -125,11 +105,9 @@ static int rockchip_pcie_phy_power_off(struct phy *phy)
 
 	guard(mutex)(&rk_phy->pcie_mutex);
 
-	regmap_write(rk_phy->reg_base,
-		     rk_phy->phy_data->pcie_laneoff,
-		     HIWORD_UPDATE(PHY_LANE_IDLE_OFF,
-				   PHY_LANE_IDLE_MASK,
-				   PHY_LANE_IDLE_A_SHIFT + inst->index));
+	regmap_write(rk_phy->reg_base, rk_phy->phy_data->pcie_laneoff,
+		     FIELD_PREP_WM16(PHY_LANE_IDLE_MASK,
+				     PHY_LANE_IDLE_OFF) << inst->index);
 
 	if (--rk_phy->pwr_cnt) {
 		return 0;
@@ -139,11 +117,9 @@ static int rockchip_pcie_phy_power_off(struct phy *phy)
 	if (err) {
 		dev_err(&phy->dev, "assert phy_rst err %d\n", err);
 		rk_phy->pwr_cnt++;
-		regmap_write(rk_phy->reg_base,
-			     rk_phy->phy_data->pcie_laneoff,
-			     HIWORD_UPDATE(!PHY_LANE_IDLE_OFF,
-					   PHY_LANE_IDLE_MASK,
-					   PHY_LANE_IDLE_A_SHIFT + inst->index));
+		regmap_write(rk_phy->reg_base, rk_phy->phy_data->pcie_laneoff,
+			     FIELD_PREP_WM16(PHY_LANE_IDLE_MASK,
+					     !PHY_LANE_IDLE_OFF) << inst->index);
 		return err;
 	}
 
@@ -159,11 +135,9 @@ static int rockchip_pcie_phy_power_on(struct phy *phy)
 
 	guard(mutex)(&rk_phy->pcie_mutex);
 
-	regmap_write(rk_phy->reg_base,
-		     rk_phy->phy_data->pcie_laneoff,
-		     HIWORD_UPDATE(!PHY_LANE_IDLE_OFF,
-				   PHY_LANE_IDLE_MASK,
-				   PHY_LANE_IDLE_A_SHIFT + inst->index));
+	regmap_write(rk_phy->reg_base, rk_phy->phy_data->pcie_laneoff,
+		     FIELD_PREP_WM16(PHY_LANE_IDLE_MASK,
+				     !PHY_LANE_IDLE_OFF) << inst->index);
 
 	if (rk_phy->pwr_cnt++) {
 		return 0;
@@ -177,9 +151,7 @@ static int rockchip_pcie_phy_power_on(struct phy *phy)
 	}
 
 	regmap_write(rk_phy->reg_base, rk_phy->phy_data->pcie_conf,
-		     HIWORD_UPDATE(PHY_CFG_PLL_LOCK,
-				   PHY_CFG_ADDR_MASK,
-				   PHY_CFG_ADDR_SHIFT));
+		     FIELD_PREP_WM16(PHY_CFG_ADDR_MASK, PHY_CFG_PLL_LOCK));
 
 	/*
 	 * No documented timeout value for phy operation below,
@@ -210,9 +182,7 @@ static int rockchip_pcie_phy_power_on(struct phy *phy)
 	}
 
 	regmap_write(rk_phy->reg_base, rk_phy->phy_data->pcie_conf,
-		     HIWORD_UPDATE(PHY_CFG_PLL_LOCK,
-				   PHY_CFG_ADDR_MASK,
-				   PHY_CFG_ADDR_SHIFT));
+		     FIELD_PREP_WM16(PHY_CFG_ADDR_MASK, PHY_CFG_PLL_LOCK));
 
 	err = regmap_read_poll_timeout(rk_phy->reg_base,
 				       rk_phy->phy_data->pcie_status,

-- 
2.51.0



From peng.fan at nxp.com  Mon Aug 25 01:36:41 2025
From: peng.fan at nxp.com (Peng Fan)
Date: Mon, 25 Aug 2025 16:36:41 +0800
Subject: [PATCH v2 0/5] phy: phy-can-transceiver: Support TJA1048/TJA1051
Message-ID: <20250825-can-v2-0-c461e9fcbc14@nxp.com>

TJA1048 is a Dual channel can transceiver with Sleep mode supported.
TJA1051 is a Single Channel can transceiver with Sleep mode supported.

To support them:
patch 1: add binding doc
patch 2: To support dual channel,
   - Introduce new flag CAN_TRANSCEIVER_DUAL_CH to indicate the phy
     has two channels.
   - Introduce can_transceiver_priv as a higher level encapsulation for
     phy, mux_state, num_ch.
   - Alloc a phy for each channel
patch 3,4,5: Update dts to use phys

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
---
Changes in v2:
- Update standby-gpios constraints per Conor's comments
- Drop patch 2 which is not needed.
- Link to v1: https://lore.kernel.org/r/20250822-can-v1-0-c075f702adea at nxp.com

---
Peng Fan (5):
      dt-bindings: phy: ti,tcan104x-can: Document NXP TJA1051/1048
      phy: phy-can-transceiver: Add dual channel support for TJA1048
      arm64: dts: imx95-15x15-evk: Use phys to replace xceiver-supply
      arm64: dts: imx8mp-evk: Use phys to replace xceiver-supply
      arm64: dts: imx93-11x11-evk: Use phys to replace xceiver-supply

 .../devicetree/bindings/phy/ti,tcan104x-can.yaml   |  33 +++++-
 arch/arm64/boot/dts/freescale/imx8mp-evk.dts       |  43 +++-----
 arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts  |  17 ++-
 arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts  |  13 ++-
 drivers/phy/phy-can-transceiver.c                  | 117 +++++++++++++++------
 5 files changed, 140 insertions(+), 83 deletions(-)
---
base-commit: b4498e5df1daaf2832141a27c1e5bc34a7553087
change-id: 20250821-can-c832cb4f0323

Best regards,
-- 
Peng Fan <peng.fan at nxp.com>



From peng.fan at nxp.com  Mon Aug 25 01:36:42 2025
From: peng.fan at nxp.com (Peng Fan)
Date: Mon, 25 Aug 2025 16:36:42 +0800
Subject: [PATCH v2 1/5] dt-bindings: phy: ti,tcan104x-can: Document NXP
 TJA1051/1048
In-Reply-To: <20250825-can-v2-0-c461e9fcbc14@nxp.com>
References: <20250825-can-v2-0-c461e9fcbc14@nxp.com>
Message-ID: <20250825-can-v2-1-c461e9fcbc14@nxp.com>

The TJA1051 is a high-speed CAN transceiver which is a pin-compatible
alternative for TI TCAN1043 with Sleep mode supported, and has a compatible
programming model, therefore use ti,tcan1043 as fallback compatible.

The TJA1048 is a dual high-speed CAN transceiver with Sleep mode supported.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 .../devicetree/bindings/phy/ti,tcan104x-can.yaml   | 33 ++++++++++++++++++++--
 1 file changed, 30 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml b/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
index 4a8c3829d85d3c4a4963750d03567c1c345beb91..3ae08815225d82b6a09cf8a6deacadbddf781fed 100644
--- a/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
+++ b/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
@@ -19,18 +19,23 @@ properties:
           - enum:
               - microchip,ata6561
           - const: ti,tcan1042
+      - items:
+          - enum:
+              - nxp,tja1051
+          - const: ti,tcan1043
       - enum:
           - ti,tcan1042
           - ti,tcan1043
+          - nxp,tja1048
           - nxp,tjr1443
 
-  '#phy-cells':
-    const: 0
+  '#phy-cells': true
 
   standby-gpios:
     description:
       gpio node to toggle standby signal on transceiver
-    maxItems: 1
+    minItems: 1
+    maxItems: 2
 
   enable-gpios:
     description:
@@ -53,12 +58,34 @@ required:
   - compatible
   - '#phy-cells'
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: nxp,tja1048
+    then:
+      properties:
+        '#phy-cells':
+          const: 1
+        standby-gpios:
+          minItems: 2
+          maxItems: 2
+    else:
+      properties:
+        '#phy-cells':
+          const: 0
+        standby-gpios:
+          minItems: 1
+          maxItems: 1
+
 additionalProperties: false
 
 examples:
   - |
     #include <dt-bindings/gpio/gpio.h>
 
+
     transceiver1: can-phy {
       compatible = "ti,tcan1043";
       #phy-cells = <0>;

-- 
2.37.1



From peng.fan at nxp.com  Mon Aug 25 01:36:43 2025
From: peng.fan at nxp.com (Peng Fan)
Date: Mon, 25 Aug 2025 16:36:43 +0800
Subject: [PATCH v2 2/5] phy: phy-can-transceiver: Add dual channel support
 for TJA1048
In-Reply-To: <20250825-can-v2-0-c461e9fcbc14@nxp.com>
References: <20250825-can-v2-0-c461e9fcbc14@nxp.com>
Message-ID: <20250825-can-v2-2-c461e9fcbc14@nxp.com>

- Introduce new flag CAN_TRANSCEIVER_DUAL_CH to indicate the phy
  has two channels.
- Introduce can_transceiver_priv as a higher level encapsulation for
  phy, mux_state, num_ch.
- Alloc a phy for each channel
- Support TJA1048 which is a dual high-speed CAN transceiver with
  Sleep mode supported.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/phy/phy-can-transceiver.c | 117 +++++++++++++++++++++++++++-----------
 1 file changed, 83 insertions(+), 34 deletions(-)

diff --git a/drivers/phy/phy-can-transceiver.c b/drivers/phy/phy-can-transceiver.c
index f59caff4b3d4c267feca4220bf1547b6fad08f95..8f0baf0d29536d2b18c5839d6275f020f9af7e45 100644
--- a/drivers/phy/phy-can-transceiver.c
+++ b/drivers/phy/phy-can-transceiver.c
@@ -17,13 +17,20 @@ struct can_transceiver_data {
 	u32 flags;
 #define CAN_TRANSCEIVER_STB_PRESENT	BIT(0)
 #define CAN_TRANSCEIVER_EN_PRESENT	BIT(1)
+#define CAN_TRANSCEIVER_DUAL_CH		BIT(2)
 };
 
 struct can_transceiver_phy {
 	struct phy *generic_phy;
 	struct gpio_desc *standby_gpio;
 	struct gpio_desc *enable_gpio;
+	struct can_transceiver_priv *priv;
+};
+
+struct can_transceiver_priv {
+	struct can_transceiver_phy *can_transceiver_phy;
 	struct mux_state *mux_state;
+	int num_ch;
 };
 
 /* Power on function */
@@ -32,8 +39,8 @@ static int can_transceiver_phy_power_on(struct phy *phy)
 	struct can_transceiver_phy *can_transceiver_phy = phy_get_drvdata(phy);
 	int ret;
 
-	if (can_transceiver_phy->mux_state) {
-		ret = mux_state_select(can_transceiver_phy->mux_state);
+	if (can_transceiver_phy->priv->mux_state) {
+		ret = mux_state_select(can_transceiver_phy->priv->mux_state);
 		if (ret) {
 			dev_err(&phy->dev, "Failed to select CAN mux: %d\n", ret);
 			return ret;
@@ -56,8 +63,8 @@ static int can_transceiver_phy_power_off(struct phy *phy)
 		gpiod_set_value_cansleep(can_transceiver_phy->standby_gpio, 1);
 	if (can_transceiver_phy->enable_gpio)
 		gpiod_set_value_cansleep(can_transceiver_phy->enable_gpio, 0);
-	if (can_transceiver_phy->mux_state)
-		mux_state_deselect(can_transceiver_phy->mux_state);
+	if (can_transceiver_phy->priv->mux_state)
+		mux_state_deselect(can_transceiver_phy->priv->mux_state);
 
 	return 0;
 }
@@ -76,6 +83,10 @@ static const struct can_transceiver_data tcan1043_drvdata = {
 	.flags = CAN_TRANSCEIVER_STB_PRESENT | CAN_TRANSCEIVER_EN_PRESENT,
 };
 
+static const struct can_transceiver_data tja1048_drvdata = {
+	.flags = CAN_TRANSCEIVER_STB_PRESENT | CAN_TRANSCEIVER_DUAL_CH,
+};
+
 static const struct of_device_id can_transceiver_phy_ids[] = {
 	{
 		.compatible = "ti,tcan1042",
@@ -85,6 +96,10 @@ static const struct of_device_id can_transceiver_phy_ids[] = {
 		.compatible = "ti,tcan1043",
 		.data = &tcan1043_drvdata
 	},
+	{
+		.compatible = "nxp,tja1048",
+		.data = &tja1048_drvdata
+	},
 	{
 		.compatible = "nxp,tjr1443",
 		.data = &tcan1043_drvdata
@@ -103,11 +118,27 @@ devm_mux_state_get_optional(struct device *dev, const char *mux_name)
 	return devm_mux_state_get(dev, mux_name);
 }
 
+static struct phy *can_transceiver_phy_xlate(struct device *dev, const struct of_phandle_args *args)
+{
+	struct can_transceiver_priv *priv = dev_get_drvdata(dev);
+	u32 idx;
+
+	if (priv->num_ch == 1)
+		return priv->can_transceiver_phy[0].generic_phy;
+
+	if (args->args_count != 1)
+		return ERR_PTR(-EINVAL);
+
+	idx = args->args[0];
+
+	return priv->can_transceiver_phy[idx].generic_phy;
+}
+
 static int can_transceiver_phy_probe(struct platform_device *pdev)
 {
 	struct phy_provider *phy_provider;
 	struct device *dev = &pdev->dev;
-	struct can_transceiver_phy *can_transceiver_phy;
+	struct can_transceiver_priv *priv;
 	const struct can_transceiver_data *drvdata;
 	const struct of_device_id *match;
 	struct phy *phy;
@@ -115,52 +146,70 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
 	struct gpio_desc *enable_gpio;
 	struct mux_state *mux_state;
 	u32 max_bitrate = 0;
-	int err;
-
-	can_transceiver_phy = devm_kzalloc(dev, sizeof(struct can_transceiver_phy), GFP_KERNEL);
-	if (!can_transceiver_phy)
-		return -ENOMEM;
+	int num_ch = 1;
+	int err, i;
 
 	match = of_match_node(can_transceiver_phy_ids, pdev->dev.of_node);
 	drvdata = match->data;
 
+	priv = devm_kzalloc(dev, sizeof(struct can_transceiver_priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, priv);
+
+	if (drvdata->flags & CAN_TRANSCEIVER_DUAL_CH)
+		num_ch = 2;
+
+	priv->num_ch = num_ch;
+	priv->can_transceiver_phy = devm_kcalloc(dev, num_ch, sizeof(struct can_transceiver_phy),
+						 GFP_KERNEL);
+	if (!priv->can_transceiver_phy)
+		return -ENOMEM;
+
 	mux_state = devm_mux_state_get_optional(dev, NULL);
 	if (IS_ERR(mux_state))
 		return PTR_ERR(mux_state);
 
-	can_transceiver_phy->mux_state = mux_state;
-
-	phy = devm_phy_create(dev, dev->of_node,
-			      &can_transceiver_phy_ops);
-	if (IS_ERR(phy)) {
-		dev_err(dev, "failed to create can transceiver phy\n");
-		return PTR_ERR(phy);
-	}
+	priv->mux_state = mux_state;
 
 	err = device_property_read_u32(dev, "max-bitrate", &max_bitrate);
 	if ((err != -EINVAL) && !max_bitrate)
 		dev_warn(dev, "Invalid value for transceiver max bitrate. Ignoring bitrate limit\n");
-	phy->attrs.max_link_rate = max_bitrate;
 
-	can_transceiver_phy->generic_phy = phy;
+	for (i = 0; i < num_ch; i++) {
+		phy = devm_phy_create(dev, dev->of_node, &can_transceiver_phy_ops);
+		if (IS_ERR(phy)) {
+			dev_err(dev, "failed to create can transceiver phy\n");
+			return PTR_ERR(phy);
+		}
 
-	if (drvdata->flags & CAN_TRANSCEIVER_STB_PRESENT) {
-		standby_gpio = devm_gpiod_get_optional(dev, "standby", GPIOD_OUT_HIGH);
-		if (IS_ERR(standby_gpio))
-			return PTR_ERR(standby_gpio);
-		can_transceiver_phy->standby_gpio = standby_gpio;
-	}
+		phy->attrs.max_link_rate = max_bitrate;
 
-	if (drvdata->flags & CAN_TRANSCEIVER_EN_PRESENT) {
-		enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW);
-		if (IS_ERR(enable_gpio))
-			return PTR_ERR(enable_gpio);
-		can_transceiver_phy->enable_gpio = enable_gpio;
-	}
+		priv->can_transceiver_phy[i].generic_phy = phy;
+		priv->can_transceiver_phy[i].priv = priv;
+
+		if (drvdata->flags & CAN_TRANSCEIVER_STB_PRESENT) {
+			standby_gpio = devm_gpiod_get_index_optional(dev, "standby", i,
+								     GPIOD_OUT_HIGH);
+			if (IS_ERR(standby_gpio))
+				return PTR_ERR(standby_gpio);
+			priv->can_transceiver_phy[i].standby_gpio = standby_gpio;
+		}
+
+		if (drvdata->flags & CAN_TRANSCEIVER_EN_PRESENT) {
+			enable_gpio = devm_gpiod_get_index_optional(dev, "enable", i,
+								    GPIOD_OUT_LOW);
+			if (IS_ERR(enable_gpio))
+				return PTR_ERR(enable_gpio);
+			priv->can_transceiver_phy[i].enable_gpio = enable_gpio;
+		}
 
-	phy_set_drvdata(can_transceiver_phy->generic_phy, can_transceiver_phy);
+		phy_set_drvdata(priv->can_transceiver_phy[i].generic_phy,
+				&priv->can_transceiver_phy[i]);
+	}
 
-	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+	phy_provider = devm_of_phy_provider_register(dev, can_transceiver_phy_xlate);
 
 	return PTR_ERR_OR_ZERO(phy_provider);
 }

-- 
2.37.1



From peng.fan at nxp.com  Mon Aug 25 01:36:44 2025
From: peng.fan at nxp.com (Peng Fan)
Date: Mon, 25 Aug 2025 16:36:44 +0800
Subject: [PATCH v2 3/5] arm64: dts: imx95-15x15-evk: Use phys to replace
 xceiver-supply
In-Reply-To: <20250825-can-v2-0-c461e9fcbc14@nxp.com>
References: <20250825-can-v2-0-c461e9fcbc14@nxp.com>
Message-ID: <20250825-can-v2-3-c461e9fcbc14@nxp.com>

The TJA1051T/3 used on i.MX95-15x15-EVK is actually high-speed CAN
transceiver, not a regulator supply. So use phys to reflect the truth.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts b/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
index 46f6e0fbf2b09106e6e726ff8b61522d1359cfa4..f6197ba356d49b97bf7287c3f0f86ef84f89bac9 100644
--- a/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
@@ -89,12 +89,11 @@ reg_audio_switch1: regulator-audio-switch1 {
 		gpio = <&pcal6524 0 GPIO_ACTIVE_LOW>;
 	};
 
-	reg_can2_stby: regulator-can2-stby {
-		compatible = "regulator-fixed";
-		regulator-max-microvolt = <3300000>;
-		regulator-min-microvolt = <3300000>;
-		regulator-name = "can2-stby";
-		gpio = <&pcal6524 14 GPIO_ACTIVE_LOW>;
+	flexcan2_phy: can-phy {
+		compatible = "nxp,tja1051", "ti,tcan1043";
+		#phy-cells = <0>;
+		max-bitrate = <1000000>;
+		standby-gpios = <&pcal6524 14 GPIO_ACTIVE_HIGH>;
 	};
 
 	reg_m2_pwr: regulator-m2-pwr {
@@ -300,7 +299,7 @@ &enetc_port1 {
 &flexcan2 {
 	pinctrl-0 = <&pinctrl_flexcan2>;
 	pinctrl-names = "default";
-	xceiver-supply = <&reg_can2_stby>;
+	phys = <&flexcan2_phy>;
 	status = "okay";
 };
 

-- 
2.37.1



From peng.fan at nxp.com  Mon Aug 25 01:36:45 2025
From: peng.fan at nxp.com (Peng Fan)
Date: Mon, 25 Aug 2025 16:36:45 +0800
Subject: [PATCH v2 4/5] arm64: dts: imx8mp-evk: Use phys to replace
 xceiver-supply
In-Reply-To: <20250825-can-v2-0-c461e9fcbc14@nxp.com>
References: <20250825-can-v2-0-c461e9fcbc14@nxp.com>
Message-ID: <20250825-can-v2-4-c461e9fcbc14@nxp.com>

The TJA1048 used on i.MX8MP-EVK is actually high-speed CAN
transceiver, not a regulator supply. So use phys to reflect the truth.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8mp-evk.dts | 43 +++++++++-------------------
 1 file changed, 13 insertions(+), 30 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
index c0cc5611048e6a739f13c14bbd2e7b26f2715696..d238d419d87cc7c99d472720c96aade90275cb0f 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
@@ -56,6 +56,16 @@ memory at 40000000 {
 		      <0x1 0x00000000 0 0xc0000000>;
 	};
 
+	flexcan_phy: can-phy {
+		compatible = "nxp,tja1048";
+		#phy-cells = <1>;
+		max-bitrate = <5000000>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_flexcan_phy>;
+		standby-gpios = <&gpio5 5 GPIO_ACTIVE_LOW>,
+				<&gpio4 27 GPIO_ACTIVE_LOW>;
+	};
+
 	native-hdmi-connector {
 		compatible = "hdmi-connector";
 		label = "HDMI OUT";
@@ -103,28 +113,6 @@ reg_audio_pwr: regulator-audio-pwr {
 		enable-active-high;
 	};
 
-	reg_can1_stby: regulator-can1-stby {
-		compatible = "regulator-fixed";
-		regulator-name = "can1-stby";
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_flexcan1_reg>;
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		gpio = <&gpio5 5 GPIO_ACTIVE_HIGH>;
-		enable-active-high;
-	};
-
-	reg_can2_stby: regulator-can2-stby {
-		compatible = "regulator-fixed";
-		regulator-name = "can2-stby";
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_flexcan2_reg>;
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		gpio = <&gpio4 27 GPIO_ACTIVE_HIGH>;
-		enable-active-high;
-	};
-
 	reg_pcie0: regulator-pcie {
 		compatible = "regulator-fixed";
 		pinctrl-names = "default";
@@ -431,14 +419,14 @@ ethphy1: ethernet-phy at 1 {
 &flexcan1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_flexcan1>;
-	xceiver-supply = <&reg_can1_stby>;
+	phys = <&flexcan_phy 0>;
 	status = "okay";
 };
 
 &flexcan2 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_flexcan2>;
-	xceiver-supply = <&reg_can2_stby>;
+	phys = <&flexcan_phy 1>;
 	status = "disabled";/* can2 pin conflict with pdm */
 };
 
@@ -903,14 +891,9 @@ MX8MP_IOMUXC_SAI5_RXD3__CAN2_TX         0x154
 		>;
 	};
 
-	pinctrl_flexcan1_reg: flexcan1reggrp {
+	pinctrl_flexcan_phy: flexcanphygrp {
 		fsl,pins = <
 			MX8MP_IOMUXC_SPDIF_EXT_CLK__GPIO5_IO05  0x154   /* CAN1_STBY */
-		>;
-	};
-
-	pinctrl_flexcan2_reg: flexcan2reggrp {
-		fsl,pins = <
 			MX8MP_IOMUXC_SAI2_MCLK__GPIO4_IO27      0x154   /* CAN2_STBY */
 		>;
 	};

-- 
2.37.1



From peng.fan at nxp.com  Mon Aug 25 01:36:46 2025
From: peng.fan at nxp.com (Peng Fan)
Date: Mon, 25 Aug 2025 16:36:46 +0800
Subject: [PATCH v2 5/5] arm64: dts: imx93-11x11-evk: Use phys to replace
 xceiver-supply
In-Reply-To: <20250825-can-v2-0-c461e9fcbc14@nxp.com>
References: <20250825-can-v2-0-c461e9fcbc14@nxp.com>
Message-ID: <20250825-can-v2-5-c461e9fcbc14@nxp.com>

The TJA1057 used on i.MX93 EVK is actually high-speed CAN
transceiver, not a regulator supply. So use phys to reflect the truth.

And TJA1057 is compatible with TJA1051, so use nxp,tja1051 compatible
string.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts b/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
index e24e12f04526c3a08c0bdc6134297fb010e6e926..94be59771cd05c93a6569ee08fff71bc11da21c1 100644
--- a/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
@@ -62,6 +62,13 @@ vdevbuffer: vdevbuffer at a4020000 {
 
 	};
 
+	flexcan_phy: can-phy {
+		compatible = "nxp,tja1051", "ti,tcan1043";
+		#phy-cells = <0>;
+		max-bitrate = <5000000>;
+		standby-gpios = <&adp5585 6 GPIO_ACTIVE_HIGH>;
+	};
+
 	reg_vdd_12v: regulator-vdd-12v {
 		compatible = "regulator-fixed";
 		regulator-name = "VDD_12V";
@@ -87,14 +94,6 @@ reg_audio_pwr: regulator-audio-pwr {
 		enable-active-high;
 	};
 
-	reg_can2_standby: regulator-can2-standby {
-		compatible = "regulator-fixed";
-		regulator-name = "can2-stby";
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		gpio = <&adp5585 6 GPIO_ACTIVE_LOW>;
-	};
-
 	reg_m2_pwr: regulator-m2-pwr {
 		compatible = "regulator-fixed";
 		regulator-name = "M.2-power";
@@ -284,7 +283,7 @@ ethphy2: ethernet-phy at 2 {
 &flexcan2 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_flexcan2>;
-	xceiver-supply = <&reg_can2_standby>;
+	phys = <&flexcan_phy>;
 	status = "okay";
 };
 

-- 
2.37.1



From p.zabel at pengutronix.de  Mon Aug 25 02:42:16 2025
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Mon, 25 Aug 2025 11:42:16 +0200
Subject: [PATCH 4/7] phy: allwinner: a523: add USB3/PCIe PHY driver
In-Reply-To: <20250816084700.569524-5-iuncuim@gmail.com>
References: <20250816084700.569524-1-iuncuim@gmail.com>
	 <20250816084700.569524-5-iuncuim@gmail.com>
Message-ID: <0501e21d1b6c99d18fe7e660f38b9bfafc76de53.camel@pengutronix.de>

On Sa, 2025-08-16 at 16:46 +0800, iuncuim wrote:
> From: Mikhail Kalashnikov <iuncuim at gmail.com>
> 
> The A523 family of processors features a combophy for USB 3.0 and PCIe,
> developed by Innosilicon. Simultaneous operation of both interfaces is
> not supported by design.
> Currently, the driver only adds support for USB 3.0. PCIe support is
> currently unavailable and will be added later.
> All data on phy configuration is taken from the manufacturer's BSP driver.
> 
> Signed-off-by: Mikhail Kalashnikov <iuncuim at gmail.com>
> ---
>  drivers/phy/allwinner/Kconfig                |   9 +
>  drivers/phy/allwinner/Makefile               |   1 +
>  drivers/phy/allwinner/phy-sun55i-usb3-pcie.c | 267 +++++++++++++++++++
>  3 files changed, 277 insertions(+)
>  create mode 100644 drivers/phy/allwinner/phy-sun55i-usb3-pcie.c
> 
> diff --git a/drivers/phy/allwinner/Kconfig b/drivers/phy/allwinner/Kconfig
> index fb584518b..af2a82e51 100644
> --- a/drivers/phy/allwinner/Kconfig
> +++ b/drivers/phy/allwinner/Kconfig
> @@ -57,3 +57,12 @@ config PHY_SUN50I_USB3
>  	  part of Allwinner H6 SoC.
>  
>  	  This driver controls each individual USB 2+3 host PHY combo.
> +
> +config PHY_SUN55I_USB3_PCIE
> +	tristate "Allwinner A523 Innosilicon USB3/PCIe Combophy Driver"
> +	depends on ARCH_SUNXI || COMPILE_TEST
> +	depends on RESET_CONTROLLER

This dependency is not necessary. The reset controller API is stubbed
out in case  RESET_CONTROLLER is disabled.

ARCH_SUNXI selects ARCH_HAS_RESET_CONTROLLER, which default-enables
RESET_CONTROLLER.

> +	select GENERIC_PHY
> +	help
> +	  Enable this to support the Allwinner PCIe/USB3.0 combo PHY
> +	  with Innosilicon IP block founded in A523/A527/H728/T527 SOC
> diff --git a/drivers/phy/allwinner/Makefile b/drivers/phy/allwinner/Makefile
> index bd74901a1..5948a27ef 100644
> --- a/drivers/phy/allwinner/Makefile
> +++ b/drivers/phy/allwinner/Makefile
> @@ -3,3 +3,4 @@ obj-$(CONFIG_PHY_SUN4I_USB)		+= phy-sun4i-usb.o
>  obj-$(CONFIG_PHY_SUN6I_MIPI_DPHY)	+= phy-sun6i-mipi-dphy.o
>  obj-$(CONFIG_PHY_SUN9I_USB)		+= phy-sun9i-usb.o
>  obj-$(CONFIG_PHY_SUN50I_USB3)		+= phy-sun50i-usb3.o
> +obj-$(CONFIG_PHY_SUN55I_USB3_PCIE)		+= phy-sun55i-usb3-pcie.o
> diff --git a/drivers/phy/allwinner/phy-sun55i-usb3-pcie.c b/drivers/phy/allwinner/phy-sun55i-usb3-pcie.c
> new file mode 100644
> index 000000000..905c54a67
> --- /dev/null
> +++ b/drivers/phy/allwinner/phy-sun55i-usb3-pcie.c
> @@ -0,0 +1,267 @@
[...]
> +static int sun55i_usb3_pcie_phy_init(struct phy *_phy)
> +{
> +	struct sun55i_usb3_pcie_phy *phy = phy_get_drvdata(_phy);
> +
> +	sun55i_usb3_phy_open(phy);

Given that sun55i_usb3_pcie_phy_exit() asserts the reset and disables
the clock, why isn't the clock enabled and the reset deasserted here?

As is, it looks like the code in sun55i_usb3_phy_open() could be just
folded into sun55i_usb3_pcie_phy_init().

> +	return 0;
> +}
[...]
> +static int sun55i_usb3_pcie_phy_probe(struct platform_device *pdev)
> +{
> +	struct sun55i_usb3_pcie_phy *phy;
> +	struct device *dev = &pdev->dev;
> +	struct phy_provider *phy_provider;
> +	int ret;
> +
> +	phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
> +	if (!phy)
> +		return -ENOMEM;
> +
> +	phy->dev = dev;
> +	phy->clk = devm_clk_get(dev, NULL);
> +	if (IS_ERR(phy->clk)) {
> +		if (PTR_ERR(phy->clk) != -EPROBE_DEFER)
> +			dev_err(dev, "failed to get phy clock\n");
> +		return PTR_ERR(phy->clk);
> +	}
> +
> +	phy->reset = devm_reset_control_get(dev, NULL);

Please use devm_reset_control_get_exclusive() directly.

> +	if (IS_ERR(phy->reset)) {
> +		dev_err(dev, "failed to get reset control\n");

Consider using dev_err_probe().

regards
Philipp


From kathiravan.thirumoorthy at oss.qualcomm.com  Mon Aug 25 04:52:01 2025
From: kathiravan.thirumoorthy at oss.qualcomm.com (Kathiravan Thirumoorthy)
Date: Mon, 25 Aug 2025 17:22:01 +0530
Subject: [PATCH 0/3] Fix the NULL pointer deference issue in QMP USB
 drivers
Message-ID: <20250825-qmp-null-deref-on-pm-v1-0-bbd3ca330849@oss.qualcomm.com>

In the suspend / resume callbacks, qmp->phy could be NULL because PHY is
created after the PM ops are enabled, which lead to the NULL pointer
deference.

Internally issue is reported on qcom-qmp-usb driver. Since the fix is
applicable to legacy and usbc drivers, incoporated the fixes for those
driver as well.

qcom-qmp-usb-legacy and qcom-qmp-usbc drivers are splitted out from
qcom-qmp-usb driver in v6.6 and v6.9 respectively. So splitted the
changes into 3, for ease of backporting.

Signed-off-by: Kathiravan Thirumoorthy <kathiravan.thirumoorthy at oss.qualcomm.com>
---
Poovendhan Selvaraj (3):
      phy: qcom-qmp-usb: fix NULL pointer dereference in PM callbacks
      phy: qcom-qmp-usb-legacy: fix NULL pointer dereference in PM callbacks
      phy: qcom-qmp-usbc: fix NULL pointer dereference in PM callbacks

 drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c | 4 ++--
 drivers/phy/qualcomm/phy-qcom-qmp-usb.c        | 4 ++--
 drivers/phy/qualcomm/phy-qcom-qmp-usbc.c       | 4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)
---
base-commit: 0f4c93f7eb861acab537dbe94441817a270537bf
change-id: 20250825-qmp-null-deref-on-pm-fd98a91c775b

Best regards,
-- 
Kathiravan Thirumoorthy <kathiravan.thirumoorthy at oss.qualcomm.com>



From kathiravan.thirumoorthy at oss.qualcomm.com  Mon Aug 25 04:52:02 2025
From: kathiravan.thirumoorthy at oss.qualcomm.com (Kathiravan Thirumoorthy)
Date: Mon, 25 Aug 2025 17:22:02 +0530
Subject: [PATCH 1/3] phy: qcom-qmp-usb: fix NULL pointer dereference in PM
 callbacks
In-Reply-To: <20250825-qmp-null-deref-on-pm-v1-0-bbd3ca330849@oss.qualcomm.com>
References: <20250825-qmp-null-deref-on-pm-v1-0-bbd3ca330849@oss.qualcomm.com>
Message-ID: <20250825-qmp-null-deref-on-pm-v1-1-bbd3ca330849@oss.qualcomm.com>

From: Poovendhan Selvaraj <quic_poovendh at quicinc.com>

The pm ops are enabled before qmp phy create which causes
a NULL pointer dereference when accessing qmp->phy->init_count
in the qmp_usb_runtime_suspend.

So if qmp->phy is NULL, bail out early in suspend / resume callbacks
to avoid the NULL pointer dereference in qmp_usb_runtime_suspend and
qmp_usb_runtime_resume.

Below is the stacktrace for reference:

[<818381a0>] (qmp_usb_runtime_suspend [phy_qcom_qmp_usb]) from [<4051d1d8>] (__rpm_callback+0x3c/0x110)
[<4051d1d8>] (__rpm_callback) from [<4051d2fc>] (rpm_callback+0x50/0x54)
[<4051d2fc>] (rpm_callback) from [<4051d940>] (rpm_suspend+0x23c/0x428)
[<4051d940>] (rpm_suspend) from [<4051e808>] (pm_runtime_work+0x74/0x8c)
[<4051e808>] (pm_runtime_work) from [<401311f4>] (process_scheduled_works+0x1d0/0x2c8)
[<401311f4>] (process_scheduled_works) from [<40131d48>] (worker_thread+0x260/0x2e4)
[<40131d48>] (worker_thread) from [<40138970>] (kthread+0x118/0x12c)
[<40138970>] (kthread) from [<4010013c>] (ret_from_fork+0x14/0x38)

Cc: stable at vger.kernel.org # v6.0
Fixes: 65753f38f530 ("phy: qcom-qmp-usb: drop multi-PHY support")
Signed-off-by: Poovendhan Selvaraj <quic_poovendh at quicinc.com>
Signed-off-by: Kathiravan Thirumoorthy <kathiravan.thirumoorthy at oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-usb.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
index ed646a7e705ba3259708775ed5fedbbbada13735..cd04e8f22a0fe81b086b308d02713222aa95cae3 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
@@ -1940,7 +1940,7 @@ static int __maybe_unused qmp_usb_runtime_suspend(struct device *dev)
 
 	dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->mode);
 
-	if (!qmp->phy->init_count) {
+	if (!qmp->phy || !qmp->phy->init_count) {
 		dev_vdbg(dev, "PHY not initialized, bailing out\n");
 		return 0;
 	}
@@ -1960,7 +1960,7 @@ static int __maybe_unused qmp_usb_runtime_resume(struct device *dev)
 
 	dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qmp->mode);
 
-	if (!qmp->phy->init_count) {
+	if (!qmp->phy || !qmp->phy->init_count) {
 		dev_vdbg(dev, "PHY not initialized, bailing out\n");
 		return 0;
 	}

-- 
2.34.1



From kathiravan.thirumoorthy at oss.qualcomm.com  Mon Aug 25 04:52:03 2025
From: kathiravan.thirumoorthy at oss.qualcomm.com (Kathiravan Thirumoorthy)
Date: Mon, 25 Aug 2025 17:22:03 +0530
Subject: [PATCH 2/3] phy: qcom-qmp-usb-legacy: fix NULL pointer dereference
 in PM callbacks
In-Reply-To: <20250825-qmp-null-deref-on-pm-v1-0-bbd3ca330849@oss.qualcomm.com>
References: <20250825-qmp-null-deref-on-pm-v1-0-bbd3ca330849@oss.qualcomm.com>
Message-ID: <20250825-qmp-null-deref-on-pm-v1-2-bbd3ca330849@oss.qualcomm.com>

From: Poovendhan Selvaraj <quic_poovendh at quicinc.com>

The pm ops are enabled before qmp phy create which causes
a NULL pointer dereference when accessing qmp->phy->init_count
in the qmp_usb_runtime_suspend.

So if qmp->phy is NULL, bail out early in suspend / resume callbacks
to avoid the NULL pointer dereference in qmp_usb_runtime_suspend and
qmp_usb_runtime_resume.

Cc: stable at vger.kernel.org # v6.6
Fixes: e464a3180a43 ("phy: qcom-qmp-usb: split off the legacy USB+dp_com support")
Signed-off-by: Poovendhan Selvaraj <quic_poovendh at quicinc.com>
Signed-off-by: Kathiravan Thirumoorthy <kathiravan.thirumoorthy at oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
index 8bf951b0490cfd811635df8940de1b789e21b46c..ef28e59ffd58a12d6d416a553a3a478e9691b8c5 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
@@ -988,7 +988,7 @@ static int __maybe_unused qmp_usb_legacy_runtime_suspend(struct device *dev)
 
 	dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->mode);
 
-	if (!qmp->phy->init_count) {
+	if (!qmp->phy || !qmp->phy->init_count) {
 		dev_vdbg(dev, "PHY not initialized, bailing out\n");
 		return 0;
 	}
@@ -1009,7 +1009,7 @@ static int __maybe_unused qmp_usb_legacy_runtime_resume(struct device *dev)
 
 	dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qmp->mode);
 
-	if (!qmp->phy->init_count) {
+	if (!qmp->phy || !qmp->phy->init_count) {
 		dev_vdbg(dev, "PHY not initialized, bailing out\n");
 		return 0;
 	}

-- 
2.34.1



From kathiravan.thirumoorthy at oss.qualcomm.com  Mon Aug 25 04:52:04 2025
From: kathiravan.thirumoorthy at oss.qualcomm.com (Kathiravan Thirumoorthy)
Date: Mon, 25 Aug 2025 17:22:04 +0530
Subject: [PATCH 3/3] phy: qcom-qmp-usbc: fix NULL pointer dereference in PM
 callbacks
In-Reply-To: <20250825-qmp-null-deref-on-pm-v1-0-bbd3ca330849@oss.qualcomm.com>
References: <20250825-qmp-null-deref-on-pm-v1-0-bbd3ca330849@oss.qualcomm.com>
Message-ID: <20250825-qmp-null-deref-on-pm-v1-3-bbd3ca330849@oss.qualcomm.com>

From: Poovendhan Selvaraj <quic_poovendh at quicinc.com>

The pm ops are enabled before qmp phy create which causes
a NULL pointer dereference when accessing qmp->phy->init_count
in the qmp_usb_runtime_suspend.

So if qmp->phy is NULL, bail out early in suspend / resume callbacks
to avoid the NULL pointer dereference in qmp_usb_runtime_suspend and
qmp_usb_runtime_resume.

Cc: stable at vger.kernel.org # v6.9
Fixes: 19281571a4d5 ("phy: qcom: qmp-usb: split USB-C PHY driver")
Signed-off-by: Poovendhan Selvaraj <quic_poovendh at quicinc.com>
Signed-off-by: Kathiravan Thirumoorthy <kathiravan.thirumoorthy at oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
index 5e7fcb26744a4401c3076960df9c0dcbec7fdef7..640f6520f7c1cd78f9e79843a0778c1bee790f64 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
@@ -690,7 +690,7 @@ static int __maybe_unused qmp_usbc_runtime_suspend(struct device *dev)
 
 	dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->mode);
 
-	if (!qmp->phy->init_count) {
+	if (!qmp->phy || !qmp->phy->init_count) {
 		dev_vdbg(dev, "PHY not initialized, bailing out\n");
 		return 0;
 	}
@@ -710,7 +710,7 @@ static int __maybe_unused qmp_usbc_runtime_resume(struct device *dev)
 
 	dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qmp->mode);
 
-	if (!qmp->phy->init_count) {
+	if (!qmp->phy || !qmp->phy->init_count) {
 		dev_vdbg(dev, "PHY not initialized, bailing out\n");
 		return 0;
 	}

-- 
2.34.1



From Frank.li at nxp.com  Mon Aug 25 08:39:42 2025
From: Frank.li at nxp.com (Frank Li)
Date: Mon, 25 Aug 2025 11:39:42 -0400
Subject: [PATCH v2 1/5] dt-bindings: phy: ti,tcan104x-can: Document NXP
 TJA1051/1048
In-Reply-To: <20250825-can-v2-1-c461e9fcbc14@nxp.com>
References: <20250825-can-v2-0-c461e9fcbc14@nxp.com>
 <20250825-can-v2-1-c461e9fcbc14@nxp.com>
Message-ID: <aKyDvtH0U9Idxq19@lizhi-Precision-Tower-5810>

On Mon, Aug 25, 2025 at 04:36:42PM +0800, Peng Fan wrote:
> The TJA1051 is a high-speed CAN transceiver which is a pin-compatible
> alternative for TI TCAN1043 with Sleep mode supported, and has a compatible
> programming model, therefore use ti,tcan1043 as fallback compatible.
>
> The TJA1048 is a dual high-speed CAN transceiver with Sleep mode supported.
>
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  .../devicetree/bindings/phy/ti,tcan104x-can.yaml   | 33 ++++++++++++++++++++--
>  1 file changed, 30 insertions(+), 3 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml b/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
> index 4a8c3829d85d3c4a4963750d03567c1c345beb91..3ae08815225d82b6a09cf8a6deacadbddf781fed 100644
> --- a/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
> +++ b/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
> @@ -19,18 +19,23 @@ properties:
>            - enum:
>                - microchip,ata6561
>            - const: ti,tcan1042
> +      - items:
> +          - enum:
> +              - nxp,tja1051
> +          - const: ti,tcan1043
>        - enum:
>            - ti,tcan1042
>            - ti,tcan1043
> +          - nxp,tja1048
>            - nxp,tjr1443
>
> -  '#phy-cells':
> -    const: 0
> +  '#phy-cells': true

need restrict number, although you limit in allOf, still prefer provide
wide restriction here.

     'phy-cells':
        enum: [ 0, 1]

>
>    standby-gpios:
>      description:
>        gpio node to toggle standby signal on transceiver
> -    maxItems: 1
> +    minItems: 1
> +    maxItems: 2
>
>    enable-gpios:
>      description:
> @@ -53,12 +58,34 @@ required:
>    - compatible
>    - '#phy-cells'
>
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: nxp,tja1048
> +    then:
> +      properties:
> +        '#phy-cells':
> +          const: 1
> +        standby-gpios:
> +          minItems: 2
> +          maxItems: 2
> +    else:
> +      properties:
> +        '#phy-cells':
> +          const: 0
> +        standby-gpios:
> +          minItems: 1
> +          maxItems: 1
> +
>  additionalProperties: false
>
>  examples:
>    - |
>      #include <dt-bindings/gpio/gpio.h>
>
> +

uncessary change here

Frank
>      transceiver1: can-phy {
>        compatible = "ti,tcan1043";
>        #phy-cells = <0>;
>
> --
> 2.37.1
>


From wens at csie.org  Mon Aug 25 08:41:12 2025
From: wens at csie.org (Chen-Yu Tsai)
Date: Mon, 25 Aug 2025 17:41:12 +0200
Subject: [PATCH 5/7] arm64: dts: allwinner: a523: add USB3.0 phy node
In-Reply-To: <20250816144936.3f2738cc@minigeek.lan>
References: <20250816084700.569524-1-iuncuim@gmail.com> <20250816084700.569524-6-iuncuim@gmail.com>
 <20250816144936.3f2738cc@minigeek.lan>
Message-ID: <CAGb2v64vMvs+UN4AJWZAGnU+ZQRBQBheqnRKzbMmd10UMdOxCw@mail.gmail.com>

On Sat, Aug 16, 2025 at 3:52?PM Andre Przywara <andre.przywara at arm.com> wrote:
>
> On Sat, 16 Aug 2025 16:46:58 +0800
> iuncuim <iuncuim at gmail.com> wrote:
>
> Hi,
>
> > From: Mikhail Kalashnikov <iuncuim at gmail.com>
> >
> > After adding the phy driver, we can also add phy node. In addition to the
> > clk and reset lines, the power domain PD_PCIE is declared in this node
> > according to the bsp dtb. So let's mention it.
> > Currently, phy driver does not support role selection and only works in
> > USB3.0 mode.
>
> That's the current limitation of the proposed Linux driver, but should
> not affect the binding or DT:
>
> >
> > Signed-off-by: Mikhail Kalashnikov <iuncuim at gmail.com>
> > ---
> >  arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi | 10 ++++++++++
> >  1 file changed, 10 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
> > index e4ed4fa82..233365496 100644
> > --- a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
> > +++ b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
> > @@ -606,6 +606,16 @@ mdio0: mdio {
> >                       };
> >               };
> >
> > +             combophy: phy at 4f00000 {
> > +                     compatible = "allwinner,sun55i-a523-usb3-pcie-phy";
> > +                     reg = <0x04f00000 0x100000>;
> > +                     clocks = <&ccu CLK_USB3>;
>
> Will we need more clocks (or resets) when supporting PCIe later? If
> yes, we should add them already now, even if they are not used by the
> current driver.
>
> > +                     resets = <&ccu RST_BUS_PCIE_USB3>;
> > +                     #phy-cells = <0>;
>
> I think we should use one PHY cell here, to allow users to select the
> PHY path they need. A USB3.0-only driver implementation could choose to
> ignore it, or require the number to be 0 only, rejecting anything else.
> But this way we keep compatibility with newer DTs.

Agreed. It seems this is the common case for combined PHYs. The last
cell tells which type of PHY is to be used.

ChenYu

> Cheers,
> Andre
>
> > +                     power-domains = <&pck600 PD_PCIE>;
> > +                     status = "disabled";
> > +             };
> > +
> >               ppu: power-controller at 7001400 {
> >                       compatible = "allwinner,sun55i-a523-ppu";
> >                       reg = <0x07001400 0x400>;
>


From Frank.li at nxp.com  Mon Aug 25 08:52:47 2025
From: Frank.li at nxp.com (Frank Li)
Date: Mon, 25 Aug 2025 11:52:47 -0400
Subject: [PATCH v2 2/5] phy: phy-can-transceiver: Add dual channel
 support for TJA1048
In-Reply-To: <20250825-can-v2-2-c461e9fcbc14@nxp.com>
References: <20250825-can-v2-0-c461e9fcbc14@nxp.com>
 <20250825-can-v2-2-c461e9fcbc14@nxp.com>
Message-ID: <aKyGzza24CqIwuwn@lizhi-Precision-Tower-5810>

On Mon, Aug 25, 2025 at 04:36:43PM +0800, Peng Fan wrote:
> - Introduce new flag CAN_TRANSCEIVER_DUAL_CH to indicate the phy
>   has two channels.
> - Introduce can_transceiver_priv as a higher level encapsulation for
>   phy, mux_state, num_ch.
> - Alloc a phy for each channel
> - Support TJA1048 which is a dual high-speed CAN transceiver with
>   Sleep mode supported.
>
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  drivers/phy/phy-can-transceiver.c | 117 +++++++++++++++++++++++++++-----------
>  1 file changed, 83 insertions(+), 34 deletions(-)
>
> diff --git a/drivers/phy/phy-can-transceiver.c b/drivers/phy/phy-can-transceiver.c
> index f59caff4b3d4c267feca4220bf1547b6fad08f95..8f0baf0d29536d2b18c5839d6275f020f9af7e45 100644
> --- a/drivers/phy/phy-can-transceiver.c
> +++ b/drivers/phy/phy-can-transceiver.c
> @@ -17,13 +17,20 @@ struct can_transceiver_data {
>  	u32 flags;
>  #define CAN_TRANSCEIVER_STB_PRESENT	BIT(0)
>  #define CAN_TRANSCEIVER_EN_PRESENT	BIT(1)
> +#define CAN_TRANSCEIVER_DUAL_CH		BIT(2)
>  };
>
>  struct can_transceiver_phy {
>  	struct phy *generic_phy;
>  	struct gpio_desc *standby_gpio;
>  	struct gpio_desc *enable_gpio;
> +	struct can_transceiver_priv *priv;
> +};

I suggest create new patch, just add priv (without num_ch), which simple
straight forward. Then add num_ch, which will be easy to review.

Frank

> +
> +struct can_transceiver_priv {
> +	struct can_transceiver_phy *can_transceiver_phy;
>  	struct mux_state *mux_state;
> +	int num_ch;
>  };
>
>  /* Power on function */
> @@ -32,8 +39,8 @@ static int can_transceiver_phy_power_on(struct phy *phy)
>  	struct can_transceiver_phy *can_transceiver_phy = phy_get_drvdata(phy);
>  	int ret;
>
> -	if (can_transceiver_phy->mux_state) {
> -		ret = mux_state_select(can_transceiver_phy->mux_state);
> +	if (can_transceiver_phy->priv->mux_state) {
> +		ret = mux_state_select(can_transceiver_phy->priv->mux_state);
>  		if (ret) {
>  			dev_err(&phy->dev, "Failed to select CAN mux: %d\n", ret);
>  			return ret;
> @@ -56,8 +63,8 @@ static int can_transceiver_phy_power_off(struct phy *phy)
>  		gpiod_set_value_cansleep(can_transceiver_phy->standby_gpio, 1);
>  	if (can_transceiver_phy->enable_gpio)
>  		gpiod_set_value_cansleep(can_transceiver_phy->enable_gpio, 0);
> -	if (can_transceiver_phy->mux_state)
> -		mux_state_deselect(can_transceiver_phy->mux_state);
> +	if (can_transceiver_phy->priv->mux_state)
> +		mux_state_deselect(can_transceiver_phy->priv->mux_state);
>
>  	return 0;
>  }
> @@ -76,6 +83,10 @@ static const struct can_transceiver_data tcan1043_drvdata = {
>  	.flags = CAN_TRANSCEIVER_STB_PRESENT | CAN_TRANSCEIVER_EN_PRESENT,
>  };
>
> +static const struct can_transceiver_data tja1048_drvdata = {
> +	.flags = CAN_TRANSCEIVER_STB_PRESENT | CAN_TRANSCEIVER_DUAL_CH,
> +};
> +
>  static const struct of_device_id can_transceiver_phy_ids[] = {
>  	{
>  		.compatible = "ti,tcan1042",
> @@ -85,6 +96,10 @@ static const struct of_device_id can_transceiver_phy_ids[] = {
>  		.compatible = "ti,tcan1043",
>  		.data = &tcan1043_drvdata
>  	},
> +	{
> +		.compatible = "nxp,tja1048",
> +		.data = &tja1048_drvdata
> +	},
>  	{
>  		.compatible = "nxp,tjr1443",
>  		.data = &tcan1043_drvdata
> @@ -103,11 +118,27 @@ devm_mux_state_get_optional(struct device *dev, const char *mux_name)
>  	return devm_mux_state_get(dev, mux_name);
>  }
>
> +static struct phy *can_transceiver_phy_xlate(struct device *dev, const struct of_phandle_args *args)
> +{
> +	struct can_transceiver_priv *priv = dev_get_drvdata(dev);
> +	u32 idx;
> +
> +	if (priv->num_ch == 1)
> +		return priv->can_transceiver_phy[0].generic_phy;
> +
> +	if (args->args_count != 1)
> +		return ERR_PTR(-EINVAL);
> +
> +	idx = args->args[0];
> +
> +	return priv->can_transceiver_phy[idx].generic_phy;
> +}
> +
>  static int can_transceiver_phy_probe(struct platform_device *pdev)
>  {
>  	struct phy_provider *phy_provider;
>  	struct device *dev = &pdev->dev;
> -	struct can_transceiver_phy *can_transceiver_phy;
> +	struct can_transceiver_priv *priv;
>  	const struct can_transceiver_data *drvdata;
>  	const struct of_device_id *match;
>  	struct phy *phy;
> @@ -115,52 +146,70 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
>  	struct gpio_desc *enable_gpio;
>  	struct mux_state *mux_state;
>  	u32 max_bitrate = 0;
> -	int err;
> -
> -	can_transceiver_phy = devm_kzalloc(dev, sizeof(struct can_transceiver_phy), GFP_KERNEL);
> -	if (!can_transceiver_phy)
> -		return -ENOMEM;
> +	int num_ch = 1;
> +	int err, i;
>
>  	match = of_match_node(can_transceiver_phy_ids, pdev->dev.of_node);
>  	drvdata = match->data;
>
> +	priv = devm_kzalloc(dev, sizeof(struct can_transceiver_priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	platform_set_drvdata(pdev, priv);
> +
> +	if (drvdata->flags & CAN_TRANSCEIVER_DUAL_CH)
> +		num_ch = 2;
> +
> +	priv->num_ch = num_ch;
> +	priv->can_transceiver_phy = devm_kcalloc(dev, num_ch, sizeof(struct can_transceiver_phy),
> +						 GFP_KERNEL);
> +	if (!priv->can_transceiver_phy)
> +		return -ENOMEM;
> +
>  	mux_state = devm_mux_state_get_optional(dev, NULL);
>  	if (IS_ERR(mux_state))
>  		return PTR_ERR(mux_state);
>
> -	can_transceiver_phy->mux_state = mux_state;
> -
> -	phy = devm_phy_create(dev, dev->of_node,
> -			      &can_transceiver_phy_ops);
> -	if (IS_ERR(phy)) {
> -		dev_err(dev, "failed to create can transceiver phy\n");
> -		return PTR_ERR(phy);
> -	}
> +	priv->mux_state = mux_state;
>
>  	err = device_property_read_u32(dev, "max-bitrate", &max_bitrate);
>  	if ((err != -EINVAL) && !max_bitrate)
>  		dev_warn(dev, "Invalid value for transceiver max bitrate. Ignoring bitrate limit\n");
> -	phy->attrs.max_link_rate = max_bitrate;
>
> -	can_transceiver_phy->generic_phy = phy;
> +	for (i = 0; i < num_ch; i++) {
> +		phy = devm_phy_create(dev, dev->of_node, &can_transceiver_phy_ops);
> +		if (IS_ERR(phy)) {
> +			dev_err(dev, "failed to create can transceiver phy\n");
> +			return PTR_ERR(phy);
> +		}
>
> -	if (drvdata->flags & CAN_TRANSCEIVER_STB_PRESENT) {
> -		standby_gpio = devm_gpiod_get_optional(dev, "standby", GPIOD_OUT_HIGH);
> -		if (IS_ERR(standby_gpio))
> -			return PTR_ERR(standby_gpio);
> -		can_transceiver_phy->standby_gpio = standby_gpio;
> -	}
> +		phy->attrs.max_link_rate = max_bitrate;
>
> -	if (drvdata->flags & CAN_TRANSCEIVER_EN_PRESENT) {
> -		enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW);
> -		if (IS_ERR(enable_gpio))
> -			return PTR_ERR(enable_gpio);
> -		can_transceiver_phy->enable_gpio = enable_gpio;
> -	}
> +		priv->can_transceiver_phy[i].generic_phy = phy;
> +		priv->can_transceiver_phy[i].priv = priv;
> +
> +		if (drvdata->flags & CAN_TRANSCEIVER_STB_PRESENT) {
> +			standby_gpio = devm_gpiod_get_index_optional(dev, "standby", i,
> +								     GPIOD_OUT_HIGH);
> +			if (IS_ERR(standby_gpio))
> +				return PTR_ERR(standby_gpio);
> +			priv->can_transceiver_phy[i].standby_gpio = standby_gpio;
> +		}
> +
> +		if (drvdata->flags & CAN_TRANSCEIVER_EN_PRESENT) {
> +			enable_gpio = devm_gpiod_get_index_optional(dev, "enable", i,
> +								    GPIOD_OUT_LOW);
> +			if (IS_ERR(enable_gpio))
> +				return PTR_ERR(enable_gpio);
> +			priv->can_transceiver_phy[i].enable_gpio = enable_gpio;
> +		}
>
> -	phy_set_drvdata(can_transceiver_phy->generic_phy, can_transceiver_phy);
> +		phy_set_drvdata(priv->can_transceiver_phy[i].generic_phy,
> +				&priv->can_transceiver_phy[i]);
> +	}
>
> -	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> +	phy_provider = devm_of_phy_provider_register(dev, can_transceiver_phy_xlate);
>
>  	return PTR_ERR_OR_ZERO(phy_provider);
>  }
>
> --
> 2.37.1
>


From Frank.li at nxp.com  Mon Aug 25 08:53:42 2025
From: Frank.li at nxp.com (Frank Li)
Date: Mon, 25 Aug 2025 11:53:42 -0400
Subject: [PATCH v2 3/5] arm64: dts: imx95-15x15-evk: Use phys to replace
 xceiver-supply
In-Reply-To: <20250825-can-v2-3-c461e9fcbc14@nxp.com>
References: <20250825-can-v2-0-c461e9fcbc14@nxp.com>
 <20250825-can-v2-3-c461e9fcbc14@nxp.com>
Message-ID: <aKyHBqT+VG2e7PNf@lizhi-Precision-Tower-5810>

On Mon, Aug 25, 2025 at 04:36:44PM +0800, Peng Fan wrote:
> The TJA1051T/3 used on i.MX95-15x15-EVK is actually high-speed CAN
> transceiver, not a regulator supply. So use phys to reflect the truth.
>
> Signed-off-by: Peng Fan <peng.fan at nxp.com>

Reviewed-by: Frank Li <Frank.Li at nxp.com>

> ---
>  arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts | 13 ++++++-------
>  1 file changed, 6 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts b/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
> index 46f6e0fbf2b09106e6e726ff8b61522d1359cfa4..f6197ba356d49b97bf7287c3f0f86ef84f89bac9 100644
> --- a/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
> +++ b/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
> @@ -89,12 +89,11 @@ reg_audio_switch1: regulator-audio-switch1 {
>  		gpio = <&pcal6524 0 GPIO_ACTIVE_LOW>;
>  	};
>
> -	reg_can2_stby: regulator-can2-stby {
> -		compatible = "regulator-fixed";
> -		regulator-max-microvolt = <3300000>;
> -		regulator-min-microvolt = <3300000>;
> -		regulator-name = "can2-stby";
> -		gpio = <&pcal6524 14 GPIO_ACTIVE_LOW>;
> +	flexcan2_phy: can-phy {
> +		compatible = "nxp,tja1051", "ti,tcan1043";
> +		#phy-cells = <0>;
> +		max-bitrate = <1000000>;
> +		standby-gpios = <&pcal6524 14 GPIO_ACTIVE_HIGH>;
>  	};
>
>  	reg_m2_pwr: regulator-m2-pwr {
> @@ -300,7 +299,7 @@ &enetc_port1 {
>  &flexcan2 {
>  	pinctrl-0 = <&pinctrl_flexcan2>;
>  	pinctrl-names = "default";
> -	xceiver-supply = <&reg_can2_stby>;
> +	phys = <&flexcan2_phy>;
>  	status = "okay";
>  };
>
>
> --
> 2.37.1
>


From Frank.li at nxp.com  Mon Aug 25 08:55:38 2025
From: Frank.li at nxp.com (Frank Li)
Date: Mon, 25 Aug 2025 11:55:38 -0400
Subject: [PATCH v2 4/5] arm64: dts: imx8mp-evk: Use phys to replace
 xceiver-supply
In-Reply-To: <20250825-can-v2-4-c461e9fcbc14@nxp.com>
References: <20250825-can-v2-0-c461e9fcbc14@nxp.com>
 <20250825-can-v2-4-c461e9fcbc14@nxp.com>
Message-ID: <aKyHehTGrQHWQJaD@lizhi-Precision-Tower-5810>

On Mon, Aug 25, 2025 at 04:36:45PM +0800, Peng Fan wrote:
> The TJA1048 used on i.MX8MP-EVK is actually high-speed CAN
> transceiver, not a regulator supply. So use phys to reflect the truth.

nit: wrap at 75 chars. 'transceiver', should be at first line.

Reviewed-by: Frank Li <Frank.Li at nxp.com>

>
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  arch/arm64/boot/dts/freescale/imx8mp-evk.dts | 43 +++++++++-------------------
>  1 file changed, 13 insertions(+), 30 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
> index c0cc5611048e6a739f13c14bbd2e7b26f2715696..d238d419d87cc7c99d472720c96aade90275cb0f 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
> +++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
> @@ -56,6 +56,16 @@ memory at 40000000 {
>  		      <0x1 0x00000000 0 0xc0000000>;
>  	};
>
> +	flexcan_phy: can-phy {
> +		compatible = "nxp,tja1048";
> +		#phy-cells = <1>;
> +		max-bitrate = <5000000>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pinctrl_flexcan_phy>;
> +		standby-gpios = <&gpio5 5 GPIO_ACTIVE_LOW>,
> +				<&gpio4 27 GPIO_ACTIVE_LOW>;
> +	};
> +
>  	native-hdmi-connector {
>  		compatible = "hdmi-connector";
>  		label = "HDMI OUT";
> @@ -103,28 +113,6 @@ reg_audio_pwr: regulator-audio-pwr {
>  		enable-active-high;
>  	};
>
> -	reg_can1_stby: regulator-can1-stby {
> -		compatible = "regulator-fixed";
> -		regulator-name = "can1-stby";
> -		pinctrl-names = "default";
> -		pinctrl-0 = <&pinctrl_flexcan1_reg>;
> -		regulator-min-microvolt = <3300000>;
> -		regulator-max-microvolt = <3300000>;
> -		gpio = <&gpio5 5 GPIO_ACTIVE_HIGH>;
> -		enable-active-high;
> -	};
> -
> -	reg_can2_stby: regulator-can2-stby {
> -		compatible = "regulator-fixed";
> -		regulator-name = "can2-stby";
> -		pinctrl-names = "default";
> -		pinctrl-0 = <&pinctrl_flexcan2_reg>;
> -		regulator-min-microvolt = <3300000>;
> -		regulator-max-microvolt = <3300000>;
> -		gpio = <&gpio4 27 GPIO_ACTIVE_HIGH>;
> -		enable-active-high;
> -	};
> -
>  	reg_pcie0: regulator-pcie {
>  		compatible = "regulator-fixed";
>  		pinctrl-names = "default";
> @@ -431,14 +419,14 @@ ethphy1: ethernet-phy at 1 {
>  &flexcan1 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&pinctrl_flexcan1>;
> -	xceiver-supply = <&reg_can1_stby>;
> +	phys = <&flexcan_phy 0>;
>  	status = "okay";
>  };
>
>  &flexcan2 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&pinctrl_flexcan2>;
> -	xceiver-supply = <&reg_can2_stby>;
> +	phys = <&flexcan_phy 1>;
>  	status = "disabled";/* can2 pin conflict with pdm */
>  };
>
> @@ -903,14 +891,9 @@ MX8MP_IOMUXC_SAI5_RXD3__CAN2_TX         0x154
>  		>;
>  	};
>
> -	pinctrl_flexcan1_reg: flexcan1reggrp {
> +	pinctrl_flexcan_phy: flexcanphygrp {
>  		fsl,pins = <
>  			MX8MP_IOMUXC_SPDIF_EXT_CLK__GPIO5_IO05  0x154   /* CAN1_STBY */
> -		>;
> -	};
> -
> -	pinctrl_flexcan2_reg: flexcan2reggrp {
> -		fsl,pins = <
>  			MX8MP_IOMUXC_SAI2_MCLK__GPIO4_IO27      0x154   /* CAN2_STBY */
>  		>;
>  	};
>
> --
> 2.37.1
>


From Frank.li at nxp.com  Mon Aug 25 08:58:53 2025
From: Frank.li at nxp.com (Frank Li)
Date: Mon, 25 Aug 2025 11:58:53 -0400
Subject: [PATCH v2 5/5] arm64: dts: imx93-11x11-evk: Use phys to replace
 xceiver-supply
In-Reply-To: <20250825-can-v2-5-c461e9fcbc14@nxp.com>
References: <20250825-can-v2-0-c461e9fcbc14@nxp.com>
 <20250825-can-v2-5-c461e9fcbc14@nxp.com>
Message-ID: <aKyIPZfYBAl6mrml@lizhi-Precision-Tower-5810>

On Mon, Aug 25, 2025 at 04:36:46PM +0800, Peng Fan wrote:
> The TJA1057 used on i.MX93 EVK is actually high-speed CAN
> transceiver, not a regulator supply. So use phys to reflect the truth.
>
> And TJA1057 is compatible with TJA1051, so use nxp,tja1051 compatible
> string.

Need add TJA1057 into binding, "nxp,tja1057", "ti,tcan1043". You already
touch binding doc, just add nxp,tja1057.

Frank

>
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts | 17 ++++++++---------
>  1 file changed, 8 insertions(+), 9 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts b/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
> index e24e12f04526c3a08c0bdc6134297fb010e6e926..94be59771cd05c93a6569ee08fff71bc11da21c1 100644
> --- a/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
> +++ b/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
> @@ -62,6 +62,13 @@ vdevbuffer: vdevbuffer at a4020000 {
>
>  	};
>
> +	flexcan_phy: can-phy {
> +		compatible = "nxp,tja1051", "ti,tcan1043";
> +		#phy-cells = <0>;
> +		max-bitrate = <5000000>;
> +		standby-gpios = <&adp5585 6 GPIO_ACTIVE_HIGH>;
> +	};
> +
>  	reg_vdd_12v: regulator-vdd-12v {
>  		compatible = "regulator-fixed";
>  		regulator-name = "VDD_12V";
> @@ -87,14 +94,6 @@ reg_audio_pwr: regulator-audio-pwr {
>  		enable-active-high;
>  	};
>
> -	reg_can2_standby: regulator-can2-standby {
> -		compatible = "regulator-fixed";
> -		regulator-name = "can2-stby";
> -		regulator-min-microvolt = <3300000>;
> -		regulator-max-microvolt = <3300000>;
> -		gpio = <&adp5585 6 GPIO_ACTIVE_LOW>;
> -	};
> -
>  	reg_m2_pwr: regulator-m2-pwr {
>  		compatible = "regulator-fixed";
>  		regulator-name = "M.2-power";
> @@ -284,7 +283,7 @@ ethphy2: ethernet-phy at 2 {
>  &flexcan2 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&pinctrl_flexcan2>;
> -	xceiver-supply = <&reg_can2_standby>;
> +	phys = <&flexcan_phy>;
>  	status = "okay";
>  };
>
>
> --
> 2.37.1
>


From kuba at kernel.org  Mon Aug 25 09:11:42 2025
From: kuba at kernel.org (Jakub Kicinski)
Date: Mon, 25 Aug 2025 09:11:42 -0700
Subject: [PATCH v3 01/20] bitmap: introduce hardware-specific bitfield
 operations
In-Reply-To: <20250825-byeword-update-v3-1-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
	<20250825-byeword-update-v3-1-947b841cdb29@collabora.com>
Message-ID: <20250825091142.3735f1fe@kernel.org>

On Mon, 25 Aug 2025 10:28:21 +0200 Nicolas Frattaroli wrote:
> Hardware of various vendors, but very notably Rockchip, often uses
> 32-bit registers where the upper 16-bit half of the register is a
> write-enable mask for the lower half.

Acked-by: Jakub Kicinski <kuba at kernel.org>


From kuba at kernel.org  Mon Aug 25 09:11:58 2025
From: kuba at kernel.org (Jakub Kicinski)
Date: Mon, 25 Aug 2025 09:11:58 -0700
Subject: [PATCH v3 15/20] net: stmmac: dwmac-rk: switch to
 FIELD_PREP_WM16 macro
In-Reply-To: <20250825-byeword-update-v3-15-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
	<20250825-byeword-update-v3-15-947b841cdb29@collabora.com>
Message-ID: <20250825091158.07893b12@kernel.org>

On Mon, 25 Aug 2025 10:28:35 +0200 Nicolas Frattaroli wrote:
> The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
> drivers that use constant masks.
> 
> Like many other Rockchip drivers, dwmac-rk has its own HIWORD_UPDATE
> macro. Its semantics allow us to redefine it as a wrapper to the shared
> hw_bitfield.h FIELD_PREP_WM16 macros though.
> 
> Replace the implementation of this driver's very own HIWORD_UPDATE macro
> with an instance of FIELD_PREP_WM16 from hw_bitfield.h. This keeps the
> diff easily reviewable, while giving us more compile-time error
> checking.
> 
> The related GRF_BIT macro is left alone for now; any attempt to rework
> the code to not use its own solution here would likely end up harder to
> review and less pretty for the time being.

Acked-by: Jakub Kicinski <kuba at kernel.org>


From robh at kernel.org  Mon Aug 25 15:41:08 2025
From: robh at kernel.org (Rob Herring)
Date: Mon, 25 Aug 2025 17:41:08 -0500
Subject: [PATCH v2 3/7] dt-bindings: phy: rockchip-inno-csi-dphy: add
 rk3588 variant
In-Reply-To: <20250616-rk3588-csi-dphy-v2-3-7a94f079b712@collabora.com>
References: <20250616-rk3588-csi-dphy-v2-0-7a94f079b712@collabora.com>
 <20250616-rk3588-csi-dphy-v2-3-7a94f079b712@collabora.com>
Message-ID: <20250825224108.GA766877-robh@kernel.org>

On Tue, Aug 19, 2025 at 01:00:37AM +0200, Michael Riesch wrote:
> The Rockchip RK3588 variant of the CSI-2 DPHY features two reset lines.
> Add the variant and allow for the additional reset.
> 
> Signed-off-by: Michael Riesch <michael.riesch at collabora.com>
> ---
>  .../bindings/phy/rockchip-inno-csi-dphy.yaml       | 60 ++++++++++++++++++++--
>  1 file changed, 56 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/phy/rockchip-inno-csi-dphy.yaml b/Documentation/devicetree/bindings/phy/rockchip-inno-csi-dphy.yaml
> index 42da616ae2e3..10197cc9dc47 100644
> --- a/Documentation/devicetree/bindings/phy/rockchip-inno-csi-dphy.yaml
> +++ b/Documentation/devicetree/bindings/phy/rockchip-inno-csi-dphy.yaml
> @@ -21,6 +21,7 @@ properties:
>        - rockchip,rk3326-csi-dphy
>        - rockchip,rk3368-csi-dphy
>        - rockchip,rk3568-csi-dphy
> +      - rockchip,rk3588-csi-dphy
>  
>    reg:
>      maxItems: 1
> @@ -39,18 +40,50 @@ properties:
>      maxItems: 1
>  
>    resets:
> -    items:
> -      - description: exclusive PHY reset line
> +    minItems: 1
> +    maxItems: 2

Add a description for the 2nd reset here.

>  
>    reset-names:
> -    items:
> -      - const: apb
> +    minItems: 1
> +    maxItems: 2

Add 'phy' to the list here and just minItems.

>  
>    rockchip,grf:
>      $ref: /schemas/types.yaml#/definitions/phandle
>      description:
>        Some additional phy settings are access through GRF regs.
>  
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - rockchip,px30-csi-dphy
> +              - rockchip,rk1808-csi-dphy
> +              - rockchip,rk3326-csi-dphy
> +              - rockchip,rk3368-csi-dphy
> +              - rockchip,rk3568-csi-dphy
> +    then:
> +      properties:
> +        resets:
> +          items:
> +            - description: exclusive PHY reset line
> +
> +        reset-names:
> +          items:
> +            - const: apb

Then just 'maxItems: 1' here.

> +    else:
> +      properties:
> +        resets:
> +          items:
> +            - description: APB reset line
> +            - description: PHY reset line
> +
> +        reset-names:
> +          items:
> +            - const: apb
> +            - const: phy

And 'minItems: 2' here.

> +
>  required:
>    - compatible
>    - reg
> @@ -77,3 +110,22 @@ examples:
>          reset-names = "apb";
>          rockchip,grf = <&grf>;
>      };
> +  - |
> +    #include <dt-bindings/clock/rockchip,rk3588-cru.h>
> +    #include <dt-bindings/reset/rockchip,rk3588-cru.h>
> +
> +    soc {
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +
> +        phy at fedc0000 {
> +            compatible = "rockchip,rk3588-csi-dphy";
> +            reg = <0x0 0xfedc0000 0x0 0x8000>;
> +            clocks = <&cru PCLK_CSIPHY0>;
> +            clock-names = "pclk";
> +            #phy-cells = <0>;
> +            resets = <&cru SRST_P_CSIPHY0>, <&cru SRST_CSIPHY0>;
> +            reset-names = "apb", "phy";
> +            rockchip,grf = <&csidphy0_grf>;
> +        };
> +    };
> 
> -- 
> 2.39.5
> 


From sherry.sun at nxp.com  Mon Aug 25 19:19:27 2025
From: sherry.sun at nxp.com (Sherry Sun)
Date: Tue, 26 Aug 2025 02:19:27 +0000
Subject: [PATCH v2 3/5] arm64: dts: imx95-15x15-evk: Use phys to replace
 xceiver-supply
In-Reply-To: <20250825-can-v2-3-c461e9fcbc14@nxp.com>
References: <20250825-can-v2-0-c461e9fcbc14@nxp.com>
 <20250825-can-v2-3-c461e9fcbc14@nxp.com>
Message-ID: <DB9PR04MB8429631F164C8AE7571AE3CB9239A@DB9PR04MB8429.eurprd04.prod.outlook.com>



> -----Original Message-----
> From: Peng Fan <peng.fan at nxp.com>
> Sent: Monday, August 25, 2025 4:37 PM
> To: Marc Kleine-Budde <mkl at pengutronix.de>; Vincent Mailhol
> <mailhol.vincent at wanadoo.fr>; Vinod Koul <vkoul at kernel.org>; Kishon Vijay
> Abraham I <kishon at kernel.org>; Rob Herring <robh at kernel.org>; Krzysztof
> Kozlowski <krzk+dt at kernel.org>; Conor Dooley <conor+dt at kernel.org>;
> Aswath Govindraju <a-govindraju at ti.com>; Shawn Guo
> <shawnguo at kernel.org>; Sascha Hauer <s.hauer at pengutronix.de>;
> Pengutronix Kernel Team <kernel at pengutronix.de>; Fabio Estevam
> <festevam at gmail.com>; Frank Li <frank.li at nxp.com>; Bough Chen
> <haibo.chen at nxp.com>
> Cc: linux-can at vger.kernel.org; linux-phy at lists.infradead.org;
> devicetree at vger.kernel.org; linux-kernel at vger.kernel.org;
> imx at lists.linux.dev; linux-arm-kernel at lists.infradead.org; Peng Fan
> <peng.fan at nxp.com>
> Subject: [PATCH v2 3/5] arm64: dts: imx95-15x15-evk: Use phys to replace
> xceiver-supply
> 
> The TJA1051T/3 used on i.MX95-15x15-EVK is actually high-speed CAN
> transceiver, not a regulator supply. So use phys to reflect the truth.
> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts | 13 ++++++-------
>  1 file changed, 6 insertions(+), 7 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
> b/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
> index
> 46f6e0fbf2b09106e6e726ff8b61522d1359cfa4..f6197ba356d49b97bf7287c3f0
> f86ef84f89bac9 100644
> --- a/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
> +++ b/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
> @@ -89,12 +89,11 @@ reg_audio_switch1: regulator-audio-switch1 {
>  		gpio = <&pcal6524 0 GPIO_ACTIVE_LOW>;
>  	};
> 
> -	reg_can2_stby: regulator-can2-stby {
> -		compatible = "regulator-fixed";
> -		regulator-max-microvolt = <3300000>;
> -		regulator-min-microvolt = <3300000>;
> -		regulator-name = "can2-stby";
> -		gpio = <&pcal6524 14 GPIO_ACTIVE_LOW>;
> +	flexcan2_phy: can-phy {
> +		compatible = "nxp,tja1051", "ti,tcan1043";
> +		#phy-cells = <0>;
> +		max-bitrate = <1000000>;

Hi Peng, shouldn't the max-bitrate of TJA1051 be 5000000?

Best Regards
Sherry

> +		standby-gpios = <&pcal6524 14 GPIO_ACTIVE_HIGH>;
>  	};
> 
>  	reg_m2_pwr: regulator-m2-pwr {
> @@ -300,7 +299,7 @@ &enetc_port1 {
>  &flexcan2 {
>  	pinctrl-0 = <&pinctrl_flexcan2>;
>  	pinctrl-names = "default";
> -	xceiver-supply = <&reg_can2_stby>;
> +	phys = <&flexcan2_phy>;
>  	status = "okay";
>  };
> 
> 
> --
> 2.37.1
> 


From haibo.chen at nxp.com  Mon Aug 25 19:28:46 2025
From: haibo.chen at nxp.com (Bough Chen)
Date: Tue, 26 Aug 2025 02:28:46 +0000
Subject: [PATCH v2 3/5] arm64: dts: imx95-15x15-evk: Use phys to replace
 xceiver-supply
In-Reply-To: <DB9PR04MB8429631F164C8AE7571AE3CB9239A@DB9PR04MB8429.eurprd04.prod.outlook.com>
References: <20250825-can-v2-0-c461e9fcbc14@nxp.com>
 <20250825-can-v2-3-c461e9fcbc14@nxp.com>
 <DB9PR04MB8429631F164C8AE7571AE3CB9239A@DB9PR04MB8429.eurprd04.prod.outlook.com>
Message-ID: <DU0PR04MB9496B00796E5B862A10CDF849039A@DU0PR04MB9496.eurprd04.prod.outlook.com>

> -----Original Message-----
> From: Sherry Sun <sherry.sun at nxp.com>
> Sent: 2025?8?26? 10:19
> To: Peng Fan <peng.fan at nxp.com>; Marc Kleine-Budde <mkl at pengutronix.de>;
> Vincent Mailhol <mailhol.vincent at wanadoo.fr>; Vinod Koul
> <vkoul at kernel.org>; Kishon Vijay Abraham I <kishon at kernel.org>; Rob Herring
> <robh at kernel.org>; Krzysztof Kozlowski <krzk+dt at kernel.org>; Conor Dooley
> <conor+dt at kernel.org>; Aswath Govindraju <a-govindraju at ti.com>; Shawn
> Guo <shawnguo at kernel.org>; Sascha Hauer <s.hauer at pengutronix.de>;
> Pengutronix Kernel Team <kernel at pengutronix.de>; Fabio Estevam
> <festevam at gmail.com>; Frank Li <frank.li at nxp.com>; Bough Chen
> <haibo.chen at nxp.com>
> Cc: linux-can at vger.kernel.org; linux-phy at lists.infradead.org;
> devicetree at vger.kernel.org; linux-kernel at vger.kernel.org; imx at lists.linux.dev;
> linux-arm-kernel at lists.infradead.org; Peng Fan <peng.fan at nxp.com>
> Subject: RE: [PATCH v2 3/5] arm64: dts: imx95-15x15-evk: Use phys to replace
> xceiver-supply
> 
> 
> 
> > -----Original Message-----
> > From: Peng Fan <peng.fan at nxp.com>
> > Sent: Monday, August 25, 2025 4:37 PM
> > To: Marc Kleine-Budde <mkl at pengutronix.de>; Vincent Mailhol
> > <mailhol.vincent at wanadoo.fr>; Vinod Koul <vkoul at kernel.org>; Kishon
> > Vijay Abraham I <kishon at kernel.org>; Rob Herring <robh at kernel.org>;
> > Krzysztof Kozlowski <krzk+dt at kernel.org>; Conor Dooley
> > <conor+dt at kernel.org>; Aswath Govindraju <a-govindraju at ti.com>; Shawn
> > Guo <shawnguo at kernel.org>; Sascha Hauer <s.hauer at pengutronix.de>;
> > Pengutronix Kernel Team <kernel at pengutronix.de>; Fabio Estevam
> > <festevam at gmail.com>; Frank Li <frank.li at nxp.com>; Bough Chen
> > <haibo.chen at nxp.com>
> > Cc: linux-can at vger.kernel.org; linux-phy at lists.infradead.org;
> > devicetree at vger.kernel.org; linux-kernel at vger.kernel.org;
> > imx at lists.linux.dev; linux-arm-kernel at lists.infradead.org; Peng Fan
> > <peng.fan at nxp.com>
> > Subject: [PATCH v2 3/5] arm64: dts: imx95-15x15-evk: Use phys to
> > replace xceiver-supply
> >
> > The TJA1051T/3 used on i.MX95-15x15-EVK is actually high-speed CAN
> > transceiver, not a regulator supply. So use phys to reflect the truth.
> >
> > Signed-off-by: Peng Fan <peng.fan at nxp.com>
> > ---
> >  arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts | 13 ++++++-------
> >  1 file changed, 6 insertions(+), 7 deletions(-)
> >
> > diff --git a/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
> > b/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
> > index
> >
> 46f6e0fbf2b09106e6e726ff8b61522d1359cfa4..f6197ba356d49b97bf7287c3f0
> > f86ef84f89bac9 100644
> > --- a/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
> > +++ b/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
> > @@ -89,12 +89,11 @@ reg_audio_switch1: regulator-audio-switch1 {
> >  		gpio = <&pcal6524 0 GPIO_ACTIVE_LOW>;
> >  	};
> >
> > -	reg_can2_stby: regulator-can2-stby {
> > -		compatible = "regulator-fixed";
> > -		regulator-max-microvolt = <3300000>;
> > -		regulator-min-microvolt = <3300000>;
> > -		regulator-name = "can2-stby";
> > -		gpio = <&pcal6524 14 GPIO_ACTIVE_LOW>;
> > +	flexcan2_phy: can-phy {
> > +		compatible = "nxp,tja1051", "ti,tcan1043";
> > +		#phy-cells = <0>;
> > +		max-bitrate = <1000000>;
> 
> Hi Peng, shouldn't the max-bitrate of TJA1051 be 5000000?

Yes, according to the datasheet of TJA1051, CAN FD fast phase at data rates up to 5 Mbit/s
https://www.nxp.com/docs/en/data-sheet/TJA1051.pdf

Please correct this, here the max-bitrate also limit the data bitrate.

Regards
Haibo Chen
> 
> Best Regards
> Sherry
> 
> > +		standby-gpios = <&pcal6524 14 GPIO_ACTIVE_HIGH>;
> >  	};
> >
> >  	reg_m2_pwr: regulator-m2-pwr {
> > @@ -300,7 +299,7 @@ &enetc_port1 {
> >  &flexcan2 {
> >  	pinctrl-0 = <&pinctrl_flexcan2>;
> >  	pinctrl-names = "default";
> > -	xceiver-supply = <&reg_can2_stby>;
> > +	phys = <&flexcan2_phy>;
> >  	status = "okay";
> >  };
> >
> >
> > --
> > 2.37.1
> >


From andersson at kernel.org  Mon Aug 25 19:50:30 2025
From: andersson at kernel.org (Bjorn Andersson)
Date: Mon, 25 Aug 2025 21:50:30 -0500
Subject: [PATCH 1/3] phy: qcom-qmp-usb: fix NULL pointer dereference in
 PM callbacks
In-Reply-To: <20250825-qmp-null-deref-on-pm-v1-1-bbd3ca330849@oss.qualcomm.com>
References: <20250825-qmp-null-deref-on-pm-v1-0-bbd3ca330849@oss.qualcomm.com>
 <20250825-qmp-null-deref-on-pm-v1-1-bbd3ca330849@oss.qualcomm.com>
Message-ID: <sxqgnmj4bawj7n6kan7tiutb5ynhxz6cgbtpbz2xx4ixodtdw6@q2ftbnpjouvb>

On Mon, Aug 25, 2025 at 05:22:02PM +0530, Kathiravan Thirumoorthy wrote:
> From: Poovendhan Selvaraj <quic_poovendh at quicinc.com>
> 
> The pm ops are enabled before qmp phy create which causes
> a NULL pointer dereference when accessing qmp->phy->init_count
> in the qmp_usb_runtime_suspend.
> 

How does that happen? Do we end up in the error path inbetween the
devm_pm_runtime_enable()? Or does it happen by some other means?

This would be quite useful information for others to know if they hit
the same or just a similar problem.

> So if qmp->phy is NULL, bail out early in suspend / resume callbacks
> to avoid the NULL pointer dereference in qmp_usb_runtime_suspend and
> qmp_usb_runtime_resume.
> 
> Below is the stacktrace for reference:
> 
> [<818381a0>] (qmp_usb_runtime_suspend [phy_qcom_qmp_usb]) from [<4051d1d8>] (__rpm_callback+0x3c/0x110)
> [<4051d1d8>] (__rpm_callback) from [<4051d2fc>] (rpm_callback+0x50/0x54)
> [<4051d2fc>] (rpm_callback) from [<4051d940>] (rpm_suspend+0x23c/0x428)
> [<4051d940>] (rpm_suspend) from [<4051e808>] (pm_runtime_work+0x74/0x8c)
> [<4051e808>] (pm_runtime_work) from [<401311f4>] (process_scheduled_works+0x1d0/0x2c8)
> [<401311f4>] (process_scheduled_works) from [<40131d48>] (worker_thread+0x260/0x2e4)
> [<40131d48>] (worker_thread) from [<40138970>] (kthread+0x118/0x12c)
> [<40138970>] (kthread) from [<4010013c>] (ret_from_fork+0x14/0x38)
> 
> Cc: stable at vger.kernel.org # v6.0
> Fixes: 65753f38f530 ("phy: qcom-qmp-usb: drop multi-PHY support")

Has this been a reproducible issue for last 3 years? I think the fixes
makes sense in that it introduced the indirection, but when did the
issue actually show up?

Regards,
Bjorn

> Signed-off-by: Poovendhan Selvaraj <quic_poovendh at quicinc.com>
> Signed-off-by: Kathiravan Thirumoorthy <kathiravan.thirumoorthy at oss.qualcomm.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-usb.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
> index ed646a7e705ba3259708775ed5fedbbbada13735..cd04e8f22a0fe81b086b308d02713222aa95cae3 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
> @@ -1940,7 +1940,7 @@ static int __maybe_unused qmp_usb_runtime_suspend(struct device *dev)
>  
>  	dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->mode);
>  
> -	if (!qmp->phy->init_count) {
> +	if (!qmp->phy || !qmp->phy->init_count) {
>  		dev_vdbg(dev, "PHY not initialized, bailing out\n");
>  		return 0;
>  	}
> @@ -1960,7 +1960,7 @@ static int __maybe_unused qmp_usb_runtime_resume(struct device *dev)
>  
>  	dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qmp->mode);
>  
> -	if (!qmp->phy->init_count) {
> +	if (!qmp->phy || !qmp->phy->init_count) {
>  		dev_vdbg(dev, "PHY not initialized, bailing out\n");
>  		return 0;
>  	}
> 
> -- 
> 2.34.1
> 


From luyulin at eswincomputing.com  Mon Aug 25 20:23:57 2025
From: luyulin at eswincomputing.com (luyulin at eswincomputing.com)
Date: Tue, 26 Aug 2025 11:23:57 +0800 (GMT+08:00)
Subject: [PATCH v2 2/3] dt-bindings: phy: eswin: Document for
 EIC7700 SoC SATA PHY
In-Reply-To: <20250821-precise-delightful-lyrebird-6b4275@kuoka>
References: <20250819134722.220-1-luyulin@eswincomputing.com>
 <20250820092758.803-1-luyulin@eswincomputing.com>
 <20250821-precise-delightful-lyrebird-6b4275@kuoka>
Message-ID: <3fd6740d.6d3.198e4676278.Coremail.luyulin@eswincomputing.com>

Hi,
Krzysztof

I apologize for incorrectly filling in the "In-Reply-To" field
when I first sent this patch, which caused it to lose association
with the other patches.
As a result, I have resent this patch.
Could you please help review the other patches in this patch series again?
The link to the cover letter for this patch series is:
https://lore.kernel.org/lkml/20250819134722.220-1-luyulin at eswincomputing.com/
Thank you very much for your review suggestions!
> 
> On Wed, Aug 20, 2025 at 05:27:58PM +0800, Yulin Lu wrote:
> > Add document for the SATA phy on the EIC7700 SoC platform,
> > describing its usage.
> > 
> > Signed-off-by: Yulin Lu <luyulin at eswincomputing.com>
> 
> You already sent this patch separately (!!!) and received review.
> 
> Best regards,
> Krzysztof

Best regards,
Yulin

From krishna.chundru at oss.qualcomm.com  Mon Aug 25 22:18:16 2025
From: krishna.chundru at oss.qualcomm.com (Krishna Chaitanya Chundru)
Date: Tue, 26 Aug 2025 10:48:16 +0530
Subject: [PATCH v2 0/3] arm64: dts: qcom: Add PCIe Support for sm8750
Message-ID: <20250826-pakala-v2-0-74f1f60676c6@oss.qualcomm.com>

Describe PCIe controller and PHY. Also add required system resources like
regulators, clocks, interrupts and registers configuration for PCIe.

Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
---
Changes in v2:
- Follow the x1e80100.dtsi pcie node description (Konrad).
- define phy & perst, wake in port node as per latest bindings.
- Add check in the driver to parse only pcie child nodes.
- Added acked by tag(Rob).
- Removed dtbinding and phy driver patches as they got applied.
- Link to v1: https://lore.kernel.org/r/20250809-pakala-v1-0-abf1c416dbaa at oss.qualcomm.com

---
Krishna Chaitanya Chundru (3):
      dt-bindings: PCI: qcom,pcie-sm8550: Add SM8750 compatible
      arm64: dts: qcom: sm8750: Add PCIe PHY and controller node
      PCI: qcom: Restrict port parsing only to pci child nodes

 .../devicetree/bindings/pci/qcom,pcie-sm8550.yaml  |   1 +
 arch/arm64/boot/dts/qcom/sm8750.dtsi               | 180 ++++++++++++++++++++-
 drivers/pci/controller/dwc/pcie-qcom.c             |   2 +
 3 files changed, 182 insertions(+), 1 deletion(-)
---
base-commit: b6add54ba61890450fa54fd9327d10fdfd653439
change-id: 20250809-pakala-25a7c1ddba85

Best regards,
-- 
Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>



From krishna.chundru at oss.qualcomm.com  Mon Aug 25 22:18:17 2025
From: krishna.chundru at oss.qualcomm.com (Krishna Chaitanya Chundru)
Date: Tue, 26 Aug 2025 10:48:17 +0530
Subject: [PATCH v2 1/3] dt-bindings: PCI: qcom,pcie-sm8550: Add SM8750
 compatible
In-Reply-To: <20250826-pakala-v2-0-74f1f60676c6@oss.qualcomm.com>
References: <20250826-pakala-v2-0-74f1f60676c6@oss.qualcomm.com>
Message-ID: <20250826-pakala-v2-1-74f1f60676c6@oss.qualcomm.com>

On the Qualcomm SM8750 platform the PCIe host is compatible with the
DWC controller present on the SM8550 platorm.

Acked-by: Rob Herring (Arm) <robh at kernel.org>
Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
---
 Documentation/devicetree/bindings/pci/qcom,pcie-sm8550.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-sm8550.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-sm8550.yaml
index dbce671ba011c8991842af6d6c761ec081be24cb..38b561e23c1fda677ce2d4257e1084a384648835 100644
--- a/Documentation/devicetree/bindings/pci/qcom,pcie-sm8550.yaml
+++ b/Documentation/devicetree/bindings/pci/qcom,pcie-sm8550.yaml
@@ -22,6 +22,7 @@ properties:
           - enum:
               - qcom,sar2130p-pcie
               - qcom,pcie-sm8650
+              - qcom,pcie-sm8750
           - const: qcom,pcie-sm8550
 
   reg:

-- 
2.34.1



From krishna.chundru at oss.qualcomm.com  Mon Aug 25 22:18:18 2025
From: krishna.chundru at oss.qualcomm.com (Krishna Chaitanya Chundru)
Date: Tue, 26 Aug 2025 10:48:18 +0530
Subject: [PATCH v2 2/3] arm64: dts: qcom: sm8750: Add PCIe PHY and
 controller node
In-Reply-To: <20250826-pakala-v2-0-74f1f60676c6@oss.qualcomm.com>
References: <20250826-pakala-v2-0-74f1f60676c6@oss.qualcomm.com>
Message-ID: <20250826-pakala-v2-2-74f1f60676c6@oss.qualcomm.com>

Add PCIe controller and PHY nodes which supports data rates of 8GT/s
and x2 lane.

Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/sm8750.dtsi | 180 ++++++++++++++++++++++++++++++++++-
 1 file changed, 179 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/sm8750.dtsi b/arch/arm64/boot/dts/qcom/sm8750.dtsi
index 4643705021c6ca095a16d8d7cc3adac920b21e82..b47668a64bcead3e48f58eeb2e41c04660493cb7 100644
--- a/arch/arm64/boot/dts/qcom/sm8750.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8750.dtsi
@@ -631,7 +631,7 @@ gcc: clock-controller at 100000 {
 			clocks = <&bi_tcxo_div2>,
 				 <0>,
 				 <&sleep_clk>,
-				 <0>,
+				 <&pcie0_phy>,
 				 <0>,
 				 <0>,
 				 <0>,
@@ -3304,6 +3304,184 @@ gic_its: msi-controller at 16040000 {
 			};
 		};
 
+		pcie0: pcie at 1c00000 {
+			device_type = "pci";
+			compatible = "qcom,pcie-sm8750", "qcom,pcie-sm8550";
+			reg = <0x0 0x01c00000 0x0 0x3000>,
+			      <0x0 0x40000000 0x0 0xf1d>,
+			      <0x0 0x40000f20 0x0 0xa8>,
+			      <0x0 0x40001000 0x0 0x1000>,
+			      <0x0 0x40100000 0x0 0x100000>,
+			      <0x0 0x01C03000 0x0 0x1000>;
+			reg-names = "parf",
+				    "dbi",
+				    "elbi",
+				    "atu",
+				    "config",
+				    "mhi";
+
+			#address-cells = <3>;
+			#size-cells = <2>;
+			ranges = <0x01000000 0x0 0x00000000 0x0 0x40200000 0x0 0x100000>,
+				 <0x02000000 0x0 0x40300000 0x0 0x40300000 0x0 0x23d00000>,
+				 <0x03000000 0x4 0x00000000 0x4 0x00000000 0x3 0x00000000>;
+			bus-range = <0x00 0xff>;
+
+			dma-coherent;
+
+			linux,pci-domain = <0>;
+
+			msi-map = <0x0 &gic_its 0x1400 0x1>,
+				  <0x100 &gic_its 0x1401 0x1>;
+			msi-map-mask = <0xff00>;
+
+			num-lanes = <2>;
+
+			interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 140 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 0 149 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 2 &intc 0 0 0 150 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 3 &intc 0 0 0 151 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 4 &intc 0 0 0 152 IRQ_TYPE_LEVEL_HIGH>;
+
+			clocks = <&gcc GCC_PCIE_0_AUX_CLK>,
+				 <&gcc GCC_PCIE_0_CFG_AHB_CLK>,
+				 <&gcc GCC_PCIE_0_MSTR_AXI_CLK>,
+				 <&gcc GCC_PCIE_0_SLV_AXI_CLK>,
+				 <&gcc GCC_PCIE_0_SLV_Q2A_AXI_CLK>,
+				 <&gcc GCC_DDRSS_PCIE_SF_QTB_CLK>,
+				 <&gcc GCC_AGGRE_NOC_PCIE_AXI_CLK>,
+				 <&gcc GCC_CNOC_PCIE_SF_AXI_CLK>;
+			clock-names = "aux",
+				      "cfg",
+				      "bus_master",
+				      "bus_slave",
+				      "slave_q2a",
+				      "ddrss_sf_tbu",
+				      "noc_aggr",
+				      "cnoc_sf_axi";
+
+			interconnects = <&pcie_noc MASTER_PCIE_0 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_0 QCOM_ICC_TAG_ALWAYS>;
+			interconnect-names = "pcie-mem",
+					     "cpu-pcie";
+
+			iommu-map = <0x0   &apps_smmu 0x1400 0x1>,
+				    <0x100 &apps_smmu 0x1401 0x1>;
+
+			resets = <&gcc GCC_PCIE_0_BCR>;
+			reset-names = "pci";
+
+			power-domains = <&gcc GCC_PCIE_0_GDSC>;
+
+			operating-points-v2 = <&pcie0_opp_table>;
+
+			status = "disabled";
+
+			pcie0_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 2 x2 */
+				opp-10000000 {
+					opp-hz = /bits/ 64 <10000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <1000000 1>;
+				};
+
+				/* GEN 3 x1 */
+				opp-8000000 {
+					opp-hz = /bits/ 64 <8000000>;
+					required-opps = <&rpmhpd_opp_nom>;
+					opp-peak-kBps = <984500 1>;
+				};
+
+				/* GEN 3 x2 */
+				opp-16000000 {
+					opp-hz = /bits/ 64 <16000000>;
+					required-opps = <&rpmhpd_opp_nom>;
+					opp-peak-kBps = <1969000 1>;
+				};
+
+			};
+
+			pcieport0: pcie at 0 {
+				device_type = "pci";
+				reg = <0x0 0x0 0x0 0x0 0x0>;
+				bus-range = <0x01 0xff>;
+
+				#address-cells = <3>;
+				#size-cells = <2>;
+				ranges;
+				phys = <&pcie0_phy>;
+			};
+		};
+
+		pcie0_phy: phy at 1c06000 {
+			compatible = "qcom,sm8750-qmp-gen3x2-pcie-phy";
+			reg = <0 0x01c06000 0 0x2000>;
+
+			clocks = <&gcc GCC_PCIE_0_AUX_CLK>,
+				 <&gcc GCC_PCIE_0_CFG_AHB_CLK>,
+				 <&tcsrcc TCSR_PCIE_0_CLKREF_EN>,
+				 <&gcc GCC_PCIE_0_PHY_RCHNG_CLK>,
+				 <&gcc GCC_PCIE_0_PIPE_CLK>;
+			clock-names = "aux",
+				      "cfg_ahb",
+				      "ref",
+				      "rchng",
+				      "pipe";
+
+			assigned-clocks = <&gcc GCC_PCIE_0_PHY_RCHNG_CLK>;
+			assigned-clock-rates = <100000000>;
+
+			resets = <&gcc GCC_PCIE_0_PHY_BCR>;
+			reset-names = "phy";
+
+			power-domains = <&gcc GCC_PCIE_0_PHY_GDSC>;
+
+			#clock-cells = <0>;
+			clock-output-names = "pcie0_pipe_clk";
+
+			#phy-cells = <0>;
+
+			status = "disabled";
+		};
+
 		ufs_mem_phy: phy at 1d80000 {
 			compatible = "qcom,sm8750-qmp-ufs-phy";
 			reg = <0x0 0x01d80000 0x0 0x2000>;

-- 
2.34.1



From krishna.chundru at oss.qualcomm.com  Mon Aug 25 22:18:19 2025
From: krishna.chundru at oss.qualcomm.com (Krishna Chaitanya Chundru)
Date: Tue, 26 Aug 2025 10:48:19 +0530
Subject: [PATCH v2 3/3] PCI: qcom: Restrict port parsing only to pci child
 nodes
In-Reply-To: <20250826-pakala-v2-0-74f1f60676c6@oss.qualcomm.com>
References: <20250826-pakala-v2-0-74f1f60676c6@oss.qualcomm.com>
Message-ID: <20250826-pakala-v2-3-74f1f60676c6@oss.qualcomm.com>

The qcom_pcie_parse_ports() function currently iterates over all available
child nodes of the PCIe controller's device tree node. This can lead to
attempts to parse unrelated nodes like OPP nodes, resulting in unnecessary
errors or misconfiguration.

Restrict the parsing logic to only consider child nodes named "pcie" or
"pci", which are the expected node names for PCIe ports.

Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
---
 drivers/pci/controller/dwc/pcie-qcom.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index 294babe1816e4d0c2b2343fe22d89af72afcd6cd..5dbdb69fbdd1b9b78a3ebba3cd50d78168f2d595 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -1740,6 +1740,8 @@ static int qcom_pcie_parse_ports(struct qcom_pcie *pcie)
 	int ret = -ENOENT;
 
 	for_each_available_child_of_node_scoped(dev->of_node, of_port) {
+		if (!(of_node_name_eq(of_port, "pcie") || of_node_name_eq(of_port, "pci")))
+			continue;
 		ret = qcom_pcie_parse_port(pcie, of_port);
 		if (ret)
 			goto err_port_del;

-- 
2.34.1



From wenbin.yao at oss.qualcomm.com  Mon Aug 25 23:01:46 2025
From: wenbin.yao at oss.qualcomm.com (Wenbin Yao)
Date: Mon, 25 Aug 2025 23:01:46 -0700
Subject: [PATCH v3 0/4] PCI: qcom: Add support for Glymur PCIe Gen5x4
Message-ID: <20250825-glymur_pcie5-v3-0-5c1d1730c16f@oss.qualcomm.com>

Glymur is the next generation compute SoC of Qualcomm. This patch series
aims to add support for the fifth PCIe instance on it. The fifth PCIe
instance on Glymur has a Gen5 4-lane PHY. Patch [1/4] documents PHY as a
separate compatible and Patch [2/4] documents controller as a separate
compatible. Patch [3/4] describles the new PCS offsets in a dedicated
header file. Patch [4/4] adds configuration and compatible for PHY.

The device tree changes and whatever driver patches that are not part of
this patch series will be posted separately after official announcement of
the SOC.

Signed-off-by: Wenbin Yao <wenbin.yao at oss.qualcomm.com>
---
Changes in v3:
- Keep qmp_pcie_of_match_table array sorted.
- Drop qref supply for PCIe Gen5x4 PHY.
- Link to v2: https://lore.kernel.org/r/20250821-glymur_pcie5-v2-0-cd516784ef20 at oss.qualcomm.com

Changes in v2:
- Add offsets of PLL and TXRXZ register blocks for v8.50 PHY in Patch[4/4].
- Link to v1: https://lore.kernel.org/r/20250819-glymur_pcie5-v1-0-2ea09f83cbb0 at oss.qualcomm.com

---
Prudhvi Yarlagadda (4):
      dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Document the Glymur QMP PCIe PHY
      dt-bindings: PCI: qcom: Document the Glymur PCIe Controller
      phy: qcom-qmp: pcs: Add v8.50 register offsets
      phy: qcom: qmp-pcie: Add support for Glymur PCIe Gen5x4 PHY

 .../bindings/pci/qcom,pcie-x1e80100.yaml           |  7 ++++-
 .../bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml   |  3 ++
 drivers/phy/qualcomm/phy-qcom-qmp-pcie.c           | 32 ++++++++++++++++++++++
 drivers/phy/qualcomm/phy-qcom-qmp-pcs-v8_50.h      | 13 +++++++++
 drivers/phy/qualcomm/phy-qcom-qmp.h                |  2 ++
 5 files changed, 56 insertions(+), 1 deletion(-)
---
base-commit: 886e5e7b0432360842303d587bb4a65d10741ae8
change-id: 20250818-glymur_pcie5-db4ef032e233

Best regards,
-- 
Wenbin Yao <wenbin.yao at oss.qualcomm.com>



From wenbin.yao at oss.qualcomm.com  Mon Aug 25 23:01:47 2025
From: wenbin.yao at oss.qualcomm.com (Wenbin Yao)
Date: Mon, 25 Aug 2025 23:01:47 -0700
Subject: [PATCH v3 1/4] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy:
 Document the Glymur QMP PCIe PHY
In-Reply-To: <20250825-glymur_pcie5-v3-0-5c1d1730c16f@oss.qualcomm.com>
References: <20250825-glymur_pcie5-v3-0-5c1d1730c16f@oss.qualcomm.com>
Message-ID: <20250825-glymur_pcie5-v3-1-5c1d1730c16f@oss.qualcomm.com>

From: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>

The fifth PCIe instance on Glymur has a Gen5 4-lane PHY. Document it as a
separate compatible.

Signed-off-by: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
Signed-off-by: Wenbin Yao <wenbin.yao at oss.qualcomm.com>
Acked-by: Rob Herring (Arm) <robh at kernel.org>
---
 Documentation/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 b6f140bf5b3b2f79b5c96e591ec0edb76cd45fa5..61e0e2f7ec7f9cb08447e4cd9503698c0a2d383a 100644
--- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
@@ -16,6 +16,7 @@ description:
 properties:
   compatible:
     enum:
+      - qcom,glymur-qmp-gen5x4-pcie-phy
       - qcom,qcs615-qmp-gen3x1-pcie-phy
       - qcom,qcs8300-qmp-gen4x2-pcie-phy
       - qcom,sa8775p-qmp-gen4x2-pcie-phy
@@ -176,6 +177,7 @@ allOf:
         compatible:
           contains:
             enum:
+              - qcom,glymur-qmp-gen5x4-pcie-phy
               - qcom,sa8775p-qmp-gen4x2-pcie-phy
               - qcom,sa8775p-qmp-gen4x4-pcie-phy
               - qcom,sc8280xp-qmp-gen3x1-pcie-phy
@@ -211,6 +213,7 @@ allOf:
         compatible:
           contains:
             enum:
+              - qcom,glymur-qmp-gen5x4-pcie-phy
               - qcom,sm8550-qmp-gen4x2-pcie-phy
               - qcom,sm8650-qmp-gen4x2-pcie-phy
               - qcom,x1e80100-qmp-gen4x2-pcie-phy

-- 
2.34.1



From wenbin.yao at oss.qualcomm.com  Mon Aug 25 23:01:48 2025
From: wenbin.yao at oss.qualcomm.com (Wenbin Yao)
Date: Mon, 25 Aug 2025 23:01:48 -0700
Subject: [PATCH v3 2/4] dt-bindings: PCI: qcom: Document the Glymur PCIe
 Controller
In-Reply-To: <20250825-glymur_pcie5-v3-0-5c1d1730c16f@oss.qualcomm.com>
References: <20250825-glymur_pcie5-v3-0-5c1d1730c16f@oss.qualcomm.com>
Message-ID: <20250825-glymur_pcie5-v3-2-5c1d1730c16f@oss.qualcomm.com>

From: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>

On the Qualcomm Glymur platform the PCIe host is compatible with the DWC
controller present on the X1E80100 platform. So document the PCIe
controllers found on Glymur and use the X1E80100 compatible string as a
fallback in the schema.

Signed-off-by: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
Signed-off-by: Wenbin Yao <wenbin.yao at oss.qualcomm.com>
Acked-by: Rob Herring (Arm) <robh at kernel.org>
---
 Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml
index 257068a1826492a7071600d03ca0c99babb75bd9..8600f2c74cb81bcb924fa2035d992c3bd147db31 100644
--- a/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml
+++ b/Documentation/devicetree/bindings/pci/qcom,pcie-x1e80100.yaml
@@ -16,7 +16,12 @@ description:
 
 properties:
   compatible:
-    const: qcom,pcie-x1e80100
+    oneOf:
+      - const: qcom,pcie-x1e80100
+      - items:
+          - enum:
+              - qcom,glymur-pcie
+          - const: qcom,pcie-x1e80100
 
   reg:
     minItems: 6

-- 
2.34.1



From wenbin.yao at oss.qualcomm.com  Mon Aug 25 23:01:49 2025
From: wenbin.yao at oss.qualcomm.com (Wenbin Yao)
Date: Mon, 25 Aug 2025 23:01:49 -0700
Subject: [PATCH v3 3/4] phy: qcom-qmp: pcs: Add v8.50 register offsets
In-Reply-To: <20250825-glymur_pcie5-v3-0-5c1d1730c16f@oss.qualcomm.com>
References: <20250825-glymur_pcie5-v3-0-5c1d1730c16f@oss.qualcomm.com>
Message-ID: <20250825-glymur_pcie5-v3-3-5c1d1730c16f@oss.qualcomm.com>

From: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>

The new Glymur SoC bumps up the HW version of QMP phy to v8.50 for PCIE
g5x4. Add the new PCS offsets in a dedicated header file.

Signed-off-by: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
Signed-off-by: Wenbin Yao <wenbin.yao at oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-pcs-v8_50.h | 13 +++++++++++++
 drivers/phy/qualcomm/phy-qcom-qmp.h           |  2 ++
 2 files changed, 15 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v8_50.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v8_50.h
new file mode 100644
index 0000000000000000000000000000000000000000..325c127e8eb7ad842018dce51d09a6ee54ed86ff
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v8_50.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#ifndef QCOM_PHY_QMP_PCS_V8_50_H_
+#define QCOM_PHY_QMP_PCS_V8_50_H_
+
+#define QPHY_V8_50_PCS_STATUS1			0x010
+#define QPHY_V8_50_PCS_START_CONTROL			0x05c
+#define QPHY_V8_50_PCS_POWER_DOWN_CONTROL			0x64
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.h b/drivers/phy/qualcomm/phy-qcom-qmp.h
index f58c82b2dd23e1bda616d67ab7993794b997063b..da2a7ad2cdccef1308a2b7aa71a2e5cf8bd7c1d7 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.h
@@ -58,6 +58,8 @@
 
 #include "phy-qcom-qmp-pcs-v8.h"
 
+#include "phy-qcom-qmp-pcs-v8_50.h"
+
 /* QPHY_SW_RESET bit */
 #define SW_RESET				BIT(0)
 /* QPHY_POWER_DOWN_CONTROL */

-- 
2.34.1



From wenbin.yao at oss.qualcomm.com  Mon Aug 25 23:01:50 2025
From: wenbin.yao at oss.qualcomm.com (Wenbin Yao)
Date: Mon, 25 Aug 2025 23:01:50 -0700
Subject: [PATCH v3 4/4] phy: qcom: qmp-pcie: Add support for Glymur PCIe
 Gen5x4 PHY
In-Reply-To: <20250825-glymur_pcie5-v3-0-5c1d1730c16f@oss.qualcomm.com>
References: <20250825-glymur_pcie5-v3-0-5c1d1730c16f@oss.qualcomm.com>
Message-ID: <20250825-glymur_pcie5-v3-4-5c1d1730c16f@oss.qualcomm.com>

From: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>

Add support for Gen5 x4 PCIe QMP PHY found on Glymur platform.

Signed-off-by: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
Signed-off-by: Wenbin Yao <wenbin.yao at oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index 95830dcfdec9b1f68fd55d1cc3c102985cfafcc1..011687e6191e7a496b56cd85a149b10f7f00a749 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -93,6 +93,12 @@ static const unsigned int pciephy_v6_regs_layout[QPHY_LAYOUT_SIZE] = {
 	[QPHY_PCS_POWER_DOWN_CONTROL]	= QPHY_V6_PCS_POWER_DOWN_CONTROL,
 };
 
+static const unsigned int pciephy_v8_50_regs_layout[QPHY_LAYOUT_SIZE] = {
+	[QPHY_START_CTRL]		= QPHY_V8_50_PCS_START_CONTROL,
+	[QPHY_PCS_STATUS]		= QPHY_V8_50_PCS_STATUS1,
+	[QPHY_PCS_POWER_DOWN_CONTROL]   = QPHY_V8_50_PCS_POWER_DOWN_CONTROL,
+};
+
 static const struct qmp_phy_init_tbl msm8998_pcie_serdes_tbl[] = {
 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
@@ -2963,6 +2969,7 @@ struct qmp_pcie_offsets {
 	u16 rx2;
 	u16 txz;
 	u16 rxz;
+	u16 txrxz;
 	u16 ln_shrd;
 };
 
@@ -3229,6 +3236,12 @@ static const struct qmp_pcie_offsets qmp_pcie_offsets_v6_30 = {
 	.ln_shrd	= 0x8000,
 };
 
+static const struct qmp_pcie_offsets qmp_pcie_offsets_v8_50 = {
+	.serdes     = 0x8000,
+	.pcs        = 0x9000,
+	.txrxz      = 0xd000,
+};
+
 static const struct qmp_phy_cfg ipq8074_pciephy_cfg = {
 	.lanes			= 1,
 
@@ -4258,6 +4271,22 @@ static const struct qmp_phy_cfg qmp_v6_gen4x4_pciephy_cfg = {
 	.phy_status             = PHYSTATUS_4_20,
 };
 
+static const struct qmp_phy_cfg glymur_qmp_gen5x4_pciephy_cfg = {
+	.lanes = 4,
+
+	.offsets        = &qmp_pcie_offsets_v8_50,
+
+	.reset_list     = sdm845_pciephy_reset_l,
+	.num_resets     = ARRAY_SIZE(sdm845_pciephy_reset_l),
+	.vreg_list      = qmp_phy_vreg_l,
+	.num_vregs      = ARRAY_SIZE(qmp_phy_vreg_l),
+
+	.regs           = pciephy_v8_50_regs_layout,
+
+	.pwrdn_ctrl     = SW_PWRDN | REFCLK_DRV_DSBL,
+	.phy_status     = PHYSTATUS_4_20,
+};
+
 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;
@@ -5004,6 +5033,9 @@ static int qmp_pcie_probe(struct platform_device *pdev)
 
 static const struct of_device_id qmp_pcie_of_match_table[] = {
 	{
+		.compatible = "qcom,glymur-qmp-gen5x4-pcie-phy",
+		.data = &glymur_qmp_gen5x4_pciephy_cfg,
+	}, {
 		.compatible = "qcom,ipq6018-qmp-pcie-phy",
 		.data = &ipq6018_pciephy_cfg,
 	}, {

-- 
2.34.1



From mani at kernel.org  Mon Aug 25 23:17:58 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Tue, 26 Aug 2025 11:47:58 +0530
Subject: [PATCH v2 3/3] PCI: qcom: Restrict port parsing only to pci
 child nodes
In-Reply-To: <20250826-pakala-v2-3-74f1f60676c6@oss.qualcomm.com>
References: <20250826-pakala-v2-0-74f1f60676c6@oss.qualcomm.com>
 <20250826-pakala-v2-3-74f1f60676c6@oss.qualcomm.com>
Message-ID: <rurdrz3buvb7paqgjjr7ethzvaeyvylezexcwshpj73xf7yeec@i52bla6r5tx7>

On Tue, Aug 26, 2025 at 10:48:19AM GMT, Krishna Chaitanya Chundru wrote:
> The qcom_pcie_parse_ports() function currently iterates over all available
> child nodes of the PCIe controller's device tree node. This can lead to
> attempts to parse unrelated nodes like OPP nodes, resulting in unnecessary
> errors or misconfiguration.
> 

What errors? Errors you are seeing on your setup or you envision?

> Restrict the parsing logic to only consider child nodes named "pcie" or
> "pci", which are the expected node names for PCIe ports.
> 
> Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>

Since this is a fix, 'Fixes' tag is needed.

> ---
>  drivers/pci/controller/dwc/pcie-qcom.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
> index 294babe1816e4d0c2b2343fe22d89af72afcd6cd..5dbdb69fbdd1b9b78a3ebba3cd50d78168f2d595 100644
> --- a/drivers/pci/controller/dwc/pcie-qcom.c
> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> @@ -1740,6 +1740,8 @@ static int qcom_pcie_parse_ports(struct qcom_pcie *pcie)
>  	int ret = -ENOENT;
>  
>  	for_each_available_child_of_node_scoped(dev->of_node, of_port) {
> +		if (!(of_node_name_eq(of_port, "pcie") || of_node_name_eq(of_port, "pci")))

May I know which platform has 'pci' as the node name for the bridge node? AFAIK,
all platforms defining bridge nodes have 'pcie' as the node name.

- Mani

-- 
????????? ????????


From mani at kernel.org  Mon Aug 25 23:19:44 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Tue, 26 Aug 2025 11:49:44 +0530
Subject: [PATCH v3 4/4] phy: qcom: qmp-pcie: Add support for Glymur PCIe
 Gen5x4 PHY
In-Reply-To: <20250825-glymur_pcie5-v3-4-5c1d1730c16f@oss.qualcomm.com>
References: <20250825-glymur_pcie5-v3-0-5c1d1730c16f@oss.qualcomm.com>
 <20250825-glymur_pcie5-v3-4-5c1d1730c16f@oss.qualcomm.com>
Message-ID: <fqtq3lbdnfkzngfym3k53jkrhp4addqvltvrfh35hhiiyf4qqw@2vdhide3lux5>

On Mon, Aug 25, 2025 at 11:01:50PM GMT, Wenbin Yao wrote:
> From: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
> 
> Add support for Gen5 x4 PCIe QMP PHY found on Glymur platform.
> 
> Signed-off-by: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
> Signed-off-by: Wenbin Yao <wenbin.yao at oss.qualcomm.com>

Acked-by: Manivannan Sadhasivam <mani at kernel.org>

- Mani

> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 32 ++++++++++++++++++++++++++++++++
>  1 file changed, 32 insertions(+)
> 
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
> index 95830dcfdec9b1f68fd55d1cc3c102985cfafcc1..011687e6191e7a496b56cd85a149b10f7f00a749 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
> @@ -93,6 +93,12 @@ static const unsigned int pciephy_v6_regs_layout[QPHY_LAYOUT_SIZE] = {
>  	[QPHY_PCS_POWER_DOWN_CONTROL]	= QPHY_V6_PCS_POWER_DOWN_CONTROL,
>  };
>  
> +static const unsigned int pciephy_v8_50_regs_layout[QPHY_LAYOUT_SIZE] = {
> +	[QPHY_START_CTRL]		= QPHY_V8_50_PCS_START_CONTROL,
> +	[QPHY_PCS_STATUS]		= QPHY_V8_50_PCS_STATUS1,
> +	[QPHY_PCS_POWER_DOWN_CONTROL]   = QPHY_V8_50_PCS_POWER_DOWN_CONTROL,
> +};
> +
>  static const struct qmp_phy_init_tbl msm8998_pcie_serdes_tbl[] = {
>  	QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
>  	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
> @@ -2963,6 +2969,7 @@ struct qmp_pcie_offsets {
>  	u16 rx2;
>  	u16 txz;
>  	u16 rxz;
> +	u16 txrxz;
>  	u16 ln_shrd;
>  };
>  
> @@ -3229,6 +3236,12 @@ static const struct qmp_pcie_offsets qmp_pcie_offsets_v6_30 = {
>  	.ln_shrd	= 0x8000,
>  };
>  
> +static const struct qmp_pcie_offsets qmp_pcie_offsets_v8_50 = {
> +	.serdes     = 0x8000,
> +	.pcs        = 0x9000,
> +	.txrxz      = 0xd000,
> +};
> +
>  static const struct qmp_phy_cfg ipq8074_pciephy_cfg = {
>  	.lanes			= 1,
>  
> @@ -4258,6 +4271,22 @@ static const struct qmp_phy_cfg qmp_v6_gen4x4_pciephy_cfg = {
>  	.phy_status             = PHYSTATUS_4_20,
>  };
>  
> +static const struct qmp_phy_cfg glymur_qmp_gen5x4_pciephy_cfg = {
> +	.lanes = 4,
> +
> +	.offsets        = &qmp_pcie_offsets_v8_50,
> +
> +	.reset_list     = sdm845_pciephy_reset_l,
> +	.num_resets     = ARRAY_SIZE(sdm845_pciephy_reset_l),
> +	.vreg_list      = qmp_phy_vreg_l,
> +	.num_vregs      = ARRAY_SIZE(qmp_phy_vreg_l),
> +
> +	.regs           = pciephy_v8_50_regs_layout,
> +
> +	.pwrdn_ctrl     = SW_PWRDN | REFCLK_DRV_DSBL,
> +	.phy_status     = PHYSTATUS_4_20,
> +};
> +
>  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;
> @@ -5004,6 +5033,9 @@ static int qmp_pcie_probe(struct platform_device *pdev)
>  
>  static const struct of_device_id qmp_pcie_of_match_table[] = {
>  	{
> +		.compatible = "qcom,glymur-qmp-gen5x4-pcie-phy",
> +		.data = &glymur_qmp_gen5x4_pciephy_cfg,
> +	}, {
>  		.compatible = "qcom,ipq6018-qmp-pcie-phy",
>  		.data = &ipq6018_pciephy_cfg,
>  	}, {
> 
> -- 
> 2.34.1
> 

-- 
????????? ????????


From krishna.chundru at oss.qualcomm.com  Mon Aug 25 23:24:00 2025
From: krishna.chundru at oss.qualcomm.com (Krishna Chaitanya Chundru)
Date: Tue, 26 Aug 2025 11:54:00 +0530
Subject: [PATCH v2 3/3] PCI: qcom: Restrict port parsing only to pci child
 nodes
In-Reply-To: <rurdrz3buvb7paqgjjr7ethzvaeyvylezexcwshpj73xf7yeec@i52bla6r5tx7>
References: <20250826-pakala-v2-0-74f1f60676c6@oss.qualcomm.com>
 <20250826-pakala-v2-3-74f1f60676c6@oss.qualcomm.com>
 <rurdrz3buvb7paqgjjr7ethzvaeyvylezexcwshpj73xf7yeec@i52bla6r5tx7>
Message-ID: <65755189-09e0-44f3-98d6-94e44e9b1dca@oss.qualcomm.com>



On 8/26/2025 11:47 AM, Manivannan Sadhasivam wrote:
> On Tue, Aug 26, 2025 at 10:48:19AM GMT, Krishna Chaitanya Chundru wrote:
>> The qcom_pcie_parse_ports() function currently iterates over all available
>> child nodes of the PCIe controller's device tree node. This can lead to
>> attempts to parse unrelated nodes like OPP nodes, resulting in unnecessary
>> errors or misconfiguration.
>>
> 
> What errors? Errors you are seeing on your setup or you envision?
we see driver is searching for reset in OPP node as it is not able to
find it is falling to legacy way. where there is no phy nodes defined in
the controller node probe is failling. I will add this in commit text.
> 
>> Restrict the parsing logic to only consider child nodes named "pcie" or
>> "pci", which are the expected node names for PCIe ports.
>>
>> Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
> 
> Since this is a fix, 'Fixes' tag is needed.
> 
ack.
>> ---
>>   drivers/pci/controller/dwc/pcie-qcom.c | 2 ++
>>   1 file changed, 2 insertions(+)
>>
>> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
>> index 294babe1816e4d0c2b2343fe22d89af72afcd6cd..5dbdb69fbdd1b9b78a3ebba3cd50d78168f2d595 100644
>> --- a/drivers/pci/controller/dwc/pcie-qcom.c
>> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
>> @@ -1740,6 +1740,8 @@ static int qcom_pcie_parse_ports(struct qcom_pcie *pcie)
>>   	int ret = -ENOENT;
>>   
>>   	for_each_available_child_of_node_scoped(dev->of_node, of_port) {
>> +		if (!(of_node_name_eq(of_port, "pcie") || of_node_name_eq(of_port, "pci")))
> 
> May I know which platform has 'pci' as the node name for the bridge node? AFAIK,
> all platforms defining bridge nodes have 'pcie' as the node name.
>
I see most of the qcom platforms are using pci only. for reference i see
it  in sm8650[1] & sm8550.

[1] 
https://elixir.bootlin.com/linux/v6.16.3/source/arch/arm64/boot/dts/qcom/sm8650.dtsi#L3699

- Krishna Chaitanya.
> - Mani
> 


From pritam.sutar at samsung.com  Mon Aug 25 23:37:22 2025
From: pritam.sutar at samsung.com (Pritam Manohar Sutar)
Date: Tue, 26 Aug 2025 12:07:22 +0530
Subject: [PATCH v7 5/6] dt-bindings: phy: samsung,usb3-drd-phy: add
 ExynosAutov920 combo ssphy
In-Reply-To: <20250824-rough-fresh-orangutan-eecb2f@kuoka>
References: <20250822093845.1179395-1-pritam.sutar@samsung.com>
	<CGME20250822093022epcas5p42d8c16c851769dab0e1da9d45743ab1f@epcas5p4.samsung.com>
	<20250822093845.1179395-6-pritam.sutar@samsung.com>
	<20250824-rough-fresh-orangutan-eecb2f@kuoka>
Message-ID: <007501dc1653$e36c3b50$aa44b1f0$@samsung.com>

Hi Krzysztof, 

> -----Original Message-----
> From: Krzysztof Kozlowski <krzk at kernel.org>
> Sent: 24 August 2025 02:26 PM
> To: Pritam Manohar Sutar <pritam.sutar at samsung.com>
> Cc: vkoul at kernel.org; kishon at kernel.org; robh at kernel.org;
> krzk+dt at kernel.org; conor+dt at kernel.org; alim.akhtar at samsung.com;
> andre.draszik at linaro.org; peter.griffin at linaro.org; kauschluss at disroot.org;
> ivo.ivanov.ivanov1 at gmail.com; igor.belwon at mentallysanemainliners.org;
> johan at kernel.org; m.szyprowski at samsung.com; s.nawrocki at samsung.com;
> linux-phy at lists.infradead.org; devicetree at vger.kernel.org; linux-
> kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-samsung-
> soc at vger.kernel.org; rosa.pila at samsung.com; dev.tailor at samsung.com;
> faraz.ata at samsung.com; muhammed.ali at samsung.com;
> selvarasu.g at samsung.com
> Subject: Re: [PATCH v7 5/6] dt-bindings: phy: samsung,usb3-drd-phy: add
> ExynosAutov920 combo ssphy
> 
> On Fri, Aug 22, 2025 at 03:08:44PM +0530, Pritam Manohar Sutar wrote:
> > This phy supports USB3.1 SSP+(10Gbps) protocol and is backwards
> > compatible to the USB3.0 SS(5Gbps). It requires two clocks, named
> > "phy" and "ref". The required supplies for USB3.1 are named as
> > vdd075_usb30(0.75v), vdd18_usb30(1.8v).
> 
> Please do not describe the schema, but hardware. This sentence does not help
> me in my question further.

This is a combo phy having Synopsys usb20 and usb30 phys (these 2 phys are totally different). 
One PHY only supports usb2.0 and data rates whereas another one does usb3.1 ssp+ and usb3.1 ssp
	
This patch only explains about usb30 (since these are two different phys) phy and omitted inclusion of usb20 reference (added separate patch for this patch no 3). 
	
Hope this is clear.

> 
> >
> > Add schemas for combo ssphy found on this SoC.
> >
> > Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
> > ---
> >  .../bindings/phy/samsung,usb3-drd-phy.yaml    | 23 +++++++++++++++++++
> >  1 file changed, 23 insertions(+)
> >
> > diff --git
> > a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
> > b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
> > index f0cfca5736b8..96e5bbb2e42c 100644
> > --- a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
> > +++ b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
> > @@ -34,6 +34,7 @@ properties:
> >        - samsung,exynos7870-usbdrd-phy
> >        - samsung,exynos850-usbdrd-phy
> >        - samsung,exynos990-usbdrd-phy
> > +      - samsung,exynosautov920-usb31drd-combo-ssphy
> >        - samsung,exynosautov920-usbdrd-combo-hsphy
> >        - samsung,exynosautov920-usbdrd-phy
> >
> > @@ -118,6 +119,12 @@ properties:
> >    vdd18-usb20-supply:
> >      description: 1.8V power supply for the USB 2.0 phy.
> >
> > +  dvdd075-usb30-supply:
> > +    description: 0.75V power supply for the USB 3.0 phy.
> > +
> > +  vdd18-usb30-supply:
> > +    description: 1.8V power supply for the USB 3.0 phy.
> > +
> >  required:
> >    - compatible
> >    - clocks
> > @@ -227,6 +234,7 @@ allOf:
> >                - samsung,exynos7870-usbdrd-phy
> >                - samsung,exynos850-usbdrd-phy
> >                - samsung,exynos990-usbdrd-phy
> > +              - samsung,exynosautov920-usb31drd-combo-ssphy
> >                - samsung,exynosautov920-usbdrd-combo-hsphy
> >                - samsung,exynosautov920-usbdrd-phy
> >      then:
> > @@ -262,6 +270,21 @@ allOf:
> >        properties:
> >          dvdd075-usb20-supply: false
> >          vdd18-usb20-supply: false
> > +  - if:
> > +      properties:
> > +        compatible:
> > +          contains:
> > +            enum:
> > +              - samsung,exynosautov920-usb31drd-combo-ssphy
> > +    then:
> > +      required:
> > +        - dvdd075-usb30-supply
> > +        - vdd18-usb30-supply
> 
> Why are you adding usb20 and usb30 suffixes to the supplies? These are
> separate devices, so they do not have both variants at the same time.

This is a combo phy consisting of usb2 and usb3 phys combined. 
To drive these separate phys, added suffixes for these supplies respectively.

Moreover, gs101 is also using similar convention for its usb20 and dp supplies. 
Added suffix for usb2 and usb3 as per our last communication https://lore.kernel.org/linux-phy/6e1c67d2-9bfa-442a-9d53-8c5970a2a9ef at kernel.org/

> 
> From this device point of view, the supply is called dvdd075 or vdd18.
> If you open device datasheet (not SoC datasheet), that's how it will be called,
> most likely.

Yes, Agree. In device datasheet, suffixes are not mentioned, but in our board schematic it is mentioned. 
Let me know your suggestion about adding suffixes?

> 
> Best regards,
> Krzysztof


Thank you.

Regards,
Pritam



From krzk at kernel.org  Tue Aug 26 01:27:51 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 26 Aug 2025 10:27:51 +0200
Subject: [PATCH v2 3/3] PCI: qcom: Restrict port parsing only to pci child
 nodes
In-Reply-To: <20250826-pakala-v2-3-74f1f60676c6@oss.qualcomm.com>
References: <20250826-pakala-v2-0-74f1f60676c6@oss.qualcomm.com>
 <20250826-pakala-v2-3-74f1f60676c6@oss.qualcomm.com>
Message-ID: <4583bf66-737d-4029-8f14-ce6d6a75def6@kernel.org>

On 26/08/2025 07:18, Krishna Chaitanya Chundru wrote:
> The qcom_pcie_parse_ports() function currently iterates over all available
> child nodes of the PCIe controller's device tree node. This can lead to
> attempts to parse unrelated nodes like OPP nodes, resulting in unnecessary
> errors or misconfiguration.
> 
> Restrict the parsing logic to only consider child nodes named "pcie" or
> "pci", which are the expected node names for PCIe ports.
> 
> Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
> ---
>  drivers/pci/controller/dwc/pcie-qcom.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
> index 294babe1816e4d0c2b2343fe22d89af72afcd6cd..5dbdb69fbdd1b9b78a3ebba3cd50d78168f2d595 100644
> --- a/drivers/pci/controller/dwc/pcie-qcom.c
> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> @@ -1740,6 +1740,8 @@ static int qcom_pcie_parse_ports(struct qcom_pcie *pcie)
>  	int ret = -ENOENT;
>  
>  	for_each_available_child_of_node_scoped(dev->of_node, of_port) {
> +		if (!(of_node_name_eq(of_port, "pcie") || of_node_name_eq(of_port, "pci")))


Huh? Where is this ABI documented?

Best regards,
Krzysztof


From krzk at kernel.org  Tue Aug 26 01:28:51 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 26 Aug 2025 10:28:51 +0200
Subject: [PATCH v2 3/3] PCI: qcom: Restrict port parsing only to pci child
 nodes
In-Reply-To: <rurdrz3buvb7paqgjjr7ethzvaeyvylezexcwshpj73xf7yeec@i52bla6r5tx7>
References: <20250826-pakala-v2-0-74f1f60676c6@oss.qualcomm.com>
 <20250826-pakala-v2-3-74f1f60676c6@oss.qualcomm.com>
 <rurdrz3buvb7paqgjjr7ethzvaeyvylezexcwshpj73xf7yeec@i52bla6r5tx7>
Message-ID: <b7529529-9677-4713-920f-bf36863459ca@kernel.org>

On 26/08/2025 08:17, Manivannan Sadhasivam wrote:
> On Tue, Aug 26, 2025 at 10:48:19AM GMT, Krishna Chaitanya Chundru wrote:
>> The qcom_pcie_parse_ports() function currently iterates over all available
>> child nodes of the PCIe controller's device tree node. This can lead to
>> attempts to parse unrelated nodes like OPP nodes, resulting in unnecessary
>> errors or misconfiguration.
>>
> 
> What errors? Errors you are seeing on your setup or you envision?
> 
>> Restrict the parsing logic to only consider child nodes named "pcie" or
>> "pci", which are the expected node names for PCIe ports.
>>
>> Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
> 
> Since this is a fix, 'Fixes' tag is needed.
> 
>> ---
>>  drivers/pci/controller/dwc/pcie-qcom.c | 2 ++
>>  1 file changed, 2 insertions(+)
>>
>> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
>> index 294babe1816e4d0c2b2343fe22d89af72afcd6cd..5dbdb69fbdd1b9b78a3ebba3cd50d78168f2d595 100644
>> --- a/drivers/pci/controller/dwc/pcie-qcom.c
>> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
>> @@ -1740,6 +1740,8 @@ static int qcom_pcie_parse_ports(struct qcom_pcie *pcie)
>>  	int ret = -ENOENT;
>>  
>>  	for_each_available_child_of_node_scoped(dev->of_node, of_port) {
>> +		if (!(of_node_name_eq(of_port, "pcie") || of_node_name_eq(of_port, "pci")))
> 
> May I know which platform has 'pci' as the node name for the bridge node? AFAIK,
> all platforms defining bridge nodes have 'pcie' as the node name.

It does not matter. If I name my node name as "pc" it stops working?

No, Qualcomm cannot introduce such hidden ABI.
Best regards,
Krzysztof


From krzk at kernel.org  Tue Aug 26 01:32:34 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 26 Aug 2025 10:32:34 +0200
Subject: [PATCH v2 3/3] PCI: qcom: Restrict port parsing only to pci child
 nodes
In-Reply-To: <4583bf66-737d-4029-8f14-ce6d6a75def6@kernel.org>
References: <20250826-pakala-v2-0-74f1f60676c6@oss.qualcomm.com>
 <20250826-pakala-v2-3-74f1f60676c6@oss.qualcomm.com>
 <4583bf66-737d-4029-8f14-ce6d6a75def6@kernel.org>
Message-ID: <0c732ac6-2d1a-4341-94d4-dc6734bfb959@kernel.org>

On 26/08/2025 10:27, Krzysztof Kozlowski wrote:
> On 26/08/2025 07:18, Krishna Chaitanya Chundru wrote:
>> The qcom_pcie_parse_ports() function currently iterates over all available
>> child nodes of the PCIe controller's device tree node. This can lead to
>> attempts to parse unrelated nodes like OPP nodes, resulting in unnecessary
>> errors or misconfiguration.
>>
>> Restrict the parsing logic to only consider child nodes named "pcie" or
>> "pci", which are the expected node names for PCIe ports.
>>
>> Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
>> ---
>>  drivers/pci/controller/dwc/pcie-qcom.c | 2 ++
>>  1 file changed, 2 insertions(+)
>>
>> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
>> index 294babe1816e4d0c2b2343fe22d89af72afcd6cd..5dbdb69fbdd1b9b78a3ebba3cd50d78168f2d595 100644
>> --- a/drivers/pci/controller/dwc/pcie-qcom.c
>> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
>> @@ -1740,6 +1740,8 @@ static int qcom_pcie_parse_ports(struct qcom_pcie *pcie)
>>  	int ret = -ENOENT;
>>  
>>  	for_each_available_child_of_node_scoped(dev->of_node, of_port) {
>> +		if (!(of_node_name_eq(of_port, "pcie") || of_node_name_eq(of_port, "pci")))
> 
> 
> Huh? Where is this ABI documented?

I see it actually might be documented, but you did not mention it at
all. I doubt you even checked.

Please reference exactly where is the ABI, so reviewing will be easier.

I still think though that it is wrong - we don't want device node names
to be the ABI if we already have compatibles and the children here
should have them, right?
Best regards,
Krzysztof


From krzk at kernel.org  Tue Aug 26 01:35:19 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 26 Aug 2025 10:35:19 +0200
Subject: [PATCH v7 5/6] dt-bindings: phy: samsung,usb3-drd-phy: add
 ExynosAutov920 combo ssphy
In-Reply-To: <007501dc1653$e36c3b50$aa44b1f0$@samsung.com>
References: <20250822093845.1179395-1-pritam.sutar@samsung.com>
 <CGME20250822093022epcas5p42d8c16c851769dab0e1da9d45743ab1f@epcas5p4.samsung.com>
 <20250822093845.1179395-6-pritam.sutar@samsung.com>
 <20250824-rough-fresh-orangutan-eecb2f@kuoka>
 <007501dc1653$e36c3b50$aa44b1f0$@samsung.com>
Message-ID: <83dc9435-5850-425d-b345-52e84ef9262c@kernel.org>

On 26/08/2025 08:37, Pritam Manohar Sutar wrote:
> Hi Krzysztof, 
> 
>> -----Original Message-----
>> From: Krzysztof Kozlowski <krzk at kernel.org>
>> Sent: 24 August 2025 02:26 PM
>> To: Pritam Manohar Sutar <pritam.sutar at samsung.com>
>> Cc: vkoul at kernel.org; kishon at kernel.org; robh at kernel.org;
>> krzk+dt at kernel.org; conor+dt at kernel.org; alim.akhtar at samsung.com;
>> andre.draszik at linaro.org; peter.griffin at linaro.org; kauschluss at disroot.org;
>> ivo.ivanov.ivanov1 at gmail.com; igor.belwon at mentallysanemainliners.org;
>> johan at kernel.org; m.szyprowski at samsung.com; s.nawrocki at samsung.com;
>> linux-phy at lists.infradead.org; devicetree at vger.kernel.org; linux-
>> kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-samsung-
>> soc at vger.kernel.org; rosa.pila at samsung.com; dev.tailor at samsung.com;
>> faraz.ata at samsung.com; muhammed.ali at samsung.com;
>> selvarasu.g at samsung.com
>> Subject: Re: [PATCH v7 5/6] dt-bindings: phy: samsung,usb3-drd-phy: add
>> ExynosAutov920 combo ssphy
>>
>> On Fri, Aug 22, 2025 at 03:08:44PM +0530, Pritam Manohar Sutar wrote:
>>> This phy supports USB3.1 SSP+(10Gbps) protocol and is backwards
>>> compatible to the USB3.0 SS(5Gbps). It requires two clocks, named
>>> "phy" and "ref". The required supplies for USB3.1 are named as
>>> vdd075_usb30(0.75v), vdd18_usb30(1.8v).
>>
>> Please do not describe the schema, but hardware. This sentence does not help
>> me in my question further.
> 
> This is a combo phy having Synopsys usb20 and usb30 phys (these 2 phys are totally different). 
> One PHY only supports usb2.0 and data rates whereas another one does usb3.1 ssp+ and usb3.1 ssp
> 	
> This patch only explains about usb30 (since these are two different phys) phy and omitted inclusion of usb20 reference (added separate patch for this patch no 3). 
> 	
> Hope this is clear.

No. That sentence still explains what schema is doing.

BTW, wrap your email correctly.

> 
>>
>>>
>>> Add schemas for combo ssphy found on this SoC.
>>>
>>> Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
>>> ---
>>>  .../bindings/phy/samsung,usb3-drd-phy.yaml    | 23 +++++++++++++++++++
>>>  1 file changed, 23 insertions(+)
>>>
>>> diff --git
>>> a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
>>> b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
>>> index f0cfca5736b8..96e5bbb2e42c 100644
>>> --- a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
>>> +++ b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
>>> @@ -34,6 +34,7 @@ properties:
>>>        - samsung,exynos7870-usbdrd-phy
>>>        - samsung,exynos850-usbdrd-phy
>>>        - samsung,exynos990-usbdrd-phy
>>> +      - samsung,exynosautov920-usb31drd-combo-ssphy
>>>        - samsung,exynosautov920-usbdrd-combo-hsphy
>>>        - samsung,exynosautov920-usbdrd-phy
>>>
>>> @@ -118,6 +119,12 @@ properties:
>>>    vdd18-usb20-supply:
>>>      description: 1.8V power supply for the USB 2.0 phy.
>>>
>>> +  dvdd075-usb30-supply:
>>> +    description: 0.75V power supply for the USB 3.0 phy.
>>> +
>>> +  vdd18-usb30-supply:
>>> +    description: 1.8V power supply for the USB 3.0 phy.
>>> +
>>>  required:
>>>    - compatible
>>>    - clocks
>>> @@ -227,6 +234,7 @@ allOf:
>>>                - samsung,exynos7870-usbdrd-phy
>>>                - samsung,exynos850-usbdrd-phy
>>>                - samsung,exynos990-usbdrd-phy
>>> +              - samsung,exynosautov920-usb31drd-combo-ssphy
>>>                - samsung,exynosautov920-usbdrd-combo-hsphy
>>>                - samsung,exynosautov920-usbdrd-phy
>>>      then:
>>> @@ -262,6 +270,21 @@ allOf:
>>>        properties:
>>>          dvdd075-usb20-supply: false
>>>          vdd18-usb20-supply: false
>>> +  - if:
>>> +      properties:
>>> +        compatible:
>>> +          contains:
>>> +            enum:
>>> +              - samsung,exynosautov920-usb31drd-combo-ssphy
>>> +    then:
>>> +      required:
>>> +        - dvdd075-usb30-supply
>>> +        - vdd18-usb30-supply
>>
>> Why are you adding usb20 and usb30 suffixes to the supplies? These are
>> separate devices, so they do not have both variants at the same time.
> 
> This is a combo phy consisting of usb2 and usb3 phys combined. 
> To drive these separate phys, added suffixes for these supplies respectively.

But they are separate.

> 
> Moreover, gs101 is also using similar convention for its usb20 and dp supplies. 
> Added suffix for usb2 and usb3 as per our last communication https://lore.kernel.org/linux-phy/6e1c67d2-9bfa-442a-9d53-8c5970a2a9ef at kernel.org/

Then please review patches on the list and help to improve them BEFORE
they got merged.

I questioned the suffix there, so I really do not understand why did you
added it.

> 
>>
>> From this device point of view, the supply is called dvdd075 or vdd18.
>> If you open device datasheet (not SoC datasheet), that's how it will be called,
>> most likely.
> 
> Yes, Agree. In device datasheet, suffixes are not mentioned, but in our board schematic it is mentioned. 
> Let me know your suggestion about adding suffixes?

I already said, multiple times on various discussions. You name these
based on how the inputs are called in this device.

Best regards,
Krzysztof


From kathiravan.thirumoorthy at oss.qualcomm.com  Tue Aug 26 01:39:58 2025
From: kathiravan.thirumoorthy at oss.qualcomm.com (Kathiravan Thirumoorthy)
Date: Tue, 26 Aug 2025 14:09:58 +0530
Subject: [PATCH 1/3] phy: qcom-qmp-usb: fix NULL pointer dereference in PM
 callbacks
In-Reply-To: <sxqgnmj4bawj7n6kan7tiutb5ynhxz6cgbtpbz2xx4ixodtdw6@q2ftbnpjouvb>
References: <20250825-qmp-null-deref-on-pm-v1-0-bbd3ca330849@oss.qualcomm.com>
 <20250825-qmp-null-deref-on-pm-v1-1-bbd3ca330849@oss.qualcomm.com>
 <sxqgnmj4bawj7n6kan7tiutb5ynhxz6cgbtpbz2xx4ixodtdw6@q2ftbnpjouvb>
Message-ID: <8753d857-5d72-493b-8c39-8caa84e0ba16@oss.qualcomm.com>


On 8/26/2025 8:20 AM, Bjorn Andersson wrote:
> On Mon, Aug 25, 2025 at 05:22:02PM +0530, Kathiravan Thirumoorthy wrote:
>> From: Poovendhan Selvaraj <quic_poovendh at quicinc.com>
>>
>> The pm ops are enabled before qmp phy create which causes
>> a NULL pointer dereference when accessing qmp->phy->init_count
>> in the qmp_usb_runtime_suspend.
>>
> How does that happen? Do we end up in the error path inbetween the
> devm_pm_runtime_enable()? Or does it happen by some other means?


qmp_usb_probe() is scheduled out per the below stack (collected from the 
RAM dump),


Stack trace of the kmodloader process:
 ? ? [<0x408def88>] __schedule+0x348/0x55c
 ? ? [<0x408df1f8>] schedule+0x5c/0x98
 ? ? [<0x4052c318>] rpm_resume+0x150/0x404
 ? ? [<0x4052d4e4>] pm_runtime_forbid+0x54/0x60
 ? ? [<0x629c47f0>] qmp_usb_probe+0x3c4/0x5d0 [phy_qcom_qmp_usb.ko]

 From the above snippet, we can see that the phy-create has not happened 
yet as the probe is still in pm_runtime_forbid() and qmp->phy is NULL. 
Meanwhile, qmp_usb_runtime_suspend() is called, causing the NULL pointer 
de-reference issue. Since the issue is not easily reproducible, we are 
not able to find out who/why the suspend was called.


>
> This would be quite useful information for others to know if they hit
> the same or just a similar problem.
>
>> So if qmp->phy is NULL, bail out early in suspend / resume callbacks
>> to avoid the NULL pointer dereference in qmp_usb_runtime_suspend and
>> qmp_usb_runtime_resume.
>>
>> Below is the stacktrace for reference:
>>
>> [<818381a0>] (qmp_usb_runtime_suspend [phy_qcom_qmp_usb]) from [<4051d1d8>] (__rpm_callback+0x3c/0x110)
>> [<4051d1d8>] (__rpm_callback) from [<4051d2fc>] (rpm_callback+0x50/0x54)
>> [<4051d2fc>] (rpm_callback) from [<4051d940>] (rpm_suspend+0x23c/0x428)
>> [<4051d940>] (rpm_suspend) from [<4051e808>] (pm_runtime_work+0x74/0x8c)
>> [<4051e808>] (pm_runtime_work) from [<401311f4>] (process_scheduled_works+0x1d0/0x2c8)
>> [<401311f4>] (process_scheduled_works) from [<40131d48>] (worker_thread+0x260/0x2e4)
>> [<40131d48>] (worker_thread) from [<40138970>] (kthread+0x118/0x12c)
>> [<40138970>] (kthread) from [<4010013c>] (ret_from_fork+0x14/0x38)
>>
>> Cc: stable at vger.kernel.org # v6.0
>> Fixes: 65753f38f530 ("phy: qcom-qmp-usb: drop multi-PHY support")
> Has this been a reproducible issue for last 3 years? I think the fixes
> makes sense in that it introduced the indirection, but when did the
> issue actually show up?


After migrating the QSDK Linux from 5.4 to 6.6, we are started seeing 
this issue randomly. We didn't had a chance to test in the other kernel 
versions.


>
> Regards,
> Bjorn
>
>> Signed-off-by: Poovendhan Selvaraj <quic_poovendh at quicinc.com>
>> Signed-off-by: Kathiravan Thirumoorthy <kathiravan.thirumoorthy at oss.qualcomm.com>
>> ---
>>   drivers/phy/qualcomm/phy-qcom-qmp-usb.c | 4 ++--
>>   1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
>> index ed646a7e705ba3259708775ed5fedbbbada13735..cd04e8f22a0fe81b086b308d02713222aa95cae3 100644
>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
>> @@ -1940,7 +1940,7 @@ static int __maybe_unused qmp_usb_runtime_suspend(struct device *dev)
>>   
>>   	dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->mode);
>>   
>> -	if (!qmp->phy->init_count) {
>> +	if (!qmp->phy || !qmp->phy->init_count) {
>>   		dev_vdbg(dev, "PHY not initialized, bailing out\n");
>>   		return 0;
>>   	}
>> @@ -1960,7 +1960,7 @@ static int __maybe_unused qmp_usb_runtime_resume(struct device *dev)
>>   
>>   	dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qmp->mode);
>>   
>> -	if (!qmp->phy->init_count) {
>> +	if (!qmp->phy || !qmp->phy->init_count) {
>>   		dev_vdbg(dev, "PHY not initialized, bailing out\n");
>>   		return 0;
>>   	}
>>
>> -- 
>> 2.34.1
>>


From krishna.chundru at oss.qualcomm.com  Tue Aug 26 02:03:44 2025
From: krishna.chundru at oss.qualcomm.com (Krishna Chaitanya Chundru)
Date: Tue, 26 Aug 2025 14:33:44 +0530
Subject: [PATCH v2 3/3] PCI: qcom: Restrict port parsing only to pci child
 nodes
In-Reply-To: <0c732ac6-2d1a-4341-94d4-dc6734bfb959@kernel.org>
References: <20250826-pakala-v2-0-74f1f60676c6@oss.qualcomm.com>
 <20250826-pakala-v2-3-74f1f60676c6@oss.qualcomm.com>
 <4583bf66-737d-4029-8f14-ce6d6a75def6@kernel.org>
 <0c732ac6-2d1a-4341-94d4-dc6734bfb959@kernel.org>
Message-ID: <e2d23d22-de22-47ee-b715-e7b6c36976b1@oss.qualcomm.com>



On 8/26/2025 2:02 PM, Krzysztof Kozlowski wrote:
> On 26/08/2025 10:27, Krzysztof Kozlowski wrote:
>> On 26/08/2025 07:18, Krishna Chaitanya Chundru wrote:
>>> The qcom_pcie_parse_ports() function currently iterates over all available
>>> child nodes of the PCIe controller's device tree node. This can lead to
>>> attempts to parse unrelated nodes like OPP nodes, resulting in unnecessary
>>> errors or misconfiguration.
>>>
>>> Restrict the parsing logic to only consider child nodes named "pcie" or
>>> "pci", which are the expected node names for PCIe ports.
>>>
>>> Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
>>> ---
>>>   drivers/pci/controller/dwc/pcie-qcom.c | 2 ++
>>>   1 file changed, 2 insertions(+)
>>>
>>> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
>>> index 294babe1816e4d0c2b2343fe22d89af72afcd6cd..5dbdb69fbdd1b9b78a3ebba3cd50d78168f2d595 100644
>>> --- a/drivers/pci/controller/dwc/pcie-qcom.c
>>> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
>>> @@ -1740,6 +1740,8 @@ static int qcom_pcie_parse_ports(struct qcom_pcie *pcie)
>>>   	int ret = -ENOENT;
>>>   
>>>   	for_each_available_child_of_node_scoped(dev->of_node, of_port) {
>>> +		if (!(of_node_name_eq(of_port, "pcie") || of_node_name_eq(of_port, "pci")))
>>
>>
>> Huh? Where is this ABI documented?
> 
> I see it actually might be documented, but you did not mention it at
> all. I doubt you even checked.
> 
> Please reference exactly where is the ABI, so reviewing will be easier.
> 
> I still think though that it is wrong - we don't want device node names
> to be the ABI if we already have compatibles and the children here
> should have them, right?
I intended to check for device_type to be pci, my mistake I went with
the node name, I will update the patch with this logic

if (!of_node_is_type(np, "pci"))
	continue

Thanks for reviewing it.

- Krishna Chaitanya.

> Best regards,
> Krzysztof


From ziyue.zhang at oss.qualcomm.com  Tue Aug 26 02:12:03 2025
From: ziyue.zhang at oss.qualcomm.com (Ziyue Zhang)
Date: Tue, 26 Aug 2025 17:12:03 +0800
Subject: [PATCH v11 3/5] arm64: dts: qcom: qcs8300-ride: enable pcie0 interface
In-Reply-To: <20250826091205.3625138-1-ziyue.zhang@oss.qualcomm.com>
References: <20250826091205.3625138-1-ziyue.zhang@oss.qualcomm.com>
Message-ID: <20250826091205.3625138-4-ziyue.zhang@oss.qualcomm.com>

Add configurations in devicetree for PCIe0, board related gpios,
PMIC regulators, etc for qcs8300-ride board.

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Reviewed-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
Signed-off-by: Ziyue Zhang <ziyue.zhang at oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/qcs8300-ride.dts | 42 +++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts
index 9c37a0f5ba25..9d2653007866 100644
--- a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts
+++ b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts
@@ -309,6 +309,25 @@ &iris {
 	status = "okay";
 };
 
+&pcie0 {
+	pinctrl-0 = <&pcie0_default_state>;
+	pinctrl-names = "default";
+
+	status = "okay";
+};
+
+&pcieport0 {
+	reset-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>;
+	wake-gpios = <&tlmm 0 GPIO_ACTIVE_HIGH>;
+};
+
+&pcie0_phy {
+	vdda-phy-supply = <&vreg_l6a>;
+	vdda-pll-supply = <&vreg_l5a>;
+
+	status = "okay";
+};
+
 &qupv3_id_0 {
 	status = "okay";
 };
@@ -369,6 +388,29 @@ ethernet0_mdio: ethernet0-mdio-pins {
 			bias-pull-up;
 		};
 	};
+
+	pcie0_default_state: pcie0-default-state {
+		wake-pins {
+			pins = "gpio0";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-up;
+		};
+
+		clkreq-pins {
+			pins = "gpio1";
+			function = "pcie0_clkreq";
+			drive-strength = <2>;
+			bias-pull-up;
+		};
+
+		perst-pins {
+			pins = "gpio2";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-down;
+		};
+	};
 };
 
 &uart7 {
-- 
2.43.0



From ziyue.zhang at oss.qualcomm.com  Tue Aug 26 02:12:04 2025
From: ziyue.zhang at oss.qualcomm.com (Ziyue Zhang)
Date: Tue, 26 Aug 2025 17:12:04 +0800
Subject: [PATCH v11 4/5] arm64: dts: qcom: qcs8300: enable pcie1
In-Reply-To: <20250826091205.3625138-1-ziyue.zhang@oss.qualcomm.com>
References: <20250826091205.3625138-1-ziyue.zhang@oss.qualcomm.com>
Message-ID: <20250826091205.3625138-5-ziyue.zhang@oss.qualcomm.com>

Add configurations in devicetree for PCIe1, including registers, clocks,
interrupts and phy setting sequence.

Add PCIe lane equalization preset properties for 8 GT/s and 16GT/s.

Acked-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Ziyue Zhang <ziyue.zhang at oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/qcs8300.dtsi | 131 +++++++++++++++++++++++++-
 1 file changed, 130 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/qcs8300.dtsi b/arch/arm64/boot/dts/qcom/qcs8300.dtsi
index a64890033ef1..3c5d5af1a691 100644
--- a/arch/arm64/boot/dts/qcom/qcs8300.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcs8300.dtsi
@@ -903,7 +903,7 @@ gcc: clock-controller at 100000 {
 			clocks = <&rpmhcc RPMH_CXO_CLK>,
 				 <&sleep_clk>,
 				 <&pcie0_phy>,
-				 <0>,
+				 <&pcie1_phy>,
 				 <0>,
 				 <0>,
 				 <0>,
@@ -2426,6 +2426,135 @@ pcie0_phy: phy at 1c04000 {
 			status = "disabled";
 		};
 
+		pcie1: pci at 1c10000 {
+			device_type = "pci";
+			compatible = "qcom,pcie-qcs8300", "qcom,pcie-sa8775p";
+			reg = <0x0 0x01c10000 0x0 0x3000>,
+			      <0x0 0x60000000 0x0 0xf20>,
+			      <0x0 0x60000f20 0x0 0xa8>,
+			      <0x0 0x60001000 0x0 0x4000>,
+			      <0x0 0x60100000 0x0 0x100000>,
+			      <0x0 0x01c13000 0x0 0x1000>;
+			reg-names = "parf",
+				    "dbi",
+				    "elbi",
+				    "atu",
+				    "config",
+				    "mhi";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			ranges = <0x01000000 0x0 0x00000000 0x0 0x60200000 0x0 0x100000>,
+				 <0x02000000 0x0 0x60300000 0x0 0x60300000 0x0 0x1fd00000>;
+			bus-range = <0x00 0xff>;
+
+			dma-coherent;
+
+			linux,pci-domain = <1>;
+			num-lanes = <4>;
+
+			interrupts = <GIC_SPI 519 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 518 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 GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 2 &intc GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 3 &intc GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 4 &intc GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
+
+			clocks = <&gcc GCC_PCIE_1_AUX_CLK>,
+				 <&gcc GCC_PCIE_1_CFG_AHB_CLK>,
+				 <&gcc GCC_PCIE_1_MSTR_AXI_CLK>,
+				 <&gcc GCC_PCIE_1_SLV_AXI_CLK>,
+				 <&gcc GCC_PCIE_1_SLV_Q2A_AXI_CLK>;
+			clock-names = "aux",
+				      "cfg",
+				      "bus_master",
+				      "bus_slave",
+				      "slave_q2a";
+
+			assigned-clocks = <&gcc GCC_PCIE_1_AUX_CLK>;
+			assigned-clock-rates = <19200000>;
+
+			interconnects = <&pcie_anoc MASTER_PCIE_1 QCOM_ICC_TAG_ALWAYS
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+					<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &config_noc SLAVE_PCIE_1 QCOM_ICC_TAG_ACTIVE_ONLY>;
+			interconnect-names = "pcie-mem", "cpu-pcie";
+
+			iommu-map = <0x0 &pcie_smmu 0x0080 0x1>,
+				    <0x100 &pcie_smmu 0x0081 0x1>;
+
+			resets = <&gcc GCC_PCIE_1_BCR>,
+				 <&gcc GCC_PCIE_1_LINK_DOWN_BCR>;
+			reset-names = "pci",
+				      "link_down";
+
+			power-domains = <&gcc GCC_PCIE_1_GDSC>;
+
+			eq-presets-8gts = /bits/ 16 <0x5555 0x5555 0x5555 0x5555>;
+			eq-presets-16gts = /bits/ 8 <0x55 0x55 0x55 0x55>;
+
+			status = "disabled";
+
+			pcieport1: pcie at 0 {
+				device_type = "pci";
+				reg = <0x0 0x0 0x0 0x0 0x0>;
+				bus-range = <0x01 0xff>;
+
+				#address-cells = <3>;
+				#size-cells = <2>;
+				ranges;
+				phys = <&pcie1_phy>;
+			};
+		};
+
+		pcie1_phy: phy at 1c14000 {
+			compatible = "qcom,sa8775p-qmp-gen4x4-pcie-phy";
+			reg = <0x0 0x01c14000 0x0 0x4000>;
+
+			clocks = <&gcc GCC_PCIE_1_PHY_AUX_CLK>,
+				 <&gcc GCC_PCIE_1_CFG_AHB_CLK>,
+				 <&gcc GCC_PCIE_CLKREF_EN>,
+				 <&gcc GCC_PCIE_1_PHY_RCHNG_CLK>,
+				 <&gcc GCC_PCIE_1_PIPE_CLK>,
+				 <&gcc GCC_PCIE_1_PIPEDIV2_CLK>;
+			clock-names = "aux",
+				      "cfg_ahb",
+				      "ref",
+				      "rchng",
+				      "pipe",
+				      "pipediv2";
+
+			assigned-clocks = <&gcc GCC_PCIE_1_PHY_RCHNG_CLK>;
+			assigned-clock-rates = <100000000>;
+
+			resets = <&gcc GCC_PCIE_1_PHY_BCR>;
+			reset-names = "phy";
+
+			#clock-cells = <0>;
+			clock-output-names = "pcie_1_pipe_clk";
+
+			#phy-cells = <0>;
+
+			status = "disabled";
+		};
+
 		ufs_mem_hc: ufs at 1d84000 {
 			compatible = "qcom,qcs8300-ufshc", "qcom,ufshc", "jedec,ufs-2.0";
 			reg = <0x0 0x01d84000 0x0 0x3000>;
-- 
2.43.0



From ziyue.zhang at oss.qualcomm.com  Tue Aug 26 02:12:02 2025
From: ziyue.zhang at oss.qualcomm.com (Ziyue Zhang)
Date: Tue, 26 Aug 2025 17:12:02 +0800
Subject: [PATCH v11 2/5] arm64: dts: qcom: qcs8300: enable pcie0
In-Reply-To: <20250826091205.3625138-1-ziyue.zhang@oss.qualcomm.com>
References: <20250826091205.3625138-1-ziyue.zhang@oss.qualcomm.com>
Message-ID: <20250826091205.3625138-3-ziyue.zhang@oss.qualcomm.com>

Add configurations in devicetree for PCIe0, including registers, clocks,
interrupts and phy setting sequence.

Add PCIe lane equalization preset properties for 8 GT/s and 16GT/s

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Reviewed-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
Signed-off-by: Ziyue Zhang <ziyue.zhang at oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/qcs8300.dtsi | 179 +++++++++++++++++++++++++-
 1 file changed, 178 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/qcs8300.dtsi b/arch/arm64/boot/dts/qcom/qcs8300.dtsi
index 5edb137d1471..a64890033ef1 100644
--- a/arch/arm64/boot/dts/qcom/qcs8300.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcs8300.dtsi
@@ -902,7 +902,7 @@ gcc: clock-controller at 100000 {
 			#power-domain-cells = <1>;
 			clocks = <&rpmhcc RPMH_CXO_CLK>,
 				 <&sleep_clk>,
-				 <0>,
+				 <&pcie0_phy>,
 				 <0>,
 				 <0>,
 				 <0>,
@@ -2249,6 +2249,183 @@ mmss_noc: interconnect at 17a0000 {
 			qcom,bcm-voters = <&apps_bcm_voter>;
 		};
 
+		pcie0: pci at 1c00000 {
+			device_type = "pci";
+			compatible = "qcom,pcie-qcs8300", "qcom,pcie-sa8775p";
+			reg = <0x0 0x01c00000 0x0 0x3000>,
+			      <0x0 0x40000000 0x0 0xf20>,
+			      <0x0 0x40000f20 0x0 0xa8>,
+			      <0x0 0x40001000 0x0 0x4000>,
+			      <0x0 0x40100000 0x0 0x100000>,
+			      <0x0 0x01c03000 0x0 0x1000>;
+			reg-names = "parf",
+				    "dbi",
+				    "elbi",
+				    "atu",
+				    "config",
+				    "mhi";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			ranges = <0x01000000 0x0 0x00000000 0x0 0x40200000 0x0 0x100000>,
+				 <0x02000000 0x0 0x40300000 0x0 0x40300000 0x0 0x1fd00000>;
+			bus-range = <0x00 0xff>;
+
+			dma-coherent;
+
+			linux,pci-domain = <0>;
+			num-lanes = <2>;
+
+			interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 306 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 GIC_SPI 434 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 2 &intc GIC_SPI 435 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 3 &intc GIC_SPI 438 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 4 &intc GIC_SPI 439 IRQ_TYPE_LEVEL_HIGH>;
+
+			clocks = <&gcc GCC_PCIE_0_AUX_CLK>,
+				 <&gcc GCC_PCIE_0_CFG_AHB_CLK>,
+				 <&gcc GCC_PCIE_0_MSTR_AXI_CLK>,
+				 <&gcc GCC_PCIE_0_SLV_AXI_CLK>,
+				 <&gcc GCC_PCIE_0_SLV_Q2A_AXI_CLK>;
+			clock-names = "aux",
+				      "cfg",
+				      "bus_master",
+				      "bus_slave",
+				      "slave_q2a";
+
+			assigned-clocks = <&gcc GCC_PCIE_0_AUX_CLK>;
+			assigned-clock-rates = <19200000>;
+
+			interconnects = <&pcie_anoc MASTER_PCIE_0 QCOM_ICC_TAG_ALWAYS
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+					<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &config_noc SLAVE_PCIE_0 QCOM_ICC_TAG_ACTIVE_ONLY>;
+			interconnect-names = "pcie-mem",
+					     "cpu-pcie";
+
+			iommu-map = <0x0 &pcie_smmu 0x0000 0x1>,
+				    <0x100 &pcie_smmu 0x0001 0x1>;
+
+			resets = <&gcc GCC_PCIE_0_BCR>,
+				 <&gcc GCC_PCIE_0_LINK_DOWN_BCR>;
+			reset-names = "pci",
+				      "link_down";
+
+			power-domains = <&gcc GCC_PCIE_0_GDSC>;
+
+			eq-presets-8gts = /bits/ 16 <0x5555 0x5555>;
+			eq-presets-16gts = /bits/ 8 <0x55 0x55>;
+
+			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_svs_l1>;
+					opp-peak-kBps = <250000 1>;
+				};
+
+				/* GEN 1 x2 and GEN 2 x1 */
+				opp-5000000 {
+					opp-hz = /bits/ 64 <5000000>;
+					required-opps = <&rpmhpd_opp_svs_l1>;
+					opp-peak-kBps = <500000 1>;
+				};
+
+				/* GEN 2 x2 */
+				opp-10000000 {
+					opp-hz = /bits/ 64 <10000000>;
+					required-opps = <&rpmhpd_opp_svs_l1>;
+					opp-peak-kBps = <1000000 1>;
+				};
+
+				/* GEN 3 x1 */
+				opp-8000000 {
+					opp-hz = /bits/ 64 <8000000>;
+					required-opps = <&rpmhpd_opp_svs_l1>;
+					opp-peak-kBps = <984500 1>;
+				};
+
+				/* GEN 3 x2 and GEN 4 x1 */
+				opp-16000000 {
+					opp-hz = /bits/ 64 <16000000>;
+					required-opps = <&rpmhpd_opp_nom>;
+					opp-peak-kBps = <1969000 1>;
+				};
+
+				/* GEN 4 x2 */
+				opp-32000000 {
+					opp-hz = /bits/ 64 <32000000>;
+					required-opps = <&rpmhpd_opp_nom>;
+					opp-peak-kBps = <3938000 1>;
+				};
+			};
+
+			pcieport0: pcie at 0 {
+				device_type = "pci";
+				reg = <0x0 0x0 0x0 0x0 0x0>;
+				bus-range = <0x01 0xff>;
+
+				#address-cells = <3>;
+				#size-cells = <2>;
+				ranges;
+				phys = <&pcie0_phy>;
+			};
+		};
+
+		pcie0_phy: phy at 1c04000 {
+			compatible = "qcom,qcs8300-qmp-gen4x2-pcie-phy";
+			reg = <0x0 0x01c04000 0x0 0x2000>;
+
+			clocks = <&gcc GCC_PCIE_0_PHY_AUX_CLK>,
+				 <&gcc GCC_PCIE_0_CFG_AHB_CLK>,
+				 <&gcc GCC_PCIE_CLKREF_EN>,
+				 <&gcc GCC_PCIE_0_PHY_RCHNG_CLK>,
+				 <&gcc GCC_PCIE_0_PIPE_CLK>,
+				 <&gcc GCC_PCIE_0_PIPEDIV2_CLK>;
+			clock-names = "aux",
+				      "cfg_ahb",
+				      "ref",
+				      "rchng",
+				      "pipe",
+				      "pipediv2";
+
+			resets = <&gcc GCC_PCIE_0_PHY_BCR>;
+			reset-names = "phy";
+
+			assigned-clocks = <&gcc GCC_PCIE_0_PHY_RCHNG_CLK>;
+			assigned-clock-rates = <100000000>;
+
+			#clock-cells = <0>;
+			clock-output-names = "pcie_0_pipe_clk";
+
+			#phy-cells = <0>;
+
+			status = "disabled";
+		};
+
 		ufs_mem_hc: ufs at 1d84000 {
 			compatible = "qcom,qcs8300-ufshc", "qcom,ufshc", "jedec,ufs-2.0";
 			reg = <0x0 0x01d84000 0x0 0x3000>;
-- 
2.43.0



From ziyue.zhang at oss.qualcomm.com  Tue Aug 26 02:12:01 2025
From: ziyue.zhang at oss.qualcomm.com (Ziyue Zhang)
Date: Tue, 26 Aug 2025 17:12:01 +0800
Subject: [PATCH v11 1/5] dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Update pcie phy bindings for qcs8300
In-Reply-To: <20250826091205.3625138-1-ziyue.zhang@oss.qualcomm.com>
References: <20250826091205.3625138-1-ziyue.zhang@oss.qualcomm.com>
Message-ID: <20250826091205.3625138-2-ziyue.zhang@oss.qualcomm.com>

The gcc_aux_clk is not required by the PCIe PHY on qcs8300 and is not
specified in the device tree node. Hence, move the qcs8300 phy
compatibility entry into the list of PHYs that require six clocks.

Removed the phy_aux clock from the PCIe PHY binding as it is no longer
used by any instance.

Fixes: e46e59b77a9e ("dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Document the QCS8300 QMP PCIe PHY Gen4 x2")

Signed-off-by: Ziyue Zhang <ziyue.zhang at oss.qualcomm.com>
Acked-by: Rob Herring (Arm) <robh at kernel.org>
Reviewed-by: Johan Hovold <johan+linaro at kernel.org>
---
 .../phy/qcom,sc8280xp-qmp-pcie-phy.yaml         | 17 ++---------------
 1 file changed, 2 insertions(+), 15 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 119b4ff36dbd..d94d08752cec 100644
--- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
@@ -55,7 +55,7 @@ properties:
 
   clocks:
     minItems: 5
-    maxItems: 7
+    maxItems: 6
 
   clock-names:
     minItems: 5
@@ -66,7 +66,6 @@ properties:
       - enum: [rchng, refgen]
       - const: pipe
       - const: pipediv2
-      - const: phy_aux
 
   power-domains:
     maxItems: 1
@@ -178,6 +177,7 @@ allOf:
         compatible:
           contains:
             enum:
+              - qcom,qcs8300-qmp-gen4x2-pcie-phy
               - qcom,sa8775p-qmp-gen4x2-pcie-phy
               - qcom,sa8775p-qmp-gen4x4-pcie-phy
               - qcom,sc8280xp-qmp-gen3x1-pcie-phy
@@ -195,19 +195,6 @@ allOf:
         clock-names:
           minItems: 6
 
-  - if:
-      properties:
-        compatible:
-          contains:
-            enum:
-              - qcom,qcs8300-qmp-gen4x2-pcie-phy
-    then:
-      properties:
-        clocks:
-          minItems: 7
-        clock-names:
-          minItems: 7
-
   - if:
       properties:
         compatible:
-- 
2.43.0



From ziyue.zhang at oss.qualcomm.com  Tue Aug 26 02:12:05 2025
From: ziyue.zhang at oss.qualcomm.com (Ziyue Zhang)
Date: Tue, 26 Aug 2025 17:12:05 +0800
Subject: [PATCH v11 5/5] arm64: dts: qcom: qcs8300-ride: enable pcie1 interface
In-Reply-To: <20250826091205.3625138-1-ziyue.zhang@oss.qualcomm.com>
References: <20250826091205.3625138-1-ziyue.zhang@oss.qualcomm.com>
Message-ID: <20250826091205.3625138-6-ziyue.zhang@oss.qualcomm.com>

Add configurations in devicetree for PCIe1, board related gpios,
PMIC regulators, etc for qcs8300-ride platform.

Reviewed-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
Signed-off-by: Ziyue Zhang <ziyue.zhang at oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/qcs8300-ride.dts | 42 +++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts
index 9d2653007866..51f299fff910 100644
--- a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts
+++ b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts
@@ -328,6 +328,25 @@ &pcie0_phy {
 	status = "okay";
 };
 
+&pcie1 {
+	pinctrl-0 = <&pcie1_default_state>;
+	pinctrl-names = "default";
+
+	status = "okay";
+};
+
+&pcieport1 {
+	reset-gpios = <&tlmm 23 GPIO_ACTIVE_LOW>;
+	wake-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>;
+};
+
+&pcie1_phy {
+	vdda-phy-supply = <&vreg_l6a>;
+	vdda-pll-supply = <&vreg_l5a>;
+
+	status = "okay";
+};
+
 &qupv3_id_0 {
 	status = "okay";
 };
@@ -411,6 +430,29 @@ perst-pins {
 			bias-pull-down;
 		};
 	};
+
+   pcie1_default_state: pcie1-default-state {
+		wake-pins {
+			pins = "gpio21";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-up;
+		};
+
+		clkreq-pins {
+			pins = "gpio22";
+			function = "pcie1_clkreq";
+			drive-strength = <2>;
+			bias-pull-up;
+		};
+
+		perst-pins {
+			pins = "gpio23";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-down;
+		};
+	};
 };
 
 &uart7 {
-- 
2.43.0



From ziyue.zhang at oss.qualcomm.com  Tue Aug 26 02:12:00 2025
From: ziyue.zhang at oss.qualcomm.com (Ziyue Zhang)
Date: Tue, 26 Aug 2025 17:12:00 +0800
Subject: [PATCH v11 0/5] pci: qcom: Add QCS8300 PCIe support
Message-ID: <20250826091205.3625138-1-ziyue.zhang@oss.qualcomm.com>

This series depend on this patch
https://lore.kernel.org/all/20250826-pakala-v2-3-74f1f60676c6 at oss.qualcomm.com/

This series adds document, phy, configs support for PCIe in QCS8300.
It also adds 'link_down' reset for sa8775p.

Have follwing changes:
	- Add dedicated schema for the PCIe controllers found on QCS8300.
	- Add compatible for qcs8300 platform.
	- Add configurations in devicetree for PCIe0, including registers, clocks, interrupts and phy setting sequence.
	- Add configurations in devicetree for PCIe1, including registers, clocks, interrupts and phy setting sequence.

Signed-off-by: Krishna chaitanya chundru <quic_krichai at quicinc.com>
Signed-off-by: Ziyue Zhang <quic_ziyuzhan at quicinc.com>
---
Changes in v11:
- move phy/perst/wake to pcie bridge node (Mani)
- Link to v10: https://lore.kernel.org/all/20250811071131.982983-1-ziyue.zhang at oss.qualcomm.com/

Changes in v10:
- Update PHY max_items (Johan)
- Link to v9: https://lore.kernel.org/all/20250725104037.4054070-1-ziyue.zhang at oss.qualcomm.com/

Changes in v9:
- Fix DTB error (Vinod)
- Link to v8: https://lore.kernel.org/all/20250714081529.3847385-1-ziyue.zhang at oss.qualcomm.com/

Changes in v8:
- rebase sc8280xp-qmp-pcie-phy change to solve conflicts.
- Add Fixes tag to phy change (Johan)
- Link to v7: https://lore.kernel.org/all/20250625092539.762075-1-quic_ziyuzhan at quicinc.com/

Changes in v7:
- rebase qcs8300-ride.dtsi change to solve conflicts.
- Link to v6: https://lore.kernel.org/all/20250529035635.4162149-1-quic_ziyuzhan at quicinc.com/

Changes in v6:
- move the qcs8300 and sa8775p phy compatibility entry into the list of PHYs that require six clocks
- Update QCS8300 and sa8775p phy dt, remove aux clock.
- Fixed compile error found by kernel test robot
- Link to v5: https://lore.kernel.org/all/20250507031019.4080541-1-quic_ziyuzhan at quicinc.com/

Changes in v5:
- Add QCOM PCIe controller version in commit msg (Mani)
- Modify platform dts change subject (Dmitry)
- Fixed compile error found by kernel test robot
- Link to v4: https://lore.kernel.org/linux-phy/20241220055239.2744024-1-quic_ziyuzhan at quicinc.com/

Changes in v4:
- Add received tag
- Fixed compile error found by kernel test robot
- Link to v3: https://lore.kernel.org/lkml/202412211301.bQO6vXpo-lkp at intel.com/T/#mdd63e5be39acbf879218aef91c87b12d4540e0f7

Changes in v3:
- Add received tag(Rob & Dmitry)
- Update pcie_phy in gcc node to soc dtsi(Dmitry & Konrad)
- remove pcieprot0 node(Konrad & Mani)
- Fix format comments(Konrad)
- Update base-commit to tag: next-20241213(Bjorn)
- Corrected of_device_id.data from 1.9.0 to 1.34.0.
- Link to v2: https://lore.kernel.org/all/20241128081056.1361739-1-quic_ziyuzhan at quicinc.com/

Changes in v2:
- Fix some format comments and match the style in x1e80100(Konrad)
- Add global interrupt for PCIe0 and PCIe1(Konrad)
- split the soc dtsi and the platform dts into two changes(Konrad)
- Link to v1: https://lore.kernel.org/all/20241114095409.2682558-1-quic_ziyuzhan at quicinc.com/

Ziyue Zhang (5):
  dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Update pcie phy bindings
    for qcs8300
  arm64: dts: qcom: qcs8300: enable pcie0
  arm64: dts: qcom: qcs8300-ride: enable pcie0 interface
  arm64: dts: qcom: qcs8300: enable pcie1
  arm64: dts: qcom: qcs8300-ride: enable pcie1 interface

 .../phy/qcom,sc8280xp-qmp-pcie-phy.yaml       |  17 +-
 arch/arm64/boot/dts/qcom/qcs8300-ride.dts     |  84 +++++
 arch/arm64/boot/dts/qcom/qcs8300.dtsi         | 310 +++++++++++++++++-
 3 files changed, 394 insertions(+), 17 deletions(-)


base-commit: 6c68f4c0a147c025ae0b25fab688c7c47964a02f
-- 
2.43.0



From mani at kernel.org  Tue Aug 26 02:26:03 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Tue, 26 Aug 2025 14:56:03 +0530
Subject: [PATCH v2 3/3] PCI: qcom: Restrict port parsing only to pci
 child nodes
In-Reply-To: <b7529529-9677-4713-920f-bf36863459ca@kernel.org>
References: <20250826-pakala-v2-0-74f1f60676c6@oss.qualcomm.com>
 <20250826-pakala-v2-3-74f1f60676c6@oss.qualcomm.com>
 <rurdrz3buvb7paqgjjr7ethzvaeyvylezexcwshpj73xf7yeec@i52bla6r5tx7>
 <b7529529-9677-4713-920f-bf36863459ca@kernel.org>
Message-ID: <p6yacm6hkhp4rgtl2xn677kek24ksczvtuersxnou4kmxmp7go@tmoy7gn4hrhx>

On Tue, Aug 26, 2025 at 10:28:51AM GMT, Krzysztof Kozlowski wrote:
> On 26/08/2025 08:17, Manivannan Sadhasivam wrote:
> > On Tue, Aug 26, 2025 at 10:48:19AM GMT, Krishna Chaitanya Chundru wrote:
> >> The qcom_pcie_parse_ports() function currently iterates over all available
> >> child nodes of the PCIe controller's device tree node. This can lead to
> >> attempts to parse unrelated nodes like OPP nodes, resulting in unnecessary
> >> errors or misconfiguration.
> >>
> > 
> > What errors? Errors you are seeing on your setup or you envision?
> > 
> >> Restrict the parsing logic to only consider child nodes named "pcie" or
> >> "pci", which are the expected node names for PCIe ports.
> >>
> >> Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
> > 
> > Since this is a fix, 'Fixes' tag is needed.
> > 
> >> ---
> >>  drivers/pci/controller/dwc/pcie-qcom.c | 2 ++
> >>  1 file changed, 2 insertions(+)
> >>
> >> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
> >> index 294babe1816e4d0c2b2343fe22d89af72afcd6cd..5dbdb69fbdd1b9b78a3ebba3cd50d78168f2d595 100644
> >> --- a/drivers/pci/controller/dwc/pcie-qcom.c
> >> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> >> @@ -1740,6 +1740,8 @@ static int qcom_pcie_parse_ports(struct qcom_pcie *pcie)
> >>  	int ret = -ENOENT;
> >>  
> >>  	for_each_available_child_of_node_scoped(dev->of_node, of_port) {
> >> +		if (!(of_node_name_eq(of_port, "pcie") || of_node_name_eq(of_port, "pci")))
> > 
> > May I know which platform has 'pci' as the node name for the bridge node? AFAIK,
> > all platforms defining bridge nodes have 'pcie' as the node name.
> 
> It does not matter. If I name my node name as "pc" it stops working?
> 
> No, Qualcomm cannot introduce such hidden ABI.

There is no hidden ABI that Qcom is introducing. We are just trying to reuse the
standard node names documented in the devicetree spec. So you are saying that
we should not rely on it even though it is documented? Maybe because, the dt
tooling is not yet screaming if people put non-standard names in DT?

- Mani

-- 
????????? ????????


From mani at kernel.org  Tue Aug 26 02:28:31 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Tue, 26 Aug 2025 14:58:31 +0530
Subject: [PATCH v2 3/3] PCI: qcom: Restrict port parsing only to pci
 child nodes
In-Reply-To: <e2d23d22-de22-47ee-b715-e7b6c36976b1@oss.qualcomm.com>
References: <20250826-pakala-v2-0-74f1f60676c6@oss.qualcomm.com>
 <20250826-pakala-v2-3-74f1f60676c6@oss.qualcomm.com>
 <4583bf66-737d-4029-8f14-ce6d6a75def6@kernel.org>
 <0c732ac6-2d1a-4341-94d4-dc6734bfb959@kernel.org>
 <e2d23d22-de22-47ee-b715-e7b6c36976b1@oss.qualcomm.com>
Message-ID: <3ah45g7o3vaswanur7id3ypii3773scg3x46wrkxet3jywnyhi@l2za3z3su624>

On Tue, Aug 26, 2025 at 02:33:44PM GMT, Krishna Chaitanya Chundru wrote:
> 
> 
> On 8/26/2025 2:02 PM, Krzysztof Kozlowski wrote:
> > On 26/08/2025 10:27, Krzysztof Kozlowski wrote:
> > > On 26/08/2025 07:18, Krishna Chaitanya Chundru wrote:
> > > > The qcom_pcie_parse_ports() function currently iterates over all available
> > > > child nodes of the PCIe controller's device tree node. This can lead to
> > > > attempts to parse unrelated nodes like OPP nodes, resulting in unnecessary
> > > > errors or misconfiguration.
> > > > 
> > > > Restrict the parsing logic to only consider child nodes named "pcie" or
> > > > "pci", which are the expected node names for PCIe ports.
> > > > 
> > > > Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
> > > > ---
> > > >   drivers/pci/controller/dwc/pcie-qcom.c | 2 ++
> > > >   1 file changed, 2 insertions(+)
> > > > 
> > > > diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
> > > > index 294babe1816e4d0c2b2343fe22d89af72afcd6cd..5dbdb69fbdd1b9b78a3ebba3cd50d78168f2d595 100644
> > > > --- a/drivers/pci/controller/dwc/pcie-qcom.c
> > > > +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> > > > @@ -1740,6 +1740,8 @@ static int qcom_pcie_parse_ports(struct qcom_pcie *pcie)
> > > >   	int ret = -ENOENT;
> > > >   	for_each_available_child_of_node_scoped(dev->of_node, of_port) {
> > > > +		if (!(of_node_name_eq(of_port, "pcie") || of_node_name_eq(of_port, "pci")))
> > > 
> > > 
> > > Huh? Where is this ABI documented?
> > 
> > I see it actually might be documented, but you did not mention it at
> > all. I doubt you even checked.
> > 
> > Please reference exactly where is the ABI, so reviewing will be easier.
> > 
> > I still think though that it is wrong - we don't want device node names
> > to be the ABI if we already have compatibles and the children here
> > should have them, right?
> I intended to check for device_type to be pci, my mistake I went with
> the node name, I will update the patch with this logic
> 
> if (!of_node_is_type(np, "pci"))
> 	continue
> 

Yes, we can rely on it as it is a required property for PCI bridge nodes.

- Mani

-- 
????????? ????????


From krzk at kernel.org  Tue Aug 26 02:29:37 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 26 Aug 2025 11:29:37 +0200
Subject: [PATCH v2 3/3] PCI: qcom: Restrict port parsing only to pci child
 nodes
In-Reply-To: <p6yacm6hkhp4rgtl2xn677kek24ksczvtuersxnou4kmxmp7go@tmoy7gn4hrhx>
References: <20250826-pakala-v2-0-74f1f60676c6@oss.qualcomm.com>
 <20250826-pakala-v2-3-74f1f60676c6@oss.qualcomm.com>
 <rurdrz3buvb7paqgjjr7ethzvaeyvylezexcwshpj73xf7yeec@i52bla6r5tx7>
 <b7529529-9677-4713-920f-bf36863459ca@kernel.org>
 <p6yacm6hkhp4rgtl2xn677kek24ksczvtuersxnou4kmxmp7go@tmoy7gn4hrhx>
Message-ID: <dfd9cc8b-8103-4fa9-8b3b-c31ae7c4970a@kernel.org>

On 26/08/2025 11:26, Manivannan Sadhasivam wrote:
> On Tue, Aug 26, 2025 at 10:28:51AM GMT, Krzysztof Kozlowski wrote:
>> On 26/08/2025 08:17, Manivannan Sadhasivam wrote:
>>> On Tue, Aug 26, 2025 at 10:48:19AM GMT, Krishna Chaitanya Chundru wrote:
>>>> The qcom_pcie_parse_ports() function currently iterates over all available
>>>> child nodes of the PCIe controller's device tree node. This can lead to
>>>> attempts to parse unrelated nodes like OPP nodes, resulting in unnecessary
>>>> errors or misconfiguration.
>>>>
>>>
>>> What errors? Errors you are seeing on your setup or you envision?
>>>
>>>> Restrict the parsing logic to only consider child nodes named "pcie" or
>>>> "pci", which are the expected node names for PCIe ports.
>>>>
>>>> Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
>>>
>>> Since this is a fix, 'Fixes' tag is needed.
>>>
>>>> ---
>>>>  drivers/pci/controller/dwc/pcie-qcom.c | 2 ++
>>>>  1 file changed, 2 insertions(+)
>>>>
>>>> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
>>>> index 294babe1816e4d0c2b2343fe22d89af72afcd6cd..5dbdb69fbdd1b9b78a3ebba3cd50d78168f2d595 100644
>>>> --- a/drivers/pci/controller/dwc/pcie-qcom.c
>>>> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
>>>> @@ -1740,6 +1740,8 @@ static int qcom_pcie_parse_ports(struct qcom_pcie *pcie)
>>>>  	int ret = -ENOENT;
>>>>  
>>>>  	for_each_available_child_of_node_scoped(dev->of_node, of_port) {
>>>> +		if (!(of_node_name_eq(of_port, "pcie") || of_node_name_eq(of_port, "pci")))
>>>
>>> May I know which platform has 'pci' as the node name for the bridge node? AFAIK,
>>> all platforms defining bridge nodes have 'pcie' as the node name.
>>
>> It does not matter. If I name my node name as "pc" it stops working?
>>
>> No, Qualcomm cannot introduce such hidden ABI.
> 
> There is no hidden ABI that Qcom is introducing. We are just trying to reuse the
> standard node names documented in the devicetree spec. So you are saying that
> we should not rely on it even though it is documented? Maybe because, the dt
> tooling is not yet screaming if people put non-standard names in DT?
> 

If it is documented, you can use it, but I doubted first the author even
checked that. Otherwise commit message would say that.

As I mentioned in other response, I still find it discouraged pattern if
you have (and you do have!) compatibles.


Best regards,
Krzysztof


From mani at kernel.org  Tue Aug 26 03:20:07 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Tue, 26 Aug 2025 15:50:07 +0530
Subject: [PATCH v2 3/3] PCI: qcom: Restrict port parsing only to pci
 child nodes
In-Reply-To: <dfd9cc8b-8103-4fa9-8b3b-c31ae7c4970a@kernel.org>
References: <20250826-pakala-v2-0-74f1f60676c6@oss.qualcomm.com>
 <20250826-pakala-v2-3-74f1f60676c6@oss.qualcomm.com>
 <rurdrz3buvb7paqgjjr7ethzvaeyvylezexcwshpj73xf7yeec@i52bla6r5tx7>
 <b7529529-9677-4713-920f-bf36863459ca@kernel.org>
 <p6yacm6hkhp4rgtl2xn677kek24ksczvtuersxnou4kmxmp7go@tmoy7gn4hrhx>
 <dfd9cc8b-8103-4fa9-8b3b-c31ae7c4970a@kernel.org>
Message-ID: <ei7qtgj7jegwaafrjdccoaz3tg7klnms4dyiqdumwxdvnucp4c@euose4y6vkqg>

On Tue, Aug 26, 2025 at 11:29:37AM GMT, Krzysztof Kozlowski wrote:
> On 26/08/2025 11:26, Manivannan Sadhasivam wrote:
> > On Tue, Aug 26, 2025 at 10:28:51AM GMT, Krzysztof Kozlowski wrote:
> >> On 26/08/2025 08:17, Manivannan Sadhasivam wrote:
> >>> On Tue, Aug 26, 2025 at 10:48:19AM GMT, Krishna Chaitanya Chundru wrote:
> >>>> The qcom_pcie_parse_ports() function currently iterates over all available
> >>>> child nodes of the PCIe controller's device tree node. This can lead to
> >>>> attempts to parse unrelated nodes like OPP nodes, resulting in unnecessary
> >>>> errors or misconfiguration.
> >>>>
> >>>
> >>> What errors? Errors you are seeing on your setup or you envision?
> >>>
> >>>> Restrict the parsing logic to only consider child nodes named "pcie" or
> >>>> "pci", which are the expected node names for PCIe ports.
> >>>>
> >>>> Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
> >>>
> >>> Since this is a fix, 'Fixes' tag is needed.
> >>>
> >>>> ---
> >>>>  drivers/pci/controller/dwc/pcie-qcom.c | 2 ++
> >>>>  1 file changed, 2 insertions(+)
> >>>>
> >>>> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
> >>>> index 294babe1816e4d0c2b2343fe22d89af72afcd6cd..5dbdb69fbdd1b9b78a3ebba3cd50d78168f2d595 100644
> >>>> --- a/drivers/pci/controller/dwc/pcie-qcom.c
> >>>> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> >>>> @@ -1740,6 +1740,8 @@ static int qcom_pcie_parse_ports(struct qcom_pcie *pcie)
> >>>>  	int ret = -ENOENT;
> >>>>  
> >>>>  	for_each_available_child_of_node_scoped(dev->of_node, of_port) {
> >>>> +		if (!(of_node_name_eq(of_port, "pcie") || of_node_name_eq(of_port, "pci")))
> >>>
> >>> May I know which platform has 'pci' as the node name for the bridge node? AFAIK,
> >>> all platforms defining bridge nodes have 'pcie' as the node name.
> >>
> >> It does not matter. If I name my node name as "pc" it stops working?
> >>
> >> No, Qualcomm cannot introduce such hidden ABI.
> > 
> > There is no hidden ABI that Qcom is introducing. We are just trying to reuse the
> > standard node names documented in the devicetree spec. So you are saying that
> > we should not rely on it even though it is documented? Maybe because, the dt
> > tooling is not yet screaming if people put non-standard names in DT?
> > 
> 
> If it is documented, you can use it, but I doubted first the author even
> checked that. Otherwise commit message would say that.
> 
> As I mentioned in other response, I still find it discouraged pattern if
> you have (and you do have!) compatibles.
> 

Compatibles for the PCI bridges are not mandatory, so we cannot use it. But
'device_type' is and Krishna is going to use that instead.

- Mani

-- 
????????? ????????


From prashanth.k at oss.qualcomm.com  Tue Aug 26 03:52:54 2025
From: prashanth.k at oss.qualcomm.com (Prashanth K)
Date: Tue, 26 Aug 2025 16:22:54 +0530
Subject: [PATCH] phy: qcom: m31-eusb2: Fix the error log while enabling clock
Message-ID: <20250826105254.3758803-1-prashanth.k@oss.qualcomm.com>

While enabling clock, we incorrectly log 'ref clk' as 'cfg ahb clk'
Fix this since the devicetree bindings mentions it as ref clock.

Signed-off-by: Prashanth K <prashanth.k at oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-m31-eusb2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-m31-eusb2.c b/drivers/phy/qualcomm/phy-qcom-m31-eusb2.c
index bf32572566c4..0a0d2d9fc846 100644
--- a/drivers/phy/qualcomm/phy-qcom-m31-eusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-m31-eusb2.c
@@ -196,7 +196,7 @@ static int m31eusb2_phy_init(struct phy *uphy)
 
 	ret = clk_prepare_enable(phy->clk);
 	if (ret) {
-		dev_err(&uphy->dev, "failed to enable cfg ahb clock, %d\n", ret);
+		dev_err(&uphy->dev, "failed to enable ref clock, %d\n", ret);
 		goto disable_repeater;
 	}
 
-- 
2.25.1



From krishna.chundru at oss.qualcomm.com  Tue Aug 26 04:02:52 2025
From: krishna.chundru at oss.qualcomm.com (Krishna Chaitanya Chundru)
Date: Tue, 26 Aug 2025 16:32:52 +0530
Subject: [PATCH v3 0/3] arm64: dts: qcom: Add PCIe Support for sm8750
Message-ID: <20250826-pakala-v3-0-721627bd5bb0@oss.qualcomm.com>

Describe PCIe controller and PHY. Also add required system resources like
regulators, clocks, interrupts and registers configuration for PCIe.

The qcom_pcie_parse_ports() function currently iterates over all available
child nodes of the PCIe controller's device tree node. This includes
unrelated nodes such as OPP (Operating Performance Points) nodes, which do
not contain the expected 'reset' and 'phy' properties. As a result, parsing
fails and the driver falls back to the legacy method of parsing the
controller node directly. However, this fallback also fails when properties
are shifted to the root port, leading to probe failure.

Fix this by restricting the parsing logic to only consider child nodes with
device_type = "pci", which is the expected and required property for PCIe
ports as defined in pci-bus-common.yaml.

Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
---
Changes in v3:
- Use device_type to find pci node or not instead of node name.
- Link to v2: https://lore.kernel.org/r/20250826-pakala-v2-0-74f1f60676c6 at oss.qualcomm.com

Changes in v2:
- Follow the x1e80100.dtsi pcie node description (Konrad).
- define phy & perst, wake in port node as per latest bindings.
- Add check in the driver to parse only pcie child nodes.
- Added acked by tag(Rob).
- Removed dtbinding and phy driver patches as they got applied.
- Link to v1: https://lore.kernel.org/r/20250809-pakala-v1-0-abf1c416dbaa at oss.qualcomm.com

---
Krishna Chaitanya Chundru (3):
      dt-bindings: PCI: qcom,pcie-sm8550: Add SM8750 compatible
      arm64: dts: qcom: sm8750: Add PCIe PHY and controller node
      PCI: qcom: Restrict port parsing only to pci child nodes

 .../devicetree/bindings/pci/qcom,pcie-sm8550.yaml  |   1 +
 arch/arm64/boot/dts/qcom/sm8750.dtsi               | 180 ++++++++++++++++++++-
 drivers/pci/controller/dwc/pcie-qcom.c             |   2 +
 3 files changed, 182 insertions(+), 1 deletion(-)
---
base-commit: b6add54ba61890450fa54fd9327d10fdfd653439
change-id: 20250809-pakala-25a7c1ddba85

Best regards,
-- 
Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>



From krishna.chundru at oss.qualcomm.com  Tue Aug 26 04:02:53 2025
From: krishna.chundru at oss.qualcomm.com (Krishna Chaitanya Chundru)
Date: Tue, 26 Aug 2025 16:32:53 +0530
Subject: [PATCH v3 1/3] dt-bindings: PCI: qcom,pcie-sm8550: Add SM8750
 compatible
In-Reply-To: <20250826-pakala-v3-0-721627bd5bb0@oss.qualcomm.com>
References: <20250826-pakala-v3-0-721627bd5bb0@oss.qualcomm.com>
Message-ID: <20250826-pakala-v3-1-721627bd5bb0@oss.qualcomm.com>

On the Qualcomm SM8750 platform the PCIe host is compatible with the
DWC controller present on the SM8550 platorm.

Acked-by: Rob Herring (Arm) <robh at kernel.org>
Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
---
 Documentation/devicetree/bindings/pci/qcom,pcie-sm8550.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-sm8550.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-sm8550.yaml
index dbce671ba011c8991842af6d6c761ec081be24cb..38b561e23c1fda677ce2d4257e1084a384648835 100644
--- a/Documentation/devicetree/bindings/pci/qcom,pcie-sm8550.yaml
+++ b/Documentation/devicetree/bindings/pci/qcom,pcie-sm8550.yaml
@@ -22,6 +22,7 @@ properties:
           - enum:
               - qcom,sar2130p-pcie
               - qcom,pcie-sm8650
+              - qcom,pcie-sm8750
           - const: qcom,pcie-sm8550
 
   reg:

-- 
2.34.1



From krishna.chundru at oss.qualcomm.com  Tue Aug 26 04:02:54 2025
From: krishna.chundru at oss.qualcomm.com (Krishna Chaitanya Chundru)
Date: Tue, 26 Aug 2025 16:32:54 +0530
Subject: [PATCH v3 2/3] arm64: dts: qcom: sm8750: Add PCIe PHY and
 controller node
In-Reply-To: <20250826-pakala-v3-0-721627bd5bb0@oss.qualcomm.com>
References: <20250826-pakala-v3-0-721627bd5bb0@oss.qualcomm.com>
Message-ID: <20250826-pakala-v3-2-721627bd5bb0@oss.qualcomm.com>

Add PCIe controller and PHY nodes which supports data rates of 8GT/s
and x2 lane.

Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/sm8750.dtsi | 180 ++++++++++++++++++++++++++++++++++-
 1 file changed, 179 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/sm8750.dtsi b/arch/arm64/boot/dts/qcom/sm8750.dtsi
index 4643705021c6ca095a16d8d7cc3adac920b21e82..b47668a64bcead3e48f58eeb2e41c04660493cb7 100644
--- a/arch/arm64/boot/dts/qcom/sm8750.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8750.dtsi
@@ -631,7 +631,7 @@ gcc: clock-controller at 100000 {
 			clocks = <&bi_tcxo_div2>,
 				 <0>,
 				 <&sleep_clk>,
-				 <0>,
+				 <&pcie0_phy>,
 				 <0>,
 				 <0>,
 				 <0>,
@@ -3304,6 +3304,184 @@ gic_its: msi-controller at 16040000 {
 			};
 		};
 
+		pcie0: pcie at 1c00000 {
+			device_type = "pci";
+			compatible = "qcom,pcie-sm8750", "qcom,pcie-sm8550";
+			reg = <0x0 0x01c00000 0x0 0x3000>,
+			      <0x0 0x40000000 0x0 0xf1d>,
+			      <0x0 0x40000f20 0x0 0xa8>,
+			      <0x0 0x40001000 0x0 0x1000>,
+			      <0x0 0x40100000 0x0 0x100000>,
+			      <0x0 0x01C03000 0x0 0x1000>;
+			reg-names = "parf",
+				    "dbi",
+				    "elbi",
+				    "atu",
+				    "config",
+				    "mhi";
+
+			#address-cells = <3>;
+			#size-cells = <2>;
+			ranges = <0x01000000 0x0 0x00000000 0x0 0x40200000 0x0 0x100000>,
+				 <0x02000000 0x0 0x40300000 0x0 0x40300000 0x0 0x23d00000>,
+				 <0x03000000 0x4 0x00000000 0x4 0x00000000 0x3 0x00000000>;
+			bus-range = <0x00 0xff>;
+
+			dma-coherent;
+
+			linux,pci-domain = <0>;
+
+			msi-map = <0x0 &gic_its 0x1400 0x1>,
+				  <0x100 &gic_its 0x1401 0x1>;
+			msi-map-mask = <0xff00>;
+
+			num-lanes = <2>;
+
+			interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 140 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 0 149 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 2 &intc 0 0 0 150 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 3 &intc 0 0 0 151 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 4 &intc 0 0 0 152 IRQ_TYPE_LEVEL_HIGH>;
+
+			clocks = <&gcc GCC_PCIE_0_AUX_CLK>,
+				 <&gcc GCC_PCIE_0_CFG_AHB_CLK>,
+				 <&gcc GCC_PCIE_0_MSTR_AXI_CLK>,
+				 <&gcc GCC_PCIE_0_SLV_AXI_CLK>,
+				 <&gcc GCC_PCIE_0_SLV_Q2A_AXI_CLK>,
+				 <&gcc GCC_DDRSS_PCIE_SF_QTB_CLK>,
+				 <&gcc GCC_AGGRE_NOC_PCIE_AXI_CLK>,
+				 <&gcc GCC_CNOC_PCIE_SF_AXI_CLK>;
+			clock-names = "aux",
+				      "cfg",
+				      "bus_master",
+				      "bus_slave",
+				      "slave_q2a",
+				      "ddrss_sf_tbu",
+				      "noc_aggr",
+				      "cnoc_sf_axi";
+
+			interconnects = <&pcie_noc MASTER_PCIE_0 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_0 QCOM_ICC_TAG_ALWAYS>;
+			interconnect-names = "pcie-mem",
+					     "cpu-pcie";
+
+			iommu-map = <0x0   &apps_smmu 0x1400 0x1>,
+				    <0x100 &apps_smmu 0x1401 0x1>;
+
+			resets = <&gcc GCC_PCIE_0_BCR>;
+			reset-names = "pci";
+
+			power-domains = <&gcc GCC_PCIE_0_GDSC>;
+
+			operating-points-v2 = <&pcie0_opp_table>;
+
+			status = "disabled";
+
+			pcie0_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 2 x2 */
+				opp-10000000 {
+					opp-hz = /bits/ 64 <10000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <1000000 1>;
+				};
+
+				/* GEN 3 x1 */
+				opp-8000000 {
+					opp-hz = /bits/ 64 <8000000>;
+					required-opps = <&rpmhpd_opp_nom>;
+					opp-peak-kBps = <984500 1>;
+				};
+
+				/* GEN 3 x2 */
+				opp-16000000 {
+					opp-hz = /bits/ 64 <16000000>;
+					required-opps = <&rpmhpd_opp_nom>;
+					opp-peak-kBps = <1969000 1>;
+				};
+
+			};
+
+			pcieport0: pcie at 0 {
+				device_type = "pci";
+				reg = <0x0 0x0 0x0 0x0 0x0>;
+				bus-range = <0x01 0xff>;
+
+				#address-cells = <3>;
+				#size-cells = <2>;
+				ranges;
+				phys = <&pcie0_phy>;
+			};
+		};
+
+		pcie0_phy: phy at 1c06000 {
+			compatible = "qcom,sm8750-qmp-gen3x2-pcie-phy";
+			reg = <0 0x01c06000 0 0x2000>;
+
+			clocks = <&gcc GCC_PCIE_0_AUX_CLK>,
+				 <&gcc GCC_PCIE_0_CFG_AHB_CLK>,
+				 <&tcsrcc TCSR_PCIE_0_CLKREF_EN>,
+				 <&gcc GCC_PCIE_0_PHY_RCHNG_CLK>,
+				 <&gcc GCC_PCIE_0_PIPE_CLK>;
+			clock-names = "aux",
+				      "cfg_ahb",
+				      "ref",
+				      "rchng",
+				      "pipe";
+
+			assigned-clocks = <&gcc GCC_PCIE_0_PHY_RCHNG_CLK>;
+			assigned-clock-rates = <100000000>;
+
+			resets = <&gcc GCC_PCIE_0_PHY_BCR>;
+			reset-names = "phy";
+
+			power-domains = <&gcc GCC_PCIE_0_PHY_GDSC>;
+
+			#clock-cells = <0>;
+			clock-output-names = "pcie0_pipe_clk";
+
+			#phy-cells = <0>;
+
+			status = "disabled";
+		};
+
 		ufs_mem_phy: phy at 1d80000 {
 			compatible = "qcom,sm8750-qmp-ufs-phy";
 			reg = <0x0 0x01d80000 0x0 0x2000>;

-- 
2.34.1



From krishna.chundru at oss.qualcomm.com  Tue Aug 26 04:02:55 2025
From: krishna.chundru at oss.qualcomm.com (Krishna Chaitanya Chundru)
Date: Tue, 26 Aug 2025 16:32:55 +0530
Subject: [PATCH v3 3/3] PCI: qcom: Restrict port parsing only to pci child
 nodes
In-Reply-To: <20250826-pakala-v3-0-721627bd5bb0@oss.qualcomm.com>
References: <20250826-pakala-v3-0-721627bd5bb0@oss.qualcomm.com>
Message-ID: <20250826-pakala-v3-3-721627bd5bb0@oss.qualcomm.com>

The qcom_pcie_parse_ports() function currently iterates over all available
child nodes of the PCIe controller's device tree node. This includes
unrelated nodes such as OPP (Operating Performance Points) nodes, which do
not contain the expected 'reset' and 'phy' properties. As a result, parsing
fails and the driver falls back to the legacy method of parsing the
controller node directly. However, this fallback also fails when properties
are shifted to the root port, leading to probe failure.

Fix this by restricting the parsing logic to only consider child nodes with
device_type = "pci", which is the expected and required property for PCIe
ports as defined in pci-bus-common.yaml.

Fixes: a2fbecdbbb9d ("PCI: qcom: Add support for parsing the new Root Port binding")
Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
---
 drivers/pci/controller/dwc/pcie-qcom.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index 294babe1816e4d0c2b2343fe22d89af72afcd6cd..fbed7130d7475aafb0d8adf07427c3495921152f 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -1740,6 +1740,8 @@ static int qcom_pcie_parse_ports(struct qcom_pcie *pcie)
 	int ret = -ENOENT;
 
 	for_each_available_child_of_node_scoped(dev->of_node, of_port) {
+		if (!of_node_is_type(of_port, "pci"))
+			continue;
 		ret = qcom_pcie_parse_port(pcie, of_port);
 		if (ret)
 			goto err_port_del;

-- 
2.34.1



From robh at kernel.org  Tue Aug 26 06:56:45 2025
From: robh at kernel.org (Rob Herring (Arm))
Date: Tue, 26 Aug 2025 08:56:45 -0500
Subject: [PATCH v3 0/3] arm64: dts: qcom: Add PCIe Support for sm8750
In-Reply-To: <20250826-pakala-v3-0-721627bd5bb0@oss.qualcomm.com>
References: <20250826-pakala-v3-0-721627bd5bb0@oss.qualcomm.com>
Message-ID: <175621649862.159548.14099860400165270689.robh@kernel.org>


On Tue, 26 Aug 2025 16:32:52 +0530, Krishna Chaitanya Chundru wrote:
> Describe PCIe controller and PHY. Also add required system resources like
> regulators, clocks, interrupts and registers configuration for PCIe.
> 
> The qcom_pcie_parse_ports() function currently iterates over all available
> child nodes of the PCIe controller's device tree node. This includes
> unrelated nodes such as OPP (Operating Performance Points) nodes, which do
> not contain the expected 'reset' and 'phy' properties. As a result, parsing
> fails and the driver falls back to the legacy method of parsing the
> controller node directly. However, this fallback also fails when properties
> are shifted to the root port, leading to probe failure.
> 
> Fix this by restricting the parsing logic to only consider child nodes with
> device_type = "pci", which is the expected and required property for PCIe
> ports as defined in pci-bus-common.yaml.
> 
> Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
> ---
> Changes in v3:
> - Use device_type to find pci node or not instead of node name.
> - Link to v2: https://lore.kernel.org/r/20250826-pakala-v2-0-74f1f60676c6 at oss.qualcomm.com
> 
> Changes in v2:
> - Follow the x1e80100.dtsi pcie node description (Konrad).
> - define phy & perst, wake in port node as per latest bindings.
> - Add check in the driver to parse only pcie child nodes.
> - Added acked by tag(Rob).
> - Removed dtbinding and phy driver patches as they got applied.
> - Link to v1: https://lore.kernel.org/r/20250809-pakala-v1-0-abf1c416dbaa at oss.qualcomm.com
> 
> ---
> Krishna Chaitanya Chundru (3):
>       dt-bindings: PCI: qcom,pcie-sm8550: Add SM8750 compatible
>       arm64: dts: qcom: sm8750: Add PCIe PHY and controller node
>       PCI: qcom: Restrict port parsing only to pci child nodes
> 
>  .../devicetree/bindings/pci/qcom,pcie-sm8550.yaml  |   1 +
>  arch/arm64/boot/dts/qcom/sm8750.dtsi               | 180 ++++++++++++++++++++-
>  drivers/pci/controller/dwc/pcie-qcom.c             |   2 +
>  3 files changed, 182 insertions(+), 1 deletion(-)
> ---
> base-commit: b6add54ba61890450fa54fd9327d10fdfd653439
> change-id: 20250809-pakala-25a7c1ddba85
> 
> Best regards,
> --
> Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.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


This patch series was applied (using b4) to base:
 Base: using specified base-commit b6add54ba61890450fa54fd9327d10fdfd653439

If this is not the correct base, please add 'base-commit' tag
(or use b4 which does this automatically)

New warnings running 'make CHECK_DTBS=y for arch/arm64/boot/dts/qcom/' for 20250826-pakala-v3-0-721627bd5bb0 at oss.qualcomm.com:

arch/arm64/boot/dts/qcom/sm8750-mtp.dtb: /soc at 0/phy at 1c06000: failed to match any schema with compatible: ['qcom,sm8750-qmp-gen3x2-pcie-phy']
arch/arm64/boot/dts/qcom/sm8750-qrd.dtb: /soc at 0/phy at 1c06000: failed to match any schema with compatible: ['qcom,sm8750-qmp-gen3x2-pcie-phy']







From josua at solid-run.com  Tue Aug 26 11:32:03 2025
From: josua at solid-run.com (Josua Mayer)
Date: Tue, 26 Aug 2025 20:32:03 +0200
Subject: [PATCH] phy: lynx-28g: check return value when calling
 lynx_28g_pll_get
Message-ID: <20250826-lynx-28g-nullptr-v1-1-e4de0098f822@solid-run.com>

The lynx_28g_pll_get function may return NULL when called with an
unsupported submode argument.

This function is only called from the lynx_28g_lane_set_{10gbaser,sgmii}
functions, and lynx_28g_set_mode checks available modes before setting a
protocol.

NXP vendor kernel based on v6.6.52 however is missing any checks and
connecting a 2.5/5gbase-t ethernet phy can cause null pointer
dereference [1].

Check return value at every invocation and abort in the unlikely error
case. Further print a warning message the first time lynx_28g_pll_get
returns null, to catch this case should it occur after future changes.

[1]
[  127.019924] fsl_dpaa2_eth dpni.4 eth5: dpmac_set_protocol(2500base-x) = -ENOTSUPP
[  127.027451] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000014
[  127.036245] Mem abort info:
[  127.039044]   ESR = 0x0000000096000004
[  127.042794]   EC = 0x25: DABT (current EL), IL = 32 bits
[  127.048107]   SET = 0, FnV = 0
[  127.051161]   EA = 0, S1PTW = 0
[  127.054301]   FSC = 0x04: level 0 translation fault
[  127.059179] Data abort info:
[  127.062059]   ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
[  127.067547]   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
[  127.072596]   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[  127.077907] user pgtable: 4k pages, 48-bit VAs, pgdp=00000020816c9000
[  127.084344] [0000000000000014] pgd=0000000000000000, p4d=0000000000000000
[  127.091133] Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP
[  127.097390] Modules linked in: cfg80211 rfkill fsl_jr_uio caam_jr dpaa2_caam caamkeyblob_desc crypto_engine caamhash_desc onboard_usb_hub caamalg_desc crct10dif_ce libdes caam error at24 rtc_ds1307 rtc_fsl_ftm_alarm nvmem_layerscape_sfp layerscape_edac_mod dm_mod nfnetlink ip_tables
[  127.122436] CPU: 5 PID: 96 Comm: kworker/u35:0 Not tainted 6.6.52-g3578ef896722 #10
[  127.130083] Hardware name: SolidRun LX2162A Clearfog (DT)
[  127.135470] Workqueue: events_power_efficient phylink_resolve
[  127.141219] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[  127.148170] pc : lynx_28g_set_lane_mode+0x300/0x818
[  127.153041] lr : lynx_28g_set_lane_mode+0x2fc/0x818
[  127.157909] sp : ffff8000806f3b80
[  127.161212] x29: ffff8000806f3b80 x28: 0000000000000000 x27: 0000000000000000
[  127.168340] x26: ffff29d6c11f3098 x25: 0000000000000000 x24: 0000000000000000
[  127.175467] x23: ffff29d6c11f31f0 x22: ffff29d6c11f3080 x21: 0000000000000001
[  127.182595] x20: ffff29d6c11f4c00 x19: 0000000000000000 x18: 0000000000000006
[  127.189722] x17: 4f4e452d203d2029 x16: 782d657361623030 x15: 3532286c6f636f74
[  127.196849] x14: 6f72705f7465735f x13: ffffd7a8ff991cc0 x12: 0000000000000acb
[  127.203976] x11: 0000000000000399 x10: ffffd7a8ff9e9cc0 x9 : 0000000000000000
[  127.211104] x8 : 0000000000000000 x7 : 0000000000000000 x6 : ffff29d6c11f3080
[  127.218231] x5 : 0000000000000000 x4 : 0000000040800030 x3 : 000000000000034c
[  127.225358] x2 : ffff29d6c11f3080 x1 : 000000000000034c x0 : 0000000000000000
[  127.232486] Call trace:
[  127.234921]  lynx_28g_set_lane_mode+0x300/0x818
[  127.239443]  lynx_28g_set_mode+0x12c/0x148
[  127.243529]  phy_set_mode_ext+0x5c/0xa8
[  127.247356]  lynx_pcs_config+0x64/0x294
[  127.251184]  phylink_major_config+0x184/0x49c
[  127.255532]  phylink_resolve+0x2a0/0x5d8
[  127.259446]  process_one_work+0x138/0x248
[  127.263448]  worker_thread+0x320/0x438
[  127.267187]  kthread+0x114/0x118
[  127.270406]  ret_from_fork+0x10/0x20
[  127.273973] Code: 2a1303e1 aa0603e0 97fffd3b aa0003e5 (b9401400)
[  127.280055] ---[ end trace 0000000000000000 ]---

Signed-off-by: Josua Mayer <josua at solid-run.com>
---
 drivers/phy/freescale/phy-fsl-lynx-28g.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-lynx-28g.c b/drivers/phy/freescale/phy-fsl-lynx-28g.c
index f7994e8983c8ecf52148ba4024684c0c452fc5a1..c20d2636c5e9c079d9178fdfa9030dd8041ce0ba 100644
--- a/drivers/phy/freescale/phy-fsl-lynx-28g.c
+++ b/drivers/phy/freescale/phy-fsl-lynx-28g.c
@@ -188,6 +188,10 @@ static struct lynx_28g_pll *lynx_28g_pll_get(struct lynx_28g_priv *priv,
 			return pll;
 	}
 
+	/* no pll supports requested mode, either caller forgot to check
+	 * lynx_28g_supports_lane_mode, or this is a bug.
+	 */
+	dev_WARN_ONCE(priv->dev, 1, "no pll for interface %s\n", phy_modes(intf));
 	return NULL;
 }
 
@@ -276,8 +280,12 @@ static void lynx_28g_lane_set_sgmii(struct lynx_28g_lane *lane)
 	lynx_28g_lane_rmw(lane, LNaGCR0, PROTO_SEL_SGMII, PROTO_SEL_MSK);
 	lynx_28g_lane_rmw(lane, LNaGCR0, IF_WIDTH_10_BIT, IF_WIDTH_MSK);
 
-	/* Switch to the PLL that works with this interface type */
+	/* Find the PLL that works with this interface type */
 	pll = lynx_28g_pll_get(priv, PHY_INTERFACE_MODE_SGMII);
+	if (unlikely(pll == NULL))
+		return;
+
+	/* Switch to the PLL that works with this interface type */
 	lynx_28g_lane_set_pll(lane, pll);
 
 	/* Choose the portion of clock net to be used on this lane */
@@ -312,8 +320,12 @@ static void lynx_28g_lane_set_10gbaser(struct lynx_28g_lane *lane)
 	lynx_28g_lane_rmw(lane, LNaGCR0, PROTO_SEL_XFI, PROTO_SEL_MSK);
 	lynx_28g_lane_rmw(lane, LNaGCR0, IF_WIDTH_20_BIT, IF_WIDTH_MSK);
 
-	/* Switch to the PLL that works with this interface type */
+	/* Find the PLL that works with this interface type */
 	pll = lynx_28g_pll_get(priv, PHY_INTERFACE_MODE_10GBASER);
+	if (unlikely(pll == NULL))
+		return;
+
+	/* Switch to the PLL that works with this interface type */
 	lynx_28g_lane_set_pll(lane, pll);
 
 	/* Choose the portion of clock net to be used on this lane */

---
base-commit: 8f5ae30d69d7543eee0d70083daf4de8fe15d585
change-id: 20250826-lynx-28g-nullptr-15de2b5b1eb6

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



From dmitry.osipenko at collabora.com  Tue Aug 26 13:43:57 2025
From: dmitry.osipenko at collabora.com (Dmitry Osipenko)
Date: Tue, 26 Aug 2025 23:43:57 +0300
Subject: [PATCH v3 04/20] media: synopsys: hdmirx: replace macros with
 bitfield variants
In-Reply-To: <20250825-byeword-update-v3-4-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
 <20250825-byeword-update-v3-4-947b841cdb29@collabora.com>
Message-ID: <676d88d1-c15a-4648-a4c5-c668e40b12f0@collabora.com>

On 8/25/25 11:28, Nicolas Frattaroli wrote:
> The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
> drivers that use constant masks.
> 
> Replace the UPDATE macro with bitfield.h's FIELD_PREP, to give us
> additional error checking.
> 
> Also, replace the HIWORD_UPDATE macro at the same time with the new
> FIELD_PREP_WM16 macro in hw_bitfield.h, which also gives us additional
> error checking.
> 
> The UPDATE/HIWORD_UPDATE macros are left as wrappers around the
> replacement macros, in order to not rock the boat too much, and keep the
> changes easy to review.
> 
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
> ---
>  drivers/media/platform/synopsys/hdmirx/snps_hdmirx.h | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.h b/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.h
> index 220ab99ca61152b36b0a08b398ddefdb985709a5..b26668a98aafd1682b8342cc11f84666a13f07a3 100644
> --- a/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.h
> +++ b/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.h
> @@ -8,10 +8,12 @@
>  #ifndef DW_HDMIRX_H
>  #define DW_HDMIRX_H
>  
> +#include <linux/bitfield.h>
>  #include <linux/bitops.h>
> +#include <linux/hw_bitfield.h>
>  
> -#define UPDATE(x, h, l)		(((x) << (l)) & GENMASK((h), (l)))
> -#define HIWORD_UPDATE(v, h, l)	(((v) << (l)) | (GENMASK((h), (l)) << 16))
> +#define UPDATE(x, h, l)		(FIELD_PREP(GENMASK((h), (l)), (x)))
> +#define HIWORD_UPDATE(v, h, l)	(FIELD_PREP_WM16(GENMASK((h), (l)), (v)))

Nit: the extra parens around FIELD_PREP may be omitted

Acked-by: Dmitry Osipenko <dmitry.osipenko at collabora.com>

-- 
Best regards,
Dmitry


From yury.norov at gmail.com  Tue Aug 26 18:09:26 2025
From: yury.norov at gmail.com (Yury Norov)
Date: Tue, 26 Aug 2025 21:09:26 -0400
Subject: [PATCH v3 00/20] BYEWORD_UPDATE: unifying (most) HIWORD_UPDATE
 macros
In-Reply-To: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
Message-ID: <aK5aujavDc4PvvjO@yury>

Hi Nicolas,

Thanks for the work!

On Mon, Aug 25, 2025 at 10:28:20AM +0200, Nicolas Frattaroli wrote:
> This series was spawned by [1], where I was asked to move every instance
> of HIWORD_UPDATE et al that I could find to a common macro in the same
> series that I am introducing said common macro.
> 
> The first patch of the series introduces a new header file,
> hw_bitfield.h, which contains two new macros: FIELD_PREP_WM16 and
> FIELD_PREP_WM16_CONST. The latter can be used in initializers.
> 
> I've cheekily added the hw_bitfield.h header to the BITMAP API section
> of the MAINTAINERS file.
> 
> This macro definition checks that the mask fits, and that the value fits
> in the mask. Like FIELD_PREP, it also shifts the value up to the mask,
> so turning off a bit does not require using the mask as a value. Masks
> are also required to be contiguous, like with FIELD_PREP.
> 
> For each definition of such a macro, the driver(s) that used it were
> evaluated for three different treatments:
>  - full conversion to the new macro, for cases where replacing the
>    implementation of the old macro wouldn't have worked, or where the
>    conversion was trivial. These are the most complex patches in this
>    series, as they sometimes have to pull apart definitions of masks
>    and values due to the new semantics, which require a contiguous
>    mask and shift the value for us.
>  - replacing the implementation of the old macro with an instance of the
>    new macro, done where I felt it made the patch much easier to review
>    because I didn't want to drop a big diff on people.
>  - skipping conversion entirely, usually because the mask is
>    non-constant and it's not trivial to make it constant. Sometimes an
>    added complication is that said non-constant mask is either used in a
>    path where runtime overhead may not be desirable, or in an
>    initializer.
> 
> Left out of conversion:
>  - drivers/mmc/host/sdhci-of-arasan.c: mask is non-constant.

+ Michal Simek <michal.simek at amd.com>

>  - drivers/phy/rockchip/phy-rockchip-inno-csidphy.c: mask is
>    non-constant likely by way of runtime pointer dereferencing, even if
>    struct and members are made const.

+ Vinod Koul <vkoul at kernel.org> (already in the list)

>  - drivers/clk/rockchip/clk.h: way too many clock drivers use non-const
>    masks in the context of an initializer.

+ Heiko Stuebner <heiko at sntech.de> (already in the list)

Guys, can you please take a look? Would be nice to finish the
consolidation.

--

I'll take #1 and the acknowledged (or at least reviewed) per-driver
fixes in bitmap-for-next in 2-3 weeks before the end of cycle.
Everyone, please send your tags!

Nicolas, please ping me if I forget. For the rest of the series, in
case of no feedback from maintainers, let's wait for one more merge
window, and then move everything altogether.

Thanks,
Yury


From dmitry.baryshkov at oss.qualcomm.com  Tue Aug 26 18:45:12 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Wed, 27 Aug 2025 04:45:12 +0300
Subject: [PATCH v3 4/4] phy: qcom: qmp-pcie: Add support for Glymur PCIe
 Gen5x4 PHY
In-Reply-To: <20250825-glymur_pcie5-v3-4-5c1d1730c16f@oss.qualcomm.com>
References: <20250825-glymur_pcie5-v3-0-5c1d1730c16f@oss.qualcomm.com>
 <20250825-glymur_pcie5-v3-4-5c1d1730c16f@oss.qualcomm.com>
Message-ID: <ohzgigqvqdgaee27fdozzpt67i5cpp53jkj2rh226kf6sgr6d4@jsgqpno52x5z>

On Mon, Aug 25, 2025 at 11:01:50PM -0700, Wenbin Yao wrote:
> From: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
> 
> Add support for Gen5 x4 PCIe QMP PHY found on Glymur platform.
> 
> Signed-off-by: Prudhvi Yarlagadda <quic_pyarlaga at quicinc.com>
> Signed-off-by: Wenbin Yao <wenbin.yao at oss.qualcomm.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 32 ++++++++++++++++++++++++++++++++
>  1 file changed, 32 insertions(+)
> 

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>


-- 
With best wishes
Dmitry


From amadeus at jmu.edu.cn  Tue Aug 26 23:40:10 2025
From: amadeus at jmu.edu.cn (Chukun Pan)
Date: Wed, 27 Aug 2025 14:40:10 +0800
Subject: [PATCH 4/7] phy: allwinner: a523: add USB3/PCIe PHY driver
In-Reply-To: <20250816084700.569524-5-iuncuim@gmail.com>
References: <20250816084700.569524-5-iuncuim@gmail.com>
Message-ID: <20250827064010.55675-1-amadeus@jmu.edu.cn>

Hi,

> --- a/drivers/phy/allwinner/Makefile
> +++ b/drivers/phy/allwinner/Makefile
> @@ -3,3 +3,4 @@ obj-$(CONFIG_PHY_SUN4I_USB)		+= phy-sun4i-usb.o
>  obj-$(CONFIG_PHY_SUN6I_MIPI_DPHY)	+= phy-sun6i-mipi-dphy.o
>  obj-$(CONFIG_PHY_SUN9I_USB)		+= phy-sun9i-usb.o
>  obj-$(CONFIG_PHY_SUN50I_USB3)		+= phy-sun50i-usb3.o
> +obj-$(CONFIG_PHY_SUN55I_USB3_PCIE)		+= phy-sun55i-usb3-pcie.o

Would it be better to call it phy-sun55i-combophy ?

> --- /dev/null
> +++ b/drivers/phy/allwinner/phy-sun55i-usb3-pcie.c
> ...
> +static int sun55i_usb3_pcie_phy_init(struct phy *_phy)
> +{
> +	struct sun55i_usb3_pcie_phy *phy = phy_get_drvdata(_phy);
> +
> +	sun55i_usb3_phy_open(phy);

Maybe we need to add `case PHY_TYPE_USB3:`
And use <&combophy PHY_TYPE_USB3> in the DT

> +
> +	return 0;
> +}
> ...

> +static const struct of_device_id sun55i_usb3_pcie_phy_of_match[] = {
> +	{ .compatible = "allwinner,sun55i-a523-usb3-pcie-phy" },

Would it be better to use "allwinner,sun55i-a523-combophy" as
the compatible?

> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, sun55i_usb3_pcie_phy_of_match);

Thanks,
Chukun


From heiko at sntech.de  Tue Aug 26 23:50:49 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 27 Aug 2025 08:50:49 +0200
Subject: [PATCH v3 01/20] bitmap: introduce hardware-specific bitfield operations
In-Reply-To: <20250825-byeword-update-v3-1-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
 <20250825-byeword-update-v3-1-947b841cdb29@collabora.com>
Message-ID: <9063025.MhkbZ0Pkbq@phil>

Am Montag, 25. August 2025, 10:28:21 Mitteleurop?ische Sommerzeit schrieb Nicolas Frattaroli:
> Hardware of various vendors, but very notably Rockchip, often uses
> 32-bit registers where the upper 16-bit half of the register is a
> write-enable mask for the lower half.
> 
> This type of hardware setup allows for more granular concurrent register
> write access.
> 
> Over the years, many drivers have hand-rolled their own version of this
> macro, usually without any checks, often called something like
> HIWORD_UPDATE or FIELD_PREP_HIWORD, commonly with slightly different
> semantics between them.
> 
> Clearly there is a demand for such a macro, and thus the demand should
> be satisfied in a common header file. As this is a convention that spans
> across multiple vendors, and similar conventions may also have
> cross-vendor adoption, it's best if it lives in a vendor-agnostic header
> file that can be expanded over time.
> 
> Add hw_bitfield.h with two macros: FIELD_PREP_WM16, and
> FIELD_PREP_WM16_CONST. The latter is a version that can be used in
> initializers, like FIELD_PREP_CONST.
> 
> Suggested-by: Yury Norov [NVIDIA] <yury.norov at gmail.com>
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>

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




From heiko at sntech.de  Tue Aug 26 23:53:23 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 27 Aug 2025 08:53:23 +0200
Subject: [PATCH v3 02/20] mmc: dw_mmc-rockchip: switch to FIELD_PREP_WM16 macro
In-Reply-To: <20250825-byeword-update-v3-2-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
 <20250825-byeword-update-v3-2-947b841cdb29@collabora.com>
Message-ID: <11595144.NyiUUSuA9g@phil>

Am Montag, 25. August 2025, 10:28:22 Mitteleurop?ische Sommerzeit schrieb Nicolas Frattaroli:
> The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
> drivers that use constant masks.
> 
> Switch to the new FIELD_PREP_WM16 macro in hw_bitfield.h, which has
> error checking. Instead of redefining the driver's HIWORD_UPDATE macro
> in this case, replace the two only instances of it with the new macro,
> as I could test that they result in an equivalent value.
> 
> Acked-by: Ulf Hansson <ulf.hansson at linaro.org>
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>

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

and going from $random-hex-value to GENMASK is a nice added benefit




From heiko at sntech.de  Tue Aug 26 23:55:24 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 27 Aug 2025 08:55:24 +0200
Subject: [PATCH v3 03/20] soc: rockchip: grf: switch to FIELD_PREP_WM16_CONST
 macro
In-Reply-To: <20250825-byeword-update-v3-3-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
 <20250825-byeword-update-v3-3-947b841cdb29@collabora.com>
Message-ID: <6548370.QJadu78ljV@phil>

Am Montag, 25. August 2025, 10:28:23 Mitteleurop?ische Sommerzeit schrieb Nicolas Frattaroli:
> The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
> drivers that use constant masks.
> 
> Switch the rockchip grf driver to the FIELD_PREP_WM16_CONST macro, which
> brings with it more error checking while still being able to be used in
> initializers.
> 
> All HIWORD_UPDATE instances and its definition are removed from the
> driver, as the conversion here is obvious, and static_asserts were used
> during development to make sure the ones greater than one bit in width
> were really equivalent.
> 
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>


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




From heiko at sntech.de  Wed Aug 27 00:07:05 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 27 Aug 2025 09:07:05 +0200
Subject: [PATCH v3 04/20] media: synopsys: hdmirx: replace macros with bitfield
 variants
In-Reply-To: <20250825-byeword-update-v3-4-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
 <20250825-byeword-update-v3-4-947b841cdb29@collabora.com>
Message-ID: <5651006.Lt9SDvczpP@phil>

Am Montag, 25. August 2025, 10:28:24 Mitteleurop?ische Sommerzeit schrieb Nicolas Frattaroli:
> The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
> drivers that use constant masks.
> 
> Replace the UPDATE macro with bitfield.h's FIELD_PREP, to give us
> additional error checking.
> 
> Also, replace the HIWORD_UPDATE macro at the same time with the new
> FIELD_PREP_WM16 macro in hw_bitfield.h, which also gives us additional
> error checking.
> 
> The UPDATE/HIWORD_UPDATE macros are left as wrappers around the
> replacement macros, in order to not rock the boat too much, and keep the
> changes easy to review.
> 
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>

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




From heiko at sntech.de  Wed Aug 27 00:09:12 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 27 Aug 2025 09:09:12 +0200
Subject: [PATCH v3 05/20] drm/rockchip: lvds: switch to FIELD_PREP_WM16 macro
In-Reply-To: <20250825-byeword-update-v3-5-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
 <20250825-byeword-update-v3-5-947b841cdb29@collabora.com>
Message-ID: <5226092.Mh6RI2rZIc@phil>

Am Montag, 25. August 2025, 10:28:25 Mitteleurop?ische Sommerzeit schrieb Nicolas Frattaroli:
> The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
> drivers that use constant masks.
> 
> Remove rockchip_lvds.h's own HIWORD_UPDATE macro, and replace all
> instances of it with hw_bitfield.h's FIELD_PREP_WM16 macro, which gives
> us more error checking.
> 
> For the slightly-less-trivial case of the 2-bit width instance, the
> results were checked during development to match all possible input
> values (0 to 3, inclusive).
> 
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>

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




From heiko at sntech.de  Wed Aug 27 00:13:18 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 27 Aug 2025 09:13:18 +0200
Subject: [PATCH v3 06/20] phy: rockchip-emmc: switch to FIELD_PREP_WM16 macro
In-Reply-To: <20250825-byeword-update-v3-6-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
 <20250825-byeword-update-v3-6-947b841cdb29@collabora.com>
Message-ID: <6820610.MHq7AAxBmi@phil>

Am Montag, 25. August 2025, 10:28:26 Mitteleurop?ische Sommerzeit schrieb Nicolas Frattaroli:
> The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
> drivers that use constant masks.
> 
> Replace the implementation of the rockchip eMMC PHY driver's
> HIWORD_UPDATE macro with hw_bitfield.h's FIELD_PREP_WM16. This makes the
> change more easily reviewable.
> 
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>

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




From heiko at sntech.de  Wed Aug 27 00:22:04 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 27 Aug 2025 09:22:04 +0200
Subject: [PATCH v3 07/20] drm/rockchip: dsi: switch to FIELD_PREP_WM16* macros
In-Reply-To: <20250825-byeword-update-v3-7-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
 <20250825-byeword-update-v3-7-947b841cdb29@collabora.com>
Message-ID: <4886676.atdPhlSkOF@phil>

Am Montag, 25. August 2025, 10:28:27 Mitteleurop?ische Sommerzeit schrieb Nicolas Frattaroli:
> The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
> drivers that use constant masks.
> 
> Remove this driver's HIWORD_UPDATE macro, and replace instances of it
> with either FIELD_PREP_WM16 or FIELD_PREP_WM16_CONST, depending on
> whether they're in an initializer. This gives us better error checking,
> which already saved me some trouble during this refactor.
> 
> The driver's HIWORD_UPDATE macro doesn't shift up the value, but expects
> a pre-shifted value. Meanwhile, FIELD_PREP_WM16 and
> FIELD_PREP_WM16_CONST will shift the value for us, based on the given
> mask. So a few things that used to be a HIWORD_UPDATE(VERY_LONG_FOO,
> VERY_LONG_FOO) are now a somewhat more pleasant
> FIELD_PREP_WM16(VERY_LONG_FOO, 1).
> 
> There are some non-trivial refactors here. A few literals needed a UL
> suffix added to stop them from unintentionally overflowing as a signed
> long. To make sure all of these cases are caught, and not just the ones
> where the FIELD_PREP_WM16* macros use such a value as a mask, just mark
> every literal that's used as a mask as unsigned.
> 
> Non-contiguous masks also have to be split into multiple
> FIELD_PREP_WM16* instances, as the macro's checks and shifting logic
> rely on contiguous masks.
> 
> This is compile-tested only.
> 
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>

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




From heiko at sntech.de  Wed Aug 27 00:22:46 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 27 Aug 2025 09:22:46 +0200
Subject: [PATCH v3 08/20] drm/rockchip: vop2: switch to FIELD_PREP_WM16 macro
In-Reply-To: <20250825-byeword-update-v3-8-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
 <20250825-byeword-update-v3-8-947b841cdb29@collabora.com>
Message-ID: <5228954.Icojqenx9y@phil>

Am Montag, 25. August 2025, 10:28:28 Mitteleurop?ische Sommerzeit schrieb Nicolas Frattaroli:
> The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
> drivers that use constant masks.
> 
> Remove VOP2's HIWORD_UPDATE macro from the vop2 header file, and replace
> all instances in rockchip_vop2_reg.c (the only user of this particular
> HIWORD_UPDATE definition) with equivalent FIELD_PREP_WM16 instances. This
> gives us better error checking.
> 
> Reviewed-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
> Tested-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>

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




From heiko at sntech.de  Wed Aug 27 00:25:38 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 27 Aug 2025 09:25:38 +0200
Subject: [PATCH v3 09/20] phy: rockchip-samsung-dcphy: switch to FIELD_PREP_WM16
 macro
In-Reply-To: <20250825-byeword-update-v3-9-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
 <20250825-byeword-update-v3-9-947b841cdb29@collabora.com>
Message-ID: <5502100.jE0xQCEvom@phil>

Am Montag, 25. August 2025, 10:28:29 Mitteleurop?ische Sommerzeit schrieb Nicolas Frattaroli:
> The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
> drivers that use constant masks.
> 
> phy-rockchip-samsung-dcphy is actually an exemplary example, where the
> similarities to FIELD_PREP were spotted and the driver local macro has
> the same semantics as the new FIELD_PREP_WM16 hw_bitfield.h macro.
> 
> Still, get rid of FIELD_PREP_HIWORD now that a shared implementation
> exists, replacing the two instances of it with FIELD_PREP_WM16. This
> gives us slightly better error checking; the value is now checked to fit
> in 16 bits.
> 
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>

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




From heiko at sntech.de  Wed Aug 27 00:30:18 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 27 Aug 2025 09:30:18 +0200
Subject: [PATCH v3 10/20] drm/rockchip: dw_hdmi_qp: switch to FIELD_PREP_WM16
 macro
In-Reply-To: <20250825-byeword-update-v3-10-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
 <20250825-byeword-update-v3-10-947b841cdb29@collabora.com>
Message-ID: <881125850.0ifERbkFSE@phil>

Am Montag, 25. August 2025, 10:28:30 Mitteleurop?ische Sommerzeit schrieb Nicolas Frattaroli:
> The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
> drivers that use constant masks.
> 
> Replace this driver's HIWORD_UPDATE with the FIELD_PREP_WM16 macro from
> hw_bitfield.h. While at it, disambiguate the GRF write to SOC_CON7 by
> splitting the definition into the individual bitflags. This is done
> because FIELD_PREP_WM16 shifts the value for us according to the mask,
> so writing the mask to itself to enable two bits is no longer something
> that can be done. It should also not be done anyway because it hides the
> true meaning of those two individual bit flags.
> 
> HDMI output with this patch has been tested on both RK3588 and RK3576.
> On the former, with both present HDMI connectors.
> 
> Reviewed-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
> Tested-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>

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




From heiko at sntech.de  Wed Aug 27 00:32:26 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 27 Aug 2025 09:32:26 +0200
Subject: [PATCH v3 11/20] drm/rockchip: inno-hdmi: switch to FIELD_PREP_WM16 macro
In-Reply-To: <20250825-byeword-update-v3-11-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
 <20250825-byeword-update-v3-11-947b841cdb29@collabora.com>
Message-ID: <5006976.yKVeVyVuyW@phil>

Am Montag, 25. August 2025, 10:28:31 Mitteleurop?ische Sommerzeit schrieb Nicolas Frattaroli:
> The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
> drivers that use constant masks.
> 
> The inno-hdmi driver's own HIWORD_UPDATE macro is instantiated only
> twice. Remove it, and replace its uses with FIELD_PREP_WM16. Since
> FIELD_PREP_WM16 shifts the value for us, we replace using the mask as
> the value by simply using 1 instead.
> 
> With the new FIELD_PREP_WM16 macro, we gain better error checking and a
> central shared definition.
> 
> This has been compile-tested only as I lack hardware this old, but the
> change is trivial enough that I am fairly certain it's equivalent.
> 
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>

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




From heiko at sntech.de  Wed Aug 27 00:34:44 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 27 Aug 2025 09:34:44 +0200
Subject: [PATCH v3 12/20] phy: rockchip-usb: switch to FIELD_PREP_WM16 macro
In-Reply-To: <20250825-byeword-update-v3-12-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
 <20250825-byeword-update-v3-12-947b841cdb29@collabora.com>
Message-ID: <5249188.NgBsaNRSFp@phil>

Am Montag, 25. August 2025, 10:28:32 Mitteleurop?ische Sommerzeit schrieb Nicolas Frattaroli:
> The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
> drivers that use constant masks.
> 
> Remove this driver's HIWORD_UPDATE macro, and replace all instances of
> it with (hopefully) equivalent FIELD_PREP_WM16 instances. To do this, a
> few of the defines are being adjusted, as FIELD_PREP_WM16 shifts up the
> value for us. This gets rid of the icky update(mask, mask) shenanigans.
> 
> The benefit of using FIELD_PREP_WM16 is that it does more checking of
> the input, hopefully catching errors. In practice, a shared definition
> makes code more readable than several different flavours of the same
> macro, and the shifted value helps as well.
> 
> I do not have the hardware that uses this particular driver, so it's
> compile-tested only as far as my own testing goes.
> 
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>

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




From heiko at sntech.de  Wed Aug 27 00:37:41 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 27 Aug 2025 09:37:41 +0200
Subject: [PATCH v3 13/20] drm/rockchip: dw_hdmi: switch to FIELD_PREP_WM16* macros
In-Reply-To: <20250825-byeword-update-v3-13-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
 <20250825-byeword-update-v3-13-947b841cdb29@collabora.com>
Message-ID: <18528244.tv2OnDr8pf@phil>

Am Montag, 25. August 2025, 10:28:33 Mitteleurop?ische Sommerzeit schrieb Nicolas Frattaroli:
> The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
> drivers that use constant masks.
> 
> Remove this driver's very own HIWORD_UPDATE macro, and replace all
> instances of it with equivalent instantiations of FIELD_PREP_WM16 or
> FIELD_PREP_WM16_CONST, depending on whether it's in an initializer.
> 
> This gives us better error checking, and a centrally agreed upon
> signature for this macro, to ease in code comprehension.
> 
> Because FIELD_PREP_WM16/FIELD_PREP_WM16_CONST shifts the value to the
> mask (like FIELD_PREP et al do), a lot of macro instantiations get
> easier to read.
> 
> This was tested on an RK3568 ODROID M1, as well as an RK3399 ROCKPro64.
> 
> Reviewed-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
> Tested-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>

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




From heiko at sntech.de  Wed Aug 27 00:39:22 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 27 Aug 2025 09:39:22 +0200
Subject: [PATCH v3 14/20] ASoC: rockchip: i2s-tdm: switch to FIELD_PREP_WM16_CONST
 macro
In-Reply-To: <20250825-byeword-update-v3-14-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
 <20250825-byeword-update-v3-14-947b841cdb29@collabora.com>
Message-ID: <5725847.BddDVKsqQX@phil>

Am Montag, 25. August 2025, 10:28:34 Mitteleurop?ische Sommerzeit schrieb Nicolas Frattaroli:
> The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
> drivers that use constant masks.
> 
> Replace the implementation of this driver's HIWORD_UPDATE macro with an
> instance of FIELD_PREP_WM16_CONST. The const variant is chosen here
> because some of the header defines are then used in initializers.
> 
> This gives us some compile-time error checking, while keeping the diff
> very small and easy to review.
> 
> Acked-by: Mark Brown <broonie at kernel.org>
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>

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




From heiko at sntech.de  Wed Aug 27 00:40:28 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 27 Aug 2025 09:40:28 +0200
Subject: [PATCH v3 15/20] net: stmmac: dwmac-rk: switch to FIELD_PREP_WM16 macro
In-Reply-To: <20250825-byeword-update-v3-15-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
 <20250825-byeword-update-v3-15-947b841cdb29@collabora.com>
Message-ID: <12530943.rMLUfLXkoz@phil>

Am Montag, 25. August 2025, 10:28:35 Mitteleurop?ische Sommerzeit schrieb Nicolas Frattaroli:
> The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
> drivers that use constant masks.
> 
> Like many other Rockchip drivers, dwmac-rk has its own HIWORD_UPDATE
> macro. Its semantics allow us to redefine it as a wrapper to the shared
> hw_bitfield.h FIELD_PREP_WM16 macros though.
> 
> Replace the implementation of this driver's very own HIWORD_UPDATE macro
> with an instance of FIELD_PREP_WM16 from hw_bitfield.h. This keeps the
> diff easily reviewable, while giving us more compile-time error
> checking.
> 
> The related GRF_BIT macro is left alone for now; any attempt to rework
> the code to not use its own solution here would likely end up harder to
> review and less pretty for the time being.
> 
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>

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




From heiko at sntech.de  Wed Aug 27 00:56:55 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 27 Aug 2025 09:56:55 +0200
Subject: [PATCH v3 16/20] PCI: rockchip: Switch to FIELD_PREP_WM16* macros
In-Reply-To: <20250825-byeword-update-v3-16-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
 <20250825-byeword-update-v3-16-947b841cdb29@collabora.com>
Message-ID: <7681880.cEBGB3zze1@phil>

Am Montag, 25. August 2025, 10:28:36 Mitteleurop?ische Sommerzeit schrieb Nicolas Frattaroli:
> The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
> drivers that use constant masks.
> 
> The Rockchip PCI driver, like many other Rockchip drivers, has its very
> own definition of HIWORD_UPDATE.
> 
> Remove it, and replace its usage with either FIELD_PREP_WM16, or two new
> header local macros for setting/clearing a bit with the high mask, which
> use FIELD_PREP_WM16_CONST internally. In the process, ENCODE_LANES
> needed to be adjusted, as FIELD_PREP_WM16* shifts the value for us.
> 
> That this is equivalent was verified by first making all FIELD_PREP_WM16
> instances FIELD_PREP_WM16_CONST, then doing a static_assert() comparing
> it to the old macro (and for those with parameters, static_asserting for
> the full range of possible values with the old encode macro).
> 
> What we get out of this is compile time error checking to make sure the
> value actually fits in the mask, and that the mask fits in the register,
> and also generally less icky code that writes shifted values when it
> actually just meant to set and clear a handful of bits.
> 
> Acked-by: Bjorn Helgaas <bhelgaas at google.com>
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>

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




From heiko at sntech.de  Wed Aug 27 00:58:04 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 27 Aug 2025 09:58:04 +0200
Subject: [PATCH v3 17/20] PCI: dw-rockchip: Switch to FIELD_PREP_WM16 macro
In-Reply-To: <20250825-byeword-update-v3-17-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
 <20250825-byeword-update-v3-17-947b841cdb29@collabora.com>
Message-ID: <5730130.X9hSmTKtgW@phil>

Am Montag, 25. August 2025, 10:28:37 Mitteleurop?ische Sommerzeit schrieb Nicolas Frattaroli:
> The era of hand-rolled HIWORD_UPDATE macros is over.
> 
> Like many other Rockchip drivers, pcie-dw-rockchip brings with it its
> very own flavour of HIWORD_UPDATE. It's occasionally used without a
> constant mask, which complicates matters. HIWORD_UPDATE_BIT is a
> confusingly named addition, as it doesn't update the bit, it actually
> sets all bits in the value to 1. HIWORD_DISABLE_BIT is similarly
> confusing; it disables several bits at once by using the value as a mask
> and the inverse of value as the value, and the "disabling only these"
> effect comes from the hardware actually using the mask. The more obvious
> approach would've been HIWORD_UPDATE(val, 0) in my opinion.
> 
> This is part of the motivation why this patch uses hw_bitfield.h's
> FIELD_PREP_WM16 instead, where possible. FIELD_PREP_WM16 requires a
> constant bit mask, which isn't possible where the irq number is used to
> generate a bit mask. For that purpose, we replace it with a more robust
> macro than what was there but that should also bring close to zero
> runtime overhead: we actually mask the IRQ number to make sure we're not
> writing garbage.
> 
> For the remaining bits, there also are some caveats. For starters, the
> PCIE_CLIENT_ENABLE_LTSSM and PCIE_CLIENT_DISABLE_LTSSM were named in a
> manner that isn't quite truthful to what they do. Their modification
> actually spans not just the LTSSM bit but also another bit, flipping
> only the LTSSM one, but keeping the other (which according to the TRM
> has a reset value of 0) always enabled. This other bit is reserved as of
> the IP version RK3588 uses at least, and I have my doubts as to whether
> it was meant to be set, and whether it was meant to be set in that code
> path. Either way, it's confusing.
> 
> Replace it with just writing either 1 or 0 to the LTSSM bit, using the
> new FIELD_PREP_WM16 macro from hw_bitfield.h, which grants us the
> benefit of better compile-time error checking.
> 
> The change of no longer setting the reserved bit doesn't appear to
> change the behaviour on RK3568 in RC mode, where it's not marked as
> reserved.
> 
> PCIE_CLIENT_RC_MODE/PCIE_CLIENT_EP_MODE was another field that wasn't
> super clear on what the bit field modification actually is. As far as I
> can tell, switching to RC mode doesn't actually write the correct value
> to the field if any of its bits have been set previously, as it only
> updates one bit of a 4 bit field.
> 
> Replace it by actually writing the full values to the field, using the
> new FIELD_PREP_WM16 macro, which grants us the benefit of better
> compile-time error checking.
> 
> This patch was tested on RK3588 (PCIe3 x4 controller), RK3576 (PCIe2 x1
> controller) and RK3568 (PCIe x2 controller), all in RC mode.
> 
> Acked-by: Bjorn Helgaas <bhelgaas at google.com>
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>

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




From heiko at sntech.de  Wed Aug 27 01:03:27 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 27 Aug 2025 10:03:27 +0200
Subject: [PATCH v3 18/20] PM / devfreq: rockchip-dfi: switch to FIELD_PREP_WM16
 macro
In-Reply-To: <20250825-byeword-update-v3-18-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
 <20250825-byeword-update-v3-18-947b841cdb29@collabora.com>
Message-ID: <16814931.dW097sEU6C@phil>

Am Montag, 25. August 2025, 10:28:38 Mitteleurop?ische Sommerzeit schrieb Nicolas Frattaroli:
> The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
> drivers that use constant masks.
> 
> Like many other Rockchip drivers, rockchip-dfi brings with it its own
> HIWORD_UPDATE macro. This variant doesn't shift the value (and like the
> others, doesn't do any checking).
> 
> Remove it, and replace instances of it with hw_bitfield.h's
> FIELD_PREP_WM16.  Since FIELD_PREP_WM16 requires contiguous masks and
> shifts the value for us, some reshuffling of definitions needs to
> happen.
> 
> This gives us better compile-time error checking, and in my opinion,
> nicer code.
> 
> Tested on an RK3568 ODROID-M1 board, and an RK3588 ROCK 5B board.
> 
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>

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




From heiko at sntech.de  Wed Aug 27 01:04:24 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 27 Aug 2025 10:04:24 +0200
Subject: [PATCH v3 20/20] phy: rockchip-pcie: switch to FIELD_PREP_WM16 macro
In-Reply-To: <20250825-byeword-update-v3-20-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
 <20250825-byeword-update-v3-20-947b841cdb29@collabora.com>
Message-ID: <5143535.KlZ2vcFHjT@phil>

Am Montag, 25. August 2025, 10:28:40 Mitteleurop?ische Sommerzeit schrieb Nicolas Frattaroli:
> The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
> drivers that use constant masks.
> 
> The Rockchip PCIe PHY driver, used on the RK3399, has its own definition
> of HIWORD_UPDATE.
> 
> Remove it, and replace instances of it with hw_bitfield.h's
> FIELD_PREP_WM16. To achieve this, some mask defines are reshuffled, as
> FIELD_PREP_WM16 uses the mask as both the mask of bits to write and to
> derive the shift amount from in order to shift the value.
> 
> In order to ensure that the mask is always a constant, the inst->index
> shift is performed after the FIELD_PREP_WM16, as this is a runtime
> value.
> 
> From this, we gain compile-time error checking, and in my humble opinion
> nicer code, as well as a single definition of this macro across the
> entire codebase to aid in code comprehension.
> 
> Tested on a RK3399 ROCKPro64, where PCIe still works as expected when
> accessing an NVMe drive.
> 
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>


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




From heiko at sntech.de  Wed Aug 27 01:06:39 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 27 Aug 2025 10:06:39 +0200
Subject: [PATCH v3 19/20] clk: sp7021: switch to FIELD_PREP_WM16 macro
In-Reply-To: <20250825-byeword-update-v3-19-947b841cdb29@collabora.com>
References: <20250825-byeword-update-v3-0-947b841cdb29@collabora.com>
 <20250825-byeword-update-v3-19-947b841cdb29@collabora.com>
Message-ID: <5154190.bB369e8A3T@phil>

Am Montag, 25. August 2025, 10:28:39 Mitteleurop?ische Sommerzeit schrieb Nicolas Frattaroli:
> The sp7021 clock driver has its own shifted high word mask macro,
> similar to the ones many Rockchip drivers have.
> 
> Remove it, and replace instances of it with hw_bitfield.h's
> FIELD_PREP_WM16 macro, which does the same thing except in a common
> macro that also does compile-time error checking.
> 
> This was compile-tested with 32-bit ARM with Clang, no runtime tests
> were performed as I lack the hardware. However, I verified that fix
> commit 5c667d5a5a3e ("clk: sp7021: Adjust width of _m in HWM_FIELD_PREP()")
> is not regressed. No warning is produced.
> 
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>

While I have no connection with that specific piece of hardware,
the change itself looks correct, so

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




From xiangxu.yin at oss.qualcomm.com  Wed Aug 27 05:17:39 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Wed, 27 Aug 2025 20:17:39 +0800
Subject: [PATCH v3 09/14] phy: qcom: qmp-usbc: Add DP PHY ops for USB/DP
 switchable Type-C PHYs
In-Reply-To: <3pr7ninjxr4pgsz56dr6ojjmx27fzzszmtt6mx4r6qaqt25tnc@nrgx5qiqc7z4>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-9-a43bd25ec39c@oss.qualcomm.com>
 <3pr7ninjxr4pgsz56dr6ojjmx27fzzszmtt6mx4r6qaqt25tnc@nrgx5qiqc7z4>
Message-ID: <9bf7f51b-dcfb-4ff8-848e-dcf144936f2e@oss.qualcomm.com>


On 8/20/2025 7:45 PM, Dmitry Baryshkov wrote:
> On Wed, Aug 20, 2025 at 05:34:51PM +0800, Xiangxu Yin wrote:
>> Define qmp_usbc_dp_phy_ops struct to support DP mode on USB/DP
>> switchable PHYs.
>>
>> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
>> ---
>>  drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 163 +++++++++++++++++++++++++++++++
>>  1 file changed, 163 insertions(+)
>>
>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
>> index 1508a4a5f57aff85318485b79528325f28a825a4..a1495a2029cf038bb65c36e42d0a4f633e544558 100644
>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
>> @@ -22,6 +22,8 @@
>>  #include <linux/slab.h>
>>  #include <linux/usb/typec.h>
>>  #include <linux/usb/typec_mux.h>
>> +#include <dt-bindings/phy/phy-qcom-qmp.h>
>> +#include <drm/bridge/aux-bridge.h>
> This one is not necessary yet


Ok, will remove unnecessary aux-bridge related part.


>>  
>>  #include "phy-qcom-qmp-common.h"
>>  
> [...]
>
>>  static const struct phy_ops qmp_usbc_usb_phy_ops = {
>>  	.init		= qmp_usbc_usb_enable,
>>  	.exit		= qmp_usbc_usb_disable,
>> @@ -1095,6 +1248,16 @@ static const struct phy_ops qmp_usbc_usb_phy_ops = {
>>  	.owner		= THIS_MODULE,
>>  };
>>  
>> +static const struct phy_ops qmp_usbc_dp_phy_ops = {
> Please try restructuring your patches so that there are no unused
> warnings in the middle of the series. You can split the next patch into
> 'parse' and 'enable' parts, then squash this patch into the 'enable'
> one.


You mean it's better to define and register new functions in the same patch?

where they're first used, to avoid unused warnings??And for things like parse_dt and phy_ops,

it's fine to split them into separate patches if each part is used right away?


>
>> +	.init		= qmp_usbc_dp_enable,
>> +	.exit		= qmp_usbc_dp_disable,
>> +	.configure	= qmp_usbc_dp_configure,
>> +	.calibrate	= qmp_usbc_dp_calibrate,
>> +	.power_on	= qmp_usbc_dp_power_on,
>> +	.power_off	= qmp_usbc_dp_power_off,
>> +	.owner		= THIS_MODULE,
>> +};
>> +
>>  static void qmp_usbc_enable_autonomous_mode(struct qmp_usbc *qmp)
>>  {
>>  	const struct qmp_phy_cfg *cfg = qmp->cfg;
>>
>> -- 
>> 2.34.1
>>


From xiangxu.yin at oss.qualcomm.com  Wed Aug 27 05:23:41 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Wed, 27 Aug 2025 20:23:41 +0800
Subject: [PATCH v3 10/14] phy: qcom: qmp-usbc: Add TCSR parsing and USB/DP
 mode mutex handling
In-Reply-To: <i4rc5siu4q2o4sjk3j4bex7b7qdrs26y6lxsfnike7e7kqdva3@xddrd7vowtlb>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-10-a43bd25ec39c@oss.qualcomm.com>
 <i4rc5siu4q2o4sjk3j4bex7b7qdrs26y6lxsfnike7e7kqdva3@xddrd7vowtlb>
Message-ID: <08997fc3-8175-4638-96ea-ac15ad20160c@oss.qualcomm.com>


On 8/20/2025 7:24 PM, Dmitry Baryshkov wrote:
> On Wed, Aug 20, 2025 at 05:34:52PM +0800, Xiangxu Yin wrote:
>> Parse TCSR registers to support DP mode signaling via dp_phy_mode_reg.
>> Introduce mutual exclusion between USB and DP PHY modes to prevent
>> simultaneous activation. Also update com_init/com_exit to reflect DP
>> mode initialization and cleanup.
>>
>> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
>> ---
>>  drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 60 +++++++++++++++++++++++++-------
>>  1 file changed, 47 insertions(+), 13 deletions(-)
>>
>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
>> index a1495a2029cf038bb65c36e42d0a4f633e544558..821398653bef23e1915d9d3a3a2950b0bfbefb9a 100644
>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
>> @@ -674,7 +674,7 @@ static const struct qmp_phy_cfg qcs615_usb3dp_phy_cfg = {
>>  	.num_vregs		= ARRAY_SIZE(qmp_phy_usbdp_vreg_l),
>>  };
>>  
>> -static int qmp_usbc_com_init(struct phy *phy)
>> +static int qmp_usbc_com_init(struct phy *phy, bool is_dp)
>>  {
>>  	struct qmp_usbc *qmp = phy_get_drvdata(phy);
>>  	const struct qmp_phy_cfg *cfg = qmp->cfg;
>> @@ -704,15 +704,20 @@ static int qmp_usbc_com_init(struct phy *phy)
>>  	if (ret)
>>  		goto err_assert_reset;
>>  
>> -	qphy_setbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], SW_PWRDN);
>> +	if (!is_dp) {
>> +		qphy_setbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], SW_PWRDN);
> Why? Don't we need to program those bits for DP PHY too?
>
> If not, move them to USB init call.


For these USB3DP PHY series, USB registers in pcs_misc will don?t affect DP.?

I?ll move them to USB init call.


>>  
>>  #define SW_PORTSELECT_VAL			BIT(0)
>>  #define SW_PORTSELECT_MUX			BIT(1)
>> -	/* Use software based port select and switch on typec orientation */
>> -	val = SW_PORTSELECT_MUX;
>> -	if (qmp->orientation == TYPEC_ORIENTATION_REVERSE)
>> -		val |= SW_PORTSELECT_VAL;
>> -	writel(val, qmp->pcs_misc);
>> +		/* Use software based port select and switch on typec orientation */
>> +		val = SW_PORTSELECT_MUX;
>> +		if (qmp->orientation == TYPEC_ORIENTATION_REVERSE)
>> +			val |= SW_PORTSELECT_VAL;
>> +		writel(val, qmp->pcs_misc);
>> +	}
>> +
>> +	if (qmp->tcsr_map && qmp->dp_phy_mode_reg)
>> +		regmap_write(qmp->tcsr_map, qmp->dp_phy_mode_reg, is_dp);
> Write this reg directly from USB / DP init.


Ok.


>>  
>>  	return 0;
>>  
>> @@ -733,6 +738,9 @@ static int qmp_usbc_com_exit(struct phy *phy)
>>  
>>  	clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks);
>>  
>> +	if (qmp->tcsr_map && qmp->dp_phy_mode_reg)
>> +		regmap_write(qmp->tcsr_map, qmp->dp_phy_mode_reg, 0);
> Why?


Since this is a switchable PHY, it makes more sense to set it only during enable.
I?ll remove the TCSR handling from com_exit in the next patch.


>> +
>>  	regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
>>  
>>  	return 0;
>> @@ -1045,6 +1053,17 @@ static int qmp_usbc_usb_power_off(struct phy *phy)
>>  	return 0;
>>  }
>>  
>> +static int qmp_check_mutex_phy(struct qmp_usbc *qmp, bool is_dp)
>> +{
>> +	if ((is_dp && qmp->usb_init_count) ||
>> +	    (!is_dp && qmp->dp_init_count)) {
>> +		dev_err(qmp->dev, "%s PHY busy\n", is_dp ? "USB" : "DP");
> "PHY is configured for %s, can not enable %s\n"


Ack.


>> +		return -EBUSY;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>>  static int qmp_usbc_usb_enable(struct phy *phy)
>>  {
>>  	struct qmp_usbc *qmp = phy_get_drvdata(phy);
>> @@ -1052,7 +1071,11 @@ static int qmp_usbc_usb_enable(struct phy *phy)
>>  
>>  	mutex_lock(&qmp->phy_mutex);
>>  
>> -	ret = qmp_usbc_com_init(phy);
>> +	ret = qmp_check_mutex_phy(qmp, false);
>> +	if (ret)
>> +		goto out_unlock;
>> +
>> +	ret = qmp_usbc_com_init(phy, false);
>>  	if (ret)
>>  		goto out_unlock;
>>  
>> @@ -1103,7 +1126,11 @@ static int qmp_usbc_dp_enable(struct phy *phy)
>>  
>>  	mutex_lock(&qmp->phy_mutex);
>>  
>> -	ret = qmp_usbc_com_init(phy);
>> +	ret = qmp_check_mutex_phy(qmp, true);
>> +	if (ret)
>> +		goto dp_init_unlock;
>> +
>> +	ret = qmp_usbc_com_init(phy, true);
>>  	if (ret)
>>  		goto dp_init_unlock;
>>  
>> @@ -1467,7 +1494,7 @@ static int qmp_usbc_typec_switch_set(struct typec_switch_dev *sw,
>>  		qmp_usbc_usb_power_off(qmp->usb_phy);
>>  		qmp_usbc_com_exit(qmp->usb_phy);
>>  
>> -		qmp_usbc_com_init(qmp->usb_phy);
>> +		qmp_usbc_com_init(qmp->usb_phy, false);
>>  		qmp_usbc_usb_power_on(qmp->usb_phy);
>>  	}
>>  
>> @@ -1602,13 +1629,13 @@ static int qmp_usbc_parse_usb_dt(struct qmp_usbc *qmp)
>>  	return 0;
>>  }
>>  
>> -static int qmp_usbc_parse_vls_clamp(struct qmp_usbc *qmp)
>> +static int qmp_usbc_parse_tcsr(struct qmp_usbc *qmp)
>>  {
>>  	struct of_phandle_args tcsr_args;
>>  	struct device *dev = qmp->dev;
>>  	int ret;
>>  
>> -	/*  for backwards compatibility ignore if there is no property */
>> +	/*  for backwards compatibility ignore if there is 1 or no property */
>>  	ret = of_parse_phandle_with_fixed_args(dev->of_node, "qcom,tcsr-reg", 1, 0,
>>  					       &tcsr_args);
>>  	if (ret == -ENOENT)
>> @@ -1623,6 +1650,13 @@ static int qmp_usbc_parse_vls_clamp(struct qmp_usbc *qmp)
>>  
>>  	qmp->vls_clamp_reg = tcsr_args.args[0];
>>  
>> +	ret = of_parse_phandle_with_fixed_args(dev->of_node, "qcom,tcsr-reg", 1, 1,
>> +					       &tcsr_args);
>> +	if (ret == -ENOENT)
>> +		return 0;
>> +
>> +	qmp->dp_phy_mode_reg = tcsr_args.args[0];
>> +
>>  	return 0;
>>  }
>>  
>> @@ -1665,7 +1699,7 @@ static int qmp_usbc_probe(struct platform_device *pdev)
>>  	if (ret)
>>  		return ret;
>>  
>> -	ret = qmp_usbc_parse_vls_clamp(qmp);
>> +	ret = qmp_usbc_parse_tcsr(qmp);
>>  	if (ret)
>>  		return ret;
>>  
>>
>> -- 
>> 2.34.1
>>


From xiangxu.yin at oss.qualcomm.com  Wed Aug 27 05:34:39 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Wed, 27 Aug 2025 20:34:39 +0800
Subject: [PATCH v3 11/14] phy: qcom: qmp-usbc: Finalize USB/DP switchable
 PHY support
In-Reply-To: <jjsijdmh4hdbgd2boebtrmzvblvhz2hnl7mtv5ga76ine2fnsb@i72dz3r4lbjp>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-11-a43bd25ec39c@oss.qualcomm.com>
 <jjsijdmh4hdbgd2boebtrmzvblvhz2hnl7mtv5ga76ine2fnsb@i72dz3r4lbjp>
Message-ID: <82d19340-b887-4093-9d24-4b2e19b99f8b@oss.qualcomm.com>


On 8/20/2025 7:42 PM, Dmitry Baryshkov wrote:
> On Wed, Aug 20, 2025 at 05:34:53PM +0800, Xiangxu Yin wrote:
>> Complete USB/DP switchable PHY integration by adding DP clock
>> registration, aux bridge setup, and DT parsing. Implement clock
>> provider logic for USB and DP branches, and extend PHY translation
>> to support both USB and DP instances.
>>
>> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
>> ---
>>  drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 331 ++++++++++++++++++++++++++++---
>>  1 file changed, 299 insertions(+), 32 deletions(-)
>>
>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
>> index 821398653bef23e1915d9d3a3a2950b0bfbefb9a..74b9f75c8864efe270f394bfbfd748793dada1f5 100644
>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
>> @@ -995,6 +995,11 @@ static int qmp_usbc_usb_power_on(struct phy *phy)
>>  	qmp_configure(qmp->dev, qmp->serdes, cfg->serdes_tbl,
>>  		      cfg->serdes_tbl_num);
>>  
>> +	if (IS_ERR(qmp->pipe_clk)) {
>> +		return dev_err_probe(qmp->dev, PTR_ERR(qmp->pipe_clk),
>> +				     "pipe clock not defined\n");
>> +	}
> No, this should not be allowed.


Ok, will fix in next patch.


>> +
>>  	ret = clk_prepare_enable(qmp->pipe_clk);
>>  	if (ret) {
>>  		dev_err(qmp->dev, "pipe_clk enable failed err=%d\n", ret);
>> @@ -1365,11 +1370,13 @@ static int __maybe_unused qmp_usbc_runtime_resume(struct device *dev)
>>  	if (ret)
>>  		return ret;
>>  
>> -	ret = clk_prepare_enable(qmp->pipe_clk);
>> -	if (ret) {
>> -		dev_err(dev, "pipe_clk enable failed, err=%d\n", ret);
>> -		clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks);
>> -		return ret;
>> +	if (!IS_ERR(qmp->pipe_clk)) {
> Similarly.


Ack.


>> +		ret = clk_prepare_enable(qmp->pipe_clk);
>> +		if (ret) {
>> +			dev_err(dev, "pipe_clk enable failed, err=%d\n", ret);
>> +			clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks);
>> +			return ret;
>> +		}
>>  	}
>>  
>>  	qmp_usbc_disable_autonomous_mode(qmp);
>> @@ -1422,9 +1429,23 @@ static int qmp_usbc_clk_init(struct qmp_usbc *qmp)
>>  	return devm_clk_bulk_get_optional(dev, num, qmp->clks);
>>  }
>>  
>> -static void phy_clk_release_provider(void *res)
>> +static struct clk_hw *qmp_usbc_clks_hw_get(struct of_phandle_args *clkspec, void *data)
>>  {
>> -	of_clk_del_provider(res);
>> +	struct qmp_usbc *qmp = data;
>> +
>> +	if (clkspec->args_count == 0)
>> +		return &qmp->pipe_clk_fixed.hw;
>> +
>> +	switch (clkspec->args[0]) {
>> +	case QMP_USB43DP_USB3_PIPE_CLK:
>> +		return &qmp->pipe_clk_fixed.hw;
>> +	case QMP_USB43DP_DP_LINK_CLK:
>> +		return &qmp->dp_link_hw;
>> +	case QMP_USB43DP_DP_VCO_DIV_CLK:
>> +		return &qmp->dp_pixel_hw;
>> +	}
>> +
>> +	return ERR_PTR(-EINVAL);
>>  }
>>  
>>  /*
>> @@ -1453,8 +1474,11 @@ static int phy_pipe_clk_register(struct qmp_usbc *qmp, struct device_node *np)
>>  
>>  	ret = of_property_read_string(np, "clock-output-names", &init.name);
>>  	if (ret) {
>> -		dev_err(qmp->dev, "%pOFn: No clock-output-names\n", np);
>> -		return ret;
>> +		char name[64];
>> +
>> +		/* Clock name is not mandatory. */
>> +		snprintf(name, sizeof(name), "%s::pipe_clk", dev_name(qmp->dev));
>> +		init.name = name;
>>  	}
>>  
>>  	init.ops = &clk_fixed_rate_ops;
>> @@ -1463,19 +1487,7 @@ static int phy_pipe_clk_register(struct qmp_usbc *qmp, struct device_node *np)
>>  	fixed->fixed_rate = 125000000;
>>  	fixed->hw.init = &init;
>>  
>> -	ret = devm_clk_hw_register(qmp->dev, &fixed->hw);
>> -	if (ret)
>> -		return ret;
>> -
>> -	ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &fixed->hw);
>> -	if (ret)
>> -		return ret;
>> -
>> -	/*
>> -	 * Roll a devm action because the clock provider is the child node, but
>> -	 * the child node is not actually a device.
>> -	 */
>> -	return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
>> +	return devm_clk_hw_register(qmp->dev, &fixed->hw);
>>  }
>>  
>>  #if IS_ENABLED(CONFIG_TYPEC)
>> @@ -1660,6 +1672,235 @@ static int qmp_usbc_parse_tcsr(struct qmp_usbc *qmp)
>>  	return 0;
>>  }
>>  
>> +static int qmp_usbc_parse_usb3dp_dt(struct qmp_usbc *qmp)
>> +{
>> +	struct platform_device *pdev = to_platform_device(qmp->dev);
>> +	const struct qmp_phy_cfg *cfg = qmp->cfg;
>> +	const struct qmp_usbc_offsets *offs = cfg->offsets;
>> +	struct device *dev = qmp->dev;
>> +	void __iomem *base;
>> +	int ret;
>> +
>> +	base = devm_platform_ioremap_resource(pdev, 0);
>> +	if (IS_ERR(base))
>> +		return PTR_ERR(base);
>> +
>> +	qmp->dp_serdes = base + offs->dp_serdes;
>> +	qmp->dp_tx = base + offs->dp_txa;
>> +	qmp->dp_tx2 = base + offs->dp_txb;
>> +	qmp->dp_dp_phy = base + offs->dp_dp_phy;
> Squash this into qmp_usbc_parse_dt(). Set these fields if
> dp_serdes != 0.


Ack.


>> +	qmp->serdes = base + offs->serdes;
>> +	qmp->pcs = base + offs->pcs;
>> +	if (offs->pcs_misc)
>> +		qmp->pcs_misc = base + offs->pcs_misc;
>> +	qmp->tx = base + offs->tx;
>> +	qmp->rx = base + offs->rx;
>> +
>> +	qmp->tx2 = base + offs->tx2;
>> +	qmp->rx2 = base + offs->rx2;
>> +
>> +	ret = qmp_usbc_clk_init(qmp);
>> +	if (ret)
>> +		return ret;
>> +
>> +	qmp->pipe_clk = devm_clk_get(dev, "pipe");
>> +	if (IS_ERR(qmp->pipe_clk)) {
>> +		/* usb3dp allow no pipe clk define */
>> +		if (cfg->type == QMP_PHY_USBC_USB3_ONLY)
>> +			return dev_err_probe(dev, PTR_ERR(qmp->pipe_clk),
>> +						"failed to get pipe clock\n");
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +/*
>> + * Display Port PLL driver block diagram for branch clocks
>> + *
>> + *              +------------------------------+
>> + *              |         DP_VCO_CLK           |
>> + *              |                              |
>> + *              |    +-------------------+     |
>> + *              |    |   (DP PLL/VCO)    |     |
>> + *              |    +---------+---------+     |
>> + *              |              v               |
>> + *              |   +----------+-----------+   |
>> + *              |   | hsclk_divsel_clk_src |   |
>> + *              |   +----------+-----------+   |
>> + *              +------------------------------+
>> + *                              |
>> + *          +---------<---------v------------>----------+
>> + *          |                                           |
>> + * +--------v----------------+                          |
>> + * |    dp_phy_pll_link_clk  |                          |
>> + * |     link_clk            |                          |
>> + * +--------+----------------+                          |
>> + *          |                                           |
>> + *          |                                           |
>> + *          v                                           v
>> + * Input to DISPCC block                                |
>> + * for link clk, crypto clk                             |
>> + * and interface clock                                  |
>> + *                                                      |
>> + *                                                      |
>> + *      +--------<------------+-----------------+---<---+
>> + *      |                     |                 |
>> + * +----v---------+  +--------v-----+  +--------v------+
>> + * | vco_divided  |  | vco_divided  |  | vco_divided   |
>> + * |    _clk_src  |  |    _clk_src  |  |    _clk_src   |
>> + * |              |  |              |  |               |
>> + * |divsel_six    |  |  divsel_two  |  |  divsel_four  |
>> + * +-------+------+  +-----+--------+  +--------+------+
>> + *         |                 |                  |
>> + *         v---->----------v-------------<------v
>> + *                         |
>> + *              +----------+-----------------+
>> + *              |   dp_phy_pll_vco_div_clk   |
>> + *              +---------+------------------+
>> + *                        |
>> + *                        v
>> + *              Input to DISPCC block
>> + *              for DP pixel clock
>> + *
>> + */
>> +static int qmp_dp_pixel_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
>> +{
>> +	switch (req->rate) {
>> +	case 1620000000UL / 2:
>> +	case 2700000000UL / 2:
>> +	/* 5.4 and 8.1 GHz are same link rate as 2.7GHz, i.e. div 4 and div 6 */
>> +		return 0;
>> +	default:
>> +		return -EINVAL;
>> +	}
>> +}
>> +
>> +static unsigned long qmp_dp_pixel_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
>> +{
>> +	const struct qmp_usbc *qmp;
>> +	const struct phy_configure_opts_dp *dp_opts;
>> +
>> +	qmp = container_of(hw, struct qmp_usbc, dp_pixel_hw);
>> +
>> +	dp_opts = &qmp->dp_opts;
>> +
>> +	switch (dp_opts->link_rate) {
>> +	case 1620:
>> +		return 1620000000UL / 2;
>> +	case 2700:
>> +		return 2700000000UL / 2;
>> +	case 5400:
>> +		return 5400000000UL / 4;
>> +	default:
>> +		return 0;
>> +	}
>> +}
>> +
>> +static const struct clk_ops qmp_dp_pixel_clk_ops = {
>> +	.determine_rate	= qmp_dp_pixel_clk_determine_rate,
>> +	.recalc_rate	= qmp_dp_pixel_clk_recalc_rate,
>> +};
>> +
>> +static int qmp_dp_link_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
>> +{
>> +	switch (req->rate) {
>> +	case 162000000:
>> +	case 270000000:
>> +	case 540000000:
>> +		return 0;
>> +	default:
>> +		return -EINVAL;
>> +	}
>> +}
>> +
>> +static unsigned long qmp_dp_link_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
>> +{
>> +	const struct qmp_usbc *qmp;
>> +	const struct phy_configure_opts_dp *dp_opts;
>> +
>> +	qmp = container_of(hw, struct qmp_usbc, dp_link_hw);
>> +	dp_opts = &qmp->dp_opts;
>> +
>> +	switch (dp_opts->link_rate) {
>> +	case 1620:
>> +	case 2700:
>> +	case 5400:
>> +		return dp_opts->link_rate * 100000;
>> +	default:
>> +		return 0;
>> +	}
>> +}
>> +
>> +static const struct clk_ops qmp_dp_link_clk_ops = {
>> +	.determine_rate	= qmp_dp_link_clk_determine_rate,
>> +	.recalc_rate	= qmp_dp_link_clk_recalc_rate,
>> +};
>> +
>> +static int phy_dp_clks_register(struct qmp_usbc *qmp, struct device_node *np)
>> +{
>> +	struct clk_init_data init = { };
>> +	char name[64];
>> +	int ret;
>> +
>> +	snprintf(name, sizeof(name), "%s::link_clk", dev_name(qmp->dev));
>> +	init.ops = &qmp_dp_link_clk_ops;
>> +	init.name = name;
>> +	qmp->dp_link_hw.init = &init;
>> +	ret = devm_clk_hw_register(qmp->dev, &qmp->dp_link_hw);
>> +	if (ret < 0) {
>> +		dev_err(qmp->dev, "link clk reg fail ret=%d\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	snprintf(name, sizeof(name), "%s::vco_div_clk", dev_name(qmp->dev));
>> +	init.ops = &qmp_dp_pixel_clk_ops;
>> +	init.name = name;
>> +	qmp->dp_pixel_hw.init = &init;
>> +	ret = devm_clk_hw_register(qmp->dev, &qmp->dp_pixel_hw);
>> +	if (ret) {
>> +		dev_err(qmp->dev, "pxl clk reg fail ret=%d\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static int qmp_usbc_register_clocks(struct qmp_usbc *qmp, struct device_node *np)
>> +{
>> +	int ret;
>> +
>> +	if (!IS_ERR(qmp->pipe_clk)) {
>> +		ret = phy_pipe_clk_register(qmp, np);
>> +		if (ret)
>> +			return ret;
>> +	}
>> +
>> +	if (qmp->cfg->type == QMP_PHY_USBC_USB3_DP) {
> if dp_serdes != 0


Ack.


>> +		ret = phy_dp_clks_register(qmp, np);
>> +		if (ret)
>> +			return ret;
>> +	}
>> +
>> +	return devm_of_clk_add_hw_provider(qmp->dev, qmp_usbc_clks_hw_get, qmp);
>> +}
>> +
>> +static struct phy *qmp_usbc_phy_xlate(struct device *dev, const struct of_phandle_args *args)
>> +{
>> +	struct qmp_usbc *qmp = dev_get_drvdata(dev);
>> +
>> +	if (args->args_count == 0)
>> +		return qmp->usb_phy;
>> +
>> +	switch (args->args[0]) {
>> +	case QMP_USB43DP_USB3_PHY:
>> +		return qmp->usb_phy;
>> +	case QMP_USB43DP_DP_PHY:
>> +		return qmp->dp_phy;
>> +	}
>> +
>> +	return ERR_PTR(-EINVAL);
>> +}
>> +
>>  static int qmp_usbc_probe(struct platform_device *pdev)
>>  {
>>  	struct device *dev = &pdev->dev;
>> @@ -1703,16 +1944,32 @@ static int qmp_usbc_probe(struct platform_device *pdev)
>>  	if (ret)
>>  		return ret;
>>  
>> -	/* Check for legacy binding with child node. */
>> -	np = of_get_child_by_name(dev->of_node, "phy");
>> -	if (np) {
>> -		ret = qmp_usbc_parse_usb_dt_legacy(qmp, np);
>> -	} else {
>> +	if (qmp->cfg->type == QMP_PHY_USBC_USB3_DP) {
> Should not be necessary.


Got it. I?ll merge the parsing logic into a single qmp_usbc_parse_dt function.

Also, I checked the compatible strings in the dtsi files for this PHY series
looks like no current product uses the legacy binding.?
I?ll drop qmp_usbc_parse_usb_dt_legacy in the next version.


>>  		np = of_node_get(dev->of_node);
>> -		ret = qmp_usbc_parse_usb_dt(qmp);
>> +
>> +		ret = qmp_usbc_parse_usb3dp_dt(qmp);
>> +		if (ret) {
>> +			dev_err(qmp->dev, "parse DP dt fail ret=%d\n", ret);
>> +			goto err_node_put;
>> +		}
>> +
>> +		ret = drm_aux_bridge_register(dev);
>> +		if (ret) {
>> +			dev_err(qmp->dev, "aux bridge reg fail ret=%d\n", ret);
>> +			goto err_node_put;
>> +		}
>> +	} else {
>> +		/* Check for legacy binding with child node. */
>> +		np = of_get_child_by_name(dev->of_node, "phy");
>> +		if (np) {
>> +			ret = qmp_usbc_parse_usb_dt_legacy(qmp, np);
>> +		} else {
>> +			np = of_node_get(dev->of_node);
>> +			ret = qmp_usbc_parse_usb_dt(qmp);
>> +		}
>> +		if (ret)
>> +			goto err_node_put;
>>  	}
>> -	if (ret)
>> -		goto err_node_put;
>>  
>>  	pm_runtime_set_active(dev);
>>  	ret = devm_pm_runtime_enable(dev);
>> @@ -1724,7 +1981,7 @@ static int qmp_usbc_probe(struct platform_device *pdev)
>>  	 */
>>  	pm_runtime_forbid(dev);
>>  
>> -	ret = phy_pipe_clk_register(qmp, np);
>> +	ret = qmp_usbc_register_clocks(qmp, np);
>>  	if (ret)
>>  		goto err_node_put;
>>  
>> @@ -1737,9 +1994,19 @@ static int qmp_usbc_probe(struct platform_device *pdev)
>>  
>>  	phy_set_drvdata(qmp->usb_phy, qmp);
>>  
>> +	if (qmp->cfg->type == QMP_PHY_USBC_USB3_DP) {
> if dp_serdes != 0


Ack.


>> +		qmp->dp_phy = devm_phy_create(dev, np, &qmp_usbc_dp_phy_ops);
>> +		if (IS_ERR(qmp->dp_phy)) {
>> +			ret = PTR_ERR(qmp->dp_phy);
>> +			dev_err(dev, "failed to create PHY: %d\n", ret);
>> +			goto err_node_put;
>> +		}
>> +		phy_set_drvdata(qmp->dp_phy, qmp);
>> +	}
>> +
>>  	of_node_put(np);
>>  
>> -	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
>> +	phy_provider = devm_of_phy_provider_register(dev, qmp_usbc_phy_xlate);
>>  
>>  	return PTR_ERR_OR_ZERO(phy_provider);
>>  
>>
>> -- 
>> 2.34.1
>>


From xiangxu.yin at oss.qualcomm.com  Wed Aug 27 05:35:51 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Wed, 27 Aug 2025 20:35:51 +0800
Subject: [PATCH v3 14/14] drm/msm/dp: Add support for lane mapping
 configuration
In-Reply-To: <wwn24kjpwexl66hd3wufa53lkqojb2bkpdogtxwr3uqotjpf3u@hclfgsv64ajn>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-14-a43bd25ec39c@oss.qualcomm.com>
 <wwn24kjpwexl66hd3wufa53lkqojb2bkpdogtxwr3uqotjpf3u@hclfgsv64ajn>
Message-ID: <521fc2c7-d58f-4051-89b4-4c5a5a29d798@oss.qualcomm.com>


On 8/20/2025 7:49 PM, Dmitry Baryshkov wrote:
> On Wed, Aug 20, 2025 at 05:34:56PM +0800, Xiangxu Yin wrote:
>> Since max_dp_lanes and max_dp_link_rate are link-specific parameters,
>> move their parsing from dp_panel to dp_link for better separation
>> of concerns.
>>
>> Add lane mapping configuration for the DisplayPort (DP) controller on
>> the QCS615 platform.
> Separate patch


Ok. will separate in next patch.


>> QCS615 platform requires non-default logical-to-physical lane mapping
>> due to its unique hardware routing. Unlike the standard mapping sequence
>> <0 1 2 3>, QCS615 uses <3 2 0 1>, which necessitates explicit
>> configuration via the data-lanes property in the device tree. This
>> ensures correct signal routing between the DP controller and PHY.
>>
>> The DP PHY supports polarity inversion (PN swap) but does not support
>> lane swapping. Therefore, lane mapping should be handled in the DP
>> controller domain using REG_DP_LOGICAL2PHYSICAL_LANE_MAPPING.
>>
>> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
>> ---
>>  drivers/gpu/drm/msm/dp/dp_ctrl.c  | 10 ++---
>>  drivers/gpu/drm/msm/dp/dp_link.c  | 71 +++++++++++++++++++++++++++++++++++
>>  drivers/gpu/drm/msm/dp/dp_link.h  |  5 +++
>>  drivers/gpu/drm/msm/dp/dp_panel.c | 78 +++++----------------------------------
>>  drivers/gpu/drm/msm/dp/dp_panel.h |  3 --
>>  5 files changed, 90 insertions(+), 77 deletions(-)
>>


From xiangxu.yin at oss.qualcomm.com  Wed Aug 27 06:28:00 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Wed, 27 Aug 2025 21:28:00 +0800
Subject: [PATCH v3 07/14] phy: qcom: qmp-usbc: Move reset and regulator
 config into PHY cfg
In-Reply-To: <llrt3xnd5gagovnmyzqebp2da5v67bkxjntfcgc5r5auamspyj@7v5taph3i3c4>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-7-a43bd25ec39c@oss.qualcomm.com>
 <ofvzduf5xyip7w6yde2xwsrvv3tdh7ew3yyzeya2qzpqty3j7p@bnetyjowhdn5>
 <6f7c3962-ccfc-4400-a77f-399b06da93e1@oss.qualcomm.com>
 <llrt3xnd5gagovnmyzqebp2da5v67bkxjntfcgc5r5auamspyj@7v5taph3i3c4>
Message-ID: <f3cc06c1-25d2-40f4-bd77-8a9c51b40efa@oss.qualcomm.com>


On 8/22/2025 6:08 PM, Dmitry Baryshkov wrote:
> On Fri, Aug 22, 2025 at 04:29:28PM +0800, Xiangxu Yin wrote:
>> On 8/20/2025 7:30 PM, Dmitry Baryshkov wrote:
>>> On Wed, Aug 20, 2025 at 05:34:49PM +0800, Xiangxu Yin wrote:
>>>> Refactor reset and regulator configuration to be managed via qmp_phy_cfg
>>>> instead of hardcoded lists. This enables per-PHY customization and
>>>> simplifies initialization logic for USB-only and USB/DP switchable PHYs.
>>> Please split into two patches in order to simplify reviewing.
>>
>> Ok, will split reset and regulator part.
>>
>>
>>>> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
>>>> ---
>>>>  drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 108 +++++++++++++++----------------
>>>>  1 file changed, 53 insertions(+), 55 deletions(-)
>>>>
>>>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
>>>> index 61128d606238321d1b573655b3b987226aa2d594..4e797b7e65da0e3a827efa9a179f1c150c1b8b00 100644
>>>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
>>>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
>>>> @@ -421,8 +421,9 @@ struct qmp_phy_cfg {
>>>>  	int (*configure_dp_phy)(struct qmp_usbc *qmp);
>>>>  	int (*calibrate_dp_phy)(struct qmp_usbc *qmp);
>>>>  
>>>> -	/* regulators to be requested */
>>>> -	const char * const *vreg_list;
>>>> +	const char * const *reset_list;
>>>> +	int num_resets;
>>>> +	const struct regulator_bulk_data *vreg_list;
>>>>  	int num_vregs;
>>>>  
>>>>  	/* array of registers with different offsets */
>>>> @@ -453,7 +454,6 @@ struct qmp_usbc {
>>>>  	struct clk_hw dp_pixel_hw;
>>>>  	struct clk_bulk_data *clks;
>>>>  	int num_clks;
>>>> -	int num_resets;
>>>>  	struct reset_control_bulk_data *resets;
>>>>  	struct regulator_bulk_data *vregs;
>>>>  
>>>> @@ -514,9 +514,18 @@ static const char * const usb3phy_reset_l[] = {
>>>>  	"phy_phy", "phy",
>>>>  };
>>>>  
>>>> -/* list of regulators */
>>>> -static const char * const qmp_phy_vreg_l[] = {
>>>> -	"vdda-phy", "vdda-pll",
>>>> +static const char * const usb3dpphy_reset_l[] = {
>>>> +	"phy_phy", "dp_phy",
>>>> +};
>>>> +
>>>> +static const struct regulator_bulk_data qmp_phy_usb_vreg_l[] = {
>>>> +	{ .supply = "vdda-phy" },
>>>> +	{ .supply = "vdda-pll" },
>>> Please fill in the values for all platforms. It well might be that they
>>> all share the same current requirements.
>>
>> I checked previous DP projects and found all platforms configured vdda-phy with 21.8mA and vdda-pll with 36mA.
> No. On SDM660 and MSM8998 DP defines 73.4 mA for 0.9V supply and
> 12.560 mA for 1.8 V supply.
>
>> However, I didn?t find USB load configs in downstream and from SoC related power grids:
> Please check the actual HW documentation for those platforms.
>
>> QCS615
>> L12A: VDDA_USB0_SS_1P8/VDDA_USB1_SS_1P8 Ipk:20ma
>> L5A: VDDA_USB0_SS_0P9/VDDA_USB1_SS_0P9 Ipk:50mA
>>
>> sm6150
>> L11A: VDDA_USB0_SS_1P8/VDDA_USB1_SS_1P8 Ipk:20ma
>> L4A: VDDA_USB0_SS_0P9/VDDA_USB1_SS_0P9 Ipk:50mA
>>
>> SM6115
>> L12A: VDDA_USB_SS_DP_1P8 Ipk:13.3mA
>> L4A: VDDA_USB_SS_DP_CORE Ipk:66.1mA
>>
>> QCM2290
>> L13A: VDDA_USB_SS_DP_1P8 Ipk:13.3mA
>> L12A: VDDA_USB_SS_DP_CORE Ipk:66.1mA
>>
>> sdm660
>> LDO10A: VDDA_USB_SS_1P8 Ipk:14mA
>> LDO1B: VDDA_USB_SS_CORE Ipk:68.6mA
>>
>> msm8998
>> L2A: VDDA_USB_SS_1P2 Ipk:14.2mA
>> L1A: VDDA_USB_SS_CORE Ipk:68.6mA
>>
>> It seems the USB power requirements vary across platforms, and the
>> 21800 ?A load for vdda-phy exceeds the Ipk range in most cases.
> Ipk being ?


IPK: Instantaneous Peak Current


>> I also tested removing the load settings for USB+DP PHY, and DP still works fine.
> It mostly works either because we don't allow mode switching on older
> platforms (yet) or because somebody else has already voted and that vote
> keeps the required mode.
>
> As you've started looking on specifying proper current load, please
> finish the work.


Discussed with chip validation and power SW teams.

The power grid tables are primarily used to ensure each module receives?
the correct voltage, and they define the Ipk for each submodule.?

While they don?t specify recommended regulator load values, the Ipk values
reflect the expected power domain strength and can help estimate the voting
strength needed for each supply.

Since regulator load is mainly used for voting, I?ll define init_load_uA in
the next patch based on each SoC?s Ipk values to better align with hardware expectations.


>> So, can we keep the regulator config as original qmp_phy_vreg_l?
>> static const char * const qmp_phy_vreg_l[] = { "vdda-phy", "vdda-pll"}?
>>
>>
>>>> +};
>>>> +
>>>> +static const struct regulator_bulk_data qmp_phy_usbdp_vreg_l[] = {
>>>> +	{ .supply = "vdda-phy", .init_load_uA = 21800 },
>>>> +	{ .supply = "vdda-phy", .init_load_uA = 36000 },
>>> Typo
>>
>> Sorry for Typo, will fix in next patch.
>>
>>
>>>>  };
>>>>  
>>>>  static const struct qmp_usbc_offsets qmp_usbc_offsets_v3_qcm2290 = {
>>>> @@ -569,8 +578,10 @@ static const struct qmp_phy_cfg msm8998_usb3phy_cfg = {
>>>>  	.rx_tbl_num             = ARRAY_SIZE(msm8998_usb3_rx_tbl),
>>>>  	.pcs_tbl                = msm8998_usb3_pcs_tbl,
>>>>  	.pcs_tbl_num            = ARRAY_SIZE(msm8998_usb3_pcs_tbl),
>>>> -	.vreg_list              = qmp_phy_vreg_l,
>>>> -	.num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
>>>> +	.reset_list		= usb3phy_reset_l,
>>>> +	.num_resets		= ARRAY_SIZE(usb3phy_reset_l),
>>>> +	.vreg_list              = qmp_phy_usb_vreg_l,
>>>> +	.num_vregs              = ARRAY_SIZE(qmp_phy_usb_vreg_l),
>>>>  	.regs                   = qmp_v3_usb3phy_regs_layout,
>>>>  };
>>>>  
>>>> @@ -586,8 +597,10 @@ static const struct qmp_phy_cfg qcm2290_usb3phy_cfg = {
>>>>  	.rx_tbl_num		= ARRAY_SIZE(qcm2290_usb3_rx_tbl),
>>>>  	.pcs_tbl		= qcm2290_usb3_pcs_tbl,
>>>>  	.pcs_tbl_num		= ARRAY_SIZE(qcm2290_usb3_pcs_tbl),
>>>> -	.vreg_list		= qmp_phy_vreg_l,
>>>> -	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
>>>> +	.reset_list		= usb3phy_reset_l,
>>>> +	.num_resets		= ARRAY_SIZE(usb3phy_reset_l),
>>>> +	.vreg_list		= qmp_phy_usb_vreg_l,
>>>> +	.num_vregs		= ARRAY_SIZE(qmp_phy_usb_vreg_l),
>>>>  	.regs			= qmp_v3_usb3phy_regs_layout_qcm2290,
>>>>  };
>>>>  
>>>> @@ -603,8 +616,10 @@ static const struct qmp_phy_cfg sdm660_usb3phy_cfg = {
>>>>  	.rx_tbl_num		= ARRAY_SIZE(sdm660_usb3_rx_tbl),
>>>>  	.pcs_tbl		= qcm2290_usb3_pcs_tbl,
>>>>  	.pcs_tbl_num		= ARRAY_SIZE(qcm2290_usb3_pcs_tbl),
>>>> -	.vreg_list		= qmp_phy_vreg_l,
>>>> -	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
>>>> +	.reset_list		= usb3phy_reset_l,
>>>> +	.num_resets		= ARRAY_SIZE(usb3phy_reset_l),
>>>> +	.vreg_list		= qmp_phy_usb_vreg_l,
>>>> +	.num_vregs		= ARRAY_SIZE(qmp_phy_usb_vreg_l),
>>>>  	.regs			= qmp_v3_usb3phy_regs_layout_qcm2290,
>>>>  };
>>>>  
>>>> @@ -637,6 +652,11 @@ static const struct qmp_phy_cfg qcs615_usb3dp_phy_cfg = {
>>>>  
>>>>  	.swing_tbl		= &qmp_dp_voltage_swing_hbr2_rbr,
>>>>  	.pre_emphasis_tbl	= &qmp_dp_pre_emphasis_hbr2_rbr,
>>>> +
>>>> +	.reset_list		= usb3dpphy_reset_l,
>>>> +	.num_resets		= ARRAY_SIZE(usb3dpphy_reset_l),
>>>> +	.vreg_list		= qmp_phy_usbdp_vreg_l,
>>>> +	.num_vregs		= ARRAY_SIZE(qmp_phy_usbdp_vreg_l),
>>>>  };
>>>>  
>>>>  static int qmp_usbc_com_init(struct phy *phy)
>>>> @@ -653,13 +673,13 @@ static int qmp_usbc_com_init(struct phy *phy)
>>>>  		return ret;
>>>>  	}
>>>>  
>>>> -	ret = reset_control_bulk_assert(qmp->num_resets, qmp->resets);
>>>> +	ret = reset_control_bulk_assert(cfg->num_resets, qmp->resets);
>>>>  	if (ret) {
>>>>  		dev_err(qmp->dev, "reset assert failed\n");
>>>>  		goto err_disable_regulators;
>>>>  	}
>>>>  
>>>> -	ret = reset_control_bulk_deassert(qmp->num_resets, qmp->resets);
>>>> +	ret = reset_control_bulk_deassert(cfg->num_resets, qmp->resets);
>>>>  	if (ret) {
>>>>  		dev_err(qmp->dev, "reset deassert failed\n");
>>>>  		goto err_disable_regulators;
>>>> @@ -682,7 +702,7 @@ static int qmp_usbc_com_init(struct phy *phy)
>>>>  	return 0;
>>>>  
>>>>  err_assert_reset:
>>>> -	reset_control_bulk_assert(qmp->num_resets, qmp->resets);
>>>> +	reset_control_bulk_assert(cfg->num_resets, qmp->resets);
>>>>  err_disable_regulators:
>>>>  	regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
>>>>  
>>>> @@ -694,7 +714,7 @@ static int qmp_usbc_com_exit(struct phy *phy)
>>>>  	struct qmp_usbc *qmp = phy_get_drvdata(phy);
>>>>  	const struct qmp_phy_cfg *cfg = qmp->cfg;
>>>>  
>>>> -	reset_control_bulk_assert(qmp->num_resets, qmp->resets);
>>>> +	reset_control_bulk_assert(cfg->num_resets, qmp->resets);
>>>>  
>>>>  	clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks);
>>>>  
>>>> @@ -921,42 +941,22 @@ static const struct dev_pm_ops qmp_usbc_pm_ops = {
>>>>  			   qmp_usbc_runtime_resume, NULL)
>>>>  };
>>>>  
>>>> -static int qmp_usbc_vreg_init(struct qmp_usbc *qmp)
>>>> +static int qmp_usbc_reset_init(struct qmp_usbc *qmp)
>>>>  {
>>>>  	const struct qmp_phy_cfg *cfg = qmp->cfg;
>>>> -	struct device *dev = qmp->dev;
>>>> -	int num = cfg->num_vregs;
>>>> -	int i;
>>>> -
>>>> -	qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL);
>>>> -	if (!qmp->vregs)
>>>> -		return -ENOMEM;
>>>> -
>>>> -	for (i = 0; i < num; i++)
>>>> -		qmp->vregs[i].supply = cfg->vreg_list[i];
>>>> -
>>>> -	return devm_regulator_bulk_get(dev, num, qmp->vregs);
>>>> -}
>>>> -
>>>> -static int qmp_usbc_reset_init(struct qmp_usbc *qmp,
>>>> -			      const char *const *reset_list,
>>>> -			      int num_resets)
>>>> -{
>>>>  	struct device *dev = qmp->dev;
>>>>  	int i;
>>>>  	int ret;
>>>>  
>>>> -	qmp->resets = devm_kcalloc(dev, num_resets,
>>>> +	qmp->resets = devm_kcalloc(dev, cfg->num_resets,
>>>>  				   sizeof(*qmp->resets), GFP_KERNEL);
>>>>  	if (!qmp->resets)
>>>>  		return -ENOMEM;
>>>>  
>>>> -	for (i = 0; i < num_resets; i++)
>>>> -		qmp->resets[i].id = reset_list[i];
>>>> +	for (i = 0; i < cfg->num_resets; i++)
>>>> +		qmp->resets[i].id = cfg->reset_list[i];
>>>>  
>>>> -	qmp->num_resets = num_resets;
>>>> -
>>>> -	ret = devm_reset_control_bulk_get_exclusive(dev, num_resets, qmp->resets);
>>>> +	ret = devm_reset_control_bulk_get_exclusive(dev, cfg->num_resets, qmp->resets);
>>>>  	if (ret)
>>>>  		return dev_err_probe(dev, ret, "failed to get resets\n");
>>>>  
>>>> @@ -1146,11 +1146,6 @@ static int qmp_usbc_parse_usb_dt_legacy(struct qmp_usbc *qmp, struct device_node
>>>>  
>>>>  	qmp->num_clks = ret;
>>>>  
>>>> -	ret = qmp_usbc_reset_init(qmp, usb3phy_legacy_reset_l,
>>>> -				 ARRAY_SIZE(usb3phy_legacy_reset_l));
>>>> -	if (ret)
>>>> -		return ret;
>>>> -
>>>>  	return 0;
>>>>  }
>>>>  
>>>> @@ -1187,14 +1182,9 @@ static int qmp_usbc_parse_usb_dt(struct qmp_usbc *qmp)
>>>>  	qmp->pipe_clk = devm_clk_get(dev, "pipe");
>>>>  	if (IS_ERR(qmp->pipe_clk)) {
>>>>  		return dev_err_probe(dev, PTR_ERR(qmp->pipe_clk),
>>>> -				     "failed to get pipe clock\n");
>>>> +					"failed to get pipe clock\n");
>>> unrelated
>>
>> Ack.
>>
>>
>>>>  	}
>>>>  
>>>> -	ret = qmp_usbc_reset_init(qmp, usb3phy_reset_l,
>>>> -				 ARRAY_SIZE(usb3phy_reset_l));
>>>> -	if (ret)
>>>> -		return ret;
>>>> -
>>>>  	return 0;
>>>>  }
>>>>  
>>>> @@ -1228,6 +1218,7 @@ static int qmp_usbc_probe(struct platform_device *pdev)
>>>>  	struct phy_provider *phy_provider;
>>>>  	struct device_node *np;
>>>>  	struct qmp_usbc *qmp;
>>>> +	const struct qmp_phy_cfg *cfg;
>>>>  	int ret;
>>>>  
>>>>  	qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL);
>>>> @@ -1239,13 +1230,20 @@ static int qmp_usbc_probe(struct platform_device *pdev)
>>>>  
>>>>  	qmp->orientation = TYPEC_ORIENTATION_NORMAL;
>>>>  
>>>> -	qmp->cfg = of_device_get_match_data(dev);
>>>> -	if (!qmp->cfg)
>>>> +	cfg = of_device_get_match_data(dev);
>>>> +	if (!cfg)
>>>>  		return -EINVAL;
>>>>  
>>>> +	qmp->cfg = cfg;
>>> Why? This doesn't seem related at all.
>>
>> I added the?|cfg|?variable to simplify access to?|num_vregs|?and?|vreg_list|?in the following lines,?
>>
>> avoiding repeated?|qmp->cfg->...|?usage.?
>>
>> If this is considered unrelated, I?ll remove it in the next version.
> This all gets clogged in a mixture of regulator and reset changes.
> Hopefully it will be more obvious with the patches being split.
>
>>
>>>> +
>>>>  	mutex_init(&qmp->phy_mutex);
>>>>  
>>>> -	ret = qmp_usbc_vreg_init(qmp);
>>>> +	ret = qmp_usbc_reset_init(qmp);
>>>> +	if (ret)
>>>> +		return ret;
>>>> +
>>>> +	ret = devm_regulator_bulk_get_const(qmp->dev, cfg->num_vregs,
>>>> +					 cfg->vreg_list, &qmp->vregs);
>>>>  	if (ret)
>>>>  		return ret;
>>>>  
>>>>
>>>> -- 
>>>> 2.34.1
>>>>


From dmitry.baryshkov at oss.qualcomm.com  Wed Aug 27 07:31:11 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Wed, 27 Aug 2025 17:31:11 +0300
Subject: [PATCH v3 07/14] phy: qcom: qmp-usbc: Move reset and regulator
 config into PHY cfg
In-Reply-To: <f3cc06c1-25d2-40f4-bd77-8a9c51b40efa@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-7-a43bd25ec39c@oss.qualcomm.com>
 <ofvzduf5xyip7w6yde2xwsrvv3tdh7ew3yyzeya2qzpqty3j7p@bnetyjowhdn5>
 <6f7c3962-ccfc-4400-a77f-399b06da93e1@oss.qualcomm.com>
 <llrt3xnd5gagovnmyzqebp2da5v67bkxjntfcgc5r5auamspyj@7v5taph3i3c4>
 <f3cc06c1-25d2-40f4-bd77-8a9c51b40efa@oss.qualcomm.com>
Message-ID: <osav4kwxytfuxvnf26ugdw2qasd753smywsux5punuegbkxqgq@fp3r4esqiqyq>

On Wed, Aug 27, 2025 at 09:28:00PM +0800, Xiangxu Yin wrote:
> 
> On 8/22/2025 6:08 PM, Dmitry Baryshkov wrote:
> > On Fri, Aug 22, 2025 at 04:29:28PM +0800, Xiangxu Yin wrote:
> >> On 8/20/2025 7:30 PM, Dmitry Baryshkov wrote:
> >>> On Wed, Aug 20, 2025 at 05:34:49PM +0800, Xiangxu Yin wrote:
> >>>> Refactor reset and regulator configuration to be managed via qmp_phy_cfg
> >>>> instead of hardcoded lists. This enables per-PHY customization and
> >>>> simplifies initialization logic for USB-only and USB/DP switchable PHYs.
> >>> Please split into two patches in order to simplify reviewing.
> >>
> >> Ok, will split reset and regulator part.
> >>
> >>
> >>>> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
> >>>> ---
> >>>>  drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 108 +++++++++++++++----------------
> >>>>  1 file changed, 53 insertions(+), 55 deletions(-)
> >>>>
> >>>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> >>>> index 61128d606238321d1b573655b3b987226aa2d594..4e797b7e65da0e3a827efa9a179f1c150c1b8b00 100644
> >>>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> >>>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> >>>> @@ -421,8 +421,9 @@ struct qmp_phy_cfg {
> >>>>  	int (*configure_dp_phy)(struct qmp_usbc *qmp);
> >>>>  	int (*calibrate_dp_phy)(struct qmp_usbc *qmp);
> >>>>  
> >>>> -	/* regulators to be requested */
> >>>> -	const char * const *vreg_list;
> >>>> +	const char * const *reset_list;
> >>>> +	int num_resets;
> >>>> +	const struct regulator_bulk_data *vreg_list;
> >>>>  	int num_vregs;
> >>>>  
> >>>>  	/* array of registers with different offsets */
> >>>> @@ -453,7 +454,6 @@ struct qmp_usbc {
> >>>>  	struct clk_hw dp_pixel_hw;
> >>>>  	struct clk_bulk_data *clks;
> >>>>  	int num_clks;
> >>>> -	int num_resets;
> >>>>  	struct reset_control_bulk_data *resets;
> >>>>  	struct regulator_bulk_data *vregs;
> >>>>  
> >>>> @@ -514,9 +514,18 @@ static const char * const usb3phy_reset_l[] = {
> >>>>  	"phy_phy", "phy",
> >>>>  };
> >>>>  
> >>>> -/* list of regulators */
> >>>> -static const char * const qmp_phy_vreg_l[] = {
> >>>> -	"vdda-phy", "vdda-pll",
> >>>> +static const char * const usb3dpphy_reset_l[] = {
> >>>> +	"phy_phy", "dp_phy",
> >>>> +};
> >>>> +
> >>>> +static const struct regulator_bulk_data qmp_phy_usb_vreg_l[] = {
> >>>> +	{ .supply = "vdda-phy" },
> >>>> +	{ .supply = "vdda-pll" },
> >>> Please fill in the values for all platforms. It well might be that they
> >>> all share the same current requirements.
> >>
> >> I checked previous DP projects and found all platforms configured vdda-phy with 21.8mA and vdda-pll with 36mA.
> > No. On SDM660 and MSM8998 DP defines 73.4 mA for 0.9V supply and
> > 12.560 mA for 1.8 V supply.
> >
> >> However, I didn?t find USB load configs in downstream and from SoC related power grids:
> > Please check the actual HW documentation for those platforms.
> >
> >> QCS615
> >> L12A: VDDA_USB0_SS_1P8/VDDA_USB1_SS_1P8 Ipk:20ma
> >> L5A: VDDA_USB0_SS_0P9/VDDA_USB1_SS_0P9 Ipk:50mA
> >>
> >> sm6150
> >> L11A: VDDA_USB0_SS_1P8/VDDA_USB1_SS_1P8 Ipk:20ma
> >> L4A: VDDA_USB0_SS_0P9/VDDA_USB1_SS_0P9 Ipk:50mA
> >>
> >> SM6115
> >> L12A: VDDA_USB_SS_DP_1P8 Ipk:13.3mA
> >> L4A: VDDA_USB_SS_DP_CORE Ipk:66.1mA
> >>
> >> QCM2290
> >> L13A: VDDA_USB_SS_DP_1P8 Ipk:13.3mA
> >> L12A: VDDA_USB_SS_DP_CORE Ipk:66.1mA
> >>
> >> sdm660
> >> LDO10A: VDDA_USB_SS_1P8 Ipk:14mA
> >> LDO1B: VDDA_USB_SS_CORE Ipk:68.6mA
> >>
> >> msm8998
> >> L2A: VDDA_USB_SS_1P2 Ipk:14.2mA
> >> L1A: VDDA_USB_SS_CORE Ipk:68.6mA
> >>
> >> It seems the USB power requirements vary across platforms, and the
> >> 21800 ?A load for vdda-phy exceeds the Ipk range in most cases.
> > Ipk being ?
> 
> 
> IPK: Instantaneous Peak Current
> 
> 
> >> I also tested removing the load settings for USB+DP PHY, and DP still works fine.
> > It mostly works either because we don't allow mode switching on older
> > platforms (yet) or because somebody else has already voted and that vote
> > keeps the required mode.
> >
> > As you've started looking on specifying proper current load, please
> > finish the work.
> 
> 
> Discussed with chip validation and power SW teams.
> 
> The power grid tables are primarily used to ensure each module receives?
> the correct voltage, and they define the Ipk for each submodule.?
> 
> While they don?t specify recommended regulator load values, the Ipk values
> reflect the expected power domain strength and can help estimate the voting
> strength needed for each supply.
> 
> Since regulator load is mainly used for voting, I?ll define init_load_uA in
> the next patch based on each SoC?s Ipk values to better align with hardware expectations.

If the Ipk is defined per module, then it's fine.

-- 
With best wishes
Dmitry


From mani at kernel.org  Wed Aug 27 07:55:44 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Wed, 27 Aug 2025 20:25:44 +0530
Subject: [PATCH v3 0/3] arm64: dts: qcom: Add PCIe Support for sm8750
In-Reply-To: <20250826-pakala-v3-0-721627bd5bb0@oss.qualcomm.com>
References: <20250826-pakala-v3-0-721627bd5bb0@oss.qualcomm.com>
Message-ID: <55lm2trwh3l62om2ozjmywfy6cj4l7iiy5sx66rqawjqcnn6ix@ycqbusd7pi5v>

On Tue, Aug 26, 2025 at 04:32:52PM GMT, Krishna Chaitanya Chundru wrote:
> Describe PCIe controller and PHY. Also add required system resources like
> regulators, clocks, interrupts and registers configuration for PCIe.
> 
> The qcom_pcie_parse_ports() function currently iterates over all available
> child nodes of the PCIe controller's device tree node. This includes
> unrelated nodes such as OPP (Operating Performance Points) nodes, which do
> not contain the expected 'reset' and 'phy' properties. As a result, parsing
> fails and the driver falls back to the legacy method of parsing the
> controller node directly. However, this fallback also fails when properties
> are shifted to the root port, leading to probe failure.
> 
> Fix this by restricting the parsing logic to only consider child nodes with
> device_type = "pci", which is the expected and required property for PCIe
> ports as defined in pci-bus-common.yaml.
> 
> Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru at oss.qualcomm.com>
> ---
> Changes in v3:
> - Use device_type to find pci node or not instead of node name.
> - Link to v2: https://lore.kernel.org/r/20250826-pakala-v2-0-74f1f60676c6 at oss.qualcomm.com
> 
> Changes in v2:
> - Follow the x1e80100.dtsi pcie node description (Konrad).
> - define phy & perst, wake in port node as per latest bindings.
> - Add check in the driver to parse only pcie child nodes.
> - Added acked by tag(Rob).
> - Removed dtbinding and phy driver patches as they got applied.
> - Link to v1: https://lore.kernel.org/r/20250809-pakala-v1-0-abf1c416dbaa at oss.qualcomm.com
> 
> ---
> Krishna Chaitanya Chundru (3):
>       dt-bindings: PCI: qcom,pcie-sm8550: Add SM8750 compatible
>       arm64: dts: qcom: sm8750: Add PCIe PHY and controller node
>       PCI: qcom: Restrict port parsing only to pci child nodes

Applied patches 1 and 3, thanks!

- Mani

-- 
????????? ????????


From sven at kernel.org  Wed Aug 27 09:07:04 2025
From: sven at kernel.org (Sven Peter)
Date: Wed, 27 Aug 2025 18:07:04 +0200
Subject: [PATCH RFC 01/22] dt-bindings: usb: snps,dwc3: Allow multiple
 iommus
In-Reply-To: <e4c730d2-6ee1-46d7-850b-8ebbe0a1bfcd@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
 <20250821-atcphy-6-17-v1-1-172beda182b8@kernel.org>
 <20250822-skinny-clay-harrier-64dc58@kuoka>
 <e4c730d2-6ee1-46d7-850b-8ebbe0a1bfcd@kernel.org>
Message-ID: <a89ba427-b174-42c3-b3b4-5e4079942c3c@kernel.org>

On 24.08.25 10:31, Krzysztof Kozlowski wrote:
> On 22/08/2025 09:22, Krzysztof Kozlowski wrote:
>> On Thu, Aug 21, 2025 at 03:38:53PM +0000, Sven Peter wrote:
>>> Apple's dwc3 variant requires two iommus.
>>>
>>> Signed-off-by: Sven Peter <sven at kernel.org>
>>> ---
>>>   Documentation/devicetree/bindings/usb/snps,dwc3.yaml | 2 +-
>>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
>>> index 4380bb6fa2f08a475b557e80467abc2861f622e2..6d35dcc605c01977f4fc6fdb6f12976f1cef2b9e 100644
>>> --- a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
>>> +++ b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
>>> @@ -60,7 +60,7 @@ properties:
>>>     dma-coherent: true
>>>   
>>>     iommus:
>>> -    maxItems: 1
>>> +    maxItems: 2
>>
>> Never tested. You anyway need specific constraints.
> I realized that's pretty vague, so clarifying: you changed all bindings
> to have two iommus and that's unexpected. All other devices have only
> one IOMMU mapping here, so they need to stay like that. If these IOMMUs
> differ, you should also list them, but probably that's not the case here.

Makes sense, thanks for the detailed explanation.

I don't quite understand why this controller needs two iommus but they 
must essentially be programmed to the same mapping for xhci to work.
All of device mode goes through one of them and xhci buffers are split 
between the two iommus (iirc I saw the command ring using the first one 
and the event ring the second one and then just decided to program them 
the same since anything else would result in a big mess).



Thanks,


Sven



From dmitry.baryshkov at oss.qualcomm.com  Wed Aug 27 09:12:11 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Wed, 27 Aug 2025 19:12:11 +0300
Subject: [PATCH v3 09/14] phy: qcom: qmp-usbc: Add DP PHY ops for USB/DP
 switchable Type-C PHYs
In-Reply-To: <9bf7f51b-dcfb-4ff8-848e-dcf144936f2e@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-9-a43bd25ec39c@oss.qualcomm.com>
 <3pr7ninjxr4pgsz56dr6ojjmx27fzzszmtt6mx4r6qaqt25tnc@nrgx5qiqc7z4>
 <9bf7f51b-dcfb-4ff8-848e-dcf144936f2e@oss.qualcomm.com>
Message-ID: <hy66bjkygfz2qdhatdyxpw2cktaeohguwdg3ydowubarqebfzr@2rjjxghmhdya>

On Wed, Aug 27, 2025 at 08:17:39PM +0800, Xiangxu Yin wrote:
> 
> On 8/20/2025 7:45 PM, Dmitry Baryshkov wrote:
> > On Wed, Aug 20, 2025 at 05:34:51PM +0800, Xiangxu Yin wrote:
> >> Define qmp_usbc_dp_phy_ops struct to support DP mode on USB/DP
> >> switchable PHYs.
> >>
> >> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
> >> ---
> >>  drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 163 +++++++++++++++++++++++++++++++
> >>  1 file changed, 163 insertions(+)
> >>
> >> @@ -1095,6 +1248,16 @@ static const struct phy_ops qmp_usbc_usb_phy_ops = {
> >>  	.owner		= THIS_MODULE,
> >>  };
> >>  
> >> +static const struct phy_ops qmp_usbc_dp_phy_ops = {
> > Please try restructuring your patches so that there are no unused
> > warnings in the middle of the series. You can split the next patch into
> > 'parse' and 'enable' parts, then squash this patch into the 'enable'
> > one.
> 
> 
> You mean it's better to define and register new functions in the same patch?
> 
> where they're first used, to avoid unused warnings??And for things like parse_dt and phy_ops,
> 
> it's fine to split them into separate patches if each part is used right away?

Yes.

> 
> 
> >
> >> +	.init		= qmp_usbc_dp_enable,
> >> +	.exit		= qmp_usbc_dp_disable,
> >> +	.configure	= qmp_usbc_dp_configure,
> >> +	.calibrate	= qmp_usbc_dp_calibrate,
> >> +	.power_on	= qmp_usbc_dp_power_on,
> >> +	.power_off	= qmp_usbc_dp_power_off,
> >> +	.owner		= THIS_MODULE,
> >> +};
> >> +
> >>  static void qmp_usbc_enable_autonomous_mode(struct qmp_usbc *qmp)
> >>  {
> >>  	const struct qmp_phy_cfg *cfg = qmp->cfg;
> >>
> >> -- 
> >> 2.34.1
> >>

-- 
With best wishes
Dmitry


From dmitry.baryshkov at oss.qualcomm.com  Wed Aug 27 09:14:55 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Wed, 27 Aug 2025 19:14:55 +0300
Subject: [PATCH v3 11/14] phy: qcom: qmp-usbc: Finalize USB/DP switchable
 PHY support
In-Reply-To: <82d19340-b887-4093-9d24-4b2e19b99f8b@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-11-a43bd25ec39c@oss.qualcomm.com>
 <jjsijdmh4hdbgd2boebtrmzvblvhz2hnl7mtv5ga76ine2fnsb@i72dz3r4lbjp>
 <82d19340-b887-4093-9d24-4b2e19b99f8b@oss.qualcomm.com>
Message-ID: <inxoswyre3qalrb3dj3lz3b5vmnpnkyy3hh4oum3z6p7yqlo2v@7g67yvvb25tc>

On Wed, Aug 27, 2025 at 08:34:39PM +0800, Xiangxu Yin wrote:
> 
> On 8/20/2025 7:42 PM, Dmitry Baryshkov wrote:
> > On Wed, Aug 20, 2025 at 05:34:53PM +0800, Xiangxu Yin wrote:
> >> Complete USB/DP switchable PHY integration by adding DP clock
> >> registration, aux bridge setup, and DT parsing. Implement clock
> >> provider logic for USB and DP branches, and extend PHY translation
> >> to support both USB and DP instances.
> >>
> >> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
> >> ---
> >>  drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 331 ++++++++++++++++++++++++++++---
> >>  1 file changed, 299 insertions(+), 32 deletions(-)
> >>
> >>  static int qmp_usbc_probe(struct platform_device *pdev)
> >>  {
> >>  	struct device *dev = &pdev->dev;
> >> @@ -1703,16 +1944,32 @@ static int qmp_usbc_probe(struct platform_device *pdev)
> >>  	if (ret)
> >>  		return ret;
> >>  
> >> -	/* Check for legacy binding with child node. */
> >> -	np = of_get_child_by_name(dev->of_node, "phy");
> >> -	if (np) {
> >> -		ret = qmp_usbc_parse_usb_dt_legacy(qmp, np);
> >> -	} else {
> >> +	if (qmp->cfg->type == QMP_PHY_USBC_USB3_DP) {
> > Should not be necessary.
> 
> 
> Got it. I?ll merge the parsing logic into a single qmp_usbc_parse_dt function.
> 
> Also, I checked the compatible strings in the dtsi files for this PHY series
> looks like no current product uses the legacy binding.?
> I?ll drop qmp_usbc_parse_usb_dt_legacy in the next version.


No. It's _legacy_, it has been implemented in order to support old DTs,
which existed at some point but then were refactored into the current
state. You can't randomly drop DT support.

> 
> 
> >>  		np = of_node_get(dev->of_node);
> >> -		ret = qmp_usbc_parse_usb_dt(qmp);
> >> +
> >> +		ret = qmp_usbc_parse_usb3dp_dt(qmp);
> >> +		if (ret) {
> >> +			dev_err(qmp->dev, "parse DP dt fail ret=%d\n", ret);
> >> +			goto err_node_put;
> >> +		}
> >> +
> >> +		ret = drm_aux_bridge_register(dev);
> >> +		if (ret) {
> >> +			dev_err(qmp->dev, "aux bridge reg fail ret=%d\n", ret);
> >> +			goto err_node_put;
> >> +		}

-- 
With best wishes
Dmitry


From xiangxu.yin at oss.qualcomm.com  Wed Aug 27 18:40:51 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Thu, 28 Aug 2025 09:40:51 +0800
Subject: [PATCH v3 07/14] phy: qcom: qmp-usbc: Move reset and regulator
 config into PHY cfg
In-Reply-To: <osav4kwxytfuxvnf26ugdw2qasd753smywsux5punuegbkxqgq@fp3r4esqiqyq>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-7-a43bd25ec39c@oss.qualcomm.com>
 <ofvzduf5xyip7w6yde2xwsrvv3tdh7ew3yyzeya2qzpqty3j7p@bnetyjowhdn5>
 <6f7c3962-ccfc-4400-a77f-399b06da93e1@oss.qualcomm.com>
 <llrt3xnd5gagovnmyzqebp2da5v67bkxjntfcgc5r5auamspyj@7v5taph3i3c4>
 <f3cc06c1-25d2-40f4-bd77-8a9c51b40efa@oss.qualcomm.com>
 <osav4kwxytfuxvnf26ugdw2qasd753smywsux5punuegbkxqgq@fp3r4esqiqyq>
Message-ID: <749ec6d1-f2f9-40f5-9c41-3443698f250a@oss.qualcomm.com>


On 8/27/2025 10:31 PM, Dmitry Baryshkov wrote:
> On Wed, Aug 27, 2025 at 09:28:00PM +0800, Xiangxu Yin wrote:
>> On 8/22/2025 6:08 PM, Dmitry Baryshkov wrote:
>>> On Fri, Aug 22, 2025 at 04:29:28PM +0800, Xiangxu Yin wrote:
>>>> On 8/20/2025 7:30 PM, Dmitry Baryshkov wrote:
>>>>> On Wed, Aug 20, 2025 at 05:34:49PM +0800, Xiangxu Yin wrote:
>>>>>> Refactor reset and regulator configuration to be managed via qmp_phy_cfg
>>>>>> instead of hardcoded lists. This enables per-PHY customization and
>>>>>> simplifies initialization logic for USB-only and USB/DP switchable PHYs.
>>>>> Please split into two patches in order to simplify reviewing.
>>>> Ok, will split reset and regulator part.
>>>>
>>>>
>>>>>> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
>>>>>> ---
>>>>>>  drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 108 +++++++++++++++----------------
>>>>>>  1 file changed, 53 insertions(+), 55 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
>>>>>> index 61128d606238321d1b573655b3b987226aa2d594..4e797b7e65da0e3a827efa9a179f1c150c1b8b00 100644
>>>>>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
>>>>>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
>>>>>> @@ -421,8 +421,9 @@ struct qmp_phy_cfg {
>>>>>>  	int (*configure_dp_phy)(struct qmp_usbc *qmp);
>>>>>>  	int (*calibrate_dp_phy)(struct qmp_usbc *qmp);
>>>>>>  
>>>>>> -	/* regulators to be requested */
>>>>>> -	const char * const *vreg_list;
>>>>>> +	const char * const *reset_list;
>>>>>> +	int num_resets;
>>>>>> +	const struct regulator_bulk_data *vreg_list;
>>>>>>  	int num_vregs;
>>>>>>  
>>>>>>  	/* array of registers with different offsets */
>>>>>> @@ -453,7 +454,6 @@ struct qmp_usbc {
>>>>>>  	struct clk_hw dp_pixel_hw;
>>>>>>  	struct clk_bulk_data *clks;
>>>>>>  	int num_clks;
>>>>>> -	int num_resets;
>>>>>>  	struct reset_control_bulk_data *resets;
>>>>>>  	struct regulator_bulk_data *vregs;
>>>>>>  
>>>>>> @@ -514,9 +514,18 @@ static const char * const usb3phy_reset_l[] = {
>>>>>>  	"phy_phy", "phy",
>>>>>>  };
>>>>>>  
>>>>>> -/* list of regulators */
>>>>>> -static const char * const qmp_phy_vreg_l[] = {
>>>>>> -	"vdda-phy", "vdda-pll",
>>>>>> +static const char * const usb3dpphy_reset_l[] = {
>>>>>> +	"phy_phy", "dp_phy",
>>>>>> +};
>>>>>> +
>>>>>> +static const struct regulator_bulk_data qmp_phy_usb_vreg_l[] = {
>>>>>> +	{ .supply = "vdda-phy" },
>>>>>> +	{ .supply = "vdda-pll" },
>>>>> Please fill in the values for all platforms. It well might be that they
>>>>> all share the same current requirements.
>>>> I checked previous DP projects and found all platforms configured vdda-phy with 21.8mA and vdda-pll with 36mA.
>>> No. On SDM660 and MSM8998 DP defines 73.4 mA for 0.9V supply and
>>> 12.560 mA for 1.8 V supply.
>>>
>>>> However, I didn?t find USB load configs in downstream and from SoC related power grids:
>>> Please check the actual HW documentation for those platforms.
>>>
>>>> QCS615
>>>> L12A: VDDA_USB0_SS_1P8/VDDA_USB1_SS_1P8 Ipk:20ma
>>>> L5A: VDDA_USB0_SS_0P9/VDDA_USB1_SS_0P9 Ipk:50mA
>>>>
>>>> sm6150
>>>> L11A: VDDA_USB0_SS_1P8/VDDA_USB1_SS_1P8 Ipk:20ma
>>>> L4A: VDDA_USB0_SS_0P9/VDDA_USB1_SS_0P9 Ipk:50mA
>>>>
>>>> SM6115
>>>> L12A: VDDA_USB_SS_DP_1P8 Ipk:13.3mA
>>>> L4A: VDDA_USB_SS_DP_CORE Ipk:66.1mA
>>>>
>>>> QCM2290
>>>> L13A: VDDA_USB_SS_DP_1P8 Ipk:13.3mA
>>>> L12A: VDDA_USB_SS_DP_CORE Ipk:66.1mA
>>>>
>>>> sdm660
>>>> LDO10A: VDDA_USB_SS_1P8 Ipk:14mA
>>>> LDO1B: VDDA_USB_SS_CORE Ipk:68.6mA
>>>>
>>>> msm8998
>>>> L2A: VDDA_USB_SS_1P2 Ipk:14.2mA
>>>> L1A: VDDA_USB_SS_CORE Ipk:68.6mA
>>>>
>>>> It seems the USB power requirements vary across platforms, and the
>>>> 21800 ?A load for vdda-phy exceeds the Ipk range in most cases.
>>> Ipk being ?
>>
>> IPK: Instantaneous Peak Current
>>
>>
>>>> I also tested removing the load settings for USB+DP PHY, and DP still works fine.
>>> It mostly works either because we don't allow mode switching on older
>>> platforms (yet) or because somebody else has already voted and that vote
>>> keeps the required mode.
>>>
>>> As you've started looking on specifying proper current load, please
>>> finish the work.
>>
>> Discussed with chip validation and power SW teams.
>>
>> The power grid tables are primarily used to ensure each module receives?
>> the correct voltage, and they define the Ipk for each submodule.?
>>
>> While they don?t specify recommended regulator load values, the Ipk values
>> reflect the expected power domain strength and can help estimate the voting
>> strength needed for each supply.
>>
>> Since regulator load is mainly used for voting, I?ll define init_load_uA in
>> the next patch based on each SoC?s Ipk values to better align with hardware expectations.
> If the Ipk is defined per module, then it's fine.


Yes, under each regulator, multiple submodules are powered, and each submodule defines its own Ipk value.




From xiangxu.yin at oss.qualcomm.com  Wed Aug 27 19:37:29 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Thu, 28 Aug 2025 10:37:29 +0800
Subject: [PATCH v3 11/14] phy: qcom: qmp-usbc: Finalize USB/DP switchable
 PHY support
In-Reply-To: <inxoswyre3qalrb3dj3lz3b5vmnpnkyy3hh4oum3z6p7yqlo2v@7g67yvvb25tc>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-11-a43bd25ec39c@oss.qualcomm.com>
 <jjsijdmh4hdbgd2boebtrmzvblvhz2hnl7mtv5ga76ine2fnsb@i72dz3r4lbjp>
 <82d19340-b887-4093-9d24-4b2e19b99f8b@oss.qualcomm.com>
 <inxoswyre3qalrb3dj3lz3b5vmnpnkyy3hh4oum3z6p7yqlo2v@7g67yvvb25tc>
Message-ID: <31a1d952-eab3-4630-8337-94a45d144199@oss.qualcomm.com>


On 8/28/2025 12:14 AM, Dmitry Baryshkov wrote:
> On Wed, Aug 27, 2025 at 08:34:39PM +0800, Xiangxu Yin wrote:
>> On 8/20/2025 7:42 PM, Dmitry Baryshkov wrote:
>>> On Wed, Aug 20, 2025 at 05:34:53PM +0800, Xiangxu Yin wrote:
>>>> Complete USB/DP switchable PHY integration by adding DP clock
>>>> registration, aux bridge setup, and DT parsing. Implement clock
>>>> provider logic for USB and DP branches, and extend PHY translation
>>>> to support both USB and DP instances.
>>>>
>>>> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
>>>> ---
>>>>  drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 331 ++++++++++++++++++++++++++++---
>>>>  1 file changed, 299 insertions(+), 32 deletions(-)
>>>>
>>>>  static int qmp_usbc_probe(struct platform_device *pdev)
>>>>  {
>>>>  	struct device *dev = &pdev->dev;
>>>> @@ -1703,16 +1944,32 @@ static int qmp_usbc_probe(struct platform_device *pdev)
>>>>  	if (ret)
>>>>  		return ret;
>>>>  
>>>> -	/* Check for legacy binding with child node. */
>>>> -	np = of_get_child_by_name(dev->of_node, "phy");
>>>> -	if (np) {
>>>> -		ret = qmp_usbc_parse_usb_dt_legacy(qmp, np);
>>>> -	} else {
>>>> +	if (qmp->cfg->type == QMP_PHY_USBC_USB3_DP) {
>>> Should not be necessary.
>>
>> Got it. I?ll merge the parsing logic into a single qmp_usbc_parse_dt function.
>>
>> Also, I checked the compatible strings in the dtsi files for this PHY series
>> looks like no current product uses the legacy binding.?
>> I?ll drop qmp_usbc_parse_usb_dt_legacy in the next version.
>
> No. It's _legacy_, it has been implemented in order to support old DTs,
> which existed at some point but then were refactored into the current
> state. You can't randomly drop DT support.


Ok, understand.


>>
>>>>  		np = of_node_get(dev->of_node);
>>>> -		ret = qmp_usbc_parse_usb_dt(qmp);
>>>> +
>>>> +		ret = qmp_usbc_parse_usb3dp_dt(qmp);
>>>> +		if (ret) {
>>>> +			dev_err(qmp->dev, "parse DP dt fail ret=%d\n", ret);
>>>> +			goto err_node_put;
>>>> +		}
>>>> +
>>>> +		ret = drm_aux_bridge_register(dev);
>>>> +		if (ret) {
>>>> +			dev_err(qmp->dev, "aux bridge reg fail ret=%d\n", ret);
>>>> +			goto err_node_put;
>>>> +		}


From xiangxu.yin at oss.qualcomm.com  Wed Aug 27 21:51:03 2025
From: xiangxu.yin at oss.qualcomm.com (Xiangxu Yin)
Date: Thu, 28 Aug 2025 12:51:03 +0800
Subject: [PATCH v3 01/14] dt-bindings: display/msm: dp-controller: Add
 sm6150
In-Reply-To: <75ra2ofecqu6tid6kr4hnyuztpl6jjaq2ksyquafyajhq2sa4d@4tkggrdqky7y>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-1-a43bd25ec39c@oss.qualcomm.com>
 <75ra2ofecqu6tid6kr4hnyuztpl6jjaq2ksyquafyajhq2sa4d@4tkggrdqky7y>
Message-ID: <8918feef-219e-4e69-8901-367189f5066d@oss.qualcomm.com>


On 8/20/2025 6:18 PM, Dmitry Baryshkov wrote:
> On Wed, Aug 20, 2025 at 05:34:43PM +0800, Xiangxu Yin wrote:
>> Add DisplayPort controller for Qualcomm SM6150 SoC.
>> While SM6150 currently shares the same configuration as SC7180,
>> its hardware capabilities differ. Explicitly listing it ensures clarity
>> and avoids potential issues if SC7180 support evolves in the future.
> I assume, it has no MST support. Am I right?


>From sm6150 ipcat, I found MST-related registers and pixel1 clk?definition.

According to the hardware spec, MST is supported, but due to limitations in clock and pipe resources,?

the maximum concurrency capability is restricted to 1920x1200 at 60 + 1280x720 at 60.


>> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.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 9923b065323bbab99de5079b674a0317f3074373..996d0132e084d401db85014a1a4e445d00d62ed8 100644
>> --- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
>> +++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
>> @@ -27,6 +27,7 @@ properties:
>>            - qcom,sc8280xp-dp
>>            - qcom,sc8280xp-edp
>>            - qcom,sdm845-dp
>> +          - qcom,sm6150-dp
>>            - qcom,sm8350-dp
>>            - qcom,sm8650-dp
>>        - items:
>>
>> -- 
>> 2.34.1
>>


From krzk at kernel.org  Wed Aug 27 23:54:18 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 28 Aug 2025 08:54:18 +0200
Subject: [PATCH RFC 01/22] dt-bindings: usb: snps,dwc3: Allow multiple
 iommus
In-Reply-To: <a89ba427-b174-42c3-b3b4-5e4079942c3c@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
 <20250821-atcphy-6-17-v1-1-172beda182b8@kernel.org>
 <20250822-skinny-clay-harrier-64dc58@kuoka>
 <e4c730d2-6ee1-46d7-850b-8ebbe0a1bfcd@kernel.org>
 <a89ba427-b174-42c3-b3b4-5e4079942c3c@kernel.org>
Message-ID: <e8934b5b-ef75-4ee0-b1e3-cc5db72b99ec@kernel.org>

On 27/08/2025 18:07, Sven Peter wrote:
> On 24.08.25 10:31, Krzysztof Kozlowski wrote:
>> On 22/08/2025 09:22, Krzysztof Kozlowski wrote:
>>> On Thu, Aug 21, 2025 at 03:38:53PM +0000, Sven Peter wrote:
>>>> Apple's dwc3 variant requires two iommus.
>>>>
>>>> Signed-off-by: Sven Peter <sven at kernel.org>
>>>> ---
>>>>   Documentation/devicetree/bindings/usb/snps,dwc3.yaml | 2 +-
>>>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
>>>> index 4380bb6fa2f08a475b557e80467abc2861f622e2..6d35dcc605c01977f4fc6fdb6f12976f1cef2b9e 100644
>>>> --- a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
>>>> +++ b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
>>>> @@ -60,7 +60,7 @@ properties:
>>>>     dma-coherent: true
>>>>   
>>>>     iommus:
>>>> -    maxItems: 1
>>>> +    maxItems: 2
>>>
>>> Never tested. You anyway need specific constraints.
>> I realized that's pretty vague, so clarifying: you changed all bindings
>> to have two iommus and that's unexpected. All other devices have only
>> one IOMMU mapping here, so they need to stay like that. If these IOMMUs
>> differ, you should also list them, but probably that's not the case here.
> 
> Makes sense, thanks for the detailed explanation.
> 
> I don't quite understand why this controller needs two iommus but they 
> must essentially be programmed to the same mapping for xhci to work.

That's fine.

> All of device mode goes through one of them and xhci buffers are split 
> between the two iommus (iirc I saw the command ring using the first one 
> and the event ring the second one and then just decided to program them 
> the same since anything else would result in a big mess).

Sure. But if you change existing bindings (existing devices) allowing
them to have two IOMMUs, this must be explicitly mentioned in commit msg
with some sort of rationale (even if rationale was "we just missed that").

Best regards,
Krzysztof


From wsa+renesas at sang-engineering.com  Thu Aug 28 01:56:06 2025
From: wsa+renesas at sang-engineering.com (Wolfram Sang)
Date: Thu, 28 Aug 2025 10:56:06 +0200
Subject: [PATCH v5 0/7] Add initial USB support for the Renesas RZ/G3S SoC
In-Reply-To: <20250819054212.486426-1-claudiu.beznea.uj@bp.renesas.com>
References: <20250819054212.486426-1-claudiu.beznea.uj@bp.renesas.com>
Message-ID: <aLAZprjeKtk4pusw@shikoro>

Hi Claudiu,

> Series adds initial USB support for the Renesas RZ/G3S SoC.
> 
> Series is split as follows:
> - patches 1-2/7		- fixes on bindings and driver for USB PHY
> - patches 3-5/7		- updates the rzg2l-usbphy-ctrl driver and documentation
> 			  with support for setting PWRRDY though SYSC
> - patches 6-7/7		- add device tree support

Can you kindly send me a working config (privately will do). I think I
enabled all the necessary config options but still get:

[    0.271024] rzg2l_usbphy_ctrl 11e00000.usbphy-ctrl: probe with driver rzg2l_usbphy_ctrl failed with error -22
...
[   10.981612] platform 11e20000.usb: deferred probe pending: platform: supplier 11e10200.usb-phy not ready
[   10.984103] platform 11e10200.usb-phy: deferred probe pending: platform: wait for supplier /soc/usbphy-ctrl at 11e00000/regulator-vbus

Thanks,

   Wolfram



From luyulin at eswincomputing.com  Thu Aug 28 03:22:40 2025
From: luyulin at eswincomputing.com (luyulin at eswincomputing.com)
Date: Thu, 28 Aug 2025 18:22:40 +0800 (GMT+08:00)
Subject: [PATCH v2 1/3] dt-bindings: ata: eswin: Document for
 EIC7700 SoC ahci
In-Reply-To: <CAL_JsqKFotNLZZXwiy7S6K8qXLdGRAnsa-1zvZRDQBE39Gf5kg@mail.gmail.com>
References: <20250819134722.220-1-luyulin@eswincomputing.com>
 <20250819135413.386-1-luyulin@eswincomputing.com>
 <CAL_JsqKFotNLZZXwiy7S6K8qXLdGRAnsa-1zvZRDQBE39Gf5kg@mail.gmail.com>
Message-ID: <692e11ca.843.198f0337528.Coremail.luyulin@eswincomputing.com>

Hello, Rob

Thank you very much for your reply.
I have a question that I would like to seek your advice on and clarify.

> 
> On Tue, Aug 19, 2025 at 8:54?AM Yulin Lu <luyulin at eswincomputing.com> wrote:
> >
> > From: luyulin <luyulin at eswincomputing.com>
> 
> Please fix your name.
> 
> >
> > Add document for the SATA AHCI controller on the EIC7700 SoC platform,
> > including descriptions of its hardware configurations.
> >
> > Signed-off-by: luyulin <luyulin at eswincomputing.com>
> 
> And here.
> 
> > ---
> >  .../bindings/ata/eswin,eic7700-ahci.yaml      | 92 +++++++++++++++++++
> >  1 file changed, 92 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/ata/eswin,eic7700-ahci.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/ata/eswin,eic7700-ahci.yaml b/Documentation/devicetree/bindings/ata/eswin,eic7700-ahci.yaml
> > new file mode 100644
> > index 000000000000..9ef58c9c2f28
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/ata/eswin,eic7700-ahci.yaml
> > @@ -0,0 +1,92 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/ata/eswin,eic7700-ahci.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Eswin EIC7700 SoC SATA Controller
> > +
> > +maintainers:
> > +  - Yulin Lu <luyulin at eswincomputing.com>
> > +  - Huan He <hehuan1 at eswincomputing.com>
> > +
> > +description:
> > +  This document defines device tree bindings for the Synopsys DWC
> > +  implementation of the AHCI SATA controller found in Eswin's
> > +  Eic7700 SoC platform.
> > +
> > +select:
> > +  properties:
> > +    compatible:
> > +      const: eswin,eic7700-ahci
> > +  required:
> > +    - compatible
> > +
> > +allOf:
> > +  - $ref: snps,dwc-ahci-common.yaml#
> > +
> > +properties:
> > +  compatible:
> > +    items:
> > +      - const: eswin,eic7700-ahci
> > +      - const: snps,dwc-ahci
> > +
> > +  reg:
> > +    maxItems: 1
> 
> Drop. snps,dwc-ahci-common.yaml already defines this.
> 
> > +
> > +  interrupts:
> > +    maxItems: 1
> 
> Drop. snps,dwc-ahci-common.yaml already defines this.
> 
> > +
> > +  ports-implemented:
> > +    const: 1
> 
> Really, your firmware should initialize the DWC specific register that
> sets this and is discoverable via a standard AHCI register.
> 

Accord to my understanding, if ports-implemented is configured in the dts,
this register will be set by the platform driver in libahci_platform.c.

Do you mean that ports-implemented should be removed from the dts,
and the corresponding register should be configured by the firmware
(which is U-Boot on the HiFive Premier P550 board)? Is this understanding correct?
If so, when the driver is removed, a reset will be triggered,
causing the configuration of this register to be lost,
which will result in an error when insmod the driver again.

Best regards,
Yulin

From dmitry.baryshkov at oss.qualcomm.com  Thu Aug 28 04:05:09 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Thu, 28 Aug 2025 14:05:09 +0300
Subject: [PATCH v3 01/14] dt-bindings: display/msm: dp-controller: Add
 sm6150
In-Reply-To: <8918feef-219e-4e69-8901-367189f5066d@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-1-a43bd25ec39c@oss.qualcomm.com>
 <75ra2ofecqu6tid6kr4hnyuztpl6jjaq2ksyquafyajhq2sa4d@4tkggrdqky7y>
 <8918feef-219e-4e69-8901-367189f5066d@oss.qualcomm.com>
Message-ID: <28b33851-24eb-428f-b046-b145342fd982@oss.qualcomm.com>

On 28/08/2025 07:51, Xiangxu Yin wrote:
> 
> On 8/20/2025 6:18 PM, Dmitry Baryshkov wrote:
>> On Wed, Aug 20, 2025 at 05:34:43PM +0800, Xiangxu Yin wrote:
>>> Add DisplayPort controller for Qualcomm SM6150 SoC.
>>> While SM6150 currently shares the same configuration as SC7180,
>>> its hardware capabilities differ. Explicitly listing it ensures clarity
>>> and avoids potential issues if SC7180 support evolves in the future.
>> I assume, it has no MST support. Am I right?
> 
> 
>  From sm6150 ipcat, I found MST-related registers and pixel1 clk?definition.

Then please describe MST as the main difference between SM6150 and 
SC7180 (which doesn't have MST).

Also this needs to be rebased on top of the MST bindings. I've picked up 
the latest posted revision, but basing on the on-list discussion I might 
need to drop it and post another iteration.

> 
> According to the hardware spec, MST is supported, but due to limitations in clock and pipe resources,
> 
> the maximum concurrency capability is restricted to 1920x1200 at 60 + 1280x720 at 60.
> 
> 
>>> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.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 9923b065323bbab99de5079b674a0317f3074373..996d0132e084d401db85014a1a4e445d00d62ed8 100644
>>> --- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
>>> +++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
>>> @@ -27,6 +27,7 @@ properties:
>>>             - qcom,sc8280xp-dp
>>>             - qcom,sc8280xp-edp
>>>             - qcom,sdm845-dp
>>> +          - qcom,sm6150-dp
>>>             - qcom,sm8350-dp
>>>             - qcom,sm8650-dp
>>>         - items:
>>>
>>> -- 
>>> 2.34.1
>>>


-- 
With best wishes
Dmitry


From liaoyuanhong at vivo.com  Thu Aug 28 05:23:54 2025
From: liaoyuanhong at vivo.com (Liao Yuanhong)
Date: Thu, 28 Aug 2025 20:23:54 +0800
Subject: [PATCH 0/3] phy: Remove redundant ternary operators
Message-ID: <20250828122401.17441-1-liaoyuanhong@vivo.com>

For ternary operators in the form of "a ? true : false", if 'a' itself
returns a boolean result, the ternary operator can be omitted. Remove
redundant ternary operators to clean up the code.

Liao Yuanhong (3):
  phy: hisilicon: Remove redundant ternary operators
  phy: renesas: rcar-gen3-usb2: Remove redundant ternary operators
  phy: rockchip: usbdp: Remove redundant ternary operators

 drivers/phy/hisilicon/phy-histb-combphy.c | 2 +-
 drivers/phy/renesas/phy-rcar-gen3-usb2.c  | 2 +-
 drivers/phy/rockchip/phy-rockchip-usbdp.c | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

-- 
2.34.1



From liaoyuanhong at vivo.com  Thu Aug 28 05:23:55 2025
From: liaoyuanhong at vivo.com (Liao Yuanhong)
Date: Thu, 28 Aug 2025 20:23:55 +0800
Subject: [PATCH 1/3] phy: hisilicon: Remove redundant ternary operators
In-Reply-To: <20250828122401.17441-1-liaoyuanhong@vivo.com>
References: <20250828122401.17441-1-liaoyuanhong@vivo.com>
Message-ID: <20250828122401.17441-2-liaoyuanhong@vivo.com>

Remove redundant ternary operators to clean up the code.

Signed-off-by: Liao Yuanhong <liaoyuanhong at vivo.com>
---
 drivers/phy/hisilicon/phy-histb-combphy.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/phy/hisilicon/phy-histb-combphy.c b/drivers/phy/hisilicon/phy-histb-combphy.c
index 7436dcae3981..9dd0bd00b4e4 100644
--- a/drivers/phy/hisilicon/phy-histb-combphy.c
+++ b/drivers/phy/hisilicon/phy-histb-combphy.c
@@ -73,7 +73,7 @@ static void nano_register_write(struct histb_combphy_priv *priv,
 
 static int is_mode_fixed(struct histb_combphy_mode *mode)
 {
-	return (mode->fixed != PHY_NONE) ? true : false;
+	return mode->fixed != PHY_NONE;
 }
 
 static int histb_combphy_set_mode(struct histb_combphy_priv *priv)
-- 
2.34.1



From liaoyuanhong at vivo.com  Thu Aug 28 05:23:56 2025
From: liaoyuanhong at vivo.com (Liao Yuanhong)
Date: Thu, 28 Aug 2025 20:23:56 +0800
Subject: [PATCH 2/3] phy: renesas: rcar-gen3-usb2: Remove redundant ternary operators
In-Reply-To: <20250828122401.17441-1-liaoyuanhong@vivo.com>
References: <20250828122401.17441-1-liaoyuanhong@vivo.com>
Message-ID: <20250828122401.17441-3-liaoyuanhong@vivo.com>

Remove redundant ternary operators to clean up the code.

Signed-off-by: Liao Yuanhong <liaoyuanhong at vivo.com>
---
 drivers/phy/renesas/phy-rcar-gen3-usb2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index 7b4a6e8b7508..bab2d4dce5b3 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -306,7 +306,7 @@ static bool rcar_gen3_check_id(struct rcar_gen3_chan *ch)
 	}
 
 	if (!ch->uses_otg_pins)
-		return (ch->dr_mode == USB_DR_MODE_HOST) ? false : true;
+		return ch->dr_mode != USB_DR_MODE_HOST;
 
 	if (ch->phy_data->no_adp_ctrl)
 		return !!(readl(ch->base + USB2_LINECTRL1) & USB2_LINECTRL1_USB2_IDMON);
-- 
2.34.1



From liaoyuanhong at vivo.com  Thu Aug 28 05:23:57 2025
From: liaoyuanhong at vivo.com (Liao Yuanhong)
Date: Thu, 28 Aug 2025 20:23:57 +0800
Subject: [PATCH 3/3] phy: rockchip: usbdp: Remove redundant ternary operators
In-Reply-To: <20250828122401.17441-1-liaoyuanhong@vivo.com>
References: <20250828122401.17441-1-liaoyuanhong@vivo.com>
Message-ID: <20250828122401.17441-4-liaoyuanhong@vivo.com>

Remove redundant ternary operators to clean up the code.

Signed-off-by: Liao Yuanhong <liaoyuanhong at vivo.com>
---
 drivers/phy/rockchip/phy-rockchip-usbdp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index 010e9d2d6fac..fba35510d88c 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -666,7 +666,7 @@ static int rk_udphy_orien_sw_set(struct typec_switch_dev *sw,
 		goto unlock_ret;
 	}
 
-	udphy->flip = (orien == TYPEC_ORIENTATION_REVERSE) ? true : false;
+	udphy->flip = orien == TYPEC_ORIENTATION_REVERSE;
 	rk_udphy_set_typec_default_mapping(udphy);
 	rk_udphy_usb_bvalid_enable(udphy, true);
 
-- 
2.34.1



From wsa+renesas at sang-engineering.com  Thu Aug 28 05:31:01 2025
From: wsa+renesas at sang-engineering.com (Wolfram Sang)
Date: Thu, 28 Aug 2025 14:31:01 +0200
Subject: [PATCH 2/3] phy: renesas: rcar-gen3-usb2: Remove redundant
 ternary operators
In-Reply-To: <20250828122401.17441-3-liaoyuanhong@vivo.com>
References: <20250828122401.17441-1-liaoyuanhong@vivo.com>
 <20250828122401.17441-3-liaoyuanhong@vivo.com>
Message-ID: <aLBMBYqEsORQwv-8@ninjato>

On Thu, Aug 28, 2025 at 08:23:56PM +0800, Liao Yuanhong wrote:
> Remove redundant ternary operators to clean up the code.
> 
> Signed-off-by: Liao Yuanhong <liaoyuanhong at vivo.com>

Reviewed-by: Wolfram Sang <wsa+renesas at sang-engineering.com>



From dmitry.baryshkov at oss.qualcomm.com  Thu Aug 28 05:57:02 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Thu, 28 Aug 2025 15:57:02 +0300
Subject: [PATCH v3 07/14] phy: qcom: qmp-usbc: Move reset and regulator
 config into PHY cfg
In-Reply-To: <749ec6d1-f2f9-40f5-9c41-3443698f250a@oss.qualcomm.com>
References: <20250820-add-displayport-support-for-qcs615-platform-v3-0-a43bd25ec39c@oss.qualcomm.com>
 <20250820-add-displayport-support-for-qcs615-platform-v3-7-a43bd25ec39c@oss.qualcomm.com>
 <ofvzduf5xyip7w6yde2xwsrvv3tdh7ew3yyzeya2qzpqty3j7p@bnetyjowhdn5>
 <6f7c3962-ccfc-4400-a77f-399b06da93e1@oss.qualcomm.com>
 <llrt3xnd5gagovnmyzqebp2da5v67bkxjntfcgc5r5auamspyj@7v5taph3i3c4>
 <f3cc06c1-25d2-40f4-bd77-8a9c51b40efa@oss.qualcomm.com>
 <osav4kwxytfuxvnf26ugdw2qasd753smywsux5punuegbkxqgq@fp3r4esqiqyq>
 <749ec6d1-f2f9-40f5-9c41-3443698f250a@oss.qualcomm.com>
Message-ID: <kndlhnsihvkq64q3tgai2jrij5mzh3c5kehe6r4imj4d7fgbc3@l3edsktmx4y3>

On Thu, Aug 28, 2025 at 09:40:51AM +0800, Xiangxu Yin wrote:
> 
> On 8/27/2025 10:31 PM, Dmitry Baryshkov wrote:
> > On Wed, Aug 27, 2025 at 09:28:00PM +0800, Xiangxu Yin wrote:
> >> On 8/22/2025 6:08 PM, Dmitry Baryshkov wrote:
> >>> On Fri, Aug 22, 2025 at 04:29:28PM +0800, Xiangxu Yin wrote:
> >>>> On 8/20/2025 7:30 PM, Dmitry Baryshkov wrote:
> >>>>> On Wed, Aug 20, 2025 at 05:34:49PM +0800, Xiangxu Yin wrote:
> >>>>>> Refactor reset and regulator configuration to be managed via qmp_phy_cfg
> >>>>>> instead of hardcoded lists. This enables per-PHY customization and
> >>>>>> simplifies initialization logic for USB-only and USB/DP switchable PHYs.
> >>>>> Please split into two patches in order to simplify reviewing.
> >>>> Ok, will split reset and regulator part.
> >>>>
> >>>>
> >>>>>> Signed-off-by: Xiangxu Yin <xiangxu.yin at oss.qualcomm.com>
> >>>>>> ---
> >>>>>>  drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 108 +++++++++++++++----------------
> >>>>>>  1 file changed, 53 insertions(+), 55 deletions(-)
> >>>>>>
> >>>>>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> >>>>>> index 61128d606238321d1b573655b3b987226aa2d594..4e797b7e65da0e3a827efa9a179f1c150c1b8b00 100644
> >>>>>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> >>>>>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> >>>>>> @@ -421,8 +421,9 @@ struct qmp_phy_cfg {
> >>>>>>  	int (*configure_dp_phy)(struct qmp_usbc *qmp);
> >>>>>>  	int (*calibrate_dp_phy)(struct qmp_usbc *qmp);
> >>>>>>  
> >>>>>> -	/* regulators to be requested */
> >>>>>> -	const char * const *vreg_list;
> >>>>>> +	const char * const *reset_list;
> >>>>>> +	int num_resets;
> >>>>>> +	const struct regulator_bulk_data *vreg_list;
> >>>>>>  	int num_vregs;
> >>>>>>  
> >>>>>>  	/* array of registers with different offsets */
> >>>>>> @@ -453,7 +454,6 @@ struct qmp_usbc {
> >>>>>>  	struct clk_hw dp_pixel_hw;
> >>>>>>  	struct clk_bulk_data *clks;
> >>>>>>  	int num_clks;
> >>>>>> -	int num_resets;
> >>>>>>  	struct reset_control_bulk_data *resets;
> >>>>>>  	struct regulator_bulk_data *vregs;
> >>>>>>  
> >>>>>> @@ -514,9 +514,18 @@ static const char * const usb3phy_reset_l[] = {
> >>>>>>  	"phy_phy", "phy",
> >>>>>>  };
> >>>>>>  
> >>>>>> -/* list of regulators */
> >>>>>> -static const char * const qmp_phy_vreg_l[] = {
> >>>>>> -	"vdda-phy", "vdda-pll",
> >>>>>> +static const char * const usb3dpphy_reset_l[] = {
> >>>>>> +	"phy_phy", "dp_phy",
> >>>>>> +};
> >>>>>> +
> >>>>>> +static const struct regulator_bulk_data qmp_phy_usb_vreg_l[] = {
> >>>>>> +	{ .supply = "vdda-phy" },
> >>>>>> +	{ .supply = "vdda-pll" },
> >>>>> Please fill in the values for all platforms. It well might be that they
> >>>>> all share the same current requirements.
> >>>> I checked previous DP projects and found all platforms configured vdda-phy with 21.8mA and vdda-pll with 36mA.
> >>> No. On SDM660 and MSM8998 DP defines 73.4 mA for 0.9V supply and
> >>> 12.560 mA for 1.8 V supply.
> >>>
> >>>> However, I didn?t find USB load configs in downstream and from SoC related power grids:
> >>> Please check the actual HW documentation for those platforms.
> >>>
> >>>> QCS615
> >>>> L12A: VDDA_USB0_SS_1P8/VDDA_USB1_SS_1P8 Ipk:20ma
> >>>> L5A: VDDA_USB0_SS_0P9/VDDA_USB1_SS_0P9 Ipk:50mA
> >>>>
> >>>> sm6150
> >>>> L11A: VDDA_USB0_SS_1P8/VDDA_USB1_SS_1P8 Ipk:20ma
> >>>> L4A: VDDA_USB0_SS_0P9/VDDA_USB1_SS_0P9 Ipk:50mA
> >>>>
> >>>> SM6115
> >>>> L12A: VDDA_USB_SS_DP_1P8 Ipk:13.3mA
> >>>> L4A: VDDA_USB_SS_DP_CORE Ipk:66.1mA
> >>>>
> >>>> QCM2290
> >>>> L13A: VDDA_USB_SS_DP_1P8 Ipk:13.3mA
> >>>> L12A: VDDA_USB_SS_DP_CORE Ipk:66.1mA
> >>>>
> >>>> sdm660
> >>>> LDO10A: VDDA_USB_SS_1P8 Ipk:14mA
> >>>> LDO1B: VDDA_USB_SS_CORE Ipk:68.6mA
> >>>>
> >>>> msm8998
> >>>> L2A: VDDA_USB_SS_1P2 Ipk:14.2mA
> >>>> L1A: VDDA_USB_SS_CORE Ipk:68.6mA
> >>>>
> >>>> It seems the USB power requirements vary across platforms, and the
> >>>> 21800 ?A load for vdda-phy exceeds the Ipk range in most cases.
> >>> Ipk being ?
> >>
> >> IPK: Instantaneous Peak Current
> >>
> >>
> >>>> I also tested removing the load settings for USB+DP PHY, and DP still works fine.
> >>> It mostly works either because we don't allow mode switching on older
> >>> platforms (yet) or because somebody else has already voted and that vote
> >>> keeps the required mode.
> >>>
> >>> As you've started looking on specifying proper current load, please
> >>> finish the work.
> >>
> >> Discussed with chip validation and power SW teams.
> >>
> >> The power grid tables are primarily used to ensure each module receives?
> >> the correct voltage, and they define the Ipk for each submodule.?
> >>
> >> While they don?t specify recommended regulator load values, the Ipk values
> >> reflect the expected power domain strength and can help estimate the voting
> >> strength needed for each supply.
> >>
> >> Since regulator load is mainly used for voting, I?ll define init_load_uA in
> >> the next patch based on each SoC?s Ipk values to better align with hardware expectations.
> > If the Ipk is defined per module, then it's fine.
> 
> 
> Yes, under each regulator, multiple submodules are powered, and each submodule defines its own Ipk value.

Ack, then it's what we were looking for!

-- 
With best wishes
Dmitry


From cassel at kernel.org  Thu Aug 28 06:05:15 2025
From: cassel at kernel.org (Niklas Cassel)
Date: Thu, 28 Aug 2025 15:05:15 +0200
Subject: [PATCH v2 1/3] dt-bindings: ata: eswin: Document for EIC7700
 SoC ahci
In-Reply-To: <692e11ca.843.198f0337528.Coremail.luyulin@eswincomputing.com>
References: <20250819134722.220-1-luyulin@eswincomputing.com>
 <20250819135413.386-1-luyulin@eswincomputing.com>
 <CAL_JsqKFotNLZZXwiy7S6K8qXLdGRAnsa-1zvZRDQBE39Gf5kg@mail.gmail.com>
 <692e11ca.843.198f0337528.Coremail.luyulin@eswincomputing.com>
Message-ID: <aLBUC116MdJqDGIJ@flawful.org>

On Thu, Aug 28, 2025 at 06:22:40PM +0800, luyulin at eswincomputing.com wrote:
> 
> Do you mean that ports-implemented should be removed from the dts,
> and the corresponding register should be configured by the firmware
> (which is U-Boot on the HiFive Premier P550 board)? Is this understanding correct?
> If so, when the driver is removed, a reset will be triggered,
> causing the configuration of this register to be lost,
> which will result in an error when insmod the driver again.

My 50 cents,

if the ports implemented register gets reset from the reset_control_reset()
in ahci_platform_assert_rsts(), then it seems like having ports-implemented
in device tree is acceptable.

There are a bunch of device trees that have this already:
arch/arm/boot/dts/qcom/qcom-apq8064.dtsi:                       ports-implemented = <0x1>;
arch/arm/boot/dts/qcom/qcom-ipq8064-v1.0.dtsi:                  ports-implemented = <0x1>;
arch/arm/boot/dts/qcom/qcom-ipq8064-v2.0.dtsi:  ports-implemented = <0x1>;
arch/arm/boot/dts/samsung/exynos5250.dtsi:                      ports-implemented = <0x1>;
arch/arm/boot/dts/socionext/uniphier-pro4.dtsi:                 ports-implemented = <1>;
arch/arm/boot/dts/socionext/uniphier-pro4.dtsi:                 ports-implemented = <1>;
arch/arm/boot/dts/socionext/uniphier-pxs2.dtsi:                 ports-implemented = <1>;
arch/arm/boot/dts/st/stih407-family.dtsi:                       ports-implemented = <0x1>;
arch/arm/boot/dts/st/stih407-family.dtsi:                       ports-implemented = <0x1>;
arch/arm/boot/dts/ti/omap/dra7-l4.dtsi:                         ports-implemented = <0x1>;
arch/arm/boot/dts/ti/omap/omap5-l4.dtsi:                                ports-implemented = <0x1>;
arch/arm64/boot/dts/mediatek/mt7622.dtsi:               ports-implemented = <0x1>;
arch/arm64/boot/dts/rockchip/rk3568.dtsi:               ports-implemented = <0x1>;
arch/arm64/boot/dts/rockchip/rk356x-base.dtsi:          ports-implemented = <0x1>;
arch/arm64/boot/dts/rockchip/rk356x-base.dtsi:          ports-implemented = <0x1>;
arch/arm64/boot/dts/rockchip/rk3576.dtsi:                       ports-implemented = <0x1>;
arch/arm64/boot/dts/rockchip/rk3576.dtsi:                       ports-implemented = <0x1>;
arch/arm64/boot/dts/rockchip/rk3588-base.dtsi:          ports-implemented = <0x1>;
arch/arm64/boot/dts/rockchip/rk3588-base.dtsi:          ports-implemented = <0x1>;
arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi:         ports-implemented = <0x1>;
arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi:                       ports-implemented = <1>;
arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi:                       ports-implemented = <1>;


Sure, if the ports implemented register was sticky (kept its value after a
reset), then I think Rob's suggestion would make sense.



Kind regards,
Niklas


From claudiu.beznea at tuxon.dev  Thu Aug 28 11:51:46 2025
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Thu, 28 Aug 2025 21:51:46 +0300
Subject: [PATCH v5 0/7] Add initial USB support for the Renesas RZ/G3S SoC
In-Reply-To: <aLAZprjeKtk4pusw@shikoro>
References: <20250819054212.486426-1-claudiu.beznea.uj@bp.renesas.com>
 <aLAZprjeKtk4pusw@shikoro>
Message-ID: <ae53d367-2ee5-49aa-82ba-86f9e84d4d25@tuxon.dev>

Hi, Wolfram,

On 8/28/25 11:56, Wolfram Sang wrote:
> Hi Claudiu,
> 
>> Series adds initial USB support for the Renesas RZ/G3S SoC.
>>
>> Series is split as follows:
>> - patches 1-2/7		- fixes on bindings and driver for USB PHY
>> - patches 3-5/7		- updates the rzg2l-usbphy-ctrl driver and documentation
>> 			  with support for setting PWRRDY though SYSC
>> - patches 6-7/7		- add device tree support
> 
> Can you kindly send me a working config (privately will do). I think I
> enabled all the necessary config options but still get:
> 
> [    0.271024] rzg2l_usbphy_ctrl 11e00000.usbphy-ctrl: probe with driver rzg2l_usbphy_ctrl failed with error -22
> ...
> [   10.981612] platform 11e20000.usb: deferred probe pending: platform: supplier 11e10200.usb-phy not ready
> [   10.984103] platform 11e10200.usb-phy: deferred probe pending: platform: wait for supplier /soc/usbphy-ctrl at 11e00000/regulator-vbus

I just checked it on latest linux-next and all good on my side. Would it be 
possible that you don't have commit 2da2740fb9c8 ("soc: renesas: rz-sysc: Add 
syscon/regmap support") in your tree?

This is how my tree looks like:

1db69bbb9c49 (HEAD) arm64: dts: renesas: rzg3s-smarc: Enable USB support
ee93ed9f0097 arm64: dts: renesas: r9a08g045: Add USB support
285447f934f3 reset: rzg2l-usbphy-ctrl: Add support for RZ/G3S SoC
8c758908876c reset: rzg2l-usbphy-ctrl: Add support for USB PWRRDY
8e41c54ab567 dt-bindings: reset: renesas,rzg2l-usbphy-ctrl: Document RZ/G3S support
02db7a65b4b3 phy: renesas: rcar-gen3-usb2: Fix an error handling path in 
rcar_gen3_phy_usb2_probe()
217453b58bdf dt-bindings: phy: renesas,usb2-phy: Mark resets as required for RZ/G3S
0f4c93f7eb86 (tag: next-20250822, linux-next/master) Add linux-next specific 
files for 20250822

and few checks on my board:

root at smarc-rzg3s:~# uname -r
6.17.0-rc2-next-20250822-00007-g1db69bbb9c49
root at smarc-rzg3s:~# [  217.627804] usb 1-1.2: USB disconnect, device number 4
[  217.627804] usb 1-1.2: USB disconnect, device number 4

root at smarc-rzg3s:~#
root at smarc-rzg3s:~#
root at smarc-rzg3s:~#
root at smarc-rzg3s:~# lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 045b:022b Hitachi, Ltd
Bus 001 Device 003: ID 8087:0029 Intel Corp. AX200 Bluetooth
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
root at smarc-rzg3s:~# [  231.154575] usb 1-1.2: new high-speed USB device number 5 
using ehci-platform
[  231.154575] usb 1-1.2: new high-speed USB device number 5 using ehci-platform
[  231.299629] usb-storage 1-1.2:1.0: USB Mass Storage device detected
[  231.299629] usb-storage 1-1.2:1.0: USB Mass Storage device detected
[  231.327087] scsi host0: usb-storage 1-1.2:1.0
[  231.327087] scsi host0: usb-storage 1-1.2:1.0
[  232.348676] scsi 0:0:0:0: Direct-Access     SanDisk  Cruzer Blade     1.00 
PQ: 0 ANSI: 6
[  232.348676] scsi 0:0:0:0: Direct-Access     SanDisk  Cruzer Blade     1.00 
PQ: 0 ANSI: 6
[  232.382829] sd 0:0:0:0: [sda] 31260672 512-byte logical blocks: (16.0 GB/14.9 
GiB)
[  232.382829] sd 0:0:0:0: [sda] 31260672 512-byte logical blocks: (16.0 GB/14.9 
GiB)
[  232.417118] sd 0:0:0:0: [sda] Write Protect is off
[  232.417118] sd 0:0:0:0: [sda] Write Protect is off
[  232.430023] sd 0:0:0:0: [sda] Write cache: disabled, read cache: enabled, 
doesn't support DPO or FUA
[  232.430023] sd 0:0:0:0: [sda] Write cache: disabled, read cache: enabled, 
doesn't support DPO or FUA
[  232.481535]  sda: sda1
[  232.481535]  sda: sda1
[  232.490719] sd 0:0:0:0: [sda] Attached SCSI removable disk
[  232.490719] sd 0:0:0:0: [sda] Attached SCSI removable disk

root at smarc-rzg3s:~#
root at smarc-rzg3s:~#
root at smarc-rzg3s:~# lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 045b:022b Hitachi, Ltd
Bus 001 Device 003: ID 8087:0029 Intel Corp. AX200 Bluetooth
Bus 001 Device 005: ID 0781:5567 SanDisk Corp. Cruzer Blade
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
root at smarc-rzg3s:~#
root at smarc-rzg3s:~#

Thank you for looking to this,
Claudiu

> 
> Thanks,
> 
>     Wolfram
> 



From igor.belwon at mentallysanemainliners.org  Thu Aug 28 13:06:25 2025
From: igor.belwon at mentallysanemainliners.org (Igor Belwon)
Date: Thu, 28 Aug 2025 22:06:25 +0200
Subject: [PATCH v1 2/2] phy: mediatek: tphy: Add software role switching
In-Reply-To: <20250814234825.810-2-me@adomerle.pw>
References: <20250814234825.810-1-me@adomerle.pw>
 <20250814234825.810-2-me@adomerle.pw>
Message-ID: <DCEBXZ0J8PYY.1D1SFSURUN457@mentallysanemainliners.org>

Hi Arseniy,

On Fri Aug 15, 2025 at 1:48 AM CEST, Arseniy Velikanov wrote:
> MediaTek USB T-PHY has broken role switching on (likely) all mobile SoCs.
> Known affected socs are: MT6735, MT6757, MT6761, MT6765, MT6768, MT6771,
> MT6785, MT6789.
>
> The downstream kernel manually controls the PHY mode by writing
> "test mode" FORCE regs. Setting all these regs fixes device/host modes, but
> breaks dual-role functionality. As a workaround we use workqueue that
> periodically checks the USB role and changes the PHY mode accordingly.
>
> To address this issue only on affected SoCs, we introduce a new
> device-tree property `mediatek,software-role-switch`. This ensures
> the workaround is applied only to broken hardware while leaving unaffected
> devices (like Chromebooks) untouched.
>
> Signed-off-by: Arseniy Velikanov <me at adomerle.pw>
> ---
>  drivers/phy/mediatek/phy-mtk-tphy.c | 148 ++++++++++++++++++++++++++++
>  1 file changed, 148 insertions(+)
>
> diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
> index f6504e0ecd1a..472859ec929c 100644
> --- a/drivers/phy/mediatek/phy-mtk-tphy.c
> +++ b/drivers/phy/mediatek/phy-mtk-tphy.c
> @@ -18,6 +18,9 @@
>  #include <linux/phy/phy.h>
>  #include <linux/platform_device.h>
>  #include <linux/regmap.h>
> +#include <linux/usb/role.h>
> +#include <linux/usb/otg.h>
> +#include <linux/workqueue.h>
>  
>  #include "phy-mtk-io.h"
>  
> @@ -111,11 +114,18 @@
>  
>  #define U3P_U2PHYDTM1		0x06C
>  #define P2C_RG_UART_EN			BIT(16)
> +#define P2C_FORCE_IDPULLUP	BIT(8)
>  #define P2C_FORCE_IDDIG		BIT(9)
> +#define P2C_FORCE_AVALID	BIT(10)
> +#define P2C_FORCE_SESSEND	BIT(12)
> +#define P2C_FORCE_VBUSVALID	BIT(13)
> +
>  #define P2C_RG_VBUSVALID		BIT(5)
>  #define P2C_RG_SESSEND			BIT(4)
> +#define P2C_RG_BVALID			BIT(3)
>  #define P2C_RG_AVALID			BIT(2)
>  #define P2C_RG_IDDIG			BIT(1)
> +#define P2C_RG_IDPULLUP			BIT(0)
>  
>  #define U3P_U2PHYBC12C		0x080
>  #define P2C_RG_CHGDT_EN		BIT(0)
> @@ -317,6 +327,8 @@ struct mtk_phy_instance {
>  		struct u3phy_banks u3_banks;
>  	};
>  	struct clk_bulk_data clks[TPHY_CLKS_CNT];
> +	struct delayed_work dr_work;
> +	struct usb_role_switch *role_switch;
>  	u32 index;
>  	u32 type;
>  	struct regmap *type_sw;
> @@ -326,14 +338,17 @@ struct mtk_phy_instance {
>  	u32 efuse_intr;
>  	u32 efuse_tx_imp;
>  	u32 efuse_rx_imp;
> +	int current_role;
>  	int eye_src;
>  	int eye_vrt;
>  	int eye_term;
>  	int intr;
>  	int discth;
>  	int pre_emphasis;
> +	int sw_get_retries;
>  	bool bc12_en;
>  	bool type_force_mode;
> +	bool software_role_switch;
>  };
>  
>  struct mtk_tphy {
> @@ -818,12 +833,118 @@ static void u2_phy_pll_26m_set(struct mtk_tphy *tphy,
>  			 P2R_RG_U2PLL_FRA_EN | P2R_RG_U2PLL_REFCLK_SEL);
>  }
>  
> +static void u2_phy_instance_role_set(struct mtk_phy_instance *instance,
> +				     int role)
> +{
> +	struct u2phy_banks *u2_banks = &instance->u2_banks;
> +	void __iomem *com = u2_banks->com;
> +
> +	instance->current_role = role;
> +
> +	/* end session before role switch */
> +	mtk_phy_set_bits(com + U3P_U2PHYDTM1, P2C_RG_SESSEND);
> +	mdelay(5);
> +	mtk_phy_clear_bits(com + U3P_U2PHYDTM1, P2C_RG_SESSEND);
> +
> +	switch (role) {
> +	case USB_ROLE_DEVICE:
> +		dev_dbg(&instance->phy->dev, "set device role\n");
> +		mtk_phy_set_bits(com + U3P_U2PHYDTM1, P2C_RG_IDDIG);
> +		break;
> +	case USB_ROLE_HOST:
> +		dev_dbg(&instance->phy->dev, "set host role\n");
> +		mtk_phy_clear_bits(com + U3P_U2PHYDTM1, P2C_RG_IDDIG);
> +		break;
> +	default:
> +		break;
> +	}
> +}
> +
> +static void u2_phy_role_switch_work(struct work_struct *work)
> +{
> +	struct mtk_phy_instance *instance =
> +		container_of(work, struct mtk_phy_instance, dr_work.work);
> +	int role;
> +
> +	if (IS_ERR_OR_NULL(instance->role_switch))
> +		instance->role_switch = usb_role_switch_get(&instance->phy->dev);
> +
> +	if (IS_ERR_OR_NULL(instance->role_switch)) {
> +		if (instance->sw_get_retries >= 10) {
> +			dev_warn(&instance->phy->dev, "failed to get role switch\n");
> +			return;
> +		}
> +
> +		instance->sw_get_retries += 1;
> +		schedule_delayed_work(&instance->dr_work, msecs_to_jiffies(500));
> +	}
> +
> +	role = usb_role_switch_get_role(instance->role_switch);
> +
> +	if (instance->current_role == role)
> +		goto reschedule_work;
> +
> +	u2_phy_instance_role_set(instance, role);
> +
> +reschedule_work:
> +	schedule_delayed_work(&instance->dr_work, msecs_to_jiffies(100));
> +}
> +
> +static int u2_phy_software_role_switch_init(struct mtk_phy_instance *instance)
> +{
> +	struct fwnode_handle *ep, *remote_ep, *usb_fwnode;
> +	struct device *usb_dev;
> +	int mode;
> +
> +	instance->sw_get_retries = 0;
> +
> +	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(&instance->phy->dev),
> +					     0,
> +					     0,
> +					     FWNODE_GRAPH_ENDPOINT_NEXT);
> +	if (!ep)
> +		return -ENODEV;
> +
> +	remote_ep = fwnode_graph_get_remote_endpoint(ep);
> +	fwnode_handle_put(ep);
> +	if (!remote_ep)
> +		return -ENODEV;
> +
> +	usb_fwnode = fwnode_graph_get_port_parent(remote_ep);
> +	fwnode_handle_put(remote_ep);
> +
> +	if (!usb_fwnode)
> +		return -ENODEV;
> +
> +	usb_dev = bus_find_device_by_fwnode(&platform_bus_type, usb_fwnode);
> +	fwnode_handle_put(usb_fwnode);
> +	if (!usb_dev)
> +		return -ENODEV;
> +
> +	mode = usb_get_role_switch_default_mode(usb_dev);
> +	if (mode == USB_DR_MODE_HOST)
> +		u2_phy_instance_role_set(instance, USB_ROLE_HOST);
> +	else
> +		u2_phy_instance_role_set(instance, USB_ROLE_DEVICE);
> +
> +	INIT_DELAYED_WORK(&instance->dr_work, u2_phy_role_switch_work);
> +
> +	return 0;
> +}
> +
>  static void u2_phy_instance_init(struct mtk_tphy *tphy,
>  	struct mtk_phy_instance *instance)
>  {
>  	struct u2phy_banks *u2_banks = &instance->u2_banks;
>  	void __iomem *com = u2_banks->com;
>  	u32 index = instance->index;
> +	int ret;
> +
> +	if (instance->software_role_switch) {
> +		ret = u2_phy_software_role_switch_init(instance);
> +		if (ret)
> +			dev_warn(&instance->phy->dev, "failed to initialize role switching\n");
> +	}
>  
>  	/* switch to USB function, and enable usb pll */
>  	mtk_phy_clear_bits(com + U3P_U2PHYDTM0, P2C_FORCE_UART_EN | P2C_FORCE_SUSPENDM);
> @@ -883,6 +1004,18 @@ static void u2_phy_instance_power_on(struct mtk_tphy *tphy,
>  
>  		mtk_phy_set_bits(com + U3P_U2PHYDTM0, P2C_RG_SUSPENDM | P2C_FORCE_SUSPENDM);
>  	}
> +
> +	if (instance->software_role_switch) {
> +		/* Set FORCE modes for manual role switching */
> +		mtk_phy_set_bits(com + U3P_U2PHYDTM1, P2C_FORCE_IDPULLUP
> +			| P2C_FORCE_IDDIG | P2C_FORCE_AVALID | P2C_FORCE_VBUSVALID
> +			| P2C_FORCE_SESSEND);
> +		mtk_phy_set_bits(com + U3P_U2PHYDTM1, P2C_RG_IDPULLUP | P2C_RG_BVALID);
> +
> +		if (!instance->role_switch)
> +			schedule_delayed_work(&instance->dr_work, msecs_to_jiffies(100));
> +	}
> +
>  	dev_dbg(tphy->dev, "%s(%d)\n", __func__, index);
>  }
>  
> @@ -906,6 +1039,9 @@ static void u2_phy_instance_power_off(struct mtk_tphy *tphy,
>  		mtk_phy_clear_bits(com + U3D_U2PHYDCR0, P2C_RG_SIF_U2PLL_FORCE_ON);
>  	}
>  
> +	if (instance->role_switch)
> +		cancel_delayed_work_sync(&instance->dr_work);
> +
>  	dev_dbg(tphy->dev, "%s(%d)\n", __func__, index);
>  }
>  
> @@ -940,6 +1076,9 @@ static void u2_phy_instance_set_mode(struct mtk_tphy *tphy,
>  		tmp &= ~P2C_RG_IDDIG;
>  		break;
>  	case PHY_MODE_USB_OTG:
> +		/* We are managing role in workqueue */
> +		if (instance->software_role_switch)
> +			return;
>  		tmp &= ~(P2C_FORCE_IDDIG | P2C_RG_IDDIG);
>  		break;
>  	default:
> @@ -1129,6 +1268,11 @@ static void phy_parse_property(struct mtk_tphy *tphy,
>  	if (instance->type == PHY_TYPE_USB3)
>  		instance->type_force_mode = device_property_read_bool(dev, "mediatek,force-mode");
>  
> +	instance->software_role_switch =
> +		device_property_read_bool(dev, "mediatek,software-role-switch");
> +	if (instance->software_role_switch)
> +		dev_info(dev, "software role switch enabled\n");
> +
>  	if (instance->type != PHY_TYPE_USB2)
>  		return;
>  
> @@ -1618,6 +1762,10 @@ static int mtk_tphy_probe(struct platform_device *pdev)
>  		struct phy *phy;
>  		int retval;
>  
> +		/* filter non-phy nodes (e.g. graphs) */
> +		if (!of_find_property(child_np, "reg", NULL))
> +			continue;
> +
>  		instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
>  		if (!instance)
>  			return -ENOMEM;

This patch made USB role-switching work on the MT6878 SoC. As such:

Tested-by: Igor Belwon <igor.belwon at mentallysanemainliners.org>

Kind regards,
Igor


From Thinh.Nguyen at synopsys.com  Thu Aug 28 15:51:46 2025
From: Thinh.Nguyen at synopsys.com (Thinh Nguyen)
Date: Thu, 28 Aug 2025 22:51:46 +0000
Subject: [PATCH RFC 07/22] usb: dwc3: apple: Adjust vendor-specific
 registers during init
In-Reply-To: <0289f92d-0d18-43d2-b98a-da8bb08e9342@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
 <20250821-atcphy-6-17-v1-7-172beda182b8@kernel.org>
 <20250821221832.zsn4rk7nomsbgytx@synopsys.com>
 <0289f92d-0d18-43d2-b98a-da8bb08e9342@kernel.org>
Message-ID: <20250828225145.lma4lp2afvmuop2l@synopsys.com>

On Sat, Aug 23, 2025, Sven Peter wrote:
> Hi Thinh,
> 
> On 22.08.25 00:18, Thinh Nguyen wrote:
> > For this patch, however, I'd prefer these vendor-specific settings to be
> > in their own glue driver. I can only imagine more changes will be
> > introduced in the future with this vendor. See if we can use the new
> > glue interface in glue.h (some call this the new "flatten" model) when
> > creating a glue driver.
> 
> Nice, thanks! Hints like that are exactly what I was hoping for when
> I sent this RFC.
> 
> When I originally started working on this I tried to use the parent/child
> model but didn't really get anywhere. This flattened model looks very useful
> though.
> 
> I think I can even move some of logic from the previous commits to
> dwc3-apple.c if I extend the glue a little bit. I'll see how that works out
> and maybe do that for the next version then.
> 

That's great! I'll look forward to your updates.

Check this change for inspirations for extending the glue interface:
https://lore.kernel.org/linux-usb/20250815004207.xwv4n6xsat44bydi at synopsys.com/T/#u

Thanks,
Thinh

From Thinh.Nguyen at synopsys.com  Thu Aug 28 16:06:02 2025
From: Thinh.Nguyen at synopsys.com (Thinh Nguyen)
Date: Thu, 28 Aug 2025 23:06:02 +0000
Subject: [PATCH RFC 05/22] usb: dwc3: apple: Do not use host-vbus-glitches
 workaround
In-Reply-To: <c052860b-c239-43a6-b05d-c8495bc1c731@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
 <20250821-atcphy-6-17-v1-5-172beda182b8@kernel.org>
 <20250821222842.fqrxjp56czc7ubok@synopsys.com>
 <c052860b-c239-43a6-b05d-c8495bc1c731@kernel.org>
Message-ID: <20250828230558.euvmnbgij46kqkeb@synopsys.com>

On Sat, Aug 23, 2025, Sven Peter wrote:
> On 22.08.25 00:28, Thinh Nguyen wrote:
> > On Thu, Aug 21, 2025, Sven Peter wrote:
> > > From: Janne Grunau <j at jannau.net>
> 
> [...]
> 
> > >   	/*
> > >   	 * Some platforms need to power off all Root hub ports immediately after DWC3 set to host
> > >   	 * mode to avoid VBUS glitch happen when xhci get reset later.
> > > +	 * On Apple platforms we must not touch any MMIO yet because dwc3
> > > +	 * will not work correctly before its PHY has been initialized.
> > 
> > This doesn't make sense, the phy should've been initialized by this
> > point. We already access MMIO before this. Even your [PATCH RFC 7/22]
> > attempts to access MMIO before this, yet accessing here causes problem.
> > Do we know when the phy get initialized then?
> 
> You're absolutely right, this doesn't make any sense!
> 
> dwc3_power_off_all_roothub_ports uses ioremap which will map the XHCI region
> as Device-nGnRE. That just doesn't work on these machines and actually
> explains the SErrors.
> Resources on these machines generally have the IORESOURCE_MEM_NONPOSTED flag
> set (via the nonposted-mmio dt property) and then use ioremap_np to map them
> using Device-nGnRnE.
> 

Ok. So the failure does not seem to be because the phy hasn't been
initialized yet, but it's because of io mapping.

Did you try to check against IORESOURCE_MEM_NONPOSTED to use ioremap_np
instead? That keeps the logic consistent between different platforms.

BR,
Thinh

From Thinh.Nguyen at synopsys.com  Thu Aug 28 16:07:45 2025
From: Thinh.Nguyen at synopsys.com (Thinh Nguyen)
Date: Thu, 28 Aug 2025 23:07:45 +0000
Subject: [PATCH RFC 04/22] usb: dwc3: apple: Reset dwc3 during role
 switches
In-Reply-To: <20250824131841.GG1270980@robin.jannau.net>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
 <20250821-atcphy-6-17-v1-4-172beda182b8@kernel.org>
 <20250821232547.qzplkafogsacnbti@synopsys.com>
 <20250824131841.GG1270980@robin.jannau.net>
Message-ID: <20250828230743.l2774axh67aivjl5@synopsys.com>

On Sun, Aug 24, 2025, Janne Grunau wrote:
> On Thu, Aug 21, 2025 at 11:25:51PM +0000, Thinh Nguyen wrote:
> > On Thu, Aug 21, 2025, Sven Peter wrote:
> > > As mad as it sounds, the dwc3 controller present on the Apple M1 must be
> > > reset and reinitialized whenever a device is unplugged from the root
> > > port or when the PHY mode is changed.
> > > 
> > > This is required for at least the following reasons:
> > > 
> > >   - The USB2 D+/D- lines are connected through a stateful eUSB2 repeater
> > >     which in turn is controlled by a variant of the TI TPS6598x USB PD
> > >     chip. When the USB PD controller detects a hotplug event it resets
> > >     the eUSB2 repeater. Afterwards, no new device is recognized before
> > >     the DWC3 core and PHY are reset as well because the eUSB2 repeater
> > >     and the PHY/dwc3 block disagree about the current state.
> > > 
> > >   - It's possible to completely break the dwc3 controller by switching
> > >     it to device mode and unplugging the cable at just the wrong time.
> > >     If this happens dwc3 behaves as if no device is connected.
> > >     CORESOFTRESET will also never clear after it has been set. The only
> > >     workaround is to trigger a hard reset of the entire dwc3 core with
> > >     its external reset line.
> > > 
> > >   - Whenever the PHY mode is changed (to e.g. transition to DisplayPort
> > >     alternate mode or USB4) dwc3 has to be shutdown and reinitialized.
> > >     Otherwise the Type-C port will not be usable until the entire SoC
> > >     has been reset.
> > > 
> > > All of this can be easily worked around by respecting transitions to
> > > USB_ROLE_NONE and making sure the external reset line is asserted when
> > > switching roles. We additionally have to ensure that the PHY is
> > > suspended during init.
> > > 
> > > Signed-off-by: Sven Peter <sven at kernel.org>
> > > ---
> > >  drivers/usb/dwc3/core.c | 61 +++++++++++++++++++++++++++++++++++++++++++++----
> > >  drivers/usb/dwc3/core.h |  3 +++
> > >  drivers/usb/dwc3/drd.c  | 11 ++++++++-
> > >  drivers/usb/dwc3/host.c |  3 ++-
> > >  4 files changed, 72 insertions(+), 6 deletions(-)
> > > 
> > > diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> > > index 8002c23a5a02acb8f3e87b2662a53998a4cf4f5c..26aa507a738f001409a97ef563c6561433a1cac5 100644
> > > --- a/drivers/usb/dwc3/core.c
> > > +++ b/drivers/usb/dwc3/core.c
> 
> ...
> 
> > >  	/*
> > >  	 * When current_dr_role is not set, there's no role switching.
> > >  	 * Only perform GCTL.CoreSoftReset when there's DRD role switching.
> > >  	 */
> > > -	if (dwc->current_dr_role && ((DWC3_IP_IS(DWC3) ||
> > > +	if (dwc->role_switch_reset_quirk ||
> > 
> > Don't override the use of GCTL.CoreSoftReset with this quirk. Not all
> > controller versions should use GCTL.CoreSoftReset, the new controller
> > version don't even have it. What version is this vendor using?
> 
> It reports DWC31, revision 190A and the unlisted version_types
> 0x736f3035 (M1), 0x736f3039 (M1 Pro/Max/Ultra) and 0x736f3130 (M2, M2
> Pro/Max/Ultra).
> 

Thanks for the info. This version should not be using
GCTL.CoreSoftReset.

BR,
Thinh

From Thinh.Nguyen at synopsys.com  Thu Aug 28 16:14:35 2025
From: Thinh.Nguyen at synopsys.com (Thinh Nguyen)
Date: Thu, 28 Aug 2025 23:14:35 +0000
Subject: [PATCH RFC 04/22] usb: dwc3: apple: Reset dwc3 during role
 switches
In-Reply-To: <bc4fa511-5dc5-4844-8206-eb55783647e8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
 <20250821-atcphy-6-17-v1-4-172beda182b8@kernel.org>
 <20250821232547.qzplkafogsacnbti@synopsys.com>
 <bc4fa511-5dc5-4844-8206-eb55783647e8@kernel.org>
Message-ID: <20250828231434.koacer62sx6hyagx@synopsys.com>

On Sun, Aug 24, 2025, Sven Peter wrote:
> On 22.08.25 01:25, Thinh Nguyen wrote:
> > 
> > > +		(dwc->current_dr_role && ((DWC3_IP_IS(DWC3) ||
> > >   			DWC3_VER_IS_PRIOR(DWC31, 190A)) &&
> > > -			desired_dr_role != DWC3_GCTL_PRTCAP_OTG)) {
> > > +			desired_dr_role != DWC3_GCTL_PRTCAP_OTG))) {
> > >   		reg = dwc3_readl(dwc->regs, DWC3_GCTL);
> > >   		reg |= DWC3_GCTL_CORESOFTRESET;
> > >   		dwc3_writel(dwc->regs, DWC3_GCTL, reg);
> > > @@ -1372,6 +1394,9 @@ static int dwc3_core_init(struct dwc3 *dwc)
> > >   	if (ret)
> > >   		goto err_exit_phy;
> > > +	if (dwc->role_switch_reset_quirk)
> > > +		dwc3_enable_susphy(dwc, true);
> > > +
> > 
> > Why do you need to enable susphy here?
> 
> The only place we actually need it is when we shut down the Type-C PHY due
> some what I assume is some hardware quirk, i.e. just before dwc3_core_exit.

Not really hardware quirk. Some low level phy commands can only be
executed while the phy is in low power.

> 
> The PHY will otherwise not be able to acquire some hardware lock (which they
> call PIPEHANDLER lock in debug strings) to switch from e.g. USB3 PHY to a
> dummy PHY for USB2 only. It then can't shut down cleanly anymore and will
> get stuck in a weird state where the port refuses to work until I reset
> everything.
> Originally it was added because we just undid some commit where susphy
> handling was made unconditional IIRC.
> 
> I'll move this to the glue driver with a comment explaining why it's
> required.
> 
> 

Perhaps this patch can give you some clues:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/usb/dwc3/core.c?id=cc5bfc4e16fc1d1c520cd7bb28646e82b6e69217

BR,
Thinh

From luyulin at eswincomputing.com  Thu Aug 28 23:22:11 2025
From: luyulin at eswincomputing.com (luyulin at eswincomputing.com)
Date: Fri, 29 Aug 2025 14:22:11 +0800 (GMT+08:00)
Subject: [PATCH v2 1/3] dt-bindings: ata: eswin: Document for
 EIC7700 SoC ahci
In-Reply-To: <aLBUC116MdJqDGIJ@flawful.org>
References: <20250819134722.220-1-luyulin@eswincomputing.com>
 <20250819135413.386-1-luyulin@eswincomputing.com>
 <CAL_JsqKFotNLZZXwiy7S6K8qXLdGRAnsa-1zvZRDQBE39Gf5kg@mail.gmail.com>
 <692e11ca.843.198f0337528.Coremail.luyulin@eswincomputing.com>
 <aLBUC116MdJqDGIJ@flawful.org>
Message-ID: <4ab70c6a.8be.198f47da494.Coremail.luyulin@eswincomputing.com>


> On Thu, Aug 28, 2025 at 06:22:40PM +0800, luyulin at eswincomputing.com wrote:
> > 
> > Do you mean that ports-implemented should be removed from the dts,
> > and the corresponding register should be configured by the firmware
> > (which is U-Boot on the HiFive Premier P550 board)? Is this understanding correct?
> > If so, when the driver is removed, a reset will be triggered,
> > causing the configuration of this register to be lost,
> > which will result in an error when insmod the driver again.
> 
> My 50 cents,
> 
> if the ports implemented register gets reset from the reset_control_reset()
> in ahci_platform_assert_rsts(), then it seems like having ports-implemented
> in device tree is acceptable.
> 

In our design, the ports implemented register gets reset from the ahci_platform_assert_rsts().

> There are a bunch of device trees that have this already:
> arch/arm/boot/dts/qcom/qcom-apq8064.dtsi:                       ports-implemented = <0x1>;
> arch/arm/boot/dts/qcom/qcom-ipq8064-v1.0.dtsi:                  ports-implemented = <0x1>;
> arch/arm/boot/dts/qcom/qcom-ipq8064-v2.0.dtsi:  ports-implemented = <0x1>;
> arch/arm/boot/dts/samsung/exynos5250.dtsi:                      ports-implemented = <0x1>;
> arch/arm/boot/dts/socionext/uniphier-pro4.dtsi:                 ports-implemented = <1>;
> arch/arm/boot/dts/socionext/uniphier-pro4.dtsi:                 ports-implemented = <1>;
> arch/arm/boot/dts/socionext/uniphier-pxs2.dtsi:                 ports-implemented = <1>;
> arch/arm/boot/dts/st/stih407-family.dtsi:                       ports-implemented = <0x1>;
> arch/arm/boot/dts/st/stih407-family.dtsi:                       ports-implemented = <0x1>;
> arch/arm/boot/dts/ti/omap/dra7-l4.dtsi:                         ports-implemented = <0x1>;
> arch/arm/boot/dts/ti/omap/omap5-l4.dtsi:                                ports-implemented = <0x1>;
> arch/arm64/boot/dts/mediatek/mt7622.dtsi:               ports-implemented = <0x1>;
> arch/arm64/boot/dts/rockchip/rk3568.dtsi:               ports-implemented = <0x1>;
> arch/arm64/boot/dts/rockchip/rk356x-base.dtsi:          ports-implemented = <0x1>;
> arch/arm64/boot/dts/rockchip/rk356x-base.dtsi:          ports-implemented = <0x1>;
> arch/arm64/boot/dts/rockchip/rk3576.dtsi:                       ports-implemented = <0x1>;
> arch/arm64/boot/dts/rockchip/rk3576.dtsi:                       ports-implemented = <0x1>;
> arch/arm64/boot/dts/rockchip/rk3588-base.dtsi:          ports-implemented = <0x1>;
> arch/arm64/boot/dts/rockchip/rk3588-base.dtsi:          ports-implemented = <0x1>;
> arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi:         ports-implemented = <0x1>;
> arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi:                       ports-implemented = <1>;
> arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi:                       ports-implemented = <1>;
> 
> 
> Sure, if the ports implemented register was sticky (kept its value after a
> reset), then I think Rob's suggestion would make sense.
> 
> 

Thank you very much for the clarification.

> 
> Kind regards,
> Niklas

Best regards,
Yulin

From peng.fan at nxp.com  Fri Aug 29 00:08:55 2025
From: peng.fan at nxp.com (Peng Fan)
Date: Fri, 29 Aug 2025 15:08:55 +0800
Subject: [PATCH v3 0/6] phy: phy-can-transceiver: Support TJA1048/TJA1051
Message-ID: <20250829-can-v3-0-3b2f34094f59@nxp.com>

TJA1048 is a Dual channel can transceiver with Sleep mode supported.
TJA1051 is a Single Channel can transceiver with Sleep mode supported.

To support them:
patch 1: add binding doc
patch 2/3: To support dual channel,
   - Introduce new flag CAN_TRANSCEIVER_DUAL_CH to indicate the phy
     has two channels.
   - Introduce can_transceiver_priv as a higher level encapsulation for
     phy, mux_state, num_ch.
   - Alloc a phy for each channel
patch 4,5,6: Update dts to use phys

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
---
Changes in v3:
- Patch 1: Add TJA1057, update #phy-cells
- Patch 2,3: Separate patch 2 into two patches per Frank, 1st introduce
  can_transceiver_priv, 2nd support dual chan by adding num_ch
- Patch 6: Change to 5Mbps rate
- Patch 4,5: Add R-b from Frank
- Link to v2: https://lore.kernel.org/r/20250825-can-v2-0-c461e9fcbc14 at nxp.com

Changes in v2:
- Update standby-gpios constraints per Conor's comments
- Drop patch 2 which is not needed.
- Link to v1: https://lore.kernel.org/r/20250822-can-v1-0-c075f702adea at nxp.com

---
Peng Fan (6):
      dt-bindings: phy: ti,tcan104x-can: Document NXP TJA105X/1048
      phy: phy-can-transceiver: Introduce can_transceiver_priv
      phy: phy-can-transceiver: Add dual channel support for TJA1048
      arm64: dts: imx95-15x15-evk: Use phys to replace xceiver-supply
      arm64: dts: imx8mp-evk: Use phys to replace xceiver-supply
      arm64: dts: imx93-11x11-evk: Use phys to replace xceiver-supply

 .../devicetree/bindings/phy/ti,tcan104x-can.yaml   |  32 +++++-
 arch/arm64/boot/dts/freescale/imx8mp-evk.dts       |  43 +++-----
 arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts  |  17 ++-
 arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts  |  13 ++-
 drivers/phy/phy-can-transceiver.c                  | 120 +++++++++++++++------
 5 files changed, 143 insertions(+), 82 deletions(-)
---
base-commit: 47e2059d930288d2225941bd30cc3fa1fe348044
change-id: 20250821-can-c832cb4f0323

Best regards,
-- 
Peng Fan <peng.fan at nxp.com>



From peng.fan at nxp.com  Fri Aug 29 00:08:56 2025
From: peng.fan at nxp.com (Peng Fan)
Date: Fri, 29 Aug 2025 15:08:56 +0800
Subject: [PATCH v3 1/6] dt-bindings: phy: ti,tcan104x-can: Document NXP
 TJA105X/1048
In-Reply-To: <20250829-can-v3-0-3b2f34094f59@nxp.com>
References: <20250829-can-v3-0-3b2f34094f59@nxp.com>
Message-ID: <20250829-can-v3-1-3b2f34094f59@nxp.com>

The TJA105[1,7] is a high-speed CAN transceiver which is a pin-compatible
alternative for TI TCAN1043 with sleep mode supported, and has a compatible
programming model, therefore use ti,tcan1043 as fallback compatible.

The TJA1048 is a dual high-speed CAN transceiver with sleep mode supported.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 .../devicetree/bindings/phy/ti,tcan104x-can.yaml   | 32 ++++++++++++++++++++--
 1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml b/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
index 4a8c3829d85d3c4a4963750d03567c1c345beb91..a225540545301e443e3460b933effbad48786597 100644
--- a/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
+++ b/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
@@ -19,18 +19,25 @@ properties:
           - enum:
               - microchip,ata6561
           - const: ti,tcan1042
+      - items:
+          - enum:
+              - nxp,tja1051
+              - nxp,tja1057
+          - const: ti,tcan1043
       - enum:
           - ti,tcan1042
           - ti,tcan1043
+          - nxp,tja1048
           - nxp,tjr1443
 
   '#phy-cells':
-    const: 0
+    enum: [0, 1]
 
   standby-gpios:
     description:
       gpio node to toggle standby signal on transceiver
-    maxItems: 1
+    minItems: 1
+    maxItems: 2
 
   enable-gpios:
     description:
@@ -53,6 +60,27 @@ required:
   - compatible
   - '#phy-cells'
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: nxp,tja1048
+    then:
+      properties:
+        '#phy-cells':
+          const: 1
+        standby-gpios:
+          minItems: 2
+          maxItems: 2
+    else:
+      properties:
+        '#phy-cells':
+          const: 0
+        standby-gpios:
+          minItems: 1
+          maxItems: 1
+
 additionalProperties: false
 
 examples:

-- 
2.37.1



From peng.fan at nxp.com  Fri Aug 29 00:08:57 2025
From: peng.fan at nxp.com (Peng Fan)
Date: Fri, 29 Aug 2025 15:08:57 +0800
Subject: [PATCH v3 2/6] phy: phy-can-transceiver: Introduce
 can_transceiver_priv
In-Reply-To: <20250829-can-v3-0-3b2f34094f59@nxp.com>
References: <20250829-can-v3-0-3b2f34094f59@nxp.com>
Message-ID: <20250829-can-v3-2-3b2f34094f59@nxp.com>

To prepare for dual-channel phy support, introduce can_transceiver_priv as
a higher level encapsulation for phy and mux_state.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/phy/phy-can-transceiver.c | 41 ++++++++++++++++++++++++++-------------
 1 file changed, 27 insertions(+), 14 deletions(-)

diff --git a/drivers/phy/phy-can-transceiver.c b/drivers/phy/phy-can-transceiver.c
index f59caff4b3d4c267feca4220bf1547b6fad08f95..6415c6af0e8414a6cc8d15958a17ee749a3f28e9 100644
--- a/drivers/phy/phy-can-transceiver.c
+++ b/drivers/phy/phy-can-transceiver.c
@@ -23,6 +23,11 @@ struct can_transceiver_phy {
 	struct phy *generic_phy;
 	struct gpio_desc *standby_gpio;
 	struct gpio_desc *enable_gpio;
+	struct can_transceiver_priv *priv;
+};
+
+struct can_transceiver_priv {
+	struct can_transceiver_phy *can_transceiver_phy;
 	struct mux_state *mux_state;
 };
 
@@ -32,8 +37,8 @@ static int can_transceiver_phy_power_on(struct phy *phy)
 	struct can_transceiver_phy *can_transceiver_phy = phy_get_drvdata(phy);
 	int ret;
 
-	if (can_transceiver_phy->mux_state) {
-		ret = mux_state_select(can_transceiver_phy->mux_state);
+	if (can_transceiver_phy->priv->mux_state) {
+		ret = mux_state_select(can_transceiver_phy->priv->mux_state);
 		if (ret) {
 			dev_err(&phy->dev, "Failed to select CAN mux: %d\n", ret);
 			return ret;
@@ -56,8 +61,8 @@ static int can_transceiver_phy_power_off(struct phy *phy)
 		gpiod_set_value_cansleep(can_transceiver_phy->standby_gpio, 1);
 	if (can_transceiver_phy->enable_gpio)
 		gpiod_set_value_cansleep(can_transceiver_phy->enable_gpio, 0);
-	if (can_transceiver_phy->mux_state)
-		mux_state_deselect(can_transceiver_phy->mux_state);
+	if (can_transceiver_phy->priv->mux_state)
+		mux_state_deselect(can_transceiver_phy->priv->mux_state);
 
 	return 0;
 }
@@ -107,7 +112,7 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
 {
 	struct phy_provider *phy_provider;
 	struct device *dev = &pdev->dev;
-	struct can_transceiver_phy *can_transceiver_phy;
+	struct can_transceiver_priv *priv;
 	const struct can_transceiver_data *drvdata;
 	const struct of_device_id *match;
 	struct phy *phy;
@@ -117,18 +122,25 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
 	u32 max_bitrate = 0;
 	int err;
 
-	can_transceiver_phy = devm_kzalloc(dev, sizeof(struct can_transceiver_phy), GFP_KERNEL);
-	if (!can_transceiver_phy)
-		return -ENOMEM;
-
 	match = of_match_node(can_transceiver_phy_ids, pdev->dev.of_node);
 	drvdata = match->data;
 
+	priv = devm_kzalloc(dev, sizeof(struct can_transceiver_priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, priv);
+
+	priv->can_transceiver_phy = devm_kzalloc(dev, sizeof(struct can_transceiver_phy),
+						 GFP_KERNEL);
+	if (!priv->can_transceiver_phy)
+		return -ENOMEM;
+
 	mux_state = devm_mux_state_get_optional(dev, NULL);
 	if (IS_ERR(mux_state))
 		return PTR_ERR(mux_state);
 
-	can_transceiver_phy->mux_state = mux_state;
+	priv->mux_state = mux_state;
 
 	phy = devm_phy_create(dev, dev->of_node,
 			      &can_transceiver_phy_ops);
@@ -142,23 +154,24 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
 		dev_warn(dev, "Invalid value for transceiver max bitrate. Ignoring bitrate limit\n");
 	phy->attrs.max_link_rate = max_bitrate;
 
-	can_transceiver_phy->generic_phy = phy;
+	priv->can_transceiver_phy->generic_phy = phy;
+	priv->can_transceiver_phy->priv = priv;
 
 	if (drvdata->flags & CAN_TRANSCEIVER_STB_PRESENT) {
 		standby_gpio = devm_gpiod_get_optional(dev, "standby", GPIOD_OUT_HIGH);
 		if (IS_ERR(standby_gpio))
 			return PTR_ERR(standby_gpio);
-		can_transceiver_phy->standby_gpio = standby_gpio;
+		priv->can_transceiver_phy->standby_gpio = standby_gpio;
 	}
 
 	if (drvdata->flags & CAN_TRANSCEIVER_EN_PRESENT) {
 		enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW);
 		if (IS_ERR(enable_gpio))
 			return PTR_ERR(enable_gpio);
-		can_transceiver_phy->enable_gpio = enable_gpio;
+		priv->can_transceiver_phy->enable_gpio = enable_gpio;
 	}
 
-	phy_set_drvdata(can_transceiver_phy->generic_phy, can_transceiver_phy);
+	phy_set_drvdata(priv->can_transceiver_phy->generic_phy, priv->can_transceiver_phy);
 
 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
 

-- 
2.37.1



From peng.fan at nxp.com  Fri Aug 29 00:08:58 2025
From: peng.fan at nxp.com (Peng Fan)
Date: Fri, 29 Aug 2025 15:08:58 +0800
Subject: [PATCH v3 3/6] phy: phy-can-transceiver: Add dual channel support
 for TJA1048
In-Reply-To: <20250829-can-v3-0-3b2f34094f59@nxp.com>
References: <20250829-can-v3-0-3b2f34094f59@nxp.com>
Message-ID: <20250829-can-v3-3-3b2f34094f59@nxp.com>

- Introduce new flag CAN_TRANSCEIVER_DUAL_CH to indicate the phy has two
  channels.
- Alloc a phy for each channel
- Support TJA1048 which is a dual high-speed CAN transceiver with sleep
  mode supported.
- Add can_transceiver_phy_xlate for parsing phy

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/phy/phy-can-transceiver.c | 91 ++++++++++++++++++++++++++++-----------
 1 file changed, 65 insertions(+), 26 deletions(-)

diff --git a/drivers/phy/phy-can-transceiver.c b/drivers/phy/phy-can-transceiver.c
index 6415c6af0e8414a6cc8d15958a17ee749a3f28e9..f06b1df76ada023f432dce892c3346f45397ab54 100644
--- a/drivers/phy/phy-can-transceiver.c
+++ b/drivers/phy/phy-can-transceiver.c
@@ -17,6 +17,7 @@ struct can_transceiver_data {
 	u32 flags;
 #define CAN_TRANSCEIVER_STB_PRESENT	BIT(0)
 #define CAN_TRANSCEIVER_EN_PRESENT	BIT(1)
+#define CAN_TRANSCEIVER_DUAL_CH		BIT(2)
 };
 
 struct can_transceiver_phy {
@@ -29,6 +30,7 @@ struct can_transceiver_phy {
 struct can_transceiver_priv {
 	struct can_transceiver_phy *can_transceiver_phy;
 	struct mux_state *mux_state;
+	int num_ch;
 };
 
 /* Power on function */
@@ -81,6 +83,10 @@ static const struct can_transceiver_data tcan1043_drvdata = {
 	.flags = CAN_TRANSCEIVER_STB_PRESENT | CAN_TRANSCEIVER_EN_PRESENT,
 };
 
+static const struct can_transceiver_data tja1048_drvdata = {
+	.flags = CAN_TRANSCEIVER_STB_PRESENT | CAN_TRANSCEIVER_DUAL_CH,
+};
+
 static const struct of_device_id can_transceiver_phy_ids[] = {
 	{
 		.compatible = "ti,tcan1042",
@@ -90,6 +96,10 @@ static const struct of_device_id can_transceiver_phy_ids[] = {
 		.compatible = "ti,tcan1043",
 		.data = &tcan1043_drvdata
 	},
+	{
+		.compatible = "nxp,tja1048",
+		.data = &tja1048_drvdata
+	},
 	{
 		.compatible = "nxp,tjr1443",
 		.data = &tcan1043_drvdata
@@ -108,6 +118,25 @@ devm_mux_state_get_optional(struct device *dev, const char *mux_name)
 	return devm_mux_state_get(dev, mux_name);
 }
 
+static struct phy *can_transceiver_phy_xlate(struct device *dev,
+					     const struct of_phandle_args *args)
+{
+	struct can_transceiver_priv *priv = dev_get_drvdata(dev);
+	u32 idx;
+
+	if (priv->num_ch == 1)
+		return priv->can_transceiver_phy[0].generic_phy;
+
+	if (args->args_count != 1)
+		return ERR_PTR(-EINVAL);
+
+	idx = args->args[0];
+	if (idx >= priv->num_ch)
+		return ERR_PTR(-EINVAL);
+
+	return priv->can_transceiver_phy[idx].generic_phy;
+}
+
 static int can_transceiver_phy_probe(struct platform_device *pdev)
 {
 	struct phy_provider *phy_provider;
@@ -120,7 +149,8 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
 	struct gpio_desc *enable_gpio;
 	struct mux_state *mux_state;
 	u32 max_bitrate = 0;
-	int err;
+	int num_ch = 1;
+	int err, i;
 
 	match = of_match_node(can_transceiver_phy_ids, pdev->dev.of_node);
 	drvdata = match->data;
@@ -131,7 +161,11 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, priv);
 
-	priv->can_transceiver_phy = devm_kzalloc(dev, sizeof(struct can_transceiver_phy),
+	if (drvdata->flags & CAN_TRANSCEIVER_DUAL_CH)
+		num_ch = 2;
+
+	priv->num_ch = num_ch;
+	priv->can_transceiver_phy = devm_kcalloc(dev, num_ch, sizeof(struct can_transceiver_phy),
 						 GFP_KERNEL);
 	if (!priv->can_transceiver_phy)
 		return -ENOMEM;
@@ -142,38 +176,43 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
 
 	priv->mux_state = mux_state;
 
-	phy = devm_phy_create(dev, dev->of_node,
-			      &can_transceiver_phy_ops);
-	if (IS_ERR(phy)) {
-		dev_err(dev, "failed to create can transceiver phy\n");
-		return PTR_ERR(phy);
-	}
-
 	err = device_property_read_u32(dev, "max-bitrate", &max_bitrate);
 	if ((err != -EINVAL) && !max_bitrate)
 		dev_warn(dev, "Invalid value for transceiver max bitrate. Ignoring bitrate limit\n");
-	phy->attrs.max_link_rate = max_bitrate;
 
-	priv->can_transceiver_phy->generic_phy = phy;
-	priv->can_transceiver_phy->priv = priv;
+	for (i = 0; i < num_ch; i++) {
+		phy = devm_phy_create(dev, dev->of_node, &can_transceiver_phy_ops);
+		if (IS_ERR(phy)) {
+			dev_err(dev, "failed to create can transceiver phy\n");
+			return PTR_ERR(phy);
+		}
 
-	if (drvdata->flags & CAN_TRANSCEIVER_STB_PRESENT) {
-		standby_gpio = devm_gpiod_get_optional(dev, "standby", GPIOD_OUT_HIGH);
-		if (IS_ERR(standby_gpio))
-			return PTR_ERR(standby_gpio);
-		priv->can_transceiver_phy->standby_gpio = standby_gpio;
-	}
+		phy->attrs.max_link_rate = max_bitrate;
 
-	if (drvdata->flags & CAN_TRANSCEIVER_EN_PRESENT) {
-		enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW);
-		if (IS_ERR(enable_gpio))
-			return PTR_ERR(enable_gpio);
-		priv->can_transceiver_phy->enable_gpio = enable_gpio;
-	}
+		priv->can_transceiver_phy[i].generic_phy = phy;
+		priv->can_transceiver_phy[i].priv = priv;
 
-	phy_set_drvdata(priv->can_transceiver_phy->generic_phy, priv->can_transceiver_phy);
+		if (drvdata->flags & CAN_TRANSCEIVER_STB_PRESENT) {
+			standby_gpio = devm_gpiod_get_index_optional(dev, "standby", i,
+								     GPIOD_OUT_HIGH);
+			if (IS_ERR(standby_gpio))
+				return PTR_ERR(standby_gpio);
+			priv->can_transceiver_phy[i].standby_gpio = standby_gpio;
+		}
+
+		if (drvdata->flags & CAN_TRANSCEIVER_EN_PRESENT) {
+			enable_gpio = devm_gpiod_get_index_optional(dev, "enable", i,
+								    GPIOD_OUT_LOW);
+			if (IS_ERR(enable_gpio))
+				return PTR_ERR(enable_gpio);
+			priv->can_transceiver_phy[i].enable_gpio = enable_gpio;
+		}
+
+		phy_set_drvdata(priv->can_transceiver_phy[i].generic_phy,
+				&priv->can_transceiver_phy[i]);
+	}
 
-	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+	phy_provider = devm_of_phy_provider_register(dev, can_transceiver_phy_xlate);
 
 	return PTR_ERR_OR_ZERO(phy_provider);
 }

-- 
2.37.1



From peng.fan at nxp.com  Fri Aug 29 00:08:59 2025
From: peng.fan at nxp.com (Peng Fan)
Date: Fri, 29 Aug 2025 15:08:59 +0800
Subject: [PATCH v3 4/6] arm64: dts: imx95-15x15-evk: Use phys to replace
 xceiver-supply
In-Reply-To: <20250829-can-v3-0-3b2f34094f59@nxp.com>
References: <20250829-can-v3-0-3b2f34094f59@nxp.com>
Message-ID: <20250829-can-v3-4-3b2f34094f59@nxp.com>

The TJA1051T/3 used on i.MX95-15x15-EVK is actually high-speed CAN
transceiver, not a regulator supply. So use phys to reflect the truth.

Reviewed-by: Frank Li <Frank.Li at nxp.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts b/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
index 148243470dd4ab03afdae949c8316f31467d1377..c229b748ca7aba2dc8cabe14d66e3d1dcd704c9a 100644
--- a/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
@@ -106,12 +106,11 @@ reg_audio_switch1: regulator-audio-switch1 {
 		gpio = <&pcal6524 0 GPIO_ACTIVE_LOW>;
 	};
 
-	reg_can2_stby: regulator-can2-stby {
-		compatible = "regulator-fixed";
-		regulator-max-microvolt = <3300000>;
-		regulator-min-microvolt = <3300000>;
-		regulator-name = "can2-stby";
-		gpio = <&pcal6524 14 GPIO_ACTIVE_LOW>;
+	flexcan2_phy: can-phy {
+		compatible = "nxp,tja1051", "ti,tcan1043";
+		#phy-cells = <0>;
+		max-bitrate = <5000000>;
+		standby-gpios = <&pcal6524 14 GPIO_ACTIVE_HIGH>;
 	};
 
 	reg_m2_pwr: regulator-m2-pwr {
@@ -317,7 +316,7 @@ &enetc_port1 {
 &flexcan2 {
 	pinctrl-0 = <&pinctrl_flexcan2>;
 	pinctrl-names = "default";
-	xceiver-supply = <&reg_can2_stby>;
+	phys = <&flexcan2_phy>;
 	status = "okay";
 };
 

-- 
2.37.1



From peng.fan at nxp.com  Fri Aug 29 00:09:00 2025
From: peng.fan at nxp.com (Peng Fan)
Date: Fri, 29 Aug 2025 15:09:00 +0800
Subject: [PATCH v3 5/6] arm64: dts: imx8mp-evk: Use phys to replace
 xceiver-supply
In-Reply-To: <20250829-can-v3-0-3b2f34094f59@nxp.com>
References: <20250829-can-v3-0-3b2f34094f59@nxp.com>
Message-ID: <20250829-can-v3-5-3b2f34094f59@nxp.com>

The TJA1048 used on i.MX8MP-EVK is actually high-speed CAN transceiver,
not a regulator supply. So use phys to reflect the truth.

Reviewed-by: Frank Li <Frank.Li at nxp.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8mp-evk.dts | 43 +++++++++-------------------
 1 file changed, 13 insertions(+), 30 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
index 3730792daf5010213cbb9f6869a8110ea28eb48a..59891627dc462d37dfd620eb68b893546cc20d6a 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
@@ -56,6 +56,16 @@ memory at 40000000 {
 		      <0x1 0x00000000 0 0xc0000000>;
 	};
 
+	flexcan_phy: can-phy {
+		compatible = "nxp,tja1048";
+		#phy-cells = <1>;
+		max-bitrate = <5000000>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_flexcan_phy>;
+		standby-gpios = <&gpio5 5 GPIO_ACTIVE_LOW>,
+				<&gpio4 27 GPIO_ACTIVE_LOW>;
+	};
+
 	native-hdmi-connector {
 		compatible = "hdmi-connector";
 		label = "HDMI OUT";
@@ -103,28 +113,6 @@ reg_audio_pwr: regulator-audio-pwr {
 		enable-active-high;
 	};
 
-	reg_can1_stby: regulator-can1-stby {
-		compatible = "regulator-fixed";
-		regulator-name = "can1-stby";
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_flexcan1_reg>;
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		gpio = <&gpio5 5 GPIO_ACTIVE_HIGH>;
-		enable-active-high;
-	};
-
-	reg_can2_stby: regulator-can2-stby {
-		compatible = "regulator-fixed";
-		regulator-name = "can2-stby";
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_flexcan2_reg>;
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		gpio = <&gpio4 27 GPIO_ACTIVE_HIGH>;
-		enable-active-high;
-	};
-
 	reg_pcie0: regulator-pcie {
 		compatible = "regulator-fixed";
 		pinctrl-names = "default";
@@ -431,14 +419,14 @@ ethphy1: ethernet-phy at 1 {
 &flexcan1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_flexcan1>;
-	xceiver-supply = <&reg_can1_stby>;
+	phys = <&flexcan_phy 0>;
 	status = "okay";
 };
 
 &flexcan2 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_flexcan2>;
-	xceiver-supply = <&reg_can2_stby>;
+	phys = <&flexcan_phy 1>;
 	status = "disabled";/* can2 pin conflict with pdm */
 };
 
@@ -903,14 +891,9 @@ MX8MP_IOMUXC_SAI5_RXD3__CAN2_TX         0x154
 		>;
 	};
 
-	pinctrl_flexcan1_reg: flexcan1reggrp {
+	pinctrl_flexcan_phy: flexcanphygrp {
 		fsl,pins = <
 			MX8MP_IOMUXC_SPDIF_EXT_CLK__GPIO5_IO05  0x154   /* CAN1_STBY */
-		>;
-	};
-
-	pinctrl_flexcan2_reg: flexcan2reggrp {
-		fsl,pins = <
 			MX8MP_IOMUXC_SAI2_MCLK__GPIO4_IO27      0x154   /* CAN2_STBY */
 		>;
 	};

-- 
2.37.1



From peng.fan at nxp.com  Fri Aug 29 00:09:01 2025
From: peng.fan at nxp.com (Peng Fan)
Date: Fri, 29 Aug 2025 15:09:01 +0800
Subject: [PATCH v3 6/6] arm64: dts: imx93-11x11-evk: Use phys to replace
 xceiver-supply
In-Reply-To: <20250829-can-v3-0-3b2f34094f59@nxp.com>
References: <20250829-can-v3-0-3b2f34094f59@nxp.com>
Message-ID: <20250829-can-v3-6-3b2f34094f59@nxp.com>

The TJA1057 used on i.MX93 EVK is actually high-speed CAN
transceiver, not a regulator supply. So use phys to reflect the truth.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts b/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
index e24e12f04526c3a08c0bdc6134297fb010e6e926..4c52f22bbfac99722184b4d8679f48c4396b557f 100644
--- a/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
@@ -62,6 +62,13 @@ vdevbuffer: vdevbuffer at a4020000 {
 
 	};
 
+	flexcan_phy: can-phy {
+		compatible = "nxp,tja1057", "ti,tcan1043";
+		#phy-cells = <0>;
+		max-bitrate = <5000000>;
+		standby-gpios = <&adp5585 6 GPIO_ACTIVE_HIGH>;
+	};
+
 	reg_vdd_12v: regulator-vdd-12v {
 		compatible = "regulator-fixed";
 		regulator-name = "VDD_12V";
@@ -87,14 +94,6 @@ reg_audio_pwr: regulator-audio-pwr {
 		enable-active-high;
 	};
 
-	reg_can2_standby: regulator-can2-standby {
-		compatible = "regulator-fixed";
-		regulator-name = "can2-stby";
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		gpio = <&adp5585 6 GPIO_ACTIVE_LOW>;
-	};
-
 	reg_m2_pwr: regulator-m2-pwr {
 		compatible = "regulator-fixed";
 		regulator-name = "M.2-power";
@@ -284,7 +283,7 @@ ethphy2: ethernet-phy at 2 {
 &flexcan2 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_flexcan2>;
-	xceiver-supply = <&reg_can2_standby>;
+	phys = <&flexcan_phy>;
 	status = "okay";
 };
 

-- 
2.37.1



From markus.stockhausen at gmx.de  Fri Aug 29 00:39:46 2025
From: markus.stockhausen at gmx.de (markus.stockhausen at gmx.de)
Date: Fri, 29 Aug 2025 09:39:46 +0200
Subject: c22/c45 descision in phy_restart_aneg()
Message-ID: <029301dc18b8$19059e80$4b10db80$@gmx.de>

Hi Russel,

once again some interesting finding from the limitations in the Realtek 
mdio driver. Remember it can only run in c22 or in c45. This time in
autonegotiation restart.

int phy_restart_aneg(struct phy_device *phydev)
{
  int ret;

  if (phydev->is_c45 && !(phydev->c45_ids.devices_in_package & BIT(0)))
    ret = genphy_c45_restart_aneg(phydev);
  else
    ret = genphy_restart_aneg(phydev);

  return ret;
}

I assume BIT(0) means MDIO_DEVS_C22PRESENT. This basically 
uses c22 for c45 PHYs if c22 presence is detected. So in our case 
it fails as soon as the bus has been switched to c45. Of course 
stupid but it is as it is. I see two options to fix the issue.

- Mask the c22 presence in the bus for all PHYs if running in c45
- Or drop the c22 condition check in above function

Any advise?

Thanks in advance.

Markus



From devnull+dimitri.fedrau.liebherr.com at kernel.org  Fri Aug 29 02:19:59 2025
From: devnull+dimitri.fedrau.liebherr.com at kernel.org (Dimitri Fedrau via B4 Relay)
Date: Fri, 29 Aug 2025 11:19:59 +0200
Subject: [PATCH v2 2/2] phy: add basic support for NXPs TJA1145 CAN
 transceiver
In-Reply-To: <20250829-tja1145-support-v2-0-60997f328979@liebherr.com>
References: <20250829-tja1145-support-v2-0-60997f328979@liebherr.com>
Message-ID: <20250829-tja1145-support-v2-2-60997f328979@liebherr.com>

From: Dimitri Fedrau <dimitri.fedrau at liebherr.com>

Add basic driver support for NXPs TJA1145 CAN transceiver which brings the
PHY up/down by switching to normal/standby mode using SPI commands.

Signed-off-by: Dimitri Fedrau <dimitri.fedrau at liebherr.com>
---
 drivers/phy/Kconfig           |  10 +++
 drivers/phy/Makefile          |   1 +
 drivers/phy/phy-nxp-tja1145.c | 185 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 196 insertions(+)

diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 58c911e1b2d20a0398f02550e938ce62633230d4..c47e2b62fa6279ee610493b028d3c14f6499ca85 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -101,6 +101,16 @@ config PHY_NXP_PTN3222
 	  schemes. It supports all three USB 2.0 data rates: Low Speed, Full
 	  Speed and High Speed.
 
+config PHY_NXP_TJA1145
+	tristate "NXP TJA1145 CAN transceiver PHY"
+	select GENERIC_PHY
+	select REGMAP_SPI
+	depends on SPI
+	help
+	  This option enables support for NXPs TJA1145 CAN transceiver as a PHY.
+	  This driver provides function for putting the transceiver in various
+	  functional modes using SPI commands.
+
 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 c670a8dac46807863c9ef990beb149082238ad16..16da564c74b0f14befb486366dcd10cd5fc67741 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_PHY_SNPS_EUSB2)		+= phy-snps-eusb2.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-$(CONFIG_PHY_NXP_TJA1145)		+= phy-nxp-tja1145.o
 obj-y					+= allwinner/	\
 					   amlogic/	\
 					   broadcom/	\
diff --git a/drivers/phy/phy-nxp-tja1145.c b/drivers/phy/phy-nxp-tja1145.c
new file mode 100644
index 0000000000000000000000000000000000000000..4d3aa5bfcd88d5755fa37e0d42bfa8293dee2155
--- /dev/null
+++ b/drivers/phy/phy-nxp-tja1145.c
@@ -0,0 +1,185 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2025 Liebherr-Electronics and Drives GmbH
+ */
+#include <linux/bitfield.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+
+#include <linux/phy/phy.h>
+#include <linux/spi/spi.h>
+
+#define TJA1145_MODE_CTRL		0x01
+#define TJA1145_MODE_CTRL_MC		GENMASK(2, 0)
+#define TJA1145_MODE_CRTL_STBY		BIT(2)
+#define TJA1145_MODE_CRTL_NORMAL	TJA1145_MODE_CTRL_MC
+
+#define TJA1145_CAN_CTRL		0x20
+#define TJA1145_CAN_CTRL_CMC		GENMASK(1, 0)
+#define TJA1145_CAN_CTRL_ACTIVE		BIT(1)
+
+#define TJA1145_IDENT			0x7e
+#define TJA1145_IDENT_TJA1145T		0x70
+
+#define TJA1145_SPI_READ_BIT		BIT(0)
+#define TJA1145T_MAX_BITRATE		1000000
+
+static int tja1145_phy_power_on(struct phy *phy)
+{
+	struct regmap *map = phy_get_drvdata(phy);
+	int ret;
+
+	/*
+	 * Switch operating mode to normal which is the active operating mode.
+	 * In this mode, the device is fully operational.
+	 */
+	ret = regmap_update_bits(map, TJA1145_MODE_CTRL, TJA1145_MODE_CTRL_MC,
+				 TJA1145_MODE_CRTL_NORMAL);
+	if (ret)
+		return ret;
+
+	/*
+	 * Switch to CAN operating mode active where the PHY can transmit and
+	 * receive data.
+	 */
+	return regmap_update_bits(map, TJA1145_CAN_CTRL, TJA1145_CAN_CTRL_CMC,
+				  TJA1145_CAN_CTRL_ACTIVE);
+}
+
+static int tja1145_phy_power_off(struct phy *phy)
+{
+	struct regmap *map = phy_get_drvdata(phy);
+
+	/*
+	 * Switch to operating mode standby, the PHY is unable to transmit or
+	 * receive data in standby mode.
+	 */
+	return regmap_update_bits(map, TJA1145_MODE_CTRL, TJA1145_MODE_CTRL_MC,
+				  TJA1145_MODE_CRTL_STBY);
+}
+
+static const struct phy_ops tja1145_phy_ops = {
+	.power_on = tja1145_phy_power_on,
+	.power_off = tja1145_phy_power_off,
+};
+
+static const struct regmap_range tja1145_wr_holes_ranges[] = {
+	regmap_reg_range(0x00, 0x00),
+	regmap_reg_range(0x02, 0x03),
+	regmap_reg_range(0x05, 0x05),
+	regmap_reg_range(0x0b, 0x1f),
+	regmap_reg_range(0x21, 0x22),
+	regmap_reg_range(0x24, 0x25),
+	regmap_reg_range(0x30, 0x4b),
+	regmap_reg_range(0x4d, 0x60),
+	regmap_reg_range(0x62, 0x62),
+	regmap_reg_range(0x65, 0x67),
+	regmap_reg_range(0x70, 0xff),
+};
+
+static const struct regmap_access_table tja1145_wr_table = {
+	.no_ranges = tja1145_wr_holes_ranges,
+	.n_no_ranges = ARRAY_SIZE(tja1145_wr_holes_ranges),
+};
+
+static const struct regmap_range tja1145_rd_holes_ranges[] = {
+	regmap_reg_range(0x00, 0x00),
+	regmap_reg_range(0x02, 0x02),
+	regmap_reg_range(0x05, 0x05),
+	regmap_reg_range(0x0b, 0x1f),
+	regmap_reg_range(0x21, 0x21),
+	regmap_reg_range(0x24, 0x25),
+	regmap_reg_range(0x30, 0x4a),
+	regmap_reg_range(0x4d, 0x5f),
+	regmap_reg_range(0x62, 0x62),
+	regmap_reg_range(0x65, 0x67),
+	regmap_reg_range(0x70, 0x7d),
+	regmap_reg_range(0x7f, 0xff),
+};
+
+static const struct regmap_access_table tja1145_rd_table = {
+	.no_ranges = tja1145_rd_holes_ranges,
+	.n_no_ranges = ARRAY_SIZE(tja1145_rd_holes_ranges),
+};
+
+
+static const struct regmap_config tja1145_regmap_config = {
+	.reg_bits = 8,
+	.reg_shift = -1,
+	.val_bits = 8,
+	.wr_table = &tja1145_wr_table,
+	.rd_table = &tja1145_rd_table,
+	.read_flag_mask = TJA1145_SPI_READ_BIT,
+	.max_register = TJA1145_IDENT,
+};
+
+static int tja1145_check_ident(struct device *dev, struct regmap *map)
+{
+	unsigned int val;
+	int ret;
+
+	ret = regmap_read(map, TJA1145_IDENT, &val);
+	if (ret)
+		return ret;
+
+	if (val != TJA1145_IDENT_TJA1145T) {
+		dev_err(dev, "Expected device id: 0x%02x, got: 0x%02x\n",
+			TJA1145_IDENT_TJA1145T, val);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int tja1145_probe(struct spi_device *spi)
+{
+	struct phy_provider *phy_provider;
+	struct device *dev = &spi->dev;
+	struct regmap *map;
+	struct phy *phy;
+	int ret;
+
+	map = devm_regmap_init_spi(spi, &tja1145_regmap_config);
+	if (IS_ERR(map))
+		return dev_err_probe(dev, PTR_ERR(map), "failed to init regmap\n");
+
+	ret = tja1145_check_ident(dev, map);
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to identify device\n");
+
+	phy = devm_phy_create(dev, dev->of_node, &tja1145_phy_ops);
+	if (IS_ERR(phy))
+		return dev_err_probe(dev, PTR_ERR(phy), "failed to create PHY\n");
+
+	phy->attrs.max_link_rate = TJA1145T_MAX_BITRATE;
+	phy_set_drvdata(phy, map);
+	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+
+	return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct spi_device_id tja1145_spi_id[] = {
+	{ "tja1145" },
+	{ }
+};
+MODULE_DEVICE_TABLE(spi, tja1145_spi_id);
+
+static const struct of_device_id tja1145_of_match[] = {
+	{ .compatible = "nxp,tja1145-can" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, tja1145_of_match);
+
+static struct spi_driver tja1145_driver = {
+	.driver = {
+		.name = "tja1145",
+		.of_match_table = tja1145_of_match,
+	},
+	.probe = tja1145_probe,
+	.id_table = tja1145_spi_id,
+};
+module_spi_driver(tja1145_driver);
+
+MODULE_DESCRIPTION("NXP TJA1145 CAN transceiver PHY driver");
+MODULE_AUTHOR("Dimitri Fedrau <dimitri.fedrau at liebherr.com>");
+MODULE_LICENSE("GPL");

-- 
2.39.5




From devnull+dimitri.fedrau.liebherr.com at kernel.org  Fri Aug 29 02:19:58 2025
From: devnull+dimitri.fedrau.liebherr.com at kernel.org (Dimitri Fedrau via B4 Relay)
Date: Fri, 29 Aug 2025 11:19:58 +0200
Subject: [PATCH v2 1/2] dt-bindings: phy: add support for NXPs TJA1145 CAN
 transceiver
In-Reply-To: <20250829-tja1145-support-v2-0-60997f328979@liebherr.com>
References: <20250829-tja1145-support-v2-0-60997f328979@liebherr.com>
Message-ID: <20250829-tja1145-support-v2-1-60997f328979@liebherr.com>

From: Dimitri Fedrau <dimitri.fedrau at liebherr.com>

Adding documentation for NXPs TJA1145 CAN transceiver.

Signed-off-by: Dimitri Fedrau <dimitri.fedrau at liebherr.com>
---
 .../devicetree/bindings/phy/nxp,tja1145-can.yaml   | 79 ++++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/nxp,tja1145-can.yaml b/Documentation/devicetree/bindings/phy/nxp,tja1145-can.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..12a8880267ef65cd9c55dd542f053ae967c7d6f3
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/nxp,tja1145-can.yaml
@@ -0,0 +1,79 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/nxp,tja1145-can.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: TJA1145 CAN transceiver
+
+maintainers:
+  - Dimitri Fedrau <dimitri.fedrau at liebherr.com>
+
+allOf:
+  - $ref: /schemas/spi/spi-peripheral-props.yaml#
+
+properties:
+  compatible:
+    const: nxp,tja1145-can
+
+  reg:
+    maxItems: 1
+
+  "#phy-cells":
+    const: 0
+
+  spi-max-frequency:
+    maximum: 4000000
+
+  spi-cpha: true
+
+  spi-cs-setup-delay-ns:
+    minimum: 50
+    default: 50
+
+  spi-cs-hold-delay-ns:
+    minimum: 50
+    default: 50
+
+  spi-cs-inactive-delay-ns:
+    minimum: 250
+    default: 250
+
+  vcc-supply:
+    description:
+      CAN transceiver supply voltage
+
+  vio-supply:
+    description:
+      Supply voltage for I/O level adaptor
+
+  vbat-supply:
+    description:
+      Battery supply voltage
+
+required:
+  - compatible
+  - reg
+  - "#phy-cells"
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    spi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+        can-phy {
+            compatible = "nxp,tja1145-can";
+            reg = <0>;
+            #phy-cells = <0>;
+            spi-max-frequency = <4000000>;
+            spi-cpha;
+            spi-cs-setup-delay-ns = <50>;
+            spi-cs-hold-delay-ns = <50>;
+            spi-cs-inactive-delay-ns = <250>;
+            vcc-supply = <&reg_5v0>;
+            vio-supply = <&reg_3v3>;
+            vbat-supply = <&reg_24v0>;
+        };
+    };

-- 
2.39.5




From devnull+dimitri.fedrau.liebherr.com at kernel.org  Fri Aug 29 02:19:57 2025
From: devnull+dimitri.fedrau.liebherr.com at kernel.org (Dimitri Fedrau via B4 Relay)
Date: Fri, 29 Aug 2025 11:19:57 +0200
Subject: [PATCH v2 0/2] phy: add basic support for NXPs TJA1145 CAN
 transceiver
Message-ID: <20250829-tja1145-support-v2-0-60997f328979@liebherr.com>

Add basic driver support for NXPs TJA1145 CAN transceiver which brings the
PHY up/down by switching to normal/standby mode using SPI commands.

Signed-off-by: Dimitri Fedrau <dimitri.fedrau at liebherr.com>
---
Changes in v2:
- bindings: Change node name in example to can-phy
- bindings: Fix order of properties, reg property is second
- bindings: Change compatible to match filename
- change compatible to nxp,tja1145-can
- Link to v1: https://lore.kernel.org/r/20250728-tja1145-support-v1-0-ebd8494d545c at liebherr.com

---
Dimitri Fedrau (2):
      dt-bindings: phy: add support for NXPs TJA1145 CAN transceiver
      phy: add basic support for NXPs TJA1145 CAN transceiver

 .../devicetree/bindings/phy/nxp,tja1145-can.yaml   |  79 +++++++++
 drivers/phy/Kconfig                                |  10 ++
 drivers/phy/Makefile                               |   1 +
 drivers/phy/phy-nxp-tja1145.c                      | 185 +++++++++++++++++++++
 4 files changed, 275 insertions(+)
---
base-commit: e373c183bc8a4a421f14ea0dd1edf4f8fd79537f
change-id: 20250726-tja1145-support-d6ccdc4d2da3

Best regards,
-- 
Dimitri Fedrau <dimitri.fedrau at liebherr.com>




From heikki.krogerus at linux.intel.com  Fri Aug 29 02:37:23 2025
From: heikki.krogerus at linux.intel.com (Heikki Krogerus)
Date: Fri, 29 Aug 2025 12:37:23 +0300
Subject: [PATCH RFC 08/22] usb: typec: tipd: Clear interrupts first
In-Reply-To: <20250821-atcphy-6-17-v1-8-172beda182b8@kernel.org>
References: <20250821-atcphy-6-17-v1-0-172beda182b8@kernel.org>
 <20250821-atcphy-6-17-v1-8-172beda182b8@kernel.org>
Message-ID: <aLF00zGWg2MPUlyJ@kuha.fi.intel.com>

On Thu, Aug 21, 2025 at 03:39:00PM +0000, Sven Peter wrote:
> Right now the interrupt handler first reads all updated status registers
> and only then clears the interrupts. It's possible that a duplicate
> interrupt for a changed register or plug state comes in after the
> interrupts have been processed but before they have been cleared:
> 
> * plug is inserted, TPS_REG_INT_PLUG_EVENT is set
> * TPS_REG_INT_EVENT1 is read
> * tps6598x_handle_plug_event() has run and registered the plug
> * plug is removed again, TPS_REG_INT_PLUG_EVENT is set (again)
> * TPS_REG_INT_CLEAR1 is written, TPS_REG_INT_PLUG_EVENT is cleared
> 
> We then have no plug connected and no pending interrupt but the tipd
> core still thinks there is a plug. It's possible to trigger this with
> e.g. a slightly broken Type-C to USB A converter.
> 
> Fix this by first clearing the interrupts and only then reading the
> updated registers.
> 
> Fixes: 45188f27b3d0 ("usb: typec: tipd: Add support for Apple CD321X")
> Fixes: 0a4c005bd171 ("usb: typec: driver for TI TPS6598x USB Power Delivery controllers")
> Cc: stable at kernel.org
> Signed-off-by: Sven Peter <sven at kernel.org>

Reviewed-by: Heikki Krogerus <heikki.krogerus at linux.intel.com>

> ---
>  drivers/usb/typec/tipd/core.c | 24 +++++++++++-------------
>  1 file changed, 11 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c
> index dcf141ada07812295a6f07e41d77f95f98116010..1c80296c3b273e24ceacb3feff432c4f6e6835cc 100644
> --- a/drivers/usb/typec/tipd/core.c
> +++ b/drivers/usb/typec/tipd/core.c
> @@ -545,24 +545,23 @@ static irqreturn_t cd321x_interrupt(int irq, void *data)
>  	if (!event)
>  		goto err_unlock;
>  
> +	tps6598x_write64(tps, TPS_REG_INT_CLEAR1, event);
> +
>  	if (!tps6598x_read_status(tps, &status))
> -		goto err_clear_ints;
> +		goto err_unlock;
>  
>  	if (event & APPLE_CD_REG_INT_POWER_STATUS_UPDATE)
>  		if (!tps6598x_read_power_status(tps))
> -			goto err_clear_ints;
> +			goto err_unlock;
>  
>  	if (event & APPLE_CD_REG_INT_DATA_STATUS_UPDATE)
>  		if (!tps6598x_read_data_status(tps))
> -			goto err_clear_ints;
> +			goto err_unlock;
>  
>  	/* Handle plug insert or removal */
>  	if (event & APPLE_CD_REG_INT_PLUG_EVENT)
>  		tps6598x_handle_plug_event(tps, status);
>  
> -err_clear_ints:
> -	tps6598x_write64(tps, TPS_REG_INT_CLEAR1, event);
> -
>  err_unlock:
>  	mutex_unlock(&tps->lock);
>  
> @@ -668,25 +667,24 @@ static irqreturn_t tps6598x_interrupt(int irq, void *data)
>  	if (!(event1[0] | event1[1] | event2[0] | event2[1]))
>  		goto err_unlock;
>  
> +	tps6598x_block_write(tps, TPS_REG_INT_CLEAR1, event1, intev_len);
> +	tps6598x_block_write(tps, TPS_REG_INT_CLEAR2, event2, intev_len);
> +
>  	if (!tps6598x_read_status(tps, &status))
> -		goto err_clear_ints;
> +		goto err_unlock;
>  
>  	if ((event1[0] | event2[0]) & TPS_REG_INT_POWER_STATUS_UPDATE)
>  		if (!tps6598x_read_power_status(tps))
> -			goto err_clear_ints;
> +			goto err_unlock;
>  
>  	if ((event1[0] | event2[0]) & TPS_REG_INT_DATA_STATUS_UPDATE)
>  		if (!tps6598x_read_data_status(tps))
> -			goto err_clear_ints;
> +			goto err_unlock;
>  
>  	/* Handle plug insert or removal */
>  	if ((event1[0] | event2[0]) & TPS_REG_INT_PLUG_EVENT)
>  		tps6598x_handle_plug_event(tps, status);
>  
> -err_clear_ints:
> -	tps6598x_block_write(tps, TPS_REG_INT_CLEAR1, event1, intev_len);
> -	tps6598x_block_write(tps, TPS_REG_INT_CLEAR2, event2, intev_len);
> -
>  err_unlock:
>  	mutex_unlock(&tps->lock);
>  
> 
> -- 
> 2.34.1
> 

-- 
heikki


From linux at armlinux.org.uk  Fri Aug 29 03:13:52 2025
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 29 Aug 2025 11:13:52 +0100
Subject: c22/c45 descision in phy_restart_aneg()
In-Reply-To: <029301dc18b8$19059e80$4b10db80$@gmx.de>
References: <029301dc18b8$19059e80$4b10db80$@gmx.de>
Message-ID: <aLF9YJh3eQtrzzqN@shell.armlinux.org.uk>

On Fri, Aug 29, 2025 at 09:39:46AM +0200, markus.stockhausen at gmx.de wrote:
> Hi Russel,

1. It's "Russell" please.
2. linux-phy at lists.infradead.org is not the correct list to be
discussing phylib issues.
3. You haven't Cc'd the other phylib maintainers.

Please resend to the correct audience. Thanks.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!


From pritam.sutar at samsung.com  Fri Aug 29 03:15:37 2025
From: pritam.sutar at samsung.com (Pritam Manohar Sutar)
Date: Fri, 29 Aug 2025 15:45:37 +0530
Subject: [PATCH v7 5/6] dt-bindings: phy: samsung,usb3-drd-phy: add
 ExynosAutov920 combo ssphy
In-Reply-To: <83dc9435-5850-425d-b345-52e84ef9262c@kernel.org>
References: <20250822093845.1179395-1-pritam.sutar@samsung.com>
	<CGME20250822093022epcas5p42d8c16c851769dab0e1da9d45743ab1f@epcas5p4.samsung.com>
	<20250822093845.1179395-6-pritam.sutar@samsung.com>
	<20250824-rough-fresh-orangutan-eecb2f@kuoka>
	<007501dc1653$e36c3b50$aa44b1f0$@samsung.com>
	<83dc9435-5850-425d-b345-52e84ef9262c@kernel.org>
Message-ID: <000401dc18cd$ec02a1b0$c407e510$@samsung.com>

Hi Krzysztof

> -----Original Message-----
> From: Krzysztof Kozlowski <krzk at kernel.org>
> Sent: 26 August 2025 02:05 PM
> To: Pritam Manohar Sutar <pritam.sutar at samsung.com>
> Cc: vkoul at kernel.org; kishon at kernel.org; robh at kernel.org;
.
.
[snip]
.
.
> >> Subject: Re: [PATCH v7 5/6] dt-bindings: phy: samsung,usb3-drd-phy:
> >> add
> >> ExynosAutov920 combo ssphy
> >>
> >> On Fri, Aug 22, 2025 at 03:08:44PM +0530, Pritam Manohar Sutar wrote:
> >>> This phy supports USB3.1 SSP+(10Gbps) protocol and is backwards
> >>> compatible to the USB3.0 SS(5Gbps). It requires two clocks, named
> >>> "phy" and "ref". The required supplies for USB3.1 are named as
> >>> vdd075_usb30(0.75v), vdd18_usb30(1.8v).
> >>
> >> Please do not describe the schema, but hardware. This sentence does
> >> not help me in my question further.
> >
> > This is a combo phy having Synopsys usb20 and usb30 phys (these 2 phys are
> totally different).
> > One PHY only supports usb2.0 and data rates whereas another one does
> > usb3.1 ssp+ and usb3.1 ssp
> >
> > This patch only explains about usb30 (since these are two different phys) phy
> and omitted inclusion of usb20 reference (added separate patch for this patch
> no 3).
> >
> > Hope this is clear.
> 
> No. That sentence still explains what schema is doing.
>

Ok, let me simplify the commit message further something like below. 
Anyways, the coverletter contains more details about it.

"dt-bindings: phy: samsung,usb3-drd-phy: add ExynosAutov920 combo ssphy

  Add schema for combo ssphy found on this SoC.
"

Please confirm if this looks fine?
If so, will reflect the similar commit messages in patch 1 and 3.

> BTW, wrap your email correctly.
> 

Sure, thanks for your input. 

> >
> >>
> >>>
> >>> Add schemas for combo ssphy found on this SoC.
> >>>
> >>> Signed-off-by: Pritam Manohar Sutar <pritam.sutar at samsung.com>
> >>> ---
> >>>  .../bindings/phy/samsung,usb3-drd-phy.yaml    | 23 +++++++++++++++++++
> >>>  1 file changed, 23 insertions(+)
> >>>
> >>> diff --git
> >>> a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
> >>> b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
> >>> index f0cfca5736b8..96e5bbb2e42c 100644
> >>> ---
> >>> a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
> >>> +++ b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yam
> >>> +++ l
> >>> @@ -34,6 +34,7 @@ properties:
> >>>        - samsung,exynos7870-usbdrd-phy
> >>>        - samsung,exynos850-usbdrd-phy
> >>>        - samsung,exynos990-usbdrd-phy
> >>> +      - samsung,exynosautov920-usb31drd-combo-ssphy
> >>>        - samsung,exynosautov920-usbdrd-combo-hsphy
> >>>        - samsung,exynosautov920-usbdrd-phy
> >>>
> >>> @@ -118,6 +119,12 @@ properties:
> >>>    vdd18-usb20-supply:
> >>>      description: 1.8V power supply for the USB 2.0 phy.
> >>>
> >>> +  dvdd075-usb30-supply:
> >>> +    description: 0.75V power supply for the USB 3.0 phy.
> >>> +
> >>> +  vdd18-usb30-supply:
> >>> +    description: 1.8V power supply for the USB 3.0 phy.
> >>> +
> >>>  required:
> >>>    - compatible
> >>>    - clocks
> >>> @@ -227,6 +234,7 @@ allOf:
> >>>                - samsung,exynos7870-usbdrd-phy
> >>>                - samsung,exynos850-usbdrd-phy
> >>>                - samsung,exynos990-usbdrd-phy
> >>> +              - samsung,exynosautov920-usb31drd-combo-ssphy
> >>>                - samsung,exynosautov920-usbdrd-combo-hsphy
> >>>                - samsung,exynosautov920-usbdrd-phy
> >>>      then:
> >>> @@ -262,6 +270,21 @@ allOf:
> >>>        properties:
> >>>          dvdd075-usb20-supply: false
> >>>          vdd18-usb20-supply: false
> >>> +  - if:
> >>> +      properties:
> >>> +        compatible:
> >>> +          contains:
> >>> +            enum:
> >>> +              - samsung,exynosautov920-usb31drd-combo-ssphy
> >>> +    then:
> >>> +      required:
> >>> +        - dvdd075-usb30-supply
> >>> +        - vdd18-usb30-supply
> >>
> >> Why are you adding usb20 and usb30 suffixes to the supplies? These
> >> are separate devices, so they do not have both variants at the same time.
> >
> > This is a combo phy consisting of usb2 and usb3 phys combined.
> > To drive these separate phys, added suffixes for these supplies respectively.
> 
> But they are separate.
> 
> >
> > Moreover, gs101 is also using similar convention for its usb20 and dp supplies.
> > Added suffix for usb2 and usb3 as per our last communication
> > https://lore.kernel.org/linux-phy/6e1c67d2-9bfa-442a-9d53-8c5970a2a9ef
> > @kernel.org/
> 
> Then please review patches on the list and help to improve them BEFORE they
> got merged.
> 
> I questioned the suffix there, so I really do not understand why did you added it.
> 
> >
> >>
> >> From this device point of view, the supply is called dvdd075 or vdd18.
> >> If you open device datasheet (not SoC datasheet), that's how it will
> >> be called, most likely.
> >
> > Yes, Agree. In device datasheet, suffixes are not mentioned, but in our board
> schematic it is mentioned.
> > Let me know your suggestion about adding suffixes?
> 
> I already said, multiple times on various discussions. You name these based on
> how the inputs are called in this device.

Ok, will remove suffixes from supplies.
And will add following supplies dvdd, vdd33 and vdd18.

Let me know, because of above changes, should be removing your 
'reviewed-by' tag from patch 1 and 3.

> 
> Best regards,
> Krzysztof

Thank you.

Regards,
Pritam



From krzk at kernel.org  Fri Aug 29 03:36:58 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 29 Aug 2025 12:36:58 +0200
Subject: [PATCH v7 5/6] dt-bindings: phy: samsung,usb3-drd-phy: add
 ExynosAutov920 combo ssphy
In-Reply-To: <000401dc18cd$ec02a1b0$c407e510$@samsung.com>
References: <20250822093845.1179395-1-pritam.sutar@samsung.com>
 <CGME20250822093022epcas5p42d8c16c851769dab0e1da9d45743ab1f@epcas5p4.samsung.com>
 <20250822093845.1179395-6-pritam.sutar@samsung.com>
 <20250824-rough-fresh-orangutan-eecb2f@kuoka>
 <007501dc1653$e36c3b50$aa44b1f0$@samsung.com>
 <83dc9435-5850-425d-b345-52e84ef9262c@kernel.org>
 <000401dc18cd$ec02a1b0$c407e510$@samsung.com>
Message-ID: <e8e99c16-ad40-4d79-be92-1aa55c13f9ea@kernel.org>

On 29/08/2025 12:15, Pritam Manohar Sutar wrote:
> Hi Krzysztof
> 
>> -----Original Message-----
>> From: Krzysztof Kozlowski <krzk at kernel.org>
>> Sent: 26 August 2025 02:05 PM
>> To: Pritam Manohar Sutar <pritam.sutar at samsung.com>
>> Cc: vkoul at kernel.org; kishon at kernel.org; robh at kernel.org;
> .
> .
> [snip]
> .
> .
>>>> Subject: Re: [PATCH v7 5/6] dt-bindings: phy: samsung,usb3-drd-phy:
>>>> add
>>>> ExynosAutov920 combo ssphy
>>>>
>>>> On Fri, Aug 22, 2025 at 03:08:44PM +0530, Pritam Manohar Sutar wrote:
>>>>> This phy supports USB3.1 SSP+(10Gbps) protocol and is backwards
>>>>> compatible to the USB3.0 SS(5Gbps). It requires two clocks, named
>>>>> "phy" and "ref". The required supplies for USB3.1 are named as
>>>>> vdd075_usb30(0.75v), vdd18_usb30(1.8v).
>>>>
>>>> Please do not describe the schema, but hardware. This sentence does
>>>> not help me in my question further.
>>>
>>> This is a combo phy having Synopsys usb20 and usb30 phys (these 2 phys are
>> totally different).
>>> One PHY only supports usb2.0 and data rates whereas another one does
>>> usb3.1 ssp+ and usb3.1 ssp
>>>
>>> This patch only explains about usb30 (since these are two different phys) phy
>> and omitted inclusion of usb20 reference (added separate patch for this patch
>> no 3).
>>>
>>> Hope this is clear.
>>
>> No. That sentence still explains what schema is doing.
>>
> 
> Ok, let me simplify the commit message further something like below. 
> Anyways, the coverletter contains more details about it.
> 
> "dt-bindings: phy: samsung,usb3-drd-phy: add ExynosAutov920 combo ssphy
> 
>   Add schema for combo ssphy found on this SoC.
> "
> 
> Please confirm if this looks fine?
> If so, will reflect the similar commit messages in patch 1 and 3.

Please read my first comment again. I do not see how does this satisfy
hardware explanation.

Best regards,
Krzysztof


From wsa+renesas at sang-engineering.com  Fri Aug 29 03:53:12 2025
From: wsa+renesas at sang-engineering.com (Wolfram Sang)
Date: Fri, 29 Aug 2025 12:53:12 +0200
Subject: [PATCH v5 0/7] Add initial USB support for the Renesas RZ/G3S SoC
In-Reply-To: <ae53d367-2ee5-49aa-82ba-86f9e84d4d25@tuxon.dev>
References: <20250819054212.486426-1-claudiu.beznea.uj@bp.renesas.com>
 <aLAZprjeKtk4pusw@shikoro>
 <ae53d367-2ee5-49aa-82ba-86f9e84d4d25@tuxon.dev>
Message-ID: <aLGGmI8bpKNVaSAa@shikoro>

Hi Claudiu,

> I just checked it on latest linux-next and all good on my side. Would it be
> possible that you don't have commit 2da2740fb9c8 ("soc: renesas: rz-sysc:
> Add syscon/regmap support") in your tree?

Yes, I added it and it made the error go away, but still no USB. I
switched to linux-next as of today, did neither help.

> This is how my tree looks like:

Mine is similar, except for a newer -next.

Let's try your config file next?

Thanks for the support,

   Wolfram



From alim.akhtar at samsung.com  Fri Aug 29 03:58:10 2025
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 29 Aug 2025 16:28:10 +0530
Subject: [PATCH v7 5/6] dt-bindings: phy: samsung,usb3-drd-phy: add
 ExynosAutov920 combo ssphy
In-Reply-To: <e8e99c16-ad40-4d79-be92-1aa55c13f9ea@kernel.org>
References: <20250822093845.1179395-1-pritam.sutar@samsung.com>
	<CGME20250822093022epcas5p42d8c16c851769dab0e1da9d45743ab1f@epcas5p4.samsung.com>
	<20250822093845.1179395-6-pritam.sutar@samsung.com>
	<20250824-rough-fresh-orangutan-eecb2f@kuoka>
	<007501dc1653$e36c3b50$aa44b1f0$@samsung.com>
	<83dc9435-5850-425d-b345-52e84ef9262c@kernel.org>
	<000401dc18cd$ec02a1b0$c407e510$@samsung.com>
	<e8e99c16-ad40-4d79-be92-1aa55c13f9ea@kernel.org>
Message-ID: <263801dc18d3$d1e20950$75a61bf0$@samsung.com>

Hi Krzysztof

> -----Original Message-----
> From: Krzysztof Kozlowski <krzk at kernel.org>
> Sent: Friday, August 29, 2025 4:07 PM
> To: Pritam Manohar Sutar <pritam.sutar at samsung.com>
> Cc: vkoul at kernel.org; kishon at kernel.org; robh at kernel.org;
> krzk+dt at kernel.org; conor+dt at kernel.org; alim.akhtar at samsung.com;
> andre.draszik at linaro.org; peter.griffin at linaro.org; kauschluss at disroot.org;
> ivo.ivanov.ivanov1 at gmail.com; igor.belwon at mentallysanemainliners.org;
> johan at kernel.org; m.szyprowski at samsung.com;
> s.nawrocki at samsung.com; linux-phy at lists.infradead.org;
> devicetree at vger.kernel.org; linux-kernel at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; linux-samsung-soc at vger.kernel.org;
> rosa.pila at samsung.com; dev.tailor at samsung.com;
> faraz.ata at samsung.com; muhammed.ali at samsung.com;
> selvarasu.g at samsung.com
> Subject: Re: [PATCH v7 5/6] dt-bindings: phy: samsung,usb3-drd-phy: add
> ExynosAutov920 combo ssphy
> 
> On 29/08/2025 12:15, Pritam Manohar Sutar wrote:
> > Hi Krzysztof
> >
> >> -----Original Message-----
> >> From: Krzysztof Kozlowski <krzk at kernel.org>
> >> Sent: 26 August 2025 02:05 PM
> >> To: Pritam Manohar Sutar <pritam.sutar at samsung.com>
> >> Cc: vkoul at kernel.org; kishon at kernel.org; robh at kernel.org;
> > .
> > .
> > [snip]
> > .
> > .
> >>>> Subject: Re: [PATCH v7 5/6] dt-bindings: phy: samsung,usb3-drd-phy:
> >>>> add
> >>>> ExynosAutov920 combo ssphy
> >>>>
> >>>> On Fri, Aug 22, 2025 at 03:08:44PM +0530, Pritam Manohar Sutar wrote:
> >>>>> This phy supports USB3.1 SSP+(10Gbps) protocol and is backwards
> >>>>> compatible to the USB3.0 SS(5Gbps). It requires two clocks, named
> >>>>> "phy" and "ref". The required supplies for USB3.1 are named as
> >>>>> vdd075_usb30(0.75v), vdd18_usb30(1.8v).
> >>>>
> >>>> Please do not describe the schema, but hardware. This sentence does
> >>>> not help me in my question further.
> >>>
> >>> This is a combo phy having Synopsys usb20 and usb30 phys (these 2
> >>> phys are
> >> totally different).
> >>> One PHY only supports usb2.0 and data rates whereas another one does
> >>> usb3.1 ssp+ and usb3.1 ssp
> >>>
> >>> This patch only explains about usb30 (since these are two different
> >>> phys) phy
> >> and omitted inclusion of usb20 reference (added separate patch for
> >> this patch no 3).
> >>>
> >>> Hope this is clear.
> >>
> >> No. That sentence still explains what schema is doing.
> >>
> >
> > Ok, let me simplify the commit message further something like below.
> > Anyways, the coverletter contains more details about it.
> >
> > "dt-bindings: phy: samsung,usb3-drd-phy: add ExynosAutov920 combo
> > ssphy
> >
> >   Add schema for combo ssphy found on this SoC.
> > "
> >
> > Please confirm if this looks fine?
> > If so, will reflect the similar commit messages in patch 1 and 3.
> 
> Please read my first comment again. I do not see how does this satisfy
> hardware explanation.
> 
Just went through the conversation above, 
until what extent hardware description need to be explain in the commit?
Do we have any guideline for the same?
Could you please help with an example from previous any commit or some other patches? 
I understand that mentioning, ?two clocks, two supplies etc" are part of schema, 
one may or may not capture that in the commit. 
However mentioning, ?this hardware (SoC) contain a combo PHY which supports usb3.1 and usb3.0" is not ok? 

> Best regards,
> Krzysztof




From krzk at kernel.org  Fri Aug 29 04:25:41 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 29 Aug 2025 13:25:41 +0200
Subject: [PATCH v7 5/6] dt-bindings: phy: samsung,usb3-drd-phy: add
 ExynosAutov920 combo ssphy
In-Reply-To: <263801dc18d3$d1e20950$75a61bf0$@samsung.com>
References: <20250822093845.1179395-1-pritam.sutar@samsung.com>
 <CGME20250822093022epcas5p42d8c16c851769dab0e1da9d45743ab1f@epcas5p4.samsung.com>
 <20250822093845.1179395-6-pritam.sutar@samsung.com>
 <20250824-rough-fresh-orangutan-eecb2f@kuoka>
 <007501dc1653$e36c3b50$aa44b1f0$@samsung.com>
 <83dc9435-5850-425d-b345-52e84ef9262c@kernel.org>
 <000401dc18cd$ec02a1b0$c407e510$@samsung.com>
 <e8e99c16-ad40-4d79-be92-1aa55c13f9ea@kernel.org>
 <263801dc18d3$d1e20950$75a61bf0$@samsung.com>
Message-ID: <6b5f20ed-4e88-441e-8f61-20866e2b39c7@kernel.org>

On 29/08/2025 12:58, Alim Akhtar wrote:
> Hi Krzysztof
> 
>> -----Original Message-----
>> From: Krzysztof Kozlowski <krzk at kernel.org>
>> Sent: Friday, August 29, 2025 4:07 PM
>> To: Pritam Manohar Sutar <pritam.sutar at samsung.com>
>> Cc: vkoul at kernel.org; kishon at kernel.org; robh at kernel.org;
>> krzk+dt at kernel.org; conor+dt at kernel.org; alim.akhtar at samsung.com;
>> andre.draszik at linaro.org; peter.griffin at linaro.org; kauschluss at disroot.org;
>> ivo.ivanov.ivanov1 at gmail.com; igor.belwon at mentallysanemainliners.org;
>> johan at kernel.org; m.szyprowski at samsung.com;
>> s.nawrocki at samsung.com; linux-phy at lists.infradead.org;
>> devicetree at vger.kernel.org; linux-kernel at vger.kernel.org; linux-arm-
>> kernel at lists.infradead.org; linux-samsung-soc at vger.kernel.org;
>> rosa.pila at samsung.com; dev.tailor at samsung.com;
>> faraz.ata at samsung.com; muhammed.ali at samsung.com;
>> selvarasu.g at samsung.com
>> Subject: Re: [PATCH v7 5/6] dt-bindings: phy: samsung,usb3-drd-phy: add
>> ExynosAutov920 combo ssphy
>>
>> On 29/08/2025 12:15, Pritam Manohar Sutar wrote:
>>> Hi Krzysztof
>>>
>>>> -----Original Message-----
>>>> From: Krzysztof Kozlowski <krzk at kernel.org>
>>>> Sent: 26 August 2025 02:05 PM
>>>> To: Pritam Manohar Sutar <pritam.sutar at samsung.com>
>>>> Cc: vkoul at kernel.org; kishon at kernel.org; robh at kernel.org;
>>> .
>>> .
>>> [snip]
>>> .
>>> .
>>>>>> Subject: Re: [PATCH v7 5/6] dt-bindings: phy: samsung,usb3-drd-phy:
>>>>>> add
>>>>>> ExynosAutov920 combo ssphy
>>>>>>
>>>>>> On Fri, Aug 22, 2025 at 03:08:44PM +0530, Pritam Manohar Sutar wrote:
>>>>>>> This phy supports USB3.1 SSP+(10Gbps) protocol and is backwards
>>>>>>> compatible to the USB3.0 SS(5Gbps). It requires two clocks, named
>>>>>>> "phy" and "ref". The required supplies for USB3.1 are named as
>>>>>>> vdd075_usb30(0.75v), vdd18_usb30(1.8v).
>>>>>>
>>>>>> Please do not describe the schema, but hardware. This sentence does
>>>>>> not help me in my question further.
>>>>>
>>>>> This is a combo phy having Synopsys usb20 and usb30 phys (these 2
>>>>> phys are
>>>> totally different).
>>>>> One PHY only supports usb2.0 and data rates whereas another one does
>>>>> usb3.1 ssp+ and usb3.1 ssp
>>>>>
>>>>> This patch only explains about usb30 (since these are two different
>>>>> phys) phy
>>>> and omitted inclusion of usb20 reference (added separate patch for
>>>> this patch no 3).
>>>>>
>>>>> Hope this is clear.
>>>>
>>>> No. That sentence still explains what schema is doing.
>>>>
>>>
>>> Ok, let me simplify the commit message further something like below.
>>> Anyways, the coverletter contains more details about it.
>>>
>>> "dt-bindings: phy: samsung,usb3-drd-phy: add ExynosAutov920 combo
>>> ssphy
>>>
>>>   Add schema for combo ssphy found on this SoC.
>>> "
>>>
>>> Please confirm if this looks fine?
>>> If so, will reflect the similar commit messages in patch 1 and 3.
>>
>> Please read my first comment again. I do not see how does this satisfy
>> hardware explanation.
>>
> Just went through the conversation above, 
> until what extent hardware description need to be explain in the commit?
> Do we have any guideline for the same?
> Could you please help with an example from previous any commit or some other patches? 
> I understand that mentioning, ?two clocks, two supplies etc" are part of schema, 
> one may or may not capture that in the commit. 
> However mentioning, ?this hardware (SoC) contain a combo PHY which supports usb3.1 and usb3.0" is not ok? 


Maybe that's just language, but to me the commit msg did not describe
hardware after first sentence, but said what schema requires (some
clocks and supplies). Other examples:
00399bbe02d2bb6fd8d6eb90573ec305616449f4
e4c9a7b475e5d0d9b2440ee48f91d1364eabd6cb

and here another anti-pattern:
23f793850e9ee7390584c0809f085d6c88de7d3f

(and before you ask why above carries my Rb tag, then note that
Samsung's revenue is around 220 billion USD, so for sure it has a lot,
really a lot of resources to review patches internally and improve their
quality before posting).

Best regards,
Krzysztof


From claudiu.beznea at tuxon.dev  Fri Aug 29 04:30:44 2025
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Fri, 29 Aug 2025 14:30:44 +0300
Subject: [PATCH v5 0/7] Add initial USB support for the Renesas RZ/G3S SoC
In-Reply-To: <aLGGmI8bpKNVaSAa@shikoro>
References: <20250819054212.486426-1-claudiu.beznea.uj@bp.renesas.com>
 <aLAZprjeKtk4pusw@shikoro> <ae53d367-2ee5-49aa-82ba-86f9e84d4d25@tuxon.dev>
 <aLGGmI8bpKNVaSAa@shikoro>
Message-ID: <be706ee5-057c-4b0a-b0d3-54ca24087f3f@tuxon.dev>

Hi, Wolfram,

On 8/29/25 13:53, Wolfram Sang wrote:
> Hi Claudiu,
> 
>> I just checked it on latest linux-next and all good on my side. Would it be
>> possible that you don't have commit 2da2740fb9c8 ("soc: renesas: rz-sysc:
>> Add syscon/regmap support") in your tree?
> 
> Yes, I added it and it made the error go away, but still no USB. I

The drivers are not probed or you see no activity when connecting USB devices?

> switched to linux-next as of today, did neither help.
> 
>> This is how my tree looks like:
> 
> Mine is similar, except for a newer -next.
> 
> Let's try your config file next?

I used arm64 defconfig (arch/arm64/configs/defconfig).

Thank you,
Claudiu


From wsa+renesas at sang-engineering.com  Fri Aug 29 04:51:01 2025
From: wsa+renesas at sang-engineering.com (Wolfram Sang)
Date: Fri, 29 Aug 2025 13:51:01 +0200
Subject: [PATCH v5 0/7] Add initial USB support for the Renesas RZ/G3S SoC
In-Reply-To: <be706ee5-057c-4b0a-b0d3-54ca24087f3f@tuxon.dev>
References: <20250819054212.486426-1-claudiu.beznea.uj@bp.renesas.com>
 <aLAZprjeKtk4pusw@shikoro>
 <ae53d367-2ee5-49aa-82ba-86f9e84d4d25@tuxon.dev>
 <aLGGmI8bpKNVaSAa@shikoro>
 <be706ee5-057c-4b0a-b0d3-54ca24087f3f@tuxon.dev>
Message-ID: <aLGUJbA0szYQ_gN4@shikoro>


> > Yes, I added it and it made the error go away, but still no USB. I
> 
> The drivers are not probed or you see no activity when connecting USB devices?

Sigh, I was so sure to have checked OHCI/EHCI but only EHCI was enabled :(

Checking with the schematics, I get it that only the rightmost USB-A
connectors on the carrier board are routed. Those two work fine now.

If that is to be expected, then for the whole series:

Tested-by: Wolfram Sang <wsa+renesas at sang-engineering.com>



From alim.akhtar at samsung.com  Fri Aug 29 04:58:21 2025
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 29 Aug 2025 17:28:21 +0530
Subject: [PATCH v7 5/6] dt-bindings: phy: samsung,usb3-drd-phy: add
 ExynosAutov920 combo ssphy
In-Reply-To: <6b5f20ed-4e88-441e-8f61-20866e2b39c7@kernel.org>
References: <20250822093845.1179395-1-pritam.sutar@samsung.com>
	<CGME20250822093022epcas5p42d8c16c851769dab0e1da9d45743ab1f@epcas5p4.samsung.com>
	<20250822093845.1179395-6-pritam.sutar@samsung.com>
	<20250824-rough-fresh-orangutan-eecb2f@kuoka>
	<007501dc1653$e36c3b50$aa44b1f0$@samsung.com>
	<83dc9435-5850-425d-b345-52e84ef9262c@kernel.org>
	<000401dc18cd$ec02a1b0$c407e510$@samsung.com>
	<e8e99c16-ad40-4d79-be92-1aa55c13f9ea@kernel.org>
	<263801dc18d3$d1e20950$75a61bf0$@samsung.com>
	<6b5f20ed-4e88-441e-8f61-20866e2b39c7@kernel.org>
Message-ID: <264501dc18dc$39afb340$ad0f19c0$@samsung.com>

Hi Krzysztof

> -----Original Message-----
> From: Krzysztof Kozlowski <krzk at kernel.org>
> Sent: Friday, August 29, 2025 4:56 PM
> To: Alim Akhtar <alim.akhtar at samsung.com>; 'Pritam Manohar Sutar'
> <pritam.sutar at samsung.com>
> Cc: vkoul at kernel.org; kishon at kernel.org; robh at kernel.org;
> krzk+dt at kernel.org; conor+dt at kernel.org; andre.draszik at linaro.org;
> 
[Snip]
> >>>>>> On Fri, Aug 22, 2025 at 03:08:44PM +0530, Pritam Manohar Sutar
> wrote:
> >>>>>>> This phy supports USB3.1 SSP+(10Gbps) protocol and is backwards
> >>>>>>> compatible to the USB3.0 SS(5Gbps). It requires two clocks,
> >>>>>>> named "phy" and "ref". The required supplies for USB3.1 are
> >>>>>>> named as vdd075_usb30(0.75v), vdd18_usb30(1.8v).
> >>>>>>
> >>>>>> Please do not describe the schema, but hardware. This sentence
> >>>>>> does not help me in my question further.
> >>>>>
> >>>>> This is a combo phy having Synopsys usb20 and usb30 phys (these 2
> >>>>> phys are
> >>>> totally different).
> >>>>> One PHY only supports usb2.0 and data rates whereas another one
> >>>>> does
> >>>>> usb3.1 ssp+ and usb3.1 ssp
> >>>>>
> >>>>> This patch only explains about usb30 (since these are two
> >>>>> different
> >>>>> phys) phy
> >>>> and omitted inclusion of usb20 reference (added separate patch for
> >>>> this patch no 3).
> >>>>>
> >>>>> Hope this is clear.
> >>>>
> >>>> No. That sentence still explains what schema is doing.
> >>>>
> >>>
> >>> Ok, let me simplify the commit message further something like below.
> >>> Anyways, the coverletter contains more details about it.
> >>>
> >>> "dt-bindings: phy: samsung,usb3-drd-phy: add ExynosAutov920 combo
> >>> ssphy
> >>>
> >>>   Add schema for combo ssphy found on this SoC.
> >>> "
> >>>
> >>> Please confirm if this looks fine?
> >>> If so, will reflect the similar commit messages in patch 1 and 3.
> >>
> >> Please read my first comment again. I do not see how does this
> >> satisfy hardware explanation.
> >>
> > Just went through the conversation above, until what extent hardware
> > description need to be explain in the commit?
> > Do we have any guideline for the same?
> > Could you please help with an example from previous any commit or some
> other patches?
> > I understand that mentioning, ?two clocks, two supplies etc" are part
> > of schema, one may or may not capture that in the commit.
> > However mentioning, ?this hardware (SoC) contain a combo PHY which
> supports usb3.1 and usb3.0" is not ok?
> 
> 
> Maybe that's just language, but to me the commit msg did not describe
> hardware after first sentence, but said what schema requires (some
> clocks and supplies). Other examples:
> 00399bbe02d2bb6fd8d6eb90573ec305616449f4
> e4c9a7b475e5d0d9b2440ee48f91d1364eabd6cb
> 
Thanks for suggestion as always, I hope the author can follow this. 

> and here another anti-pattern:
> 23f793850e9ee7390584c0809f085d6c88de7d3f
> 
> (and before you ask why above carries my Rb tag, then note that
I will not ask :-)
> Samsung's revenue is around 220 billion USD, so for sure it has a lot,
> really a lot of resources to review patches internally and improve their
> quality before posting).
> 
Hmm..., however let me check internally.

> Best regards,
> Krzysztof




From pritam.sutar at samsung.com  Fri Aug 29 05:03:16 2025
From: pritam.sutar at samsung.com (Pritam Manohar Sutar)
Date: Fri, 29 Aug 2025 17:33:16 +0530
Subject: [PATCH v7 5/6] dt-bindings: phy: samsung,usb3-drd-phy: add
 ExynosAutov920 combo ssphy
In-Reply-To: <6b5f20ed-4e88-441e-8f61-20866e2b39c7@kernel.org>
References: <20250822093845.1179395-1-pritam.sutar@samsung.com>
	<CGME20250822093022epcas5p42d8c16c851769dab0e1da9d45743ab1f@epcas5p4.samsung.com>
	<20250822093845.1179395-6-pritam.sutar@samsung.com>
	<20250824-rough-fresh-orangutan-eecb2f@kuoka>
	<007501dc1653$e36c3b50$aa44b1f0$@samsung.com>
	<83dc9435-5850-425d-b345-52e84ef9262c@kernel.org>
	<000401dc18cd$ec02a1b0$c407e510$@samsung.com>
	<e8e99c16-ad40-4d79-be92-1aa55c13f9ea@kernel.org>
	<263801dc18d3$d1e20950$75a61bf0$@samsung.com>
	<6b5f20ed-4e88-441e-8f61-20866e2b39c7@kernel.org>
Message-ID: <001101dc18dc$e97457e0$bc5d07a0$@samsung.com>

Hi Krzysztof,

> -----Original Message-----
> From: Krzysztof Kozlowski <krzk at kernel.org>
> Sent: 29 August 2025 04:56 PM
> To: Alim Akhtar <alim.akhtar at samsung.com>; 'Pritam Manohar Sutar'
> <pritam.sutar at samsung.com>
> Cc: vkoul at kernel.org; kishon at kernel.org; robh at kernel.org;
> krzk+dt at kernel.org; conor+dt at kernel.org; andre.draszik at linaro.org;
> peter.griffin at linaro.org; kauschluss at disroot.org;
> ivo.ivanov.ivanov1 at gmail.com; igor.belwon at mentallysanemainliners.org;
> johan at kernel.org; m.szyprowski at samsung.com; s.nawrocki at samsung.com;
> linux-phy at lists.infradead.org; devicetree at vger.kernel.org; linux-
> kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-samsung-
> soc at vger.kernel.org; rosa.pila at samsung.com; dev.tailor at samsung.com;
> faraz.ata at samsung.com; muhammed.ali at samsung.com;
> selvarasu.g at samsung.com
> Subject: Re: [PATCH v7 5/6] dt-bindings: phy: samsung,usb3-drd-phy: add
> ExynosAutov920 combo ssphy
> 
> On 29/08/2025 12:58, Alim Akhtar wrote:
> > Hi Krzysztof
> >
> >> -----Original Message-----
> >> From: Krzysztof Kozlowski <krzk at kernel.org>
> >> Sent: Friday, August 29, 2025 4:07 PM
> >> To: Pritam Manohar Sutar <pritam.sutar at samsung.com>
> >> Cc: vkoul at kernel.org; kishon at kernel.org; robh at kernel.org;
> >> krzk+dt at kernel.org; conor+dt at kernel.org; alim.akhtar at samsung.com;
> >> andre.draszik at linaro.org; peter.griffin at linaro.org;
> >> kauschluss at disroot.org; ivo.ivanov.ivanov1 at gmail.com;
> >> igor.belwon at mentallysanemainliners.org;
> >> johan at kernel.org; m.szyprowski at samsung.com; s.nawrocki at samsung.com;
> >> linux-phy at lists.infradead.org; devicetree at vger.kernel.org;
> >> linux-kernel at vger.kernel.org; linux-arm- kernel at lists.infradead.org;
> >> linux-samsung-soc at vger.kernel.org;
> >> rosa.pila at samsung.com; dev.tailor at samsung.com;
> faraz.ata at samsung.com;
> >> muhammed.ali at samsung.com; selvarasu.g at samsung.com
> >> Subject: Re: [PATCH v7 5/6] dt-bindings: phy: samsung,usb3-drd-phy:
> >> add
> >> ExynosAutov920 combo ssphy
> >>
> >> On 29/08/2025 12:15, Pritam Manohar Sutar wrote:
> >>> Hi Krzysztof
> >>>
> >>>> -----Original Message-----
> >>>> From: Krzysztof Kozlowski <krzk at kernel.org>
> >>>> Sent: 26 August 2025 02:05 PM
> >>>> To: Pritam Manohar Sutar <pritam.sutar at samsung.com>
> >>>> Cc: vkoul at kernel.org; kishon at kernel.org; robh at kernel.org;
> >>> .
> >>> .
> >>> [snip]
> >>> .
> >>> .
> >>>>>> Subject: Re: [PATCH v7 5/6] dt-bindings: phy: samsung,usb3-drd-phy:
> >>>>>> add
> >>>>>> ExynosAutov920 combo ssphy
> >>>>>>
> >>>>>> On Fri, Aug 22, 2025 at 03:08:44PM +0530, Pritam Manohar Sutar wrote:
> >>>>>>> This phy supports USB3.1 SSP+(10Gbps) protocol and is backwards
> >>>>>>> compatible to the USB3.0 SS(5Gbps). It requires two clocks,
> >>>>>>> named "phy" and "ref". The required supplies for USB3.1 are
> >>>>>>> named as vdd075_usb30(0.75v), vdd18_usb30(1.8v).
> >>>>>>
> >>>>>> Please do not describe the schema, but hardware. This sentence
> >>>>>> does not help me in my question further.
> >>>>>
> >>>>> This is a combo phy having Synopsys usb20 and usb30 phys (these 2
> >>>>> phys are
> >>>> totally different).
> >>>>> One PHY only supports usb2.0 and data rates whereas another one
> >>>>> does
> >>>>> usb3.1 ssp+ and usb3.1 ssp
> >>>>>
> >>>>> This patch only explains about usb30 (since these are two
> >>>>> different
> >>>>> phys) phy
> >>>> and omitted inclusion of usb20 reference (added separate patch for
> >>>> this patch no 3).
> >>>>>
> >>>>> Hope this is clear.
> >>>>
> >>>> No. That sentence still explains what schema is doing.
> >>>>
> >>>
> >>> Ok, let me simplify the commit message further something like below.
> >>> Anyways, the coverletter contains more details about it.
> >>>
> >>> "dt-bindings: phy: samsung,usb3-drd-phy: add ExynosAutov920 combo
> >>> ssphy
> >>>
> >>>   Add schema for combo ssphy found on this SoC.
> >>> "
> >>>
> >>> Please confirm if this looks fine?
> >>> If so, will reflect the similar commit messages in patch 1 and 3.
> >>
> >> Please read my first comment again. I do not see how does this
> >> satisfy hardware explanation.
> >>
> > Just went through the conversation above, until what extent hardware
> > description need to be explain in the commit?
> > Do we have any guideline for the same?
> > Could you please help with an example from previous any commit or some
> other patches?
> > I understand that mentioning, ?two clocks, two supplies etc" are part
> > of schema, one may or may not capture that in the commit.
> > However mentioning, ?this hardware (SoC) contain a combo PHY which
> supports usb3.1 and usb3.0" is not ok?
> 
> 
> Maybe that's just language, but to me the commit msg did not describe
> hardware after first sentence, but said what schema requires (some
> clocks and supplies). Other examples:
> 00399bbe02d2bb6fd8d6eb90573ec305616449f4
> e4c9a7b475e5d0d9b2440ee48f91d1364eabd6cb
> 

Thank you for the pointers, will refer the examples and 
update the commit messages accordingly. 

> and here another anti-pattern:
> 23f793850e9ee7390584c0809f085d6c88de7d3f
> 
> (and before you ask why above carries my Rb tag, then note that
> Samsung's revenue is around 220 billion USD, so for sure it has a lot,
> really a lot of resources to review patches internally and improve their
> quality before posting).
> 
> Best regards,
> Krzysztof

Thank you.

Regards,
Pritam




From claudiu.beznea at tuxon.dev  Fri Aug 29 05:17:22 2025
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Fri, 29 Aug 2025 15:17:22 +0300
Subject: [PATCH v5 0/7] Add initial USB support for the Renesas RZ/G3S SoC
In-Reply-To: <aLGUJbA0szYQ_gN4@shikoro>
References: <20250819054212.486426-1-claudiu.beznea.uj@bp.renesas.com>
 <aLAZprjeKtk4pusw@shikoro> <ae53d367-2ee5-49aa-82ba-86f9e84d4d25@tuxon.dev>
 <aLGGmI8bpKNVaSAa@shikoro> <be706ee5-057c-4b0a-b0d3-54ca24087f3f@tuxon.dev>
 <aLGUJbA0szYQ_gN4@shikoro>
Message-ID: <3731e13f-d601-4fe4-a3d2-6dd3289b6396@tuxon.dev>



On 8/29/25 14:51, Wolfram Sang wrote:
> 
>>> Yes, I added it and it made the error go away, but still no USB. I
>>
>> The drivers are not probed or you see no activity when connecting USB devices?
> 
> Sigh, I was so sure to have checked OHCI/EHCI but only EHCI was enabled :(
> 
> Checking with the schematics, I get it that only the rightmost USB-A
> connectors on the carrier board are routed. Those two work fine now.
> 
> If that is to be expected, then for the whole series:

Yes, only those 2 are routed on RZ SMARC Carrier II + RZ/G3S SMARC Module.

> 
> Tested-by: Wolfram Sang <wsa+renesas at sang-engineering.com>
> 

Thank you for doing this,
Claudiu


From krzk at kernel.org  Fri Aug 29 06:12:24 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 29 Aug 2025 15:12:24 +0200
Subject: [PATCH v2 1/2] dt-bindings: phy: add support for NXPs TJA1145 CAN
 transceiver
In-Reply-To: <20250829-tja1145-support-v2-1-60997f328979@liebherr.com>
References: <20250829-tja1145-support-v2-0-60997f328979@liebherr.com>
 <20250829-tja1145-support-v2-1-60997f328979@liebherr.com>
Message-ID: <bf925270-5410-407c-a4e0-472a427e6ef6@kernel.org>

On 29/08/2025 11:19, Dimitri Fedrau via B4 Relay wrote:
> From: Dimitri Fedrau <dimitri.fedrau at liebherr.com>
> 
> Adding documentation for NXPs TJA1145 CAN transceiver.

Pity you did not include resolution of discussions about directory and
can phy bindings here. You have entire commit msg for that, but instead
it is a copy paste of subject.

> 
> Signed-off-by: Dimitri Fedrau <dimitri.fedrau at liebherr.com>
> ---
>  .../devicetree/bindings/phy/nxp,tja1145-can.yaml   | 79 ++++++++++++++++++++++
>  1 file changed, 79 insertions(+)

> 


Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof


From robh at kernel.org  Fri Aug 29 06:50:59 2025
From: robh at kernel.org (Rob Herring (Arm))
Date: Fri, 29 Aug 2025 08:50:59 -0500
Subject: [PATCH v2 1/2] dt-bindings: phy: add support for NXPs TJA1145
 CAN transceiver
In-Reply-To: <20250829-tja1145-support-v2-1-60997f328979@liebherr.com>
References: <20250829-tja1145-support-v2-0-60997f328979@liebherr.com>
 <20250829-tja1145-support-v2-1-60997f328979@liebherr.com>
Message-ID: <175647456257.394630.17282056537152186661.robh@kernel.org>


On Fri, 29 Aug 2025 11:19:58 +0200, Dimitri Fedrau wrote:
> Adding documentation for NXPs TJA1145 CAN transceiver.
> 
> Signed-off-by: Dimitri Fedrau <dimitri.fedrau at liebherr.com>
> ---
>  .../devicetree/bindings/phy/nxp,tja1145-can.yaml   | 79 ++++++++++++++++++++++
>  1 file changed, 79 insertions(+)
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/phy/nxp,tja1145-can.example.dts:21.21-33.15: Warning (unit_address_vs_reg): /example-0/spi/can-phy: node has a reg or ranges property, but no unit name
Documentation/devicetree/bindings/phy/nxp,tja1145-can.example.dts:21.21-33.15: Warning (spi_bus_reg): /example-0/spi/can-phy: SPI bus unit address format error, expected "0"

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20250829-tja1145-support-v2-1-60997f328979 at liebherr.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  Fri Aug 29 07:21:11 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 29 Aug 2025 16:21:11 +0200
Subject: [PATCH v2 1/2] dt-bindings: phy: add support for NXPs TJA1145 CAN
 transceiver
In-Reply-To: <bf925270-5410-407c-a4e0-472a427e6ef6@kernel.org>
References: <20250829-tja1145-support-v2-0-60997f328979@liebherr.com>
 <20250829-tja1145-support-v2-1-60997f328979@liebherr.com>
 <bf925270-5410-407c-a4e0-472a427e6ef6@kernel.org>
Message-ID: <a91b8fba-8d26-441e-9da6-86e302703abc@kernel.org>

On 29/08/2025 15:12, Krzysztof Kozlowski wrote:
> On 29/08/2025 11:19, Dimitri Fedrau via B4 Relay wrote:
>> From: Dimitri Fedrau <dimitri.fedrau at liebherr.com>
>>
>> Adding documentation for NXPs TJA1145 CAN transceiver.
> 
> Pity you did not include resolution of discussions about directory and
> can phy bindings here. You have entire commit msg for that, but instead
> it is a copy paste of subject.
> 
>>
>> Signed-off-by: Dimitri Fedrau <dimitri.fedrau at liebherr.com>
>> ---
>>  .../devicetree/bindings/phy/nxp,tja1145-can.yaml   | 79 ++++++++++++++++++++++
>>  1 file changed, 79 insertions(+)
> 
>>
> 
> 
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

And un-reviewed, I missed messed example and this was never tested.

Sending untested code only makes us grumpy.

Best regards,
Krzysztof


From Frank.li at nxp.com  Fri Aug 29 07:29:53 2025
From: Frank.li at nxp.com (Frank Li)
Date: Fri, 29 Aug 2025 10:29:53 -0400
Subject: [PATCH v3 1/6] dt-bindings: phy: ti,tcan104x-can: Document NXP
 TJA105X/1048
In-Reply-To: <20250829-can-v3-1-3b2f34094f59@nxp.com>
References: <20250829-can-v3-0-3b2f34094f59@nxp.com>
 <20250829-can-v3-1-3b2f34094f59@nxp.com>
Message-ID: <aLG5YQvw1rVRc//I@lizhi-Precision-Tower-5810>

On Fri, Aug 29, 2025 at 03:08:56PM +0800, Peng Fan wrote:
> The TJA105[1,7] is a high-speed CAN transceiver which is a pin-compatible
> alternative for TI TCAN1043 with sleep mode supported, and has a compatible
> programming model, therefore use ti,tcan1043 as fallback compatible.
>
> The TJA1048 is a dual high-speed CAN transceiver with sleep mode supported.
>
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  .../devicetree/bindings/phy/ti,tcan104x-can.yaml   | 32 ++++++++++++++++++++--
>  1 file changed, 30 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml b/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
> index 4a8c3829d85d3c4a4963750d03567c1c345beb91..a225540545301e443e3460b933effbad48786597 100644
> --- a/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
> +++ b/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
> @@ -19,18 +19,25 @@ properties:
>            - enum:
>                - microchip,ata6561
>            - const: ti,tcan1042
> +      - items:
> +          - enum:
> +              - nxp,tja1051
> +              - nxp,tja1057
> +          - const: ti,tcan1043
>        - enum:
>            - ti,tcan1042
>            - ti,tcan1043
> +          - nxp,tja1048
>            - nxp,tjr1443
>
>    '#phy-cells':
> -    const: 0
> +    enum: [0, 1]
>
>    standby-gpios:
>      description:
>        gpio node to toggle standby signal on transceiver
> -    maxItems: 1
> +    minItems: 1
> +    maxItems: 2
>
>    enable-gpios:
>      description:
> @@ -53,6 +60,27 @@ required:
>    - compatible
>    - '#phy-cells'
>
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: nxp,tja1048
> +    then:
> +      properties:
> +        '#phy-cells':
> +          const: 1
> +        standby-gpios:
> +          minItems: 2
> +          maxItems: 2

maxItems already 2 at top.

> +    else:
> +      properties:
> +        '#phy-cells':
> +          const: 0
> +        standby-gpios:
> +          minItems: 1

minItems already 1 at top

Reviewed-by: Frank Li <Frank.Li at nxp.com>

> +          maxItems: 1
> +
>  additionalProperties: false
>
>  examples:
>
> --
> 2.37.1
>


From Frank.li at nxp.com  Fri Aug 29 07:32:09 2025
From: Frank.li at nxp.com (Frank Li)
Date: Fri, 29 Aug 2025 10:32:09 -0400
Subject: [PATCH v3 2/6] phy: phy-can-transceiver: Introduce
 can_transceiver_priv
In-Reply-To: <20250829-can-v3-2-3b2f34094f59@nxp.com>
References: <20250829-can-v3-0-3b2f34094f59@nxp.com>
 <20250829-can-v3-2-3b2f34094f59@nxp.com>
Message-ID: <aLG56YUI0/GBfcje@lizhi-Precision-Tower-5810>

On Fri, Aug 29, 2025 at 03:08:57PM +0800, Peng Fan wrote:
> To prepare for dual-channel phy support, introduce can_transceiver_priv as
> a higher level encapsulation for phy and mux_state.
>

Nit: Add "No functional changes."

Reviewed-by: Frank Li <Frank.Li at nxp.com>

> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  drivers/phy/phy-can-transceiver.c | 41 ++++++++++++++++++++++++++-------------
>  1 file changed, 27 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/phy/phy-can-transceiver.c b/drivers/phy/phy-can-transceiver.c
> index f59caff4b3d4c267feca4220bf1547b6fad08f95..6415c6af0e8414a6cc8d15958a17ee749a3f28e9 100644
> --- a/drivers/phy/phy-can-transceiver.c
> +++ b/drivers/phy/phy-can-transceiver.c
> @@ -23,6 +23,11 @@ struct can_transceiver_phy {
>  	struct phy *generic_phy;
>  	struct gpio_desc *standby_gpio;
>  	struct gpio_desc *enable_gpio;
> +	struct can_transceiver_priv *priv;
> +};
> +
> +struct can_transceiver_priv {
> +	struct can_transceiver_phy *can_transceiver_phy;
>  	struct mux_state *mux_state;
>  };
>
> @@ -32,8 +37,8 @@ static int can_transceiver_phy_power_on(struct phy *phy)
>  	struct can_transceiver_phy *can_transceiver_phy = phy_get_drvdata(phy);
>  	int ret;
>
> -	if (can_transceiver_phy->mux_state) {
> -		ret = mux_state_select(can_transceiver_phy->mux_state);
> +	if (can_transceiver_phy->priv->mux_state) {
> +		ret = mux_state_select(can_transceiver_phy->priv->mux_state);
>  		if (ret) {
>  			dev_err(&phy->dev, "Failed to select CAN mux: %d\n", ret);
>  			return ret;
> @@ -56,8 +61,8 @@ static int can_transceiver_phy_power_off(struct phy *phy)
>  		gpiod_set_value_cansleep(can_transceiver_phy->standby_gpio, 1);
>  	if (can_transceiver_phy->enable_gpio)
>  		gpiod_set_value_cansleep(can_transceiver_phy->enable_gpio, 0);
> -	if (can_transceiver_phy->mux_state)
> -		mux_state_deselect(can_transceiver_phy->mux_state);
> +	if (can_transceiver_phy->priv->mux_state)
> +		mux_state_deselect(can_transceiver_phy->priv->mux_state);
>
>  	return 0;
>  }
> @@ -107,7 +112,7 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
>  {
>  	struct phy_provider *phy_provider;
>  	struct device *dev = &pdev->dev;
> -	struct can_transceiver_phy *can_transceiver_phy;
> +	struct can_transceiver_priv *priv;
>  	const struct can_transceiver_data *drvdata;
>  	const struct of_device_id *match;
>  	struct phy *phy;
> @@ -117,18 +122,25 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
>  	u32 max_bitrate = 0;
>  	int err;
>
> -	can_transceiver_phy = devm_kzalloc(dev, sizeof(struct can_transceiver_phy), GFP_KERNEL);
> -	if (!can_transceiver_phy)
> -		return -ENOMEM;
> -
>  	match = of_match_node(can_transceiver_phy_ids, pdev->dev.of_node);
>  	drvdata = match->data;
>
> +	priv = devm_kzalloc(dev, sizeof(struct can_transceiver_priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	platform_set_drvdata(pdev, priv);
> +
> +	priv->can_transceiver_phy = devm_kzalloc(dev, sizeof(struct can_transceiver_phy),
> +						 GFP_KERNEL);
> +	if (!priv->can_transceiver_phy)
> +		return -ENOMEM;
> +
>  	mux_state = devm_mux_state_get_optional(dev, NULL);
>  	if (IS_ERR(mux_state))
>  		return PTR_ERR(mux_state);
>
> -	can_transceiver_phy->mux_state = mux_state;
> +	priv->mux_state = mux_state;
>
>  	phy = devm_phy_create(dev, dev->of_node,
>  			      &can_transceiver_phy_ops);
> @@ -142,23 +154,24 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
>  		dev_warn(dev, "Invalid value for transceiver max bitrate. Ignoring bitrate limit\n");
>  	phy->attrs.max_link_rate = max_bitrate;
>
> -	can_transceiver_phy->generic_phy = phy;
> +	priv->can_transceiver_phy->generic_phy = phy;
> +	priv->can_transceiver_phy->priv = priv;
>
>  	if (drvdata->flags & CAN_TRANSCEIVER_STB_PRESENT) {
>  		standby_gpio = devm_gpiod_get_optional(dev, "standby", GPIOD_OUT_HIGH);
>  		if (IS_ERR(standby_gpio))
>  			return PTR_ERR(standby_gpio);
> -		can_transceiver_phy->standby_gpio = standby_gpio;
> +		priv->can_transceiver_phy->standby_gpio = standby_gpio;
>  	}
>
>  	if (drvdata->flags & CAN_TRANSCEIVER_EN_PRESENT) {
>  		enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW);
>  		if (IS_ERR(enable_gpio))
>  			return PTR_ERR(enable_gpio);
> -		can_transceiver_phy->enable_gpio = enable_gpio;
> +		priv->can_transceiver_phy->enable_gpio = enable_gpio;
>  	}
>
> -	phy_set_drvdata(can_transceiver_phy->generic_phy, can_transceiver_phy);
> +	phy_set_drvdata(priv->can_transceiver_phy->generic_phy, priv->can_transceiver_phy);
>
>  	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
>
>
> --
> 2.37.1
>


From Frank.li at nxp.com  Fri Aug 29 07:34:51 2025
From: Frank.li at nxp.com (Frank Li)
Date: Fri, 29 Aug 2025 10:34:51 -0400
Subject: [PATCH v3 3/6] phy: phy-can-transceiver: Add dual channel
 support for TJA1048
In-Reply-To: <20250829-can-v3-3-3b2f34094f59@nxp.com>
References: <20250829-can-v3-0-3b2f34094f59@nxp.com>
 <20250829-can-v3-3-3b2f34094f59@nxp.com>
Message-ID: <aLG6izjPDAfkk4D2@lizhi-Precision-Tower-5810>

On Fri, Aug 29, 2025 at 03:08:58PM +0800, Peng Fan wrote:
> - Introduce new flag CAN_TRANSCEIVER_DUAL_CH to indicate the phy has two
>   channels.
> - Alloc a phy for each channel
> - Support TJA1048 which is a dual high-speed CAN transceiver with sleep
>   mode supported.
> - Add can_transceiver_phy_xlate for parsing phy
>
> Signed-off-by: Peng Fan <peng.fan at nxp.com>

Reviewed-by: Frank Li <Frank.Li at nxp.com>

> ---
>  drivers/phy/phy-can-transceiver.c | 91 ++++++++++++++++++++++++++++-----------
>  1 file changed, 65 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/phy/phy-can-transceiver.c b/drivers/phy/phy-can-transceiver.c
> index 6415c6af0e8414a6cc8d15958a17ee749a3f28e9..f06b1df76ada023f432dce892c3346f45397ab54 100644
> --- a/drivers/phy/phy-can-transceiver.c
> +++ b/drivers/phy/phy-can-transceiver.c
> @@ -17,6 +17,7 @@ struct can_transceiver_data {
>  	u32 flags;
>  #define CAN_TRANSCEIVER_STB_PRESENT	BIT(0)
>  #define CAN_TRANSCEIVER_EN_PRESENT	BIT(1)
> +#define CAN_TRANSCEIVER_DUAL_CH		BIT(2)
>  };
>
>  struct can_transceiver_phy {
> @@ -29,6 +30,7 @@ struct can_transceiver_phy {
>  struct can_transceiver_priv {
>  	struct can_transceiver_phy *can_transceiver_phy;
>  	struct mux_state *mux_state;
> +	int num_ch;
>  };
>
>  /* Power on function */
> @@ -81,6 +83,10 @@ static const struct can_transceiver_data tcan1043_drvdata = {
>  	.flags = CAN_TRANSCEIVER_STB_PRESENT | CAN_TRANSCEIVER_EN_PRESENT,
>  };
>
> +static const struct can_transceiver_data tja1048_drvdata = {
> +	.flags = CAN_TRANSCEIVER_STB_PRESENT | CAN_TRANSCEIVER_DUAL_CH,
> +};
> +
>  static const struct of_device_id can_transceiver_phy_ids[] = {
>  	{
>  		.compatible = "ti,tcan1042",
> @@ -90,6 +96,10 @@ static const struct of_device_id can_transceiver_phy_ids[] = {
>  		.compatible = "ti,tcan1043",
>  		.data = &tcan1043_drvdata
>  	},
> +	{
> +		.compatible = "nxp,tja1048",
> +		.data = &tja1048_drvdata
> +	},
>  	{
>  		.compatible = "nxp,tjr1443",
>  		.data = &tcan1043_drvdata
> @@ -108,6 +118,25 @@ devm_mux_state_get_optional(struct device *dev, const char *mux_name)
>  	return devm_mux_state_get(dev, mux_name);
>  }
>
> +static struct phy *can_transceiver_phy_xlate(struct device *dev,
> +					     const struct of_phandle_args *args)
> +{
> +	struct can_transceiver_priv *priv = dev_get_drvdata(dev);
> +	u32 idx;
> +
> +	if (priv->num_ch == 1)
> +		return priv->can_transceiver_phy[0].generic_phy;
> +
> +	if (args->args_count != 1)
> +		return ERR_PTR(-EINVAL);
> +
> +	idx = args->args[0];
> +	if (idx >= priv->num_ch)
> +		return ERR_PTR(-EINVAL);
> +
> +	return priv->can_transceiver_phy[idx].generic_phy;
> +}
> +
>  static int can_transceiver_phy_probe(struct platform_device *pdev)
>  {
>  	struct phy_provider *phy_provider;
> @@ -120,7 +149,8 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
>  	struct gpio_desc *enable_gpio;
>  	struct mux_state *mux_state;
>  	u32 max_bitrate = 0;
> -	int err;
> +	int num_ch = 1;
> +	int err, i;
>
>  	match = of_match_node(can_transceiver_phy_ids, pdev->dev.of_node);
>  	drvdata = match->data;
> @@ -131,7 +161,11 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
>
>  	platform_set_drvdata(pdev, priv);
>
> -	priv->can_transceiver_phy = devm_kzalloc(dev, sizeof(struct can_transceiver_phy),
> +	if (drvdata->flags & CAN_TRANSCEIVER_DUAL_CH)
> +		num_ch = 2;
> +
> +	priv->num_ch = num_ch;
> +	priv->can_transceiver_phy = devm_kcalloc(dev, num_ch, sizeof(struct can_transceiver_phy),
>  						 GFP_KERNEL);
>  	if (!priv->can_transceiver_phy)
>  		return -ENOMEM;
> @@ -142,38 +176,43 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
>
>  	priv->mux_state = mux_state;
>
> -	phy = devm_phy_create(dev, dev->of_node,
> -			      &can_transceiver_phy_ops);
> -	if (IS_ERR(phy)) {
> -		dev_err(dev, "failed to create can transceiver phy\n");
> -		return PTR_ERR(phy);
> -	}
> -
>  	err = device_property_read_u32(dev, "max-bitrate", &max_bitrate);
>  	if ((err != -EINVAL) && !max_bitrate)
>  		dev_warn(dev, "Invalid value for transceiver max bitrate. Ignoring bitrate limit\n");
> -	phy->attrs.max_link_rate = max_bitrate;
>
> -	priv->can_transceiver_phy->generic_phy = phy;
> -	priv->can_transceiver_phy->priv = priv;
> +	for (i = 0; i < num_ch; i++) {
> +		phy = devm_phy_create(dev, dev->of_node, &can_transceiver_phy_ops);
> +		if (IS_ERR(phy)) {
> +			dev_err(dev, "failed to create can transceiver phy\n");
> +			return PTR_ERR(phy);
> +		}
>
> -	if (drvdata->flags & CAN_TRANSCEIVER_STB_PRESENT) {
> -		standby_gpio = devm_gpiod_get_optional(dev, "standby", GPIOD_OUT_HIGH);
> -		if (IS_ERR(standby_gpio))
> -			return PTR_ERR(standby_gpio);
> -		priv->can_transceiver_phy->standby_gpio = standby_gpio;
> -	}
> +		phy->attrs.max_link_rate = max_bitrate;
>
> -	if (drvdata->flags & CAN_TRANSCEIVER_EN_PRESENT) {
> -		enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW);
> -		if (IS_ERR(enable_gpio))
> -			return PTR_ERR(enable_gpio);
> -		priv->can_transceiver_phy->enable_gpio = enable_gpio;
> -	}
> +		priv->can_transceiver_phy[i].generic_phy = phy;
> +		priv->can_transceiver_phy[i].priv = priv;
>
> -	phy_set_drvdata(priv->can_transceiver_phy->generic_phy, priv->can_transceiver_phy);
> +		if (drvdata->flags & CAN_TRANSCEIVER_STB_PRESENT) {
> +			standby_gpio = devm_gpiod_get_index_optional(dev, "standby", i,
> +								     GPIOD_OUT_HIGH);
> +			if (IS_ERR(standby_gpio))
> +				return PTR_ERR(standby_gpio);
> +			priv->can_transceiver_phy[i].standby_gpio = standby_gpio;
> +		}
> +
> +		if (drvdata->flags & CAN_TRANSCEIVER_EN_PRESENT) {
> +			enable_gpio = devm_gpiod_get_index_optional(dev, "enable", i,
> +								    GPIOD_OUT_LOW);
> +			if (IS_ERR(enable_gpio))
> +				return PTR_ERR(enable_gpio);
> +			priv->can_transceiver_phy[i].enable_gpio = enable_gpio;
> +		}
> +
> +		phy_set_drvdata(priv->can_transceiver_phy[i].generic_phy,
> +				&priv->can_transceiver_phy[i]);
> +	}
>
> -	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> +	phy_provider = devm_of_phy_provider_register(dev, can_transceiver_phy_xlate);
>
>  	return PTR_ERR_OR_ZERO(phy_provider);
>  }
>
> --
> 2.37.1
>


From Frank.li at nxp.com  Fri Aug 29 07:35:28 2025
From: Frank.li at nxp.com (Frank Li)
Date: Fri, 29 Aug 2025 10:35:28 -0400
Subject: [PATCH v3 6/6] arm64: dts: imx93-11x11-evk: Use phys to replace
 xceiver-supply
In-Reply-To: <20250829-can-v3-6-3b2f34094f59@nxp.com>
References: <20250829-can-v3-0-3b2f34094f59@nxp.com>
 <20250829-can-v3-6-3b2f34094f59@nxp.com>
Message-ID: <aLG6sKiHLHbVP3os@lizhi-Precision-Tower-5810>

On Fri, Aug 29, 2025 at 03:09:01PM +0800, Peng Fan wrote:
> The TJA1057 used on i.MX93 EVK is actually high-speed CAN
> transceiver, not a regulator supply. So use phys to reflect the truth.
>
> Signed-off-by: Peng Fan <peng.fan at nxp.com>

Reviewed-by: Frank Li <Frank.Li at nxp.com>

> ---
>  arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts | 17 ++++++++---------
>  1 file changed, 8 insertions(+), 9 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts b/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
> index e24e12f04526c3a08c0bdc6134297fb010e6e926..4c52f22bbfac99722184b4d8679f48c4396b557f 100644
> --- a/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
> +++ b/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
> @@ -62,6 +62,13 @@ vdevbuffer: vdevbuffer at a4020000 {
>
>  	};
>
> +	flexcan_phy: can-phy {
> +		compatible = "nxp,tja1057", "ti,tcan1043";
> +		#phy-cells = <0>;
> +		max-bitrate = <5000000>;
> +		standby-gpios = <&adp5585 6 GPIO_ACTIVE_HIGH>;
> +	};
> +
>  	reg_vdd_12v: regulator-vdd-12v {
>  		compatible = "regulator-fixed";
>  		regulator-name = "VDD_12V";
> @@ -87,14 +94,6 @@ reg_audio_pwr: regulator-audio-pwr {
>  		enable-active-high;
>  	};
>
> -	reg_can2_standby: regulator-can2-standby {
> -		compatible = "regulator-fixed";
> -		regulator-name = "can2-stby";
> -		regulator-min-microvolt = <3300000>;
> -		regulator-max-microvolt = <3300000>;
> -		gpio = <&adp5585 6 GPIO_ACTIVE_LOW>;
> -	};
> -
>  	reg_m2_pwr: regulator-m2-pwr {
>  		compatible = "regulator-fixed";
>  		regulator-name = "M.2-power";
> @@ -284,7 +283,7 @@ ethphy2: ethernet-phy at 2 {
>  &flexcan2 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&pinctrl_flexcan2>;
> -	xceiver-supply = <&reg_can2_standby>;
> +	phys = <&flexcan_phy>;
>  	status = "okay";
>  };
>
>
> --
> 2.37.1
>


From mani at kernel.org  Fri Aug 29 20:21:51 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Sat, 30 Aug 2025 08:51:51 +0530
Subject: [PATCH v3 07/12] dt-bindings: PCI: Add support for Tesla FSD SoC
In-Reply-To: <000901dc101c$917bf160$b473d420$@samsung.com>
References: <20250811154638.95732-1-shradha.t@samsung.com>
 <CGME20250811154725epcas5p428fa3370a32bc2b664a4fd8260078097@epcas5p4.samsung.com>
 <20250811154638.95732-8-shradha.t@samsung.com>
 <9e065582-9349-4f39-88b5-048d333ab8d7@kernel.org>
 <000901dc101c$917bf160$b473d420$@samsung.com>
Message-ID: <3eykohfvqgkbvwirzx63bx65d5uv774gib65bcyjlpphrssfjp@74bqakxvnkmh>

On Mon, Aug 18, 2025 at 02:16:16PM GMT, Shradha Todi wrote:
> > > +
> > > +  phys:
> > > +    maxItems: 1
> > > +
> > > +  samsung,syscon-pcie:
> > > +    $ref: /schemas/types.yaml#/definitions/phandle-array
> > > +    description: phandle for system control registers, used to
> > > +                 control signals at system level
> > 
> > What is "system level"? and what are these "signals" being controlled?
> > 
> 
> I will add a more detailed description for why the syscon is being used
> 
> > 
> > > +title: Tesla FSD SoC series PCIe Host Controller
> > > +
> > > +maintainers:
> > > +  - Shradha Todi <shradha.t at samsung.com>
> > > +
> > > +description:
> > > +  Tesla FSD SoCs PCIe host controller inherits all the common
> > > +  properties defined in samsung,exynos-pcie.yaml
> > > +
> > > +allOf:
> > > +  - $ref: /schemas/pci/samsung,exynos-pcie.yaml#
> > > +
> > > +properties:
> > > +  compatible:
> > > +    const: tesla,fsd-pcie
> > > +
> > > +  clocks:
> > > +    maxItems: 4
> > > +
> > > +  clock-names:
> > > +    items:
> > > +      - const: aux
> > > +      - const: dbi
> > > +      - const: mstr
> > > +      - const: slv
> > > +
> > > +  num-lanes:
> > > +    maximum: 4
> > > +
> > > +  samsung,syscon-pcie:
> > > +    $ref: /schemas/types.yaml#/definitions/phandle-array
> > > +    description: phandle for system control registers, used to
> > > +                 control signals at system level
> > > +
> > > +required:
> > > +  - samsung,syscon-pcie
> > 
> > clocks are required, compatible as well.
> > 
> 
> Since this was inheriting the common exynos yaml file and that had these properties
> under required, I did not mention again. Will take care in next version.
> 

dma-coherent needs to be a required property as well since this binding is
supporting only one controller, that seem to have cache coherent DMA.

> > Missing supplies, both as properties and required. PCI devices do not
> > work without power.
> > 
> 
> According to the HW design of FSD SoC, the control to manage PCIe power is given to
> a separate CPU where custom firmware runs. Therefore, the Linux side does not control
> the PCIe power supplies directly and are hence not included in the device tree.

What do you mean by 'PCIe power'? Supply to the PCIe controller/bus or the
devices connected to the bus?

- Mani

-- 
????????? ????????


From mani at kernel.org  Fri Aug 29 20:27:14 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Sat, 30 Aug 2025 08:57:14 +0530
Subject: [PATCH v3 07/12] dt-bindings: PCI: Add support for Tesla FSD SoC
In-Reply-To: <20250811154638.95732-8-shradha.t@samsung.com>
References: <20250811154638.95732-1-shradha.t@samsung.com>
 <CGME20250811154725epcas5p428fa3370a32bc2b664a4fd8260078097@epcas5p4.samsung.com>
 <20250811154638.95732-8-shradha.t@samsung.com>
Message-ID: <frnwfzh7j6x27evk6oo64cevpreq5s4tugewebcpropzmxpilf@trv2toljqptl>

On Mon, Aug 11, 2025 at 09:16:33PM GMT, Shradha Todi wrote:
> Add Tesla FSD SoC support for both RC and EP.

Add some info about the PCIe controller here. Like the data rate supported,
lanes, interrupts, any quirks etc...

> 
> Signed-off-by: Shradha Todi <shradha.t at samsung.com>
> ---
>  .../bindings/pci/tesla,fsd-pcie-ep.yaml       | 91 +++++++++++++++++++
>  .../bindings/pci/tesla,fsd-pcie.yaml          | 77 ++++++++++++++++
>  2 files changed, 168 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pci/tesla,fsd-pcie-ep.yaml
>  create mode 100644 Documentation/devicetree/bindings/pci/tesla,fsd-pcie.yaml
> 

[...]

> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/fsd-clk.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> +    soc {
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +
> +        pcierc1: pcie at 16b00000 {
> +            compatible = "tesla,fsd-pcie";
> +            reg = <0x0 0x16b00000 0x0 0x2000>,
> +                  <0x0 0x168c0000 0x0 0x1000>,
> +                  <0x0 0x18000000 0x0 0x1000>;
> +            reg-names = "dbi", "elbi", "config";
> +            ranges =  <0x82000000 0x0 0x18001000 0x0 0x18001000 0x0 0xffefff>;
> +            clocks = <&clock_fsys1 PCIE_LINK1_IPCLKPORT_AUX_ACLK>,
> +                     <&clock_fsys1 PCIE_LINK1_IPCLKPORT_DBI_ACLK>,
> +                     <&clock_fsys1 PCIE_LINK1_IPCLKPORT_MSTR_ACLK>,
> +                     <&clock_fsys1 PCIE_LINK1_IPCLKPORT_SLV_ACLK>;
> +            clock-names = "aux", "dbi", "mstr", "slv";
> +            #address-cells = <3>;
> +            #size-cells = <2>;
> +            dma-coherent;
> +            device_type = "pci";
> +            interrupts = <GIC_SPI 117 IRQ_TYPE_EDGE_RISING>;

Only one SPI interrupt? What about INTx? Don't you have any external/internal
MSI controller?

- Mani

-- 
????????? ????????


From mani at kernel.org  Fri Aug 29 20:54:28 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Sat, 30 Aug 2025 09:24:28 +0530
Subject: [PATCH v3 11/12] PCI: exynos: Add support for Tesla FSD SoC
In-Reply-To: <20250811154638.95732-12-shradha.t@samsung.com>
References: <20250811154638.95732-1-shradha.t@samsung.com>
 <CGME20250811154742epcas5p3276c7c053bedc526d9ce370dda83e195@epcas5p3.samsung.com>
 <20250811154638.95732-12-shradha.t@samsung.com>
Message-ID: <sss3py6cquhcipil3645pgc535ggfewolsld4e4g3v5yr3yvoc@3n57p4cyk43r>

On Mon, Aug 11, 2025 at 09:16:37PM GMT, Shradha Todi wrote:
> Add host and endpoint controller driver support for FSD SoC.
> 

Again, more info about the controller required.

> Signed-off-by: Shradha Todi <shradha.t at samsung.com>
> ---
>  drivers/pci/controller/dwc/pci-exynos.c | 278 ++++++++++++++++++++++++
>  1 file changed, 278 insertions(+)
> 
> diff --git a/drivers/pci/controller/dwc/pci-exynos.c b/drivers/pci/controller/dwc/pci-exynos.c
> index ef1f42236575..9aabfecdc147 100644
> --- a/drivers/pci/controller/dwc/pci-exynos.c
> +++ b/drivers/pci/controller/dwc/pci-exynos.c
> @@ -18,6 +18,8 @@
>  #include <linux/platform_device.h>
>  #include <linux/phy/phy.h>
>  #include <linux/regulator/consumer.h>
> +#include <linux/regmap.h>
> +#include <linux/mfd/syscon.h>
>  #include <linux/mod_devicetable.h>
>  #include <linux/module.h>
>  
> @@ -49,15 +51,35 @@
>  #define EXYNOS_PCIE_ELBI_SLV_ARMISC		0x120
>  #define EXYNOS_PCIE_ELBI_SLV_DBI_ENABLE		BIT(21)
>  
> +#define FSD_IRQ2_STS				0x008
> +#define FSD_IRQ_MSI_ENABLE			BIT(17)
> +#define FSD_IRQ2_EN				0x018
> +#define FSD_PCIE_APP_LTSSM_ENABLE		0x054
> +#define FSD_PCIE_LTSSM_ENABLE			0x1
> +#define FSD_PCIE_DEVICE_TYPE			0x080
> +#define FSD_DEVICE_TYPE_RC			0x4
> +#define FSD_DEVICE_TYPE_EP			0x0
> +#define FSD_PCIE_CXPL_DEBUG_00_31		0x2c8
> +
>  /* to store different SoC variants of Samsung */
>  enum samsung_pcie_variants {
> +	FSD,
>  	EXYNOS_5433,

I hope you are going to drop these variants and use the properties for specific
functionality as suggested by Bjorn.

>  };
>  
> +/* Values to be written to SYSREG to view DBI space as CDM/DBI2/IATU/DMA */
> +enum fsd_pcie_addr_type {
> +	ADDR_TYPE_DBI = 0x0,
> +	ADDR_TYPE_DBI2 = 0x12,
> +	ADDR_TYPE_ATU = 0x36,
> +	ADDR_TYPE_DMA = 0x3f,
> +};
> +
>  struct samsung_pcie_pdata {
>  	struct pci_ops				*pci_ops;
>  	const struct dw_pcie_ops		*dwc_ops;
>  	const struct dw_pcie_host_ops		*host_ops;
> +	const struct dw_pcie_ep_ops		*ep_ops;
>  	const struct samsung_res_ops		*res_ops;
>  	unsigned int				soc_variant;
>  	enum dw_pcie_device_mode		device_mode;
> @@ -67,6 +89,8 @@ struct exynos_pcie {
>  	struct dw_pcie			pci;
>  	void __iomem			*elbi_base;
>  	const struct samsung_pcie_pdata	*pdata;
> +	struct regmap			*sysreg;
> +	unsigned int			sysreg_offset;
>  	struct clk_bulk_data		*clks;
>  	struct phy			*phy;
>  	struct regulator_bulk_data	*supplies;
> @@ -334,11 +358,201 @@ static const struct dw_pcie_ops exynos_dw_pcie_ops = {
>  	.start_link = exynos_pcie_start_link,
>  };
>  
> +static void fsd_pcie_stop_link(struct dw_pcie *pci)
> +{
> +	u32 val;
> +	struct exynos_pcie *ep = to_exynos_pcie(pci);

Please use reverse Xmas order for local variables.

> +
> +	val = readl(ep->elbi_base + FSD_PCIE_APP_LTSSM_ENABLE);
> +	val &= ~FSD_PCIE_LTSSM_ENABLE;
> +	writel(val, ep->elbi_base + FSD_PCIE_APP_LTSSM_ENABLE);
> +}
> +
> +static int fsd_pcie_start_link(struct dw_pcie *pci)
> +{
> +	struct exynos_pcie *ep = to_exynos_pcie(pci);
> +	struct dw_pcie_ep *dw_ep = &pci->ep;
> +
> +	if (dw_pcie_link_up(pci))
> +		return 0;
> +
> +	writel(FSD_PCIE_LTSSM_ENABLE, ep->elbi_base + FSD_PCIE_APP_LTSSM_ENABLE);
> +
> +	/* no need to wait for link in case of host as core files take care */

What do you mean by 'core files'? DWC core driver?

> +	if (ep->pdata->device_mode == DW_PCIE_RC_TYPE)
> +		return 0;
> +
> +	/* check if the link is up or not in case of EP */
> +	if (!dw_pcie_wait_for_link(pci)) {

I presume there is no way to detect link up using the SPI interrupt?

> +		dw_pcie_ep_linkup(dw_ep);
> +		return 0;
> +	}
> +
> +	return -ETIMEDOUT;
> +}
> +
> +static irqreturn_t fsd_pcie_irq_handler(int irq, void *arg)
> +{
> +	u32 val;
> +	struct exynos_pcie *ep = arg;
> +	struct dw_pcie *pci = &ep->pci;
> +	struct dw_pcie_rp *pp = &pci->pp;
> +
> +	val = readl(ep->elbi_base + FSD_IRQ2_STS);
> +	if ((val & FSD_IRQ_MSI_ENABLE) == FSD_IRQ_MSI_ENABLE) {
> +		val &= FSD_IRQ_MSI_ENABLE;
> +		writel(val, ep->elbi_base + FSD_IRQ2_STS);
> +		dw_handle_msi_irq(pp);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static void fsd_pcie_msi_init(struct exynos_pcie *ep)
> +{
> +	int val;
> +
> +	val = readl(ep->elbi_base + FSD_IRQ2_EN);
> +	val |= FSD_IRQ_MSI_ENABLE;
> +	writel(val, ep->elbi_base + FSD_IRQ2_EN);

Could you please explain how MSI handling works? I don't understand it.

> +}
> +
> +static void __iomem *fsd_atu_setting(struct dw_pcie *pci, void __iomem *base)
> +{
> +	struct exynos_pcie *ep = to_exynos_pcie(pci);
> +
> +	if (base >= pci->atu_base) {
> +		regmap_write(ep->sysreg, ep->sysreg_offset, ADDR_TYPE_ATU);
> +		return (base - DEFAULT_DBI_ATU_OFFSET);
> +	} else if (base == pci->dbi_base) {
> +		regmap_write(ep->sysreg, ep->sysreg_offset, ADDR_TYPE_DBI);
> +	} else if (base == pci->dbi_base2) {
> +		regmap_write(ep->sysreg, ep->sysreg_offset, ADDR_TYPE_DBI2);
> +	}
> +
> +	return base;
> +}
> +
> +static u32 fsd_pcie_read_dbi(struct dw_pcie *pci, void __iomem *base,
> +				u32 reg, size_t size)
> +{
> +	void __iomem *addr;
> +	u32 val;
> +
> +	addr = fsd_atu_setting(pci, base);

The returned 'addr' seems to be static. Why can't you just store it during probe
and use the 'addr' directly?

> +	dw_pcie_read(addr + reg, size, &val);
> +
> +	return val;
> +}
> +
> +static void fsd_pcie_write_dbi(struct dw_pcie *pci, void __iomem *base,
> +				u32 reg, size_t size, u32 val)
> +{
> +	void __iomem *addr;
> +
> +	addr = fsd_atu_setting(pci, base);
> +	dw_pcie_write(addr + reg, size, val);
> +}
> +
> +static void fsd_pcie_write_dbi2(struct dw_pcie *pci, void __iomem *base,
> +				u32 reg, size_t size, u32 val)
> +{
> +	struct exynos_pcie *ep = to_exynos_pcie(pci);
> +
> +	fsd_atu_setting(pci, base);
> +	dw_pcie_write(pci->dbi_base + reg, size, val);
> +	regmap_write(ep->sysreg, ep->sysreg_offset, ADDR_TYPE_DBI);
> +}
> +
> +static bool fsd_pcie_link_up(struct dw_pcie *pci)
> +{
> +	u32 val;
> +	struct exynos_pcie *ep = to_exynos_pcie(pci);
> +
> +	val = readl(ep->elbi_base + FSD_PCIE_CXPL_DEBUG_00_31);
> +	val &= PORT_LOGIC_LTSSM_STATE_MASK;
> +
> +	return (val == PORT_LOGIC_LTSSM_STATE_L0);
> +}
> +
> +static int fsd_pcie_host_init(struct dw_pcie_rp *pp)
> +{
> +	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> +	struct exynos_pcie *ep = to_exynos_pcie(pci);
> +
> +	phy_init(ep->phy);
> +	fsd_pcie_msi_init(ep);
> +
> +	return 0;
> +}
> +
> +static const struct dw_pcie_host_ops fsd_pcie_host_ops = {
> +	.init = fsd_pcie_host_init,
> +};
> +
> +static int fsd_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
> +				 unsigned int type, u16 interrupt_num)
> +{
> +	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
> +
> +	switch (type) {
> +	case PCI_IRQ_INTX:
> +		return dw_pcie_ep_raise_intx_irq(ep, func_no);
> +	case PCI_IRQ_MSIX:
> +		dev_err(pci->dev, "EP does not support MSI-X\n");
> +		return -EINVAL;
> +	case PCI_IRQ_MSI:
> +		return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num);
> +	default:
> +		dev_err(pci->dev, "UNKNOWN IRQ type\n");

Do you want to return success below even for this error?

> +	}
> +
> +	return 0;

this should be -EOPNOTSUPP.

> +}
> +
> +static const struct pci_epc_features fsd_pcie_epc_features = {
> +	.linkup_notifier = false,

Default value is 'false'. So no need to initialize it agian.

> +	.msi_capable = true,
> +	.msix_capable = false,

Here also.

> +};
> +
> +static const struct pci_epc_features *fsd_pcie_get_features(struct dw_pcie_ep *ep)
> +{
> +	return &fsd_pcie_epc_features;
> +}
> +
> +static const struct dw_pcie_ep_ops fsd_ep_ops = {
> +	.raise_irq	= fsd_pcie_raise_irq,
> +	.get_features	= fsd_pcie_get_features,
> +};
> +
> +static void fsd_set_device_mode(struct exynos_pcie *ep)
> +{
> +	if (ep->pdata->device_mode == DW_PCIE_RC_TYPE)
> +		writel(FSD_DEVICE_TYPE_RC, ep->elbi_base + FSD_PCIE_DEVICE_TYPE);
> +	else
> +		writel(FSD_DEVICE_TYPE_EP, ep->elbi_base + FSD_PCIE_DEVICE_TYPE);
> +}
> +
> +static const struct dw_pcie_ops fsd_dw_pcie_ops = {
> +	.read_dbi	= fsd_pcie_read_dbi,
> +	.write_dbi	= fsd_pcie_write_dbi,
> +	.write_dbi2	= fsd_pcie_write_dbi2,
> +	.start_link	= fsd_pcie_start_link,
> +	.stop_link	= fsd_pcie_stop_link,
> +	.link_up	= fsd_pcie_link_up,
> +};
> +
>  static const struct samsung_res_ops exynos_res_ops_data = {
>  	.init_regulator		= exynos_init_regulator,
>  	.pcie_irq_handler	= exynos_pcie_irq_handler,
>  };
>  
> +static const struct samsung_res_ops fsd_res_ops_data = {
> +	.pcie_irq_handler	= fsd_pcie_irq_handler,
> +	.set_device_mode	= fsd_set_device_mode,
> +};
> +
>  static int exynos_pcie_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> @@ -361,6 +575,26 @@ static int exynos_pcie_probe(struct platform_device *pdev)
>  	if (IS_ERR(ep->phy))
>  		return PTR_ERR(ep->phy);
>  
> +	if (ep->pdata->soc_variant == FSD) {
> +		ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(36));
> +		if (ret)
> +			return ret;
> +
> +		ep->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
> +				"samsung,syscon-pcie");
> +		if (IS_ERR(ep->sysreg)) {
> +			dev_err(dev, "sysreg regmap lookup failed.\n");

Use dev_err_probe() here and below.

> +			return PTR_ERR(ep->sysreg);
> +		}
> +
> +		ret = of_property_read_u32_index(dev->of_node, "samsung,syscon-pcie", 1,
> +						 &ep->sysreg_offset);
> +		if (ret) {
> +			dev_err(dev, "couldn't get the register offset for syscon!\n");
> +			return ret;
> +		}
> +	}
> +
>  	/* External Local Bus interface (ELBI) registers */
>  	ep->elbi_base = devm_platform_ioremap_resource_byname(pdev, "elbi");
>  	if (IS_ERR(ep->elbi_base))
> @@ -397,6 +631,22 @@ static int exynos_pcie_probe(struct platform_device *pdev)
>  		if (ret < 0)
>  			goto fail_phy_init;
>  
> +		break;
> +	case DW_PCIE_EP_TYPE:
> +		phy_init(ep->phy);
> +
> +		ep->pci.ep.ops = pdata->ep_ops;
> +
> +		ret = dw_pcie_ep_init(&ep->pci.ep);
> +		if (ret < 0)
> +			goto fail_phy_init;
> +
> +		ret = dw_pcie_ep_init_registers(&ep->pci.ep);
> +		if (ret)
> +			goto fail_phy_init;
> +
> +		pci_epc_init_notify(ep->pci.ep.epc);

So the platform doesn't support PERST# and generates its own refclk?

- Mani

-- 
????????? ????????


From mani at kernel.org  Fri Aug 29 20:58:44 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Sat, 30 Aug 2025 09:28:44 +0530
Subject: [PATCH v3 12/12] arm64: dts: fsd: Add PCIe support for Tesla FSD
 SoC
In-Reply-To: <20250811154638.95732-13-shradha.t@samsung.com>
References: <20250811154638.95732-1-shradha.t@samsung.com>
 <CGME20250811154746epcas5p261ba0c811f9dd8748f8f241b76be6525@epcas5p2.samsung.com>
 <20250811154638.95732-13-shradha.t@samsung.com>
Message-ID: <dsa7u5pz7qmjaunzrqgpjkyv4xh427bbnpkdzvkpz3w6v6xf6v@5kxhihh4hw2j>

On Mon, Aug 11, 2025 at 09:16:38PM GMT, Shradha Todi wrote:
> Add the support for PCIe controller driver and phy driver for Tesla FSD.
> It includes support for both RC and EP.
> 
> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
> Signed-off-by: Shradha Todi <shradha.t at samsung.com>
> ---
>  arch/arm64/boot/dts/tesla/fsd-evb.dts      |  34 +++++
>  arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi |  65 +++++++++
>  arch/arm64/boot/dts/tesla/fsd.dtsi         | 147 +++++++++++++++++++++
>  3 files changed, 246 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/tesla/fsd-evb.dts b/arch/arm64/boot/dts/tesla/fsd-evb.dts
> index 9ff22e1c8723..1b63c5d72d19 100644
> --- a/arch/arm64/boot/dts/tesla/fsd-evb.dts
> +++ b/arch/arm64/boot/dts/tesla/fsd-evb.dts
> @@ -130,3 +130,37 @@ &serial_0 {
>  &ufs {
>  	status = "okay";
>  };
> +
> +&pcierc2 {

It'd be good to use underscore to differentiate RC and EP modes:

	pcie_rc1
	pcie_ep1

> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pcie1_clkreq>, <&pcie1_wake>, <&pcie1_preset>,
> +			<&pcie0_slot1>;

Could you please explain what these 'preset' and 'slot' pins are?

> +};
> +
> +&pcieep2 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pcie1_clkreq>, <&pcie1_wake>, <&pcie1_preset>,
> +			<&pcie0_slot1>;
> +};
> +
> +&pcierc0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pcie0_clkreq>, <&pcie0_wake0>, <&pcie0_preset0>,
> +			 <&pcie0_slot0>;
> +};
> +
> +&pcieep0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pcie0_clkreq>, <&pcie0_wake0>, <&pcie0_preset0>,
> +			 <&pcie0_slot0>;
> +};
> +
> +&pcierc1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pcie0_clkreq>, <&pcie0_wake1>, <&pcie0_preset0>;
> +};
> +
> +&pcieep1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pcie0_clkreq>, <&pcie0_wake1>, <&pcie0_preset0>;
> +};

[...]

> +		pcieep2: pcie-ep at 15400000 {
> +			compatible = "tesla,fsd-pcie-ep";
> +			reg = <0x0 0x15090000 0x0 0x1000>,
> +			      <0x0 0x15400000 0x0 0x2000>,
> +			      <0x0 0x15402000 0x0 0x80>,
> +			      <0x0 0x15800000 0x0 0xff0000>;
> +			reg-names = "elbi", "dbi", "dbi2", "addr_space";
> +			clocks = <&clock_fsys0 PCIE_SUBCTRL_INST0_AUX_CLK_SOC>,
> +				 <&clock_fsys0 PCIE_SUBCTRL_INST0_DBI_ACLK_SOC>,
> +				 <&clock_fsys0 PCIE_SUBCTRL_INST0_MSTR_ACLK_SOC>,
> +				 <&clock_fsys0 PCIE_SUBCTRL_INST0_SLV_ACLK_SOC>;
> +			clock-names = "aux", "dbi", "mstr", "slv";
> +			num-lanes = <4>;
> +			phys = <&pciephy0>;
> +			samsung,syscon-pcie = <&sysreg_fsys0 0x434>;
> +			status = "disabled";

So only host mode DMA is cache coherent and not endpoint? Weird.

- Mani

-- 
????????? ????????


From nitin.rawat at oss.qualcomm.com  Sat Aug 30 00:03:51 2025
From: nitin.rawat at oss.qualcomm.com (Nitin Rawat)
Date: Sat, 30 Aug 2025 12:33:51 +0530
Subject: [PATCH V4 0/2] Add regulator load support for QMP UFS PHY
Message-ID: <20250830070353.2694-1-nitin.rawat@oss.qualcomm.com>

The series improves regulator handling in the QMP UFS PHY driver and
adds load configuration support for all supported platforms.

On some SoCs, regulators are shared between the UFS PHY and other IP
blocks. To maintain stability and power efficiency, the regulator
framework needs to know the UFS PHY's peak load, as it determines the
regulator's operating mode.

The first update replaces devm_regulator_bulk_get() with
devm_regulator_bulk_get_const(), converts the regulator name array to
a bulk data structure, and uses the init_load_uA field to automatically
apply regulator_set_load() before the first enable.

The second update adds platform-specific load settings for all supported
platform to ensure proper power management where regulators are shared.

Changes from V3:
1. Addressed Mani and Dmitry comment to include phy and pll init_load_uA
   for all platform.

Changes from v2:
1. Addressed Dmitry's comment to replace devm_regulator_bulk_get() with
   devm_regulator_bulk_get_const.
2. inline the qmp_ufs_vreg_init() function

Changes from v1:
1. Addressed comments to move load configuration from device tree to
   hardcoded, per-compatible data within the driver.
2. Accordingly updated commit text to reflect the same.
3. Addressed Manivannan's comment to avoid initialization of load.

Nitin Rawat (2):
  phy: qcom-qmp-ufs: Add regulator load voting for UFS QMP PHY
  phy: qcom-qmp-ufs: Add PHY and PLL regulator load

 drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 159 ++++++++++++++++--------
 1 file changed, 108 insertions(+), 51 deletions(-)

--
2.50.1



From nitin.rawat at oss.qualcomm.com  Sat Aug 30 00:03:52 2025
From: nitin.rawat at oss.qualcomm.com (Nitin Rawat)
Date: Sat, 30 Aug 2025 12:33:52 +0530
Subject: [PATCH V4 1/2] phy: qcom-qmp-ufs: Add regulator load voting for UFS QMP PHY
In-Reply-To: <20250830070353.2694-1-nitin.rawat@oss.qualcomm.com>
References: <20250830070353.2694-1-nitin.rawat@oss.qualcomm.com>
Message-ID: <20250830070353.2694-2-nitin.rawat@oss.qualcomm.com>

From: Nitin Rawat <quic_nitirawa at quicinc.com>

On certain SoCs, power regulators are shared between the QMP UFS PHY
and other IP blocks. To ensure proper operation, the regulator
framework must be informed of the UFS PHY's load requirements.
This is essential because the regulator's operating mode?whether Low
Power or High Power?depends on the maximum expected load at any given
time, which the regulator driver needs to manage accordingly.

To support this, replace devm_regulator_bulk_get() with
devm_regulator_bulk_get_const() and inline the qmp_ufs_vreg_init()
function. additionally replace the array of regulator names with a
bulk regulator data structure, and utilize the init_load_uA field
provided by the regulator framework. This ensures that
regulator_set_load() is automatically invoked before the
first enable operation.

Reviewed-by: Manivannan Sadhasivam <mani at kernel.org>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>
Signed-off-by: Nitin Rawat <quic_nitirawa at quicinc.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 29 +++++++------------------
 1 file changed, 8 insertions(+), 21 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
index 9c69c77d10c8..aaa88ca0ef07 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
@@ -1107,7 +1107,7 @@ struct qmp_phy_cfg {
 	const struct qmp_phy_cfg_tbls tbls_hs_overlay[NUM_OVERLAY];

 	/* regulators to be requested */
-	const char * const *vreg_list;
+	const struct regulator_bulk_data *vreg_list;
 	int num_vregs;

 	/* array of registers with different offsets */
@@ -1164,9 +1164,10 @@ static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
 	readl(base + offset);
 }

-/* list of regulators */
-static const char * const qmp_phy_vreg_l[] = {
-	"vdda-phy", "vdda-pll",
+/* Default regulator bulk data (no load used) */
+static const struct regulator_bulk_data qmp_phy_vreg_l[] = {
+	{ .supply = "vdda-phy" },
+	{ .supply = "vdda-pll" },
 };

 static const struct qmp_ufs_offsets qmp_ufs_offsets = {
@@ -1890,22 +1891,6 @@ static const struct phy_ops qcom_qmp_ufs_phy_ops = {
 	.owner		= THIS_MODULE,
 };

-static int qmp_ufs_vreg_init(struct qmp_ufs *qmp)
-{
-	const struct qmp_phy_cfg *cfg = qmp->cfg;
-	struct device *dev = qmp->dev;
-	int num = cfg->num_vregs;
-	int i;
-
-	qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL);
-	if (!qmp->vregs)
-		return -ENOMEM;
-
-	for (i = 0; i < num; i++)
-		qmp->vregs[i].supply = cfg->vreg_list[i];
-
-	return devm_regulator_bulk_get(dev, num, qmp->vregs);
-}

 static int qmp_ufs_clk_init(struct qmp_ufs *qmp)
 {
@@ -2068,7 +2053,9 @@ static int qmp_ufs_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;

-	ret = qmp_ufs_vreg_init(qmp);
+	ret = devm_regulator_bulk_get_const(dev, qmp->cfg->num_vregs,
+					    qmp->cfg->vreg_list,
+					    &qmp->vregs);
 	if (ret)
 		return ret;

--
2.50.1



From nitin.rawat at oss.qualcomm.com  Sat Aug 30 00:03:53 2025
From: nitin.rawat at oss.qualcomm.com (Nitin Rawat)
Date: Sat, 30 Aug 2025 12:33:53 +0530
Subject: [PATCH V4 2/2] phy: qcom-qmp-ufs: Add PHY and PLL regulator load
In-Reply-To: <20250830070353.2694-1-nitin.rawat@oss.qualcomm.com>
References: <20250830070353.2694-1-nitin.rawat@oss.qualcomm.com>
Message-ID: <20250830070353.2694-3-nitin.rawat@oss.qualcomm.com>

From: Nitin Rawat <quic_nitirawa at quicinc.com>

Add phy and pll regulator load voting support for all supported
platforms by introducing dedicated regulator bulk data arrays
with their load values.

This ensures stable operation and proper power management for these
platforms where regulators are shared between the QMP UFS PHY and
other IP blocks by setting appropriate regulator load currents during
PHY operations.

Signed-off-by: Nitin Rawat <quic_nitirawa at quicinc.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 138 ++++++++++++++++++------
 1 file changed, 104 insertions(+), 34 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
index aaa88ca0ef07..8a280433a42b 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
@@ -1164,10 +1164,80 @@ static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
 	readl(base + offset);
 }

-/* Default regulator bulk data (no load used) */
-static const struct regulator_bulk_data qmp_phy_vreg_l[] = {
-	{ .supply = "vdda-phy" },
-	{ .supply = "vdda-pll" },
+/* Regulator bulk data with load values for specific configurations */
+static const struct regulator_bulk_data msm8996_ufsphy_vreg_l[] = {
+	{ .supply = "vdda-phy", .init_load_uA = 51400 },
+	{ .supply = "vdda-pll", .init_load_uA = 14600 },
+};
+
+static const struct regulator_bulk_data sa8775p_ufsphy_vreg_l[] = {
+	{ .supply = "vdda-phy", .init_load_uA = 137000 },
+	{ .supply = "vdda-pll", .init_load_uA = 18300 },
+};
+
+static const struct regulator_bulk_data sc7280_ufsphy_vreg_l[] = {
+	{ .supply = "vdda-phy", .init_load_uA = 97500 },
+	{ .supply = "vdda-pll", .init_load_uA = 18400 },
+};
+
+static const struct regulator_bulk_data sc8280xp_ufsphy_vreg_l[] = {
+	{ .supply = "vdda-phy", .init_load_uA = 85700 },
+	{ .supply = "vdda-pll", .init_load_uA = 18300 },
+};
+
+static const struct regulator_bulk_data sdm845_ufsphy_vreg_l[] = {
+	{ .supply = "vdda-phy", .init_load_uA = 51400 },
+	{ .supply = "vdda-pll", .init_load_uA = 14600 },
+};
+
+static const struct regulator_bulk_data sm6115_ufsphy_vreg_l[] = {
+	{ .supply = "vdda-phy", .init_load_uA = 51400 },
+	{ .supply = "vdda-pll", .init_load_uA = 14200 },
+};
+
+static const struct regulator_bulk_data sm7150_ufsphy_vreg_l[] = {
+	{ .supply = "vdda-phy", .init_load_uA = 62900 },
+	{ .supply = "vdda-pll", .init_load_uA = 18300 },
+};
+
+static const struct regulator_bulk_data sm8150_ufsphy_vreg_l[] = {
+	{ .supply = "vdda-phy", .init_load_uA = 90200 },
+	{ .supply = "vdda-pll", .init_load_uA = 19000 },
+};
+
+static const struct regulator_bulk_data sm8250_ufsphy_vreg_l[] = {
+	{ .supply = "vdda-phy", .init_load_uA = 89900 },
+	{ .supply = "vdda-pll", .init_load_uA = 18800 },
+};
+
+static const struct regulator_bulk_data sm8350_ufsphy_vreg_l[] = {
+	{ .supply = "vdda-phy", .init_load_uA = 91600 },
+	{ .supply = "vdda-pll", .init_load_uA = 19000 },
+};
+
+static const struct regulator_bulk_data sm8450_ufsphy_vreg_l[] = {
+	{ .supply = "vdda-phy", .init_load_uA = 173000 },
+	{ .supply = "vdda-pll", .init_load_uA = 24900 },
+};
+
+static const struct regulator_bulk_data sm8475_ufsphy_vreg_l[] = {
+	{ .supply = "vdda-phy", .init_load_uA = 213030 },
+	{ .supply = "vdda-pll", .init_load_uA = 18340 },
+};
+
+static const struct regulator_bulk_data sm8550_ufsphy_vreg_l[] = {
+	{ .supply = "vdda-phy", .init_load_uA = 188000 },
+	{ .supply = "vdda-pll", .init_load_uA = 18300 },
+};
+
+static const struct regulator_bulk_data sm8650_ufsphy_vreg_l[] = {
+	{ .supply = "vdda-phy", .init_load_uA = 205000 },
+	{ .supply = "vdda-pll", .init_load_uA = 17500 },
+};
+
+static const struct regulator_bulk_data sm8750_ufsphy_vreg_l[] = {
+	{ .supply = "vdda-phy", .init_load_uA = 213000 },
+	{ .supply = "vdda-pll", .init_load_uA = 18300 },
 };

 static const struct qmp_ufs_offsets qmp_ufs_offsets = {
@@ -1203,8 +1273,8 @@ static const struct qmp_phy_cfg msm8996_ufsphy_cfg = {
 		.rx_num		= ARRAY_SIZE(msm8996_ufsphy_rx),
 	},

-	.vreg_list		= qmp_phy_vreg_l,
-	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
+	.vreg_list		= msm8996_ufsphy_vreg_l,
+	.num_vregs		= ARRAY_SIZE(msm8996_ufsphy_vreg_l),

 	.regs			= ufsphy_v2_regs_layout,

@@ -1240,8 +1310,8 @@ static const struct qmp_phy_cfg sa8775p_ufsphy_cfg = {
 		.pcs_num	= ARRAY_SIZE(sm8350_ufsphy_g4_pcs),
 		.max_gear	= UFS_HS_G4,
 	},
-	.vreg_list		= qmp_phy_vreg_l,
-	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
+	.vreg_list		= sa8775p_ufsphy_vreg_l,
+	.num_vregs		= ARRAY_SIZE(sa8775p_ufsphy_vreg_l),
 	.regs			= ufsphy_v5_regs_layout,
 };

@@ -1274,8 +1344,8 @@ static const struct qmp_phy_cfg sc7280_ufsphy_cfg = {
 		.pcs_num        = ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs),
 		.max_gear	= UFS_HS_G4,
 	},
-	.vreg_list              = qmp_phy_vreg_l,
-	.num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
+	.vreg_list              = sc7280_ufsphy_vreg_l,
+	.num_vregs              = ARRAY_SIZE(sc7280_ufsphy_vreg_l),
 	.regs                   = ufsphy_v4_regs_layout,
 };

@@ -1308,8 +1378,8 @@ static const struct qmp_phy_cfg sc8280xp_ufsphy_cfg = {
 		.pcs_num	= ARRAY_SIZE(sm8350_ufsphy_g4_pcs),
 		.max_gear	= UFS_HS_G4,
 	},
-	.vreg_list		= qmp_phy_vreg_l,
-	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
+	.vreg_list		= sc8280xp_ufsphy_vreg_l,
+	.num_vregs		= ARRAY_SIZE(sc8280xp_ufsphy_vreg_l),
 	.regs			= ufsphy_v5_regs_layout,
 };

@@ -1333,8 +1403,8 @@ static const struct qmp_phy_cfg sdm845_ufsphy_cfg = {
 		.serdes		= sdm845_ufsphy_hs_b_serdes,
 		.serdes_num	= ARRAY_SIZE(sdm845_ufsphy_hs_b_serdes),
 	},
-	.vreg_list		= qmp_phy_vreg_l,
-	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
+	.vreg_list		= sdm845_ufsphy_vreg_l,
+	.num_vregs		= ARRAY_SIZE(sdm845_ufsphy_vreg_l),
 	.regs			= ufsphy_v3_regs_layout,

 	.no_pcs_sw_reset	= true,
@@ -1360,8 +1430,8 @@ static const struct qmp_phy_cfg sm6115_ufsphy_cfg = {
 		.serdes		= sm6115_ufsphy_hs_b_serdes,
 		.serdes_num	= ARRAY_SIZE(sm6115_ufsphy_hs_b_serdes),
 	},
-	.vreg_list		= qmp_phy_vreg_l,
-	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
+	.vreg_list		= sm6115_ufsphy_vreg_l,
+	.num_vregs		= ARRAY_SIZE(sm6115_ufsphy_vreg_l),
 	.regs			= ufsphy_v2_regs_layout,

 	.no_pcs_sw_reset	= true,
@@ -1387,8 +1457,8 @@ static const struct qmp_phy_cfg sm7150_ufsphy_cfg = {
 		.serdes		= sdm845_ufsphy_hs_b_serdes,
 		.serdes_num	= ARRAY_SIZE(sdm845_ufsphy_hs_b_serdes),
 	},
-	.vreg_list		= qmp_phy_vreg_l,
-	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
+	.vreg_list		= sm7150_ufsphy_vreg_l,
+	.num_vregs		= ARRAY_SIZE(sm7150_ufsphy_vreg_l),
 	.regs			= ufsphy_v3_regs_layout,

 	.no_pcs_sw_reset	= true,
@@ -1423,8 +1493,8 @@ static const struct qmp_phy_cfg sm8150_ufsphy_cfg = {
 		.pcs_num	= ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs),
 		.max_gear	= UFS_HS_G4,
 	},
-	.vreg_list		= qmp_phy_vreg_l,
-	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
+	.vreg_list		= sm8150_ufsphy_vreg_l,
+	.num_vregs		= ARRAY_SIZE(sm8150_ufsphy_vreg_l),
 	.regs			= ufsphy_v4_regs_layout,
 };

@@ -1457,8 +1527,8 @@ static const struct qmp_phy_cfg sm8250_ufsphy_cfg = {
 		.pcs_num	= ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs),
 		.max_gear	= UFS_HS_G4,
 	},
-	.vreg_list		= qmp_phy_vreg_l,
-	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
+	.vreg_list		= sm8250_ufsphy_vreg_l,
+	.num_vregs		= ARRAY_SIZE(sm8250_ufsphy_vreg_l),
 	.regs			= ufsphy_v4_regs_layout,
 };

@@ -1491,8 +1561,8 @@ static const struct qmp_phy_cfg sm8350_ufsphy_cfg = {
 		.pcs_num	= ARRAY_SIZE(sm8350_ufsphy_g4_pcs),
 		.max_gear	= UFS_HS_G4,
 	},
-	.vreg_list		= qmp_phy_vreg_l,
-	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
+	.vreg_list		= sm8350_ufsphy_vreg_l,
+	.num_vregs		= ARRAY_SIZE(sm8350_ufsphy_vreg_l),
 	.regs			= ufsphy_v5_regs_layout,
 };

@@ -1525,8 +1595,8 @@ static const struct qmp_phy_cfg sm8450_ufsphy_cfg = {
 		.pcs_num	= ARRAY_SIZE(sm8350_ufsphy_g4_pcs),
 		.max_gear	= UFS_HS_G4,
 	},
-	.vreg_list		= qmp_phy_vreg_l,
-	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
+	.vreg_list		= sm8450_ufsphy_vreg_l,
+	.num_vregs		= ARRAY_SIZE(sm8450_ufsphy_vreg_l),
 	.regs			= ufsphy_v5_regs_layout,
 };

@@ -1561,8 +1631,8 @@ static const struct qmp_phy_cfg sm8475_ufsphy_cfg = {
 		.pcs_num	= ARRAY_SIZE(sm8475_ufsphy_g4_pcs),
 		.max_gear	= UFS_HS_G4,
 	},
-	.vreg_list		= qmp_phy_vreg_l,
-	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
+	.vreg_list		= sm8475_ufsphy_vreg_l,
+	.num_vregs		= ARRAY_SIZE(sm8475_ufsphy_vreg_l),
 	.regs			= ufsphy_v6_regs_layout,
 };

@@ -1606,8 +1676,8 @@ static const struct qmp_phy_cfg sm8550_ufsphy_cfg = {
 		.pcs_num	= ARRAY_SIZE(sm8550_ufsphy_g5_pcs),
 		.max_gear	= UFS_HS_G5,
 	},
-	.vreg_list		= qmp_phy_vreg_l,
-	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
+	.vreg_list		= sm8550_ufsphy_vreg_l,
+	.num_vregs		= ARRAY_SIZE(sm8550_ufsphy_vreg_l),
 	.regs			= ufsphy_v6_regs_layout,
 };

@@ -1638,8 +1708,8 @@ static const struct qmp_phy_cfg sm8650_ufsphy_cfg = {
 		.max_gear	= UFS_HS_G5,
 	},

-	.vreg_list		= qmp_phy_vreg_l,
-	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
+	.vreg_list		= sm8650_ufsphy_vreg_l,
+	.num_vregs		= ARRAY_SIZE(sm8650_ufsphy_vreg_l),
 	.regs			= ufsphy_v6_regs_layout,
 };

@@ -1676,8 +1746,8 @@ static const struct qmp_phy_cfg sm8750_ufsphy_cfg = {
 		.max_gear	= UFS_HS_G5,
 	},

-	.vreg_list		= qmp_phy_vreg_l,
-	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
+	.vreg_list		= sm8750_ufsphy_vreg_l,
+	.num_vregs		= ARRAY_SIZE(sm8750_ufsphy_vreg_l),
 	.regs			= ufsphy_v6_regs_layout,

 };
--
2.50.1



From mani at kernel.org  Sat Aug 30 00:07:00 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Sat, 30 Aug 2025 12:37:00 +0530
Subject: [PATCH V4 2/2] phy: qcom-qmp-ufs: Add PHY and PLL regulator load
In-Reply-To: <20250830070353.2694-3-nitin.rawat@oss.qualcomm.com>
References: <20250830070353.2694-1-nitin.rawat@oss.qualcomm.com>
 <20250830070353.2694-3-nitin.rawat@oss.qualcomm.com>
Message-ID: <vmm6y7wcrm3l5ypz5bzpehzz37vkiyz2mnsainyaonokna2xmz@63opfucrawtv>

On Sat, Aug 30, 2025 at 12:33:53PM GMT, Nitin Rawat wrote:
> From: Nitin Rawat <quic_nitirawa at quicinc.com>
> 
> Add phy and pll regulator load voting support for all supported
> platforms by introducing dedicated regulator bulk data arrays
> with their load values.
> 
> This ensures stable operation and proper power management for these
> platforms where regulators are shared between the QMP UFS PHY and
> other IP blocks by setting appropriate regulator load currents during
> PHY operations.
> 
> Signed-off-by: Nitin Rawat <quic_nitirawa at quicinc.com>

I haven't cross checked the load values with downstream, but trusting that
you've done your job. So,

Acked-by: Manivannan Sadhasivam <mani at kernel.org>

- Mani

> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 138 ++++++++++++++++++------
>  1 file changed, 104 insertions(+), 34 deletions(-)
> 
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> index aaa88ca0ef07..8a280433a42b 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> @@ -1164,10 +1164,80 @@ static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
>  	readl(base + offset);
>  }
> 
> -/* Default regulator bulk data (no load used) */
> -static const struct regulator_bulk_data qmp_phy_vreg_l[] = {
> -	{ .supply = "vdda-phy" },
> -	{ .supply = "vdda-pll" },
> +/* Regulator bulk data with load values for specific configurations */
> +static const struct regulator_bulk_data msm8996_ufsphy_vreg_l[] = {
> +	{ .supply = "vdda-phy", .init_load_uA = 51400 },
> +	{ .supply = "vdda-pll", .init_load_uA = 14600 },
> +};
> +
> +static const struct regulator_bulk_data sa8775p_ufsphy_vreg_l[] = {
> +	{ .supply = "vdda-phy", .init_load_uA = 137000 },
> +	{ .supply = "vdda-pll", .init_load_uA = 18300 },
> +};
> +
> +static const struct regulator_bulk_data sc7280_ufsphy_vreg_l[] = {
> +	{ .supply = "vdda-phy", .init_load_uA = 97500 },
> +	{ .supply = "vdda-pll", .init_load_uA = 18400 },
> +};
> +
> +static const struct regulator_bulk_data sc8280xp_ufsphy_vreg_l[] = {
> +	{ .supply = "vdda-phy", .init_load_uA = 85700 },
> +	{ .supply = "vdda-pll", .init_load_uA = 18300 },
> +};
> +
> +static const struct regulator_bulk_data sdm845_ufsphy_vreg_l[] = {
> +	{ .supply = "vdda-phy", .init_load_uA = 51400 },
> +	{ .supply = "vdda-pll", .init_load_uA = 14600 },
> +};
> +
> +static const struct regulator_bulk_data sm6115_ufsphy_vreg_l[] = {
> +	{ .supply = "vdda-phy", .init_load_uA = 51400 },
> +	{ .supply = "vdda-pll", .init_load_uA = 14200 },
> +};
> +
> +static const struct regulator_bulk_data sm7150_ufsphy_vreg_l[] = {
> +	{ .supply = "vdda-phy", .init_load_uA = 62900 },
> +	{ .supply = "vdda-pll", .init_load_uA = 18300 },
> +};
> +
> +static const struct regulator_bulk_data sm8150_ufsphy_vreg_l[] = {
> +	{ .supply = "vdda-phy", .init_load_uA = 90200 },
> +	{ .supply = "vdda-pll", .init_load_uA = 19000 },
> +};
> +
> +static const struct regulator_bulk_data sm8250_ufsphy_vreg_l[] = {
> +	{ .supply = "vdda-phy", .init_load_uA = 89900 },
> +	{ .supply = "vdda-pll", .init_load_uA = 18800 },
> +};
> +
> +static const struct regulator_bulk_data sm8350_ufsphy_vreg_l[] = {
> +	{ .supply = "vdda-phy", .init_load_uA = 91600 },
> +	{ .supply = "vdda-pll", .init_load_uA = 19000 },
> +};
> +
> +static const struct regulator_bulk_data sm8450_ufsphy_vreg_l[] = {
> +	{ .supply = "vdda-phy", .init_load_uA = 173000 },
> +	{ .supply = "vdda-pll", .init_load_uA = 24900 },
> +};
> +
> +static const struct regulator_bulk_data sm8475_ufsphy_vreg_l[] = {
> +	{ .supply = "vdda-phy", .init_load_uA = 213030 },
> +	{ .supply = "vdda-pll", .init_load_uA = 18340 },
> +};
> +
> +static const struct regulator_bulk_data sm8550_ufsphy_vreg_l[] = {
> +	{ .supply = "vdda-phy", .init_load_uA = 188000 },
> +	{ .supply = "vdda-pll", .init_load_uA = 18300 },
> +};
> +
> +static const struct regulator_bulk_data sm8650_ufsphy_vreg_l[] = {
> +	{ .supply = "vdda-phy", .init_load_uA = 205000 },
> +	{ .supply = "vdda-pll", .init_load_uA = 17500 },
> +};
> +
> +static const struct regulator_bulk_data sm8750_ufsphy_vreg_l[] = {
> +	{ .supply = "vdda-phy", .init_load_uA = 213000 },
> +	{ .supply = "vdda-pll", .init_load_uA = 18300 },
>  };
> 
>  static const struct qmp_ufs_offsets qmp_ufs_offsets = {
> @@ -1203,8 +1273,8 @@ static const struct qmp_phy_cfg msm8996_ufsphy_cfg = {
>  		.rx_num		= ARRAY_SIZE(msm8996_ufsphy_rx),
>  	},
> 
> -	.vreg_list		= qmp_phy_vreg_l,
> -	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
> +	.vreg_list		= msm8996_ufsphy_vreg_l,
> +	.num_vregs		= ARRAY_SIZE(msm8996_ufsphy_vreg_l),
> 
>  	.regs			= ufsphy_v2_regs_layout,
> 
> @@ -1240,8 +1310,8 @@ static const struct qmp_phy_cfg sa8775p_ufsphy_cfg = {
>  		.pcs_num	= ARRAY_SIZE(sm8350_ufsphy_g4_pcs),
>  		.max_gear	= UFS_HS_G4,
>  	},
> -	.vreg_list		= qmp_phy_vreg_l,
> -	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
> +	.vreg_list		= sa8775p_ufsphy_vreg_l,
> +	.num_vregs		= ARRAY_SIZE(sa8775p_ufsphy_vreg_l),
>  	.regs			= ufsphy_v5_regs_layout,
>  };
> 
> @@ -1274,8 +1344,8 @@ static const struct qmp_phy_cfg sc7280_ufsphy_cfg = {
>  		.pcs_num        = ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs),
>  		.max_gear	= UFS_HS_G4,
>  	},
> -	.vreg_list              = qmp_phy_vreg_l,
> -	.num_vregs              = ARRAY_SIZE(qmp_phy_vreg_l),
> +	.vreg_list              = sc7280_ufsphy_vreg_l,
> +	.num_vregs              = ARRAY_SIZE(sc7280_ufsphy_vreg_l),
>  	.regs                   = ufsphy_v4_regs_layout,
>  };
> 
> @@ -1308,8 +1378,8 @@ static const struct qmp_phy_cfg sc8280xp_ufsphy_cfg = {
>  		.pcs_num	= ARRAY_SIZE(sm8350_ufsphy_g4_pcs),
>  		.max_gear	= UFS_HS_G4,
>  	},
> -	.vreg_list		= qmp_phy_vreg_l,
> -	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
> +	.vreg_list		= sc8280xp_ufsphy_vreg_l,
> +	.num_vregs		= ARRAY_SIZE(sc8280xp_ufsphy_vreg_l),
>  	.regs			= ufsphy_v5_regs_layout,
>  };
> 
> @@ -1333,8 +1403,8 @@ static const struct qmp_phy_cfg sdm845_ufsphy_cfg = {
>  		.serdes		= sdm845_ufsphy_hs_b_serdes,
>  		.serdes_num	= ARRAY_SIZE(sdm845_ufsphy_hs_b_serdes),
>  	},
> -	.vreg_list		= qmp_phy_vreg_l,
> -	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
> +	.vreg_list		= sdm845_ufsphy_vreg_l,
> +	.num_vregs		= ARRAY_SIZE(sdm845_ufsphy_vreg_l),
>  	.regs			= ufsphy_v3_regs_layout,
> 
>  	.no_pcs_sw_reset	= true,
> @@ -1360,8 +1430,8 @@ static const struct qmp_phy_cfg sm6115_ufsphy_cfg = {
>  		.serdes		= sm6115_ufsphy_hs_b_serdes,
>  		.serdes_num	= ARRAY_SIZE(sm6115_ufsphy_hs_b_serdes),
>  	},
> -	.vreg_list		= qmp_phy_vreg_l,
> -	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
> +	.vreg_list		= sm6115_ufsphy_vreg_l,
> +	.num_vregs		= ARRAY_SIZE(sm6115_ufsphy_vreg_l),
>  	.regs			= ufsphy_v2_regs_layout,
> 
>  	.no_pcs_sw_reset	= true,
> @@ -1387,8 +1457,8 @@ static const struct qmp_phy_cfg sm7150_ufsphy_cfg = {
>  		.serdes		= sdm845_ufsphy_hs_b_serdes,
>  		.serdes_num	= ARRAY_SIZE(sdm845_ufsphy_hs_b_serdes),
>  	},
> -	.vreg_list		= qmp_phy_vreg_l,
> -	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
> +	.vreg_list		= sm7150_ufsphy_vreg_l,
> +	.num_vregs		= ARRAY_SIZE(sm7150_ufsphy_vreg_l),
>  	.regs			= ufsphy_v3_regs_layout,
> 
>  	.no_pcs_sw_reset	= true,
> @@ -1423,8 +1493,8 @@ static const struct qmp_phy_cfg sm8150_ufsphy_cfg = {
>  		.pcs_num	= ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs),
>  		.max_gear	= UFS_HS_G4,
>  	},
> -	.vreg_list		= qmp_phy_vreg_l,
> -	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
> +	.vreg_list		= sm8150_ufsphy_vreg_l,
> +	.num_vregs		= ARRAY_SIZE(sm8150_ufsphy_vreg_l),
>  	.regs			= ufsphy_v4_regs_layout,
>  };
> 
> @@ -1457,8 +1527,8 @@ static const struct qmp_phy_cfg sm8250_ufsphy_cfg = {
>  		.pcs_num	= ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs),
>  		.max_gear	= UFS_HS_G4,
>  	},
> -	.vreg_list		= qmp_phy_vreg_l,
> -	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
> +	.vreg_list		= sm8250_ufsphy_vreg_l,
> +	.num_vregs		= ARRAY_SIZE(sm8250_ufsphy_vreg_l),
>  	.regs			= ufsphy_v4_regs_layout,
>  };
> 
> @@ -1491,8 +1561,8 @@ static const struct qmp_phy_cfg sm8350_ufsphy_cfg = {
>  		.pcs_num	= ARRAY_SIZE(sm8350_ufsphy_g4_pcs),
>  		.max_gear	= UFS_HS_G4,
>  	},
> -	.vreg_list		= qmp_phy_vreg_l,
> -	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
> +	.vreg_list		= sm8350_ufsphy_vreg_l,
> +	.num_vregs		= ARRAY_SIZE(sm8350_ufsphy_vreg_l),
>  	.regs			= ufsphy_v5_regs_layout,
>  };
> 
> @@ -1525,8 +1595,8 @@ static const struct qmp_phy_cfg sm8450_ufsphy_cfg = {
>  		.pcs_num	= ARRAY_SIZE(sm8350_ufsphy_g4_pcs),
>  		.max_gear	= UFS_HS_G4,
>  	},
> -	.vreg_list		= qmp_phy_vreg_l,
> -	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
> +	.vreg_list		= sm8450_ufsphy_vreg_l,
> +	.num_vregs		= ARRAY_SIZE(sm8450_ufsphy_vreg_l),
>  	.regs			= ufsphy_v5_regs_layout,
>  };
> 
> @@ -1561,8 +1631,8 @@ static const struct qmp_phy_cfg sm8475_ufsphy_cfg = {
>  		.pcs_num	= ARRAY_SIZE(sm8475_ufsphy_g4_pcs),
>  		.max_gear	= UFS_HS_G4,
>  	},
> -	.vreg_list		= qmp_phy_vreg_l,
> -	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
> +	.vreg_list		= sm8475_ufsphy_vreg_l,
> +	.num_vregs		= ARRAY_SIZE(sm8475_ufsphy_vreg_l),
>  	.regs			= ufsphy_v6_regs_layout,
>  };
> 
> @@ -1606,8 +1676,8 @@ static const struct qmp_phy_cfg sm8550_ufsphy_cfg = {
>  		.pcs_num	= ARRAY_SIZE(sm8550_ufsphy_g5_pcs),
>  		.max_gear	= UFS_HS_G5,
>  	},
> -	.vreg_list		= qmp_phy_vreg_l,
> -	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
> +	.vreg_list		= sm8550_ufsphy_vreg_l,
> +	.num_vregs		= ARRAY_SIZE(sm8550_ufsphy_vreg_l),
>  	.regs			= ufsphy_v6_regs_layout,
>  };
> 
> @@ -1638,8 +1708,8 @@ static const struct qmp_phy_cfg sm8650_ufsphy_cfg = {
>  		.max_gear	= UFS_HS_G5,
>  	},
> 
> -	.vreg_list		= qmp_phy_vreg_l,
> -	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
> +	.vreg_list		= sm8650_ufsphy_vreg_l,
> +	.num_vregs		= ARRAY_SIZE(sm8650_ufsphy_vreg_l),
>  	.regs			= ufsphy_v6_regs_layout,
>  };
> 
> @@ -1676,8 +1746,8 @@ static const struct qmp_phy_cfg sm8750_ufsphy_cfg = {
>  		.max_gear	= UFS_HS_G5,
>  	},
> 
> -	.vreg_list		= qmp_phy_vreg_l,
> -	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
> +	.vreg_list		= sm8750_ufsphy_vreg_l,
> +	.num_vregs		= ARRAY_SIZE(sm8750_ufsphy_vreg_l),
>  	.regs			= ufsphy_v6_regs_layout,
> 
>  };
> --
> 2.50.1
> 

-- 
????????? ????????


From claudiu.beznea at tuxon.dev  Sat Aug 30 05:39:36 2025
From: claudiu.beznea at tuxon.dev (Claudiu Beznea)
Date: Sat, 30 Aug 2025 15:39:36 +0300
Subject: [PATCH v5 4/7] reset: rzg2l-usbphy-ctrl: Add support for USB
 PWRRDY
In-Reply-To: <20250819054212.486426-5-claudiu.beznea.uj@bp.renesas.com>
References: <20250819054212.486426-1-claudiu.beznea.uj@bp.renesas.com>
 <20250819054212.486426-5-claudiu.beznea.uj@bp.renesas.com>
Message-ID: <99d7dddb-d240-4906-9c53-0f487084cff5@tuxon.dev>

Hi,

Just a gentle ping for this patch and the series in general.

(For whatever reason the cover letter didn't land in my inbox so I replied
to this patch. Appologies for any inconvenience).

Thank you,
Claudiu

On 19.08.2025 08:42, Claudiu wrote:
> From: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
> 
> On the Renesas RZ/G3S SoC, the USB PHY block has an input signal called
> PWRRDY. This signal is managed by the system controller and must be
> de-asserted after powering on the area where USB PHY resides and asserted
> before powering it off.
> 
> On power-on the USB PWRRDY signal need to be de-asserted before enabling
> clock and switching the module to normal state (through MSTOP support). The
> power-on configuration sequence must be:
> 
> 1/ PWRRDY=0
> 2/ CLK_ON=1
> 3/ MSTOP=0
> 
> On power-off the configuration sequence should be:
> 
> 1/ MSTOP=1
> 2/ CLK_ON=0
> 3/ PWRRDY=1
> 
> The CLK_ON and MSTOP functionalities are controlled by clock drivers.
> 
> After long discussions with the internal HW team, it has been confirmed
> that the HW connection b/w USB PHY block, the USB channels, the system
> controller, clock, MSTOP, PWRRDY signal is as follows:
> 
>                                ????????????????????????????????
>                                ?                              ???? CPG_CLKON_USB.CLK0_ON
>                                ?     USB CH0                  ?
> ????????????????????????????   ?????????????????????????????? ???? CPG_CLKON_USB.CLK2_ON
> ?                 ??????????   ??host controller registers  ? ?
> ?                 ?        ?   ??function controller registers?
> ?                 ? PHY0   ?????????????????????????????????? ?
> ?     USB PHY     ?        ?   ????????????????????????????????
> ?                 ??????????                ?
> ?                          ?    CPG_BUS_PERI_COM_MSTOP.MSTOP{6, 5}_ON
> ????????????????? ??????????
> ??USHPHY control? ?        ?
> ??  registers   ? ? PHY1   ?   ????????????????????????????????
> ????????????????? ?        ?????     USB CH1                  ?
> ?                 ??????????   ?????????????????????????????? ???? CPG_CLKON_USB.CLK1_ON
> ????????????????????????????   ?? host controller registers ? ?
>   ?       ?         ?          ?????????????????????????????? ?
>   ?       ?         ?          ????????????????????????????????
>   ?       ?         ?                       ?
>   ?       ?         ?           CPG_BUS_PERI_COM_MSTOP.MSTOP7_ON
>   ?PWRRDY ?         ?
>   ?       ?   CPG_CLK_ON_USB.CLK3_ON
>   ?       ?
>   ?  CPG_BUS_PERI_COM_MSTOP.MSTOP4_ON
>   ?
> ??????
> ?SYSC?
> ??????
> 
> where:
> - CPG_CLKON_USB.CLK.CLKX_ON is the register bit controlling the clock X
>   of different USB blocks, X in {0, 1, 2, 3}
> - CPG_BUS_PERI_COM_MSTOP.MSTOPX_ON is the register bit controlling the
>   MSTOP of different USB blocks, X in {4, 5, 6, 7}
> - USB PHY is the USB PHY block exposing 2 ports, port0 and port1, used
>   by the USB CH0, USB CH1
> - SYSC is the system controller block controlling the PWRRDY signal
> - USB CHx are individual USB block with host and function capabilities
>   (USB CH0 have both host and function capabilities, USB CH1 has only
>   host capabilities)
> 
> The USBPHY control registers are controlled though the
> reset-rzg2l-usbphy-ctrl driver. The USB PHY ports are controlled by
> phy_rcar_gen3_usb2 (drivers/phy/renesas/phy-rcar-gen3-usb2.c file). The
> USB PHY ports request resets from the reset-rzg2l-usbphy-ctrl driver.
> 
> The connection b/w the system controller and the USB PHY CTRL driver is
> implemented through the renesas,sysc-pwrrdy device tree property
> proposed in this patch. This property specifies the register offset and the
> bitmask required to control the PWRRDY signal.
> 
> Since the USB PHY CTRL driver needs to be probed before any other
> USB-specific driver on RZ/G3S, control of PWRRDY is passed exclusively
> to it. This guarantees the correct configuration sequence between clocks,
> MSTOP bits, and the PWRRDY bit. At the same time, changes are kept minimal
> by avoiding modifications to the USB PHY driver to also handle the PWRRDY
> itself.
> 
> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj at bp.renesas.com>
> ---
> 
> Changes in v5:
> - none
> 
> Changes in v4:
> - updated patch description
> - updated rzg2l_usbphy_ctrl_pwrrdy_init() to map directly the
>   "renesas,sysc-pwrrdy" as the SYSC signal abstraction was dropped
>   in this version, along with rz_sysc_get_signal_map()
> - dropped priv member of rzg2l_usbphy_ctrl_pwrrdy_init() as it is
>   not needed in this version
> - shift left !power_on with pwrrdy->mask as this is how the
>   regmap_update_bits() needs the last member to be
> - selected MFD_SYSCON
> 
> Changes in v3:
> - none; this patch is new
> 
>  drivers/reset/Kconfig                   |  1 +
>  drivers/reset/reset-rzg2l-usbphy-ctrl.c | 66 +++++++++++++++++++++++++
>  2 files changed, 67 insertions(+)
> 
> diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
> index 78b7078478d4..329730cbcfb9 100644
> --- a/drivers/reset/Kconfig
> +++ b/drivers/reset/Kconfig
> @@ -237,6 +237,7 @@ config RESET_RASPBERRYPI
>  config RESET_RZG2L_USBPHY_CTRL
>  	tristate "Renesas RZ/G2L USBPHY control driver"
>  	depends on ARCH_RZG2L || COMPILE_TEST
> +	select MFD_SYSCON
>  	help
>  	  Support for USBPHY Control found on RZ/G2L family. It mainly
>  	  controls reset and power down of the USB/PHY.
> diff --git a/drivers/reset/reset-rzg2l-usbphy-ctrl.c b/drivers/reset/reset-rzg2l-usbphy-ctrl.c
> index 8a7f167e405e..3856072b23a3 100644
> --- a/drivers/reset/reset-rzg2l-usbphy-ctrl.c
> +++ b/drivers/reset/reset-rzg2l-usbphy-ctrl.c
> @@ -13,6 +13,7 @@
>  #include <linux/regmap.h>
>  #include <linux/reset.h>
>  #include <linux/reset-controller.h>
> +#include <linux/mfd/syscon.h>
>  
>  #define RESET			0x000
>  #define VBENCTL			0x03c
> @@ -41,6 +42,18 @@ struct rzg2l_usbphy_ctrl_priv {
>  
>  #define rcdev_to_priv(x)	container_of(x, struct rzg2l_usbphy_ctrl_priv, rcdev)
>  
> +/**
> + * struct rzg2l_usbphy_ctrl_pwrrdy - SYSC PWRRDY signal descriptor
> + * @regmap: SYSC regmap
> + * @offset: offset into the SYSC address space for accessing PWRRDY
> + * @mask: mask into the register at offset for accessing PWRRDY
> + */
> +struct rzg2l_usbphy_ctrl_pwrrdy {
> +	struct regmap *regmap;
> +	u32 offset;
> +	u32 mask;
> +};
> +
>  static int rzg2l_usbphy_ctrl_assert(struct reset_controller_dev *rcdev,
>  				    unsigned long id)
>  {
> @@ -91,6 +104,8 @@ static int rzg2l_usbphy_ctrl_status(struct reset_controller_dev *rcdev,
>  	return !!(readl(priv->base + RESET) & port_mask);
>  }
>  
> +#define RZG2L_USBPHY_CTRL_PWRRDY	1
> +
>  static const struct of_device_id rzg2l_usbphy_ctrl_match_table[] = {
>  	{ .compatible = "renesas,rzg2l-usbphy-ctrl" },
>  	{ /* Sentinel */ }
> @@ -110,6 +125,53 @@ static const struct regmap_config rzg2l_usb_regconf = {
>  	.max_register = 1,
>  };
>  
> +static void rzg2l_usbphy_ctrl_set_pwrrdy(struct rzg2l_usbphy_ctrl_pwrrdy *pwrrdy,
> +					 bool power_on)
> +{
> +	regmap_update_bits(pwrrdy->regmap, pwrrdy->offset, pwrrdy->mask,
> +			   !power_on << pwrrdy->mask);
> +}
> +
> +static void rzg2l_usbphy_ctrl_pwrrdy_off(void *data)
> +{
> +	rzg2l_usbphy_ctrl_set_pwrrdy(data, false);
> +}
> +
> +static int rzg2l_usbphy_ctrl_pwrrdy_init(struct device *dev)
> +{
> +	struct rzg2l_usbphy_ctrl_pwrrdy *pwrrdy;
> +	struct of_phandle_args args;
> +	struct regmap *regmap;
> +	const int *data;
> +	int ret;
> +
> +	data = device_get_match_data(dev);
> +	if (data != (int *)RZG2L_USBPHY_CTRL_PWRRDY)
> +		return 0;
> +
> +	ret = of_parse_phandle_with_fixed_args(dev->of_node, "renesas,sysc-pwrrdy", 2,
> +					       0, &args);
> +	if (ret)
> +		return ret;
> +
> +	regmap = syscon_node_to_regmap(args.np);
> +	of_node_put(args.np);
> +	if (IS_ERR(regmap))
> +		return PTR_ERR(regmap);
> +
> +	pwrrdy = devm_kzalloc(dev, sizeof(*pwrrdy), GFP_KERNEL);
> +	if (!pwrrdy)
> +		return -ENOMEM;
> +
> +	pwrrdy->regmap = regmap;
> +	pwrrdy->offset = args.args[0];
> +	pwrrdy->mask = args.args[1];
> +
> +	rzg2l_usbphy_ctrl_set_pwrrdy(pwrrdy, true);
> +
> +	return devm_add_action_or_reset(dev, rzg2l_usbphy_ctrl_pwrrdy_off, pwrrdy);
> +}
> +
>  static int rzg2l_usbphy_ctrl_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> @@ -132,6 +194,10 @@ static int rzg2l_usbphy_ctrl_probe(struct platform_device *pdev)
>  	if (IS_ERR(regmap))
>  		return PTR_ERR(regmap);
>  
> +	error = rzg2l_usbphy_ctrl_pwrrdy_init(dev);
> +	if (error)
> +		return error;
> +
>  	priv->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
>  	if (IS_ERR(priv->rstc))
>  		return dev_err_probe(dev, PTR_ERR(priv->rstc),



From peng.fan at nxp.com  Sun Aug 31 20:18:10 2025
From: peng.fan at nxp.com (Peng Fan)
Date: Mon, 01 Sep 2025 11:18:10 +0800
Subject: [PATCH v4 0/6] phy: phy-can-transceiver: Support TJA1048/TJA1051
Message-ID: <20250901-can-v4-0-e42b5fe2cf9e@nxp.com>

TJA1048 is a Dual channel can transceiver with Sleep mode supported.
TJA1051 is a Single Channel can transceiver with Sleep mode supported.

To support them:
patch 1: add binding doc
patch 2/3: To support dual channel,
   - Introduce new flag CAN_TRANSCEIVER_DUAL_CH to indicate the phy
     has two channels.
   - Introduce can_transceiver_priv as a higher level encapsulation for
     phy, mux_state, num_ch.
   - Alloc a phy for each channel
patch 4,5,6: Update dts to use phys

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
Changes in v4:
- Add R-b from Frank for patch 1, 2, 3, 6
- Address the minor comments from Frank regarding min/maxItems, commit
  log
- Link to v3: https://lore.kernel.org/r/20250829-can-v3-0-3b2f34094f59 at nxp.com

Changes in v3:
- Patch 1: Add TJA1057, update #phy-cells
- Patch 2,3: Separate patch 2 into two patches per Frank, 1st introduce
  can_transceiver_priv, 2nd support dual chan by adding num_ch
- Patch 6: Change to 5Mbps rate
- Patch 4,5: Add R-b from Frank
- Link to v2: https://lore.kernel.org/r/20250825-can-v2-0-c461e9fcbc14 at nxp.com

Changes in v2:
- Update standby-gpios constraints per Conor's comments
- Drop patch 2 which is not needed.
- Link to v1: https://lore.kernel.org/r/20250822-can-v1-0-c075f702adea at nxp.com

---
Peng Fan (6):
      dt-bindings: phy: ti,tcan104x-can: Document NXP TJA105X/1048
      phy: phy-can-transceiver: Introduce can_transceiver_priv
      phy: phy-can-transceiver: Add dual channel support for TJA1048
      arm64: dts: imx95-15x15-evk: Use phys to replace xceiver-supply
      arm64: dts: imx8mp-evk: Use phys to replace xceiver-supply
      arm64: dts: imx93-11x11-evk: Use phys to replace xceiver-supply

 .../devicetree/bindings/phy/ti,tcan104x-can.yaml   |  30 +++++-
 arch/arm64/boot/dts/freescale/imx8mp-evk.dts       |  43 +++-----
 arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts  |  17 ++-
 arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts  |  13 ++-
 drivers/phy/phy-can-transceiver.c                  | 120 +++++++++++++++------
 5 files changed, 141 insertions(+), 82 deletions(-)
---
base-commit: 6aea185bfe693f3b373488217c198d2c3daed6eb
change-id: 20250821-can-c832cb4f0323

Best regards,
-- 
Peng Fan <peng.fan at nxp.com>



From peng.fan at nxp.com  Sun Aug 31 20:18:11 2025
From: peng.fan at nxp.com (Peng Fan)
Date: Mon, 01 Sep 2025 11:18:11 +0800
Subject: [PATCH v4 1/6] dt-bindings: phy: ti,tcan104x-can: Document NXP
 TJA105X/1048
In-Reply-To: <20250901-can-v4-0-e42b5fe2cf9e@nxp.com>
References: <20250901-can-v4-0-e42b5fe2cf9e@nxp.com>
Message-ID: <20250901-can-v4-1-e42b5fe2cf9e@nxp.com>

The TJA105[1,7] is a high-speed CAN transceiver which is a pin-compatible
alternative for TI TCAN1043 with sleep mode supported, and has a compatible
programming model, therefore use ti,tcan1043 as fallback compatible.

The TJA1048 is a dual high-speed CAN transceiver with sleep mode supported.

Reviewed-by: Frank Li <Frank.Li at nxp.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 .../devicetree/bindings/phy/ti,tcan104x-can.yaml   | 30 ++++++++++++++++++++--
 1 file changed, 28 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml b/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
index 4a8c3829d85d3c4a4963750d03567c1c345beb91..f8e0c24856a2ba83b5c988b246464f47e11a032f 100644
--- a/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
+++ b/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
@@ -19,18 +19,25 @@ properties:
           - enum:
               - microchip,ata6561
           - const: ti,tcan1042
+      - items:
+          - enum:
+              - nxp,tja1051
+              - nxp,tja1057
+          - const: ti,tcan1043
       - enum:
           - ti,tcan1042
           - ti,tcan1043
+          - nxp,tja1048
           - nxp,tjr1443
 
   '#phy-cells':
-    const: 0
+    enum: [0, 1]
 
   standby-gpios:
     description:
       gpio node to toggle standby signal on transceiver
-    maxItems: 1
+    minItems: 1
+    maxItems: 2
 
   enable-gpios:
     description:
@@ -53,6 +60,25 @@ required:
   - compatible
   - '#phy-cells'
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: nxp,tja1048
+    then:
+      properties:
+        '#phy-cells':
+          const: 1
+        standby-gpios:
+          minItems: 2
+    else:
+      properties:
+        '#phy-cells':
+          const: 0
+        standby-gpios:
+          maxItems: 1
+
 additionalProperties: false
 
 examples:

-- 
2.37.1



From peng.fan at nxp.com  Sun Aug 31 20:18:12 2025
From: peng.fan at nxp.com (Peng Fan)
Date: Mon, 01 Sep 2025 11:18:12 +0800
Subject: [PATCH v4 2/6] phy: phy-can-transceiver: Introduce
 can_transceiver_priv
In-Reply-To: <20250901-can-v4-0-e42b5fe2cf9e@nxp.com>
References: <20250901-can-v4-0-e42b5fe2cf9e@nxp.com>
Message-ID: <20250901-can-v4-2-e42b5fe2cf9e@nxp.com>

To prepare for dual-channel phy support, introduce can_transceiver_priv as
a higher level encapsulation for phy and mux_state.

No functional changes.

Reviewed-by: Frank Li <Frank.Li at nxp.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/phy/phy-can-transceiver.c | 41 ++++++++++++++++++++++++++-------------
 1 file changed, 27 insertions(+), 14 deletions(-)

diff --git a/drivers/phy/phy-can-transceiver.c b/drivers/phy/phy-can-transceiver.c
index f59caff4b3d4c267feca4220bf1547b6fad08f95..6415c6af0e8414a6cc8d15958a17ee749a3f28e9 100644
--- a/drivers/phy/phy-can-transceiver.c
+++ b/drivers/phy/phy-can-transceiver.c
@@ -23,6 +23,11 @@ struct can_transceiver_phy {
 	struct phy *generic_phy;
 	struct gpio_desc *standby_gpio;
 	struct gpio_desc *enable_gpio;
+	struct can_transceiver_priv *priv;
+};
+
+struct can_transceiver_priv {
+	struct can_transceiver_phy *can_transceiver_phy;
 	struct mux_state *mux_state;
 };
 
@@ -32,8 +37,8 @@ static int can_transceiver_phy_power_on(struct phy *phy)
 	struct can_transceiver_phy *can_transceiver_phy = phy_get_drvdata(phy);
 	int ret;
 
-	if (can_transceiver_phy->mux_state) {
-		ret = mux_state_select(can_transceiver_phy->mux_state);
+	if (can_transceiver_phy->priv->mux_state) {
+		ret = mux_state_select(can_transceiver_phy->priv->mux_state);
 		if (ret) {
 			dev_err(&phy->dev, "Failed to select CAN mux: %d\n", ret);
 			return ret;
@@ -56,8 +61,8 @@ static int can_transceiver_phy_power_off(struct phy *phy)
 		gpiod_set_value_cansleep(can_transceiver_phy->standby_gpio, 1);
 	if (can_transceiver_phy->enable_gpio)
 		gpiod_set_value_cansleep(can_transceiver_phy->enable_gpio, 0);
-	if (can_transceiver_phy->mux_state)
-		mux_state_deselect(can_transceiver_phy->mux_state);
+	if (can_transceiver_phy->priv->mux_state)
+		mux_state_deselect(can_transceiver_phy->priv->mux_state);
 
 	return 0;
 }
@@ -107,7 +112,7 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
 {
 	struct phy_provider *phy_provider;
 	struct device *dev = &pdev->dev;
-	struct can_transceiver_phy *can_transceiver_phy;
+	struct can_transceiver_priv *priv;
 	const struct can_transceiver_data *drvdata;
 	const struct of_device_id *match;
 	struct phy *phy;
@@ -117,18 +122,25 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
 	u32 max_bitrate = 0;
 	int err;
 
-	can_transceiver_phy = devm_kzalloc(dev, sizeof(struct can_transceiver_phy), GFP_KERNEL);
-	if (!can_transceiver_phy)
-		return -ENOMEM;
-
 	match = of_match_node(can_transceiver_phy_ids, pdev->dev.of_node);
 	drvdata = match->data;
 
+	priv = devm_kzalloc(dev, sizeof(struct can_transceiver_priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, priv);
+
+	priv->can_transceiver_phy = devm_kzalloc(dev, sizeof(struct can_transceiver_phy),
+						 GFP_KERNEL);
+	if (!priv->can_transceiver_phy)
+		return -ENOMEM;
+
 	mux_state = devm_mux_state_get_optional(dev, NULL);
 	if (IS_ERR(mux_state))
 		return PTR_ERR(mux_state);
 
-	can_transceiver_phy->mux_state = mux_state;
+	priv->mux_state = mux_state;
 
 	phy = devm_phy_create(dev, dev->of_node,
 			      &can_transceiver_phy_ops);
@@ -142,23 +154,24 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
 		dev_warn(dev, "Invalid value for transceiver max bitrate. Ignoring bitrate limit\n");
 	phy->attrs.max_link_rate = max_bitrate;
 
-	can_transceiver_phy->generic_phy = phy;
+	priv->can_transceiver_phy->generic_phy = phy;
+	priv->can_transceiver_phy->priv = priv;
 
 	if (drvdata->flags & CAN_TRANSCEIVER_STB_PRESENT) {
 		standby_gpio = devm_gpiod_get_optional(dev, "standby", GPIOD_OUT_HIGH);
 		if (IS_ERR(standby_gpio))
 			return PTR_ERR(standby_gpio);
-		can_transceiver_phy->standby_gpio = standby_gpio;
+		priv->can_transceiver_phy->standby_gpio = standby_gpio;
 	}
 
 	if (drvdata->flags & CAN_TRANSCEIVER_EN_PRESENT) {
 		enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW);
 		if (IS_ERR(enable_gpio))
 			return PTR_ERR(enable_gpio);
-		can_transceiver_phy->enable_gpio = enable_gpio;
+		priv->can_transceiver_phy->enable_gpio = enable_gpio;
 	}
 
-	phy_set_drvdata(can_transceiver_phy->generic_phy, can_transceiver_phy);
+	phy_set_drvdata(priv->can_transceiver_phy->generic_phy, priv->can_transceiver_phy);
 
 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
 

-- 
2.37.1



From peng.fan at nxp.com  Sun Aug 31 20:18:13 2025
From: peng.fan at nxp.com (Peng Fan)
Date: Mon, 01 Sep 2025 11:18:13 +0800
Subject: [PATCH v4 3/6] phy: phy-can-transceiver: Add dual channel support
 for TJA1048
In-Reply-To: <20250901-can-v4-0-e42b5fe2cf9e@nxp.com>
References: <20250901-can-v4-0-e42b5fe2cf9e@nxp.com>
Message-ID: <20250901-can-v4-3-e42b5fe2cf9e@nxp.com>

- Introduce new flag CAN_TRANSCEIVER_DUAL_CH to indicate the phy has two
  channels.
- Alloc a phy for each channel
- Support TJA1048 which is a dual high-speed CAN transceiver with sleep
  mode supported.
- Add can_transceiver_phy_xlate for parsing phy

Reviewed-by: Frank Li <Frank.Li at nxp.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/phy/phy-can-transceiver.c | 91 ++++++++++++++++++++++++++++-----------
 1 file changed, 65 insertions(+), 26 deletions(-)

diff --git a/drivers/phy/phy-can-transceiver.c b/drivers/phy/phy-can-transceiver.c
index 6415c6af0e8414a6cc8d15958a17ee749a3f28e9..f06b1df76ada023f432dce892c3346f45397ab54 100644
--- a/drivers/phy/phy-can-transceiver.c
+++ b/drivers/phy/phy-can-transceiver.c
@@ -17,6 +17,7 @@ struct can_transceiver_data {
 	u32 flags;
 #define CAN_TRANSCEIVER_STB_PRESENT	BIT(0)
 #define CAN_TRANSCEIVER_EN_PRESENT	BIT(1)
+#define CAN_TRANSCEIVER_DUAL_CH		BIT(2)
 };
 
 struct can_transceiver_phy {
@@ -29,6 +30,7 @@ struct can_transceiver_phy {
 struct can_transceiver_priv {
 	struct can_transceiver_phy *can_transceiver_phy;
 	struct mux_state *mux_state;
+	int num_ch;
 };
 
 /* Power on function */
@@ -81,6 +83,10 @@ static const struct can_transceiver_data tcan1043_drvdata = {
 	.flags = CAN_TRANSCEIVER_STB_PRESENT | CAN_TRANSCEIVER_EN_PRESENT,
 };
 
+static const struct can_transceiver_data tja1048_drvdata = {
+	.flags = CAN_TRANSCEIVER_STB_PRESENT | CAN_TRANSCEIVER_DUAL_CH,
+};
+
 static const struct of_device_id can_transceiver_phy_ids[] = {
 	{
 		.compatible = "ti,tcan1042",
@@ -90,6 +96,10 @@ static const struct of_device_id can_transceiver_phy_ids[] = {
 		.compatible = "ti,tcan1043",
 		.data = &tcan1043_drvdata
 	},
+	{
+		.compatible = "nxp,tja1048",
+		.data = &tja1048_drvdata
+	},
 	{
 		.compatible = "nxp,tjr1443",
 		.data = &tcan1043_drvdata
@@ -108,6 +118,25 @@ devm_mux_state_get_optional(struct device *dev, const char *mux_name)
 	return devm_mux_state_get(dev, mux_name);
 }
 
+static struct phy *can_transceiver_phy_xlate(struct device *dev,
+					     const struct of_phandle_args *args)
+{
+	struct can_transceiver_priv *priv = dev_get_drvdata(dev);
+	u32 idx;
+
+	if (priv->num_ch == 1)
+		return priv->can_transceiver_phy[0].generic_phy;
+
+	if (args->args_count != 1)
+		return ERR_PTR(-EINVAL);
+
+	idx = args->args[0];
+	if (idx >= priv->num_ch)
+		return ERR_PTR(-EINVAL);
+
+	return priv->can_transceiver_phy[idx].generic_phy;
+}
+
 static int can_transceiver_phy_probe(struct platform_device *pdev)
 {
 	struct phy_provider *phy_provider;
@@ -120,7 +149,8 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
 	struct gpio_desc *enable_gpio;
 	struct mux_state *mux_state;
 	u32 max_bitrate = 0;
-	int err;
+	int num_ch = 1;
+	int err, i;
 
 	match = of_match_node(can_transceiver_phy_ids, pdev->dev.of_node);
 	drvdata = match->data;
@@ -131,7 +161,11 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, priv);
 
-	priv->can_transceiver_phy = devm_kzalloc(dev, sizeof(struct can_transceiver_phy),
+	if (drvdata->flags & CAN_TRANSCEIVER_DUAL_CH)
+		num_ch = 2;
+
+	priv->num_ch = num_ch;
+	priv->can_transceiver_phy = devm_kcalloc(dev, num_ch, sizeof(struct can_transceiver_phy),
 						 GFP_KERNEL);
 	if (!priv->can_transceiver_phy)
 		return -ENOMEM;
@@ -142,38 +176,43 @@ static int can_transceiver_phy_probe(struct platform_device *pdev)
 
 	priv->mux_state = mux_state;
 
-	phy = devm_phy_create(dev, dev->of_node,
-			      &can_transceiver_phy_ops);
-	if (IS_ERR(phy)) {
-		dev_err(dev, "failed to create can transceiver phy\n");
-		return PTR_ERR(phy);
-	}
-
 	err = device_property_read_u32(dev, "max-bitrate", &max_bitrate);
 	if ((err != -EINVAL) && !max_bitrate)
 		dev_warn(dev, "Invalid value for transceiver max bitrate. Ignoring bitrate limit\n");
-	phy->attrs.max_link_rate = max_bitrate;
 
-	priv->can_transceiver_phy->generic_phy = phy;
-	priv->can_transceiver_phy->priv = priv;
+	for (i = 0; i < num_ch; i++) {
+		phy = devm_phy_create(dev, dev->of_node, &can_transceiver_phy_ops);
+		if (IS_ERR(phy)) {
+			dev_err(dev, "failed to create can transceiver phy\n");
+			return PTR_ERR(phy);
+		}
 
-	if (drvdata->flags & CAN_TRANSCEIVER_STB_PRESENT) {
-		standby_gpio = devm_gpiod_get_optional(dev, "standby", GPIOD_OUT_HIGH);
-		if (IS_ERR(standby_gpio))
-			return PTR_ERR(standby_gpio);
-		priv->can_transceiver_phy->standby_gpio = standby_gpio;
-	}
+		phy->attrs.max_link_rate = max_bitrate;
 
-	if (drvdata->flags & CAN_TRANSCEIVER_EN_PRESENT) {
-		enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW);
-		if (IS_ERR(enable_gpio))
-			return PTR_ERR(enable_gpio);
-		priv->can_transceiver_phy->enable_gpio = enable_gpio;
-	}
+		priv->can_transceiver_phy[i].generic_phy = phy;
+		priv->can_transceiver_phy[i].priv = priv;
 
-	phy_set_drvdata(priv->can_transceiver_phy->generic_phy, priv->can_transceiver_phy);
+		if (drvdata->flags & CAN_TRANSCEIVER_STB_PRESENT) {
+			standby_gpio = devm_gpiod_get_index_optional(dev, "standby", i,
+								     GPIOD_OUT_HIGH);
+			if (IS_ERR(standby_gpio))
+				return PTR_ERR(standby_gpio);
+			priv->can_transceiver_phy[i].standby_gpio = standby_gpio;
+		}
+
+		if (drvdata->flags & CAN_TRANSCEIVER_EN_PRESENT) {
+			enable_gpio = devm_gpiod_get_index_optional(dev, "enable", i,
+								    GPIOD_OUT_LOW);
+			if (IS_ERR(enable_gpio))
+				return PTR_ERR(enable_gpio);
+			priv->can_transceiver_phy[i].enable_gpio = enable_gpio;
+		}
+
+		phy_set_drvdata(priv->can_transceiver_phy[i].generic_phy,
+				&priv->can_transceiver_phy[i]);
+	}
 
-	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+	phy_provider = devm_of_phy_provider_register(dev, can_transceiver_phy_xlate);
 
 	return PTR_ERR_OR_ZERO(phy_provider);
 }

-- 
2.37.1



From peng.fan at nxp.com  Sun Aug 31 20:18:14 2025
From: peng.fan at nxp.com (Peng Fan)
Date: Mon, 01 Sep 2025 11:18:14 +0800
Subject: [PATCH v4 4/6] arm64: dts: imx95-15x15-evk: Use phys to replace
 xceiver-supply
In-Reply-To: <20250901-can-v4-0-e42b5fe2cf9e@nxp.com>
References: <20250901-can-v4-0-e42b5fe2cf9e@nxp.com>
Message-ID: <20250901-can-v4-4-e42b5fe2cf9e@nxp.com>

The TJA1051T/3 used on i.MX95-15x15-EVK is actually high-speed CAN
transceiver, not a regulator supply. So use phys to reflect the truth.

Reviewed-by: Frank Li <Frank.Li at nxp.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts b/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
index 148243470dd4ab03afdae949c8316f31467d1377..c229b748ca7aba2dc8cabe14d66e3d1dcd704c9a 100644
--- a/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
@@ -106,12 +106,11 @@ reg_audio_switch1: regulator-audio-switch1 {
 		gpio = <&pcal6524 0 GPIO_ACTIVE_LOW>;
 	};
 
-	reg_can2_stby: regulator-can2-stby {
-		compatible = "regulator-fixed";
-		regulator-max-microvolt = <3300000>;
-		regulator-min-microvolt = <3300000>;
-		regulator-name = "can2-stby";
-		gpio = <&pcal6524 14 GPIO_ACTIVE_LOW>;
+	flexcan2_phy: can-phy {
+		compatible = "nxp,tja1051", "ti,tcan1043";
+		#phy-cells = <0>;
+		max-bitrate = <5000000>;
+		standby-gpios = <&pcal6524 14 GPIO_ACTIVE_HIGH>;
 	};
 
 	reg_m2_pwr: regulator-m2-pwr {
@@ -317,7 +316,7 @@ &enetc_port1 {
 &flexcan2 {
 	pinctrl-0 = <&pinctrl_flexcan2>;
 	pinctrl-names = "default";
-	xceiver-supply = <&reg_can2_stby>;
+	phys = <&flexcan2_phy>;
 	status = "okay";
 };
 

-- 
2.37.1



From peng.fan at nxp.com  Sun Aug 31 20:18:15 2025
From: peng.fan at nxp.com (Peng Fan)
Date: Mon, 01 Sep 2025 11:18:15 +0800
Subject: [PATCH v4 5/6] arm64: dts: imx8mp-evk: Use phys to replace
 xceiver-supply
In-Reply-To: <20250901-can-v4-0-e42b5fe2cf9e@nxp.com>
References: <20250901-can-v4-0-e42b5fe2cf9e@nxp.com>
Message-ID: <20250901-can-v4-5-e42b5fe2cf9e@nxp.com>

The TJA1048 used on i.MX8MP-EVK is actually high-speed CAN transceiver,
not a regulator supply. So use phys to reflect the truth.

Reviewed-by: Frank Li <Frank.Li at nxp.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8mp-evk.dts | 43 +++++++++-------------------
 1 file changed, 13 insertions(+), 30 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
index 3730792daf5010213cbb9f6869a8110ea28eb48a..59891627dc462d37dfd620eb68b893546cc20d6a 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
@@ -56,6 +56,16 @@ memory at 40000000 {
 		      <0x1 0x00000000 0 0xc0000000>;
 	};
 
+	flexcan_phy: can-phy {
+		compatible = "nxp,tja1048";
+		#phy-cells = <1>;
+		max-bitrate = <5000000>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_flexcan_phy>;
+		standby-gpios = <&gpio5 5 GPIO_ACTIVE_LOW>,
+				<&gpio4 27 GPIO_ACTIVE_LOW>;
+	};
+
 	native-hdmi-connector {
 		compatible = "hdmi-connector";
 		label = "HDMI OUT";
@@ -103,28 +113,6 @@ reg_audio_pwr: regulator-audio-pwr {
 		enable-active-high;
 	};
 
-	reg_can1_stby: regulator-can1-stby {
-		compatible = "regulator-fixed";
-		regulator-name = "can1-stby";
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_flexcan1_reg>;
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		gpio = <&gpio5 5 GPIO_ACTIVE_HIGH>;
-		enable-active-high;
-	};
-
-	reg_can2_stby: regulator-can2-stby {
-		compatible = "regulator-fixed";
-		regulator-name = "can2-stby";
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_flexcan2_reg>;
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		gpio = <&gpio4 27 GPIO_ACTIVE_HIGH>;
-		enable-active-high;
-	};
-
 	reg_pcie0: regulator-pcie {
 		compatible = "regulator-fixed";
 		pinctrl-names = "default";
@@ -431,14 +419,14 @@ ethphy1: ethernet-phy at 1 {
 &flexcan1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_flexcan1>;
-	xceiver-supply = <&reg_can1_stby>;
+	phys = <&flexcan_phy 0>;
 	status = "okay";
 };
 
 &flexcan2 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_flexcan2>;
-	xceiver-supply = <&reg_can2_stby>;
+	phys = <&flexcan_phy 1>;
 	status = "disabled";/* can2 pin conflict with pdm */
 };
 
@@ -903,14 +891,9 @@ MX8MP_IOMUXC_SAI5_RXD3__CAN2_TX         0x154
 		>;
 	};
 
-	pinctrl_flexcan1_reg: flexcan1reggrp {
+	pinctrl_flexcan_phy: flexcanphygrp {
 		fsl,pins = <
 			MX8MP_IOMUXC_SPDIF_EXT_CLK__GPIO5_IO05  0x154   /* CAN1_STBY */
-		>;
-	};
-
-	pinctrl_flexcan2_reg: flexcan2reggrp {
-		fsl,pins = <
 			MX8MP_IOMUXC_SAI2_MCLK__GPIO4_IO27      0x154   /* CAN2_STBY */
 		>;
 	};

-- 
2.37.1



From peng.fan at nxp.com  Sun Aug 31 20:18:16 2025
From: peng.fan at nxp.com (Peng Fan)
Date: Mon, 01 Sep 2025 11:18:16 +0800
Subject: [PATCH v4 6/6] arm64: dts: imx93-11x11-evk: Use phys to replace
 xceiver-supply
In-Reply-To: <20250901-can-v4-0-e42b5fe2cf9e@nxp.com>
References: <20250901-can-v4-0-e42b5fe2cf9e@nxp.com>
Message-ID: <20250901-can-v4-6-e42b5fe2cf9e@nxp.com>

The TJA1057 used on i.MX93 EVK is actually high-speed CAN
transceiver, not a regulator supply. So use phys to reflect the truth.

Reviewed-by: Frank Li <Frank.Li at nxp.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts b/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
index e24e12f04526c3a08c0bdc6134297fb010e6e926..4c52f22bbfac99722184b4d8679f48c4396b557f 100644
--- a/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
@@ -62,6 +62,13 @@ vdevbuffer: vdevbuffer at a4020000 {
 
 	};
 
+	flexcan_phy: can-phy {
+		compatible = "nxp,tja1057", "ti,tcan1043";
+		#phy-cells = <0>;
+		max-bitrate = <5000000>;
+		standby-gpios = <&adp5585 6 GPIO_ACTIVE_HIGH>;
+	};
+
 	reg_vdd_12v: regulator-vdd-12v {
 		compatible = "regulator-fixed";
 		regulator-name = "VDD_12V";
@@ -87,14 +94,6 @@ reg_audio_pwr: regulator-audio-pwr {
 		enable-active-high;
 	};
 
-	reg_can2_standby: regulator-can2-standby {
-		compatible = "regulator-fixed";
-		regulator-name = "can2-stby";
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		gpio = <&adp5585 6 GPIO_ACTIVE_LOW>;
-	};
-
 	reg_m2_pwr: regulator-m2-pwr {
 		compatible = "regulator-fixed";
 		regulator-name = "M.2-power";
@@ -284,7 +283,7 @@ ethphy2: ethernet-phy at 2 {
 &flexcan2 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_flexcan2>;
-	xceiver-supply = <&reg_can2_standby>;
+	phys = <&flexcan_phy>;
 	status = "okay";
 };
 

-- 
2.37.1



From jacky_chou at aspeedtech.com  Sun Aug 31 22:59:12 2025
From: jacky_chou at aspeedtech.com (Jacky Chou)
Date: Mon, 1 Sep 2025 13:59:12 +0800
Subject: [PATCH v3 00/10] Add ASPEED PCIe Root Complex support
Message-ID: <20250901055922.1553550-1-jacky_chou@aspeedtech.com>

This patch series adds support for the ASPEED PCIe Root Complex,
including device tree bindings, pinctrl support, and the PCIe host controller
driver. The patches introduce the necessary device tree nodes, pinmux groups,
and driver implementation to enable PCIe functionality on ASPEED platforms.
Currently, the ASPEED PCIe Root Complex only supports a single port.

Summary of changes:
- Add device tree binding documents for ASPEED PCIe PHY, PCIe Config, and PCIe RC
- Update MAINTAINERS for new bindings and driver
- Add PCIe RC node and PERST control pin to aspeed-g6 device tree
- Implement ASPEED PCIe PHY driver
- Implement ASPEED PCIe Root Complex host controller driver

This series has been tested on AST2600/AST2700 platforms and enables PCIe device
enumeration and operation.

Jacky Chou (10):
  dt-bindings: soc: aspeed: Add ASPEED PCIe Config
  dt-bindings: phy: aspeed: Add ASPEED PCIe PHY
  dt-bindings: PCI: Add ASPEED PCIe RC support
  dt-bindings: pinctrl: aspeed,ast2600-pinctrl: Add PCIe RC PERST# group
  ARM: dts: aspeed-g6: Add AST2600 PCIe RC PERST#
  ARM: dts: aspeed-g6: Add PCIe RC and PCIe PHY node
  PHY: aspeed: Add ASPEED PCIe PHY driver
  PCI: Add FMT and TYPE definition for TLP header
  PCI: aspeed: Add ASPEED PCIe RC driver
  MAINTAINERS: Add ASPEED PCIe RC driver

 .../bindings/pci/aspeed,ast2600-pcie.yaml     |  179 +++
 .../bindings/phy/aspeed,ast2600-pcie-phy.yaml |   42 +
 .../pinctrl/aspeed,ast2600-pinctrl.yaml       |    2 +
 .../soc/aspeed/aspeed,ast2700-pcie-cfg.yaml   |   46 +
 MAINTAINERS                                   |   11 +
 .../boot/dts/aspeed/aspeed-g6-pinctrl.dtsi    |    5 +
 arch/arm/boot/dts/aspeed/aspeed-g6.dtsi       |   56 +
 drivers/pci/controller/Kconfig                |   16 +
 drivers/pci/controller/Makefile               |    1 +
 drivers/pci/controller/pcie-aspeed.c          | 1137 +++++++++++++++++
 drivers/pci/pci.h                             |   12 +
 drivers/phy/Kconfig                           |    1 +
 drivers/phy/Makefile                          |    1 +
 drivers/phy/aspeed/Kconfig                    |   15 +
 drivers/phy/aspeed/Makefile                   |    2 +
 drivers/phy/aspeed/phy-aspeed-pcie.c          |  209 +++
 16 files changed, 1735 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/aspeed,ast2600-pcie.yaml
 create mode 100644 Documentation/devicetree/bindings/phy/aspeed,ast2600-pcie-phy.yaml
 create mode 100644 Documentation/devicetree/bindings/soc/aspeed/aspeed,ast2700-pcie-cfg.yaml
 create mode 100644 drivers/pci/controller/pcie-aspeed.c
 create mode 100644 drivers/phy/aspeed/Kconfig
 create mode 100644 drivers/phy/aspeed/Makefile
 create mode 100644 drivers/phy/aspeed/phy-aspeed-pcie.c

---
v3:
 - Add ASPEED PCIe PHY driver
 - Remove the aspeed,pciecfg property from AST2600 RC node, merged into RC node
 - Update the binding doc for aspeed,ast2700-pcie-cfg to reflect the changes
 - Update the binding doc for aspeed,ast2600-pcie to reflect the changes
 - Update the binding doc for aspeed,ast2600-pinctrl to reflect the changes
 - Update the device tree source to reflect the changes
 - Adjusted the use of mutex in RC drivers to use GRAND
 - Updated from reviewer comments

v2:
 - Moved ASPEED PCIe PHY yaml binding to `soc/aspeed` directory and
   changed it as syscon
 - Added `MAINTAINERS` entry for the new PCIe RC driver
 - Updated device tree bindings to reflect the new structure
 - Refactored configuration read and write functions to main bus and
   child bus ops
 - Refactored initialization to implement multiple ports support
 - Added PCIe FMT and TYPE definitions for TLP header in
   `include/uapi/linux/pci_regs.h`
 - Updated from reviewer comments
---

-- 
2.43.0



From jacky_chou at aspeedtech.com  Sun Aug 31 22:59:13 2025
From: jacky_chou at aspeedtech.com (Jacky Chou)
Date: Mon, 1 Sep 2025 13:59:13 +0800
Subject: [PATCH v3 01/10] dt-bindings: soc: aspeed: Add ASPEED PCIe Config
In-Reply-To: <20250901055922.1553550-1-jacky_chou@aspeedtech.com>
References: <20250901055922.1553550-1-jacky_chou@aspeedtech.com>
Message-ID: <20250901055922.1553550-2-jacky_chou@aspeedtech.com>

Add the ASPEED PCIe configuration syscon block. This shared register
space is used by multiple PCIe-related devices to coordinate and manage
common PCIe settings. The binding describes the required compatible
strings and register space for the configuration node.

Signed-off-by: Jacky Chou <jacky_chou at aspeedtech.com>
---
 .../soc/aspeed/aspeed,ast2700-pcie-cfg.yaml   | 46 +++++++++++++++++++
 1 file changed, 46 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/aspeed/aspeed,ast2700-pcie-cfg.yaml

diff --git a/Documentation/devicetree/bindings/soc/aspeed/aspeed,ast2700-pcie-cfg.yaml b/Documentation/devicetree/bindings/soc/aspeed/aspeed,ast2700-pcie-cfg.yaml
new file mode 100644
index 000000000000..c1a90bb6a785
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/aspeed/aspeed,ast2700-pcie-cfg.yaml
@@ -0,0 +1,46 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/aspeed/aspeed,ast2700-pcie-cfg.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ASPEED PCIe Configuration
+
+maintainers:
+  - Jacky Chou <jacky_chou at aspeedtech.com>
+
+description:
+  The ASPEED PCIe configuration syscon block provides a set of registers shared
+  by multiple PCIe-related devices within the SoC. This node represents the
+  common configuration space that allows these devices to coordinate and manage
+  shared PCIe settings, including address mapping, control, and status
+  registers. The syscon interface enables for various PCIe devices to access
+  and modify these shared registers in a consistent and centralized manner.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - aspeed,ast2700-pcie-cfg
+      - const: syscon
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    soc0 {
+      #address-cells = <2>;
+      #size-cells = <1>;
+
+      syscon at 12c02a00 {
+        compatible = "aspeed,ast2700-pcie-cfg", "syscon";
+        reg = <0 0x12c02a00 0x80>;
+      };
+    };
-- 
2.43.0



From jacky_chou at aspeedtech.com  Sun Aug 31 22:59:14 2025
From: jacky_chou at aspeedtech.com (Jacky Chou)
Date: Mon, 1 Sep 2025 13:59:14 +0800
Subject: [PATCH v3 02/10] dt-bindings: phy: aspeed: Add ASPEED PCIe PHY
In-Reply-To: <20250901055922.1553550-1-jacky_chou@aspeedtech.com>
References: <20250901055922.1553550-1-jacky_chou@aspeedtech.com>
Message-ID: <20250901055922.1553550-3-jacky_chou@aspeedtech.com>

Introduce device-binding for ASPEED AST2600/2700 PCIe PHY.
The PCIe PHY is used for PCIe RC to configure as RC mode.

Signed-off-by: Jacky Chou <jacky_chou at aspeedtech.com>
---
 .../bindings/phy/aspeed,ast2600-pcie-phy.yaml | 42 +++++++++++++++++++
 1 file changed, 42 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/aspeed,ast2600-pcie-phy.yaml

diff --git a/Documentation/devicetree/bindings/phy/aspeed,ast2600-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/aspeed,ast2600-pcie-phy.yaml
new file mode 100644
index 000000000000..71a5cd91fb3f
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/aspeed,ast2600-pcie-phy.yaml
@@ -0,0 +1,42 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/aspeed,ast2600-pcie-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ASPEED PCIe PHY
+
+maintainers:
+  - Jacky Chou <jacky_chou at aspeedtech.com>
+
+description:
+  The ASPEED PCIe PHY provides the physical layer functionality for PCIe
+  controllers in the SoC.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - aspeed,ast2600-pcie-phy
+          - aspeed,ast2700-pcie-phy
+
+  reg:
+    maxItems: 1
+
+  "#phy-cells":
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    phy at 1e6ed200 {
+      compatible = "aspeed,ast2600-pcie-phy";
+      reg = <0x1e6ed200 0x100>;
+      #phy-cells = <0>;
+    };
-- 
2.43.0



From jacky_chou at aspeedtech.com  Sun Aug 31 22:59:15 2025
From: jacky_chou at aspeedtech.com (Jacky Chou)
Date: Mon, 1 Sep 2025 13:59:15 +0800
Subject: [PATCH v3 03/10] dt-bindings: PCI: Add ASPEED PCIe RC support
In-Reply-To: <20250901055922.1553550-1-jacky_chou@aspeedtech.com>
References: <20250901055922.1553550-1-jacky_chou@aspeedtech.com>
Message-ID: <20250901055922.1553550-4-jacky_chou@aspeedtech.com>

ASPEED AST2600 provides one PCIe RC for Gen2 and AST2700 provides three
PCIe RC for two Gen4 and one Gen2. All of these RCs have just one root
port to connect to PCIe device. And also have Mem, I/O access, legacy
interrupt and MSI.

Signed-off-by: Jacky Chou <jacky_chou at aspeedtech.com>
---
 .../bindings/pci/aspeed,ast2600-pcie.yaml     | 179 ++++++++++++++++++
 1 file changed, 179 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/aspeed,ast2600-pcie.yaml

diff --git a/Documentation/devicetree/bindings/pci/aspeed,ast2600-pcie.yaml b/Documentation/devicetree/bindings/pci/aspeed,ast2600-pcie.yaml
new file mode 100644
index 000000000000..fe75bf2961c8
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/aspeed,ast2600-pcie.yaml
@@ -0,0 +1,179 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/aspeed,ast2600-pcie.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ASPEED PCIe Root Complex Controller
+
+maintainers:
+  - Jacky Chou <jacky_chou at aspeedtech.com>
+
+description:
+  The ASPEED PCIe Root Complex controller provides PCI Express Root Complex
+  functionality for ASPEED SoCs, such as the AST2600 and AST2700.
+  This controller enables connectivity to PCIe endpoint devices, supporting
+  memory and I/O windows, MSI and legacy interrupts, and integration with
+  the SoC's clock, reset, and pinctrl subsystems.
+
+properties:
+  compatible:
+    enum:
+      - aspeed,ast2600-pcie
+      - aspeed,ast2700-pcie
+
+  reg:
+    maxItems: 1
+
+  ranges:
+    minItems: 2
+    maxItems: 2
+
+  interrupts:
+    maxItems: 1
+    description: IntX and MSI interrupt
+
+  resets:
+    items:
+      - description: PCIe controller reset
+
+  reset-names:
+    items:
+      - const: h2x
+
+  msi-parent: true
+
+  aspeed,ahbc:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to the ASPEED AHB Controller (AHBC) syscon node.
+      This reference is used by the PCIe controller to access
+      system-level configuration registers related to the AHB bus.
+      To enable AHB access for the PCIe controller.
+
+  aspeed,pciecfg:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to the ASPEED PCIe configuration syscon node.
+      This reference allows the PCIe controller to access
+      SoC-specific PCIe configuration registers. There are the others
+      functions such PCIe RC and PCIe EP will use this common register
+      to configure the SoC interfaces.
+
+  interrupt-controller:
+    description: Interrupt controller node for handling legacy PCI interrupts.
+    type: object
+    properties:
+      '#address-cells':
+        const: 0
+      '#interrupt-cells':
+        const: 1
+      interrupt-controller: true
+
+    required:
+      - '#address-cells'
+      - '#interrupt-cells'
+      - interrupt-controller
+
+    additionalProperties: false
+
+allOf:
+  - $ref: /schemas/pci/pci-host-bridge.yaml#
+  - $ref: /schemas/interrupt-controller/msi-controller.yaml#
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: aspeed,ast2600-pcie
+    then:
+      required:
+        - aspeed,ahbc
+    else:
+      properties:
+        aspeed,ahbc: false
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: aspeed,ast2700-pcie
+    then:
+      required:
+        - aspeed,pciecfg
+    else:
+      properties:
+        aspeed,pciecfg: false
+
+required:
+  - reg
+  - interrupts
+  - bus-range
+  - ranges
+  - resets
+  - reset-names
+  - msi-parent
+  - msi-controller
+  - interrupt-map-mask
+  - interrupt-map
+  - interrupt-controller
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/ast2600-clock.h>
+
+    apb {
+      #address-cells = <1>;
+      #size-cells = <1>;
+
+      pcie0: pcie at 1e770000 {
+        compatible = "aspeed,ast2600-pcie";
+        device_type = "pci";
+        reg = <0x1e770000 0x100>;
+        linux,pci-domain = <0>;
+        #address-cells = <3>;
+        #size-cells = <2>;
+        interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
+        bus-range = <0x80 0xff>;
+
+        ranges = <0x01000000 0x0 0x00018000 0x00018000 0x0 0x00008000
+            0x02000000 0x0 0x70000000 0x70000000 0x0 0x10000000>;
+
+        status = "disabled";
+
+        resets = <&syscon ASPEED_RESET_H2X>;
+        reset-names = "h2x";
+
+        #interrupt-cells = <1>;
+        msi-parent = <&pcie0>;
+        msi-controller;
+
+        aspeed,ahbc = <&ahbc>;
+
+        interrupt-map-mask = <0 0 0 7>;
+        interrupt-map = <0 0 0 1 &pcie_intc0 0>,
+                        <0 0 0 2 &pcie_intc0 1>,
+                        <0 0 0 3 &pcie_intc0 2>,
+                        <0 0 0 4 &pcie_intc0 3>;
+        pcie_intc0: interrupt-controller {
+          interrupt-controller;
+          #address-cells = <0>;
+          #interrupt-cells = <1>;
+        };
+
+        pcie at 8,0 {
+          reg = <0x804000 0 0 0 0>;
+          #address-cells = <3>;
+          #size-cells = <2>;
+          device_type = "pci";
+          resets = <&syscon ASPEED_RESET_PCIE_RC_O>;
+          reset-names = "perst";
+          clocks = <&syscon ASPEED_CLK_GATE_BCLK>;
+          pinctrl-names = "default";
+          pinctrl-0 = <&pinctrl_pcierc1_default>;
+          phys = <&pcie_phy1>;
+          ranges;
+        };
+      };
+    };
-- 
2.43.0



From jacky_chou at aspeedtech.com  Sun Aug 31 22:59:16 2025
From: jacky_chou at aspeedtech.com (Jacky Chou)
Date: Mon, 1 Sep 2025 13:59:16 +0800
Subject: [PATCH v3 04/10] dt-bindings: pinctrl: aspeed,ast2600-pinctrl: Add PCIe RC PERST# group
In-Reply-To: <20250901055922.1553550-1-jacky_chou@aspeedtech.com>
References: <20250901055922.1553550-1-jacky_chou@aspeedtech.com>
Message-ID: <20250901055922.1553550-5-jacky_chou@aspeedtech.com>

Add PCIe PERST# group to support for PCIe RC.

Signed-off-by: Jacky Chou <jacky_chou at aspeedtech.com>
---
 .../devicetree/bindings/pinctrl/aspeed,ast2600-pinctrl.yaml     | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/aspeed,ast2600-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2600-pinctrl.yaml
index 80974c46f3ef..af8979af9b45 100644
--- a/Documentation/devicetree/bindings/pinctrl/aspeed,ast2600-pinctrl.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2600-pinctrl.yaml
@@ -141,6 +141,7 @@ additionalProperties:
         - NRTS3
         - NRTS4
         - OSCCLK
+        - PCIERC1
         - PEWAKE
         - PWM0
         - PWM1
@@ -369,6 +370,7 @@ additionalProperties:
         - NRTS3
         - NRTS4
         - OSCCLK
+        - PCIERC1
         - PEWAKE
         - PWM0
         - PWM1
-- 
2.43.0



From jacky_chou at aspeedtech.com  Sun Aug 31 22:59:17 2025
From: jacky_chou at aspeedtech.com (Jacky Chou)
Date: Mon, 1 Sep 2025 13:59:17 +0800
Subject: [PATCH v3 05/10] ARM: dts: aspeed-g6: Add AST2600 PCIe RC PERST#
In-Reply-To: <20250901055922.1553550-1-jacky_chou@aspeedtech.com>
References: <20250901055922.1553550-1-jacky_chou@aspeedtech.com>
Message-ID: <20250901055922.1553550-6-jacky_chou@aspeedtech.com>

Add pinctrl support for PCIe RC PERST#.

Signed-off-by: Jacky Chou <jacky_chou at aspeedtech.com>
---
 arch/arm/boot/dts/aspeed/aspeed-g6-pinctrl.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-g6-pinctrl.dtsi b/arch/arm/boot/dts/aspeed/aspeed-g6-pinctrl.dtsi
index 289668f051eb..ea879f086c25 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-g6-pinctrl.dtsi
+++ b/arch/arm/boot/dts/aspeed/aspeed-g6-pinctrl.dtsi
@@ -2,6 +2,11 @@
 // Copyright 2019 IBM Corp.
 
 &pinctrl {
+	pinctrl_pcierc1_default: pcierc1-default {
+		function = "PCIERC1";
+		groups = "PCIERC1";
+	};
+
 	pinctrl_adc0_default: adc0_default {
 		function = "ADC0";
 		groups = "ADC0";
-- 
2.43.0



From jacky_chou at aspeedtech.com  Sun Aug 31 22:59:18 2025
From: jacky_chou at aspeedtech.com (Jacky Chou)
Date: Mon, 1 Sep 2025 13:59:18 +0800
Subject: [PATCH v3 06/10] ARM: dts: aspeed-g6: Add PCIe RC and PCIe PHY node
In-Reply-To: <20250901055922.1553550-1-jacky_chou@aspeedtech.com>
References: <20250901055922.1553550-1-jacky_chou@aspeedtech.com>
Message-ID: <20250901055922.1553550-7-jacky_chou@aspeedtech.com>

The AST2600 has one PCIe RC and add the PCIe PHY for RC.

Signed-off-by: Jacky Chou <jacky_chou at aspeedtech.com>
---
 arch/arm/boot/dts/aspeed/aspeed-g6.dtsi | 56 +++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi
index 8ed715bd53aa..a1ccc141647f 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi
+++ b/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi
@@ -379,6 +379,62 @@ rng: hwrng at 1e6e2524 {
 				quality = <100>;
 			};
 
+			pcie_phy1: phy at 1e6ed200 {
+				compatible = "aspeed,ast2600-pcie-phy";
+				reg = <0x1e6ed200 0x100>;
+				#phy-cells = <0>;
+			};
+
+			pcie0: pcie at 1e770000 {
+				compatible = "aspeed,ast2600-pcie";
+				device_type = "pci";
+				reg = <0x1e770000 0x100>;
+				linux,pci-domain = <0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
+				bus-range = <0x80 0xff>;
+
+				ranges = <0x01000000 0x0 0x00018000 0x00018000 0x0 0x00008000
+					  0x02000000 0x0 0x70000000 0x70000000 0x0 0x10000000>;
+
+				status = "disabled";
+
+				resets = <&syscon ASPEED_RESET_H2X>;
+				reset-names = "h2x";
+
+				#interrupt-cells = <1>;
+				msi-parent = <&pcie0>;
+				msi-controller;
+
+				aspeed,ahbc = <&ahbc>;
+
+				interrupt-map-mask = <0 0 0 7>;
+				interrupt-map = <0 0 0 1 &pcie_intc0 0>,
+						<0 0 0 2 &pcie_intc0 1>,
+						<0 0 0 3 &pcie_intc0 2>,
+						<0 0 0 4 &pcie_intc0 3>;
+				pcie_intc0: interrupt-controller {
+					interrupt-controller;
+					#address-cells = <0>;
+					#interrupt-cells = <1>;
+				};
+
+				pcie at 8,0 {
+					reg = <0x804000 0 0 0 0>;
+					#address-cells = <3>;
+					#size-cells = <2>;
+					device_type = "pci";
+					resets = <&syscon ASPEED_RESET_PCIE_RC_O>;
+					reset-names = "perst";
+					clocks = <&syscon ASPEED_CLK_GATE_BCLK>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&pinctrl_pcierc1_default>;
+					phys = <&pcie_phy1>;
+					ranges;
+				};
+			};
+
 			gfx: display at 1e6e6000 {
 				compatible = "aspeed,ast2600-gfx", "syscon";
 				reg = <0x1e6e6000 0x1000>;
-- 
2.43.0



From jacky_chou at aspeedtech.com  Sun Aug 31 22:59:19 2025
From: jacky_chou at aspeedtech.com (Jacky Chou)
Date: Mon, 1 Sep 2025 13:59:19 +0800
Subject: [PATCH v3 07/10] PHY: aspeed: Add ASPEED PCIe PHY driver
In-Reply-To: <20250901055922.1553550-1-jacky_chou@aspeedtech.com>
References: <20250901055922.1553550-1-jacky_chou@aspeedtech.com>
Message-ID: <20250901055922.1553550-8-jacky_chou@aspeedtech.com>

Introduce support for Aspeed PCIe PHY controller available in
AST2600/2700.

Signed-off-by: Jacky Chou <jacky_chou at aspeedtech.com>
---
 drivers/phy/Kconfig                  |   1 +
 drivers/phy/Makefile                 |   1 +
 drivers/phy/aspeed/Kconfig           |  15 ++
 drivers/phy/aspeed/Makefile          |   2 +
 drivers/phy/aspeed/phy-aspeed-pcie.c | 209 +++++++++++++++++++++++++++
 5 files changed, 228 insertions(+)
 create mode 100644 drivers/phy/aspeed/Kconfig
 create mode 100644 drivers/phy/aspeed/Makefile
 create mode 100644 drivers/phy/aspeed/phy-aspeed-pcie.c

diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 58c911e1b2d2..ac4bf46f24e2 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -103,6 +103,7 @@ config PHY_NXP_PTN3222
 
 source "drivers/phy/allwinner/Kconfig"
 source "drivers/phy/amlogic/Kconfig"
+source "drivers/phy/aspeed/Kconfig"
 source "drivers/phy/broadcom/Kconfig"
 source "drivers/phy/cadence/Kconfig"
 source "drivers/phy/freescale/Kconfig"
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index c670a8dac468..12fd50e5ea9b 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_PHY_AIROHA_PCIE)		+= phy-airoha-pcie.o
 obj-$(CONFIG_PHY_NXP_PTN3222)		+= phy-nxp-ptn3222.o
 obj-y					+= allwinner/	\
 					   amlogic/	\
+					   aspeed/	\
 					   broadcom/	\
 					   cadence/	\
 					   freescale/	\
diff --git a/drivers/phy/aspeed/Kconfig b/drivers/phy/aspeed/Kconfig
new file mode 100644
index 000000000000..6aeeca84091f
--- /dev/null
+++ b/drivers/phy/aspeed/Kconfig
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Phy drivers for Aspeed platforms
+#
+config PHY_ASPEED_PCIE
+	tristate "ASPEED PCIe PHY driver"
+	select GENERIC_PHY
+	depends on ARCH_ASPEED
+	default y
+	help
+	  This option enables support for the ASPEED PCIe PHY driver.
+	  The driver provides the necessary interface to control and
+	  configure the PCIe PHY hardware found on ASPEED SoCs.
+	  It is required for proper operation of PCIe devices on
+	  platforms using ASPEED chips.
\ No newline at end of file
diff --git a/drivers/phy/aspeed/Makefile b/drivers/phy/aspeed/Makefile
new file mode 100644
index 000000000000..7203152f44bf
--- /dev/null
+++ b/drivers/phy/aspeed/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_PHY_ASPEED_PCIE)		+= phy-aspeed-pcie.o
\ No newline at end of file
diff --git a/drivers/phy/aspeed/phy-aspeed-pcie.c b/drivers/phy/aspeed/phy-aspeed-pcie.c
new file mode 100644
index 000000000000..4b78ceeb5a5e
--- /dev/null
+++ b/drivers/phy/aspeed/phy-aspeed-pcie.c
@@ -0,0 +1,209 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2025 Aspeed Technology Inc.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/phy/pcie.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/reset.h>
+#include <linux/slab.h>
+
+/* AST2600 PCIe Host Controller Registers */
+#define PEHR_GLOBAL		0x30
+#define  AST2600_PORT_TYPE_MASK		GENMASK(5, 4)
+#define  AST2600_PORT_TYPE(x)		FIELD_PREP(AST2600_PORT_TYPE_MASK, x)
+#define PEHR_LOCK		0x7c
+#define  PCIE_UNLOCK			0xa8
+
+/* AST2700 PEHR */
+#define PEHR_MISC_58		0x58
+#define  LOCAL_SCALE_SUP		BIT(0)
+#define PEHR_MISC_5C		0x5c
+#define  CONFIG_RC_DEVICE		BIT(30)
+#define PEHR_MISC_60		0x60
+#define  AST2700_PORT_TYPE_MASK		GENMASK(7, 4)
+#define  PORT_TYPE_ROOT			BIT(6)
+#define PEHR_MISC_70		0x70
+#define  POSTED_DATA_CREDITS(x)		FIELD_PREP(GENMASK(15, 0), x)
+#define  POSTED_HEADER_CREDITS(x)	FIELD_PREP(GENMASK(27, 16), x)
+#define PEHR_MISC_78		0x78
+#define  COMPLETION_DATA_CREDITS(x)	FIELD_PREP(GENMASK(15, 0), x)
+#define  COMPLETION_HEADER_CREDITS(x)	FIELD_PREP(GENMASK(27, 16), x)
+
+/**
+ * struct aspeed_pcie_phy - PCIe PHY information
+ * @dev: pointer to device structure
+ * @reg: PCIe host register base address
+ * @phy: pointer to PHY structure
+ * @platform: platform specific information
+ */
+struct aspeed_pcie_phy {
+	struct device *dev;
+	void __iomem *reg;
+	struct phy *phy;
+	const struct aspeed_pcie_phy_platform *platform;
+};
+
+/**
+ * struct aspeed_pcie_phy_platform - Platform information
+ * @phy_ops: phy operations
+ */
+struct aspeed_pcie_phy_platform {
+	const struct phy_ops *phy_ops;
+};
+
+static int ast2600_phy_init(struct phy *phy)
+{
+	struct aspeed_pcie_phy *pcie_phy = phy_get_drvdata(phy);
+
+	writel(PCIE_UNLOCK, pcie_phy->reg + PEHR_LOCK);
+
+	return 0;
+}
+
+static int ast2600_phy_set_mode(struct phy *phy, enum phy_mode mode,
+				int submode)
+{
+	struct aspeed_pcie_phy *pcie_phy = phy_get_drvdata(phy);
+
+	switch (submode) {
+	case PHY_MODE_PCIE_RC:
+		writel(AST2600_PORT_TYPE(0x3), pcie_phy->reg + PEHR_GLOBAL);
+		break;
+	default:
+		dev_err(&phy->dev, "Unsupported submode %d\n", submode);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct phy_ops ast2600_phy_ops = {
+	.init		= ast2600_phy_init,
+	.set_mode	= ast2600_phy_set_mode,
+	.owner		= THIS_MODULE,
+};
+
+static int ast2700_phy_init(struct phy *phy)
+{
+	struct aspeed_pcie_phy *pcie_phy = phy_get_drvdata(phy);
+
+	writel(POSTED_DATA_CREDITS(0xc0) | POSTED_HEADER_CREDITS(0xa),
+	       pcie_phy->reg + PEHR_MISC_70);
+	writel(COMPLETION_DATA_CREDITS(0x30) | COMPLETION_HEADER_CREDITS(0x8),
+	       pcie_phy->reg + PEHR_MISC_78);
+	writel(LOCAL_SCALE_SUP, pcie_phy->reg + PEHR_MISC_58);
+
+	return 0;
+}
+
+static int ast2700_phy_set_mode(struct phy *phy, enum phy_mode mode,
+				int submode)
+{
+	struct aspeed_pcie_phy *pcie_phy = phy_get_drvdata(phy);
+	u32 cfg_val;
+
+	switch (submode) {
+	case PHY_MODE_PCIE_RC:
+		writel(CONFIG_RC_DEVICE, pcie_phy->reg + PEHR_MISC_5C);
+		cfg_val = readl(pcie_phy->reg + PEHR_MISC_60);
+		cfg_val &= ~AST2700_PORT_TYPE_MASK;
+		cfg_val |= PORT_TYPE_ROOT;
+		writel(cfg_val, pcie_phy->reg + PEHR_MISC_60);
+		break;
+	default:
+		dev_err(&phy->dev, "Unsupported submode %d\n", submode);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct phy_ops ast2700_phy_ops = {
+	.init		= ast2700_phy_init,
+	.set_mode	= ast2700_phy_set_mode,
+	.owner		= THIS_MODULE,
+};
+
+const struct aspeed_pcie_phy_platform pcie_phy_ast2600 = {
+	.phy_ops = &ast2600_phy_ops,
+};
+
+const struct aspeed_pcie_phy_platform pcie_phy_ast2700 = {
+	.phy_ops = &ast2700_phy_ops,
+};
+
+static int aspeed_pcie_phy_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct phy_provider *phy_provider;
+	struct aspeed_pcie_phy *pcie_phy;
+	const struct aspeed_pcie_phy_platform *md;
+
+	md = of_device_get_match_data(dev);
+	if (!md)
+		return -ENODEV;
+
+	pcie_phy = devm_kzalloc(dev, sizeof(*pcie_phy), GFP_KERNEL);
+	if (!pcie_phy)
+		return -ENOMEM;
+
+	pcie_phy->reg = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(pcie_phy->reg))
+		return PTR_ERR(pcie_phy->reg);
+
+	pcie_phy->dev = dev;
+	pcie_phy->platform = md;
+
+	pcie_phy->phy = devm_phy_create(dev, dev->of_node,
+					pcie_phy->platform->phy_ops);
+	if (IS_ERR(pcie_phy->phy))
+		return dev_err_probe(dev, PTR_ERR(pcie_phy->phy),
+				     "failed to create PHY\n");
+
+	phy_set_drvdata(pcie_phy->phy, pcie_phy);
+	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+
+	return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct of_device_id aspeed_pcie_phy_of_match_table[] = {
+	{
+		.compatible = "aspeed,ast2600-pcie-phy",
+		.data = &pcie_phy_ast2600,
+	},
+	{
+		.compatible = "aspeed,ast2700-pcie-phy",
+		.data = &pcie_phy_ast2700,
+	},
+	{ },
+};
+MODULE_DEVICE_TABLE(of, aspeed_pcie_of_match_table);
+
+static struct platform_driver aspeed_pcie_driver = {
+	.probe		= aspeed_pcie_phy_probe,
+	.driver = {
+		.name	= "aspeed-pcie-phy",
+		.of_match_table = aspeed_pcie_phy_of_match_table,
+	},
+};
+
+module_platform_driver(aspeed_pcie_driver);
+
+MODULE_AUTHOR("Jacky Chou <jacky_chou at aspeedtech.com>");
+MODULE_DESCRIPTION("ASPEED PCIe PHY");
+MODULE_LICENSE("GPL");
-- 
2.43.0



From jacky_chou at aspeedtech.com  Sun Aug 31 22:59:20 2025
From: jacky_chou at aspeedtech.com (Jacky Chou)
Date: Mon, 1 Sep 2025 13:59:20 +0800
Subject: [PATCH v3 08/10] PCI: Add FMT and TYPE definition for TLP header
In-Reply-To: <20250901055922.1553550-1-jacky_chou@aspeedtech.com>
References: <20250901055922.1553550-1-jacky_chou@aspeedtech.com>
Message-ID: <20250901055922.1553550-9-jacky_chou@aspeedtech.com>

According to PCIe specification, add FMT and TYPE definition
for TLP header.

Signed-off-by: Jacky Chou <jacky_chou at aspeedtech.com>
---
 drivers/pci/pci.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 34f65d69662e..45d47d6c4f53 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -81,6 +81,18 @@ struct pcie_tlp_log;
 #define PCIE_MSG_CODE_DEASSERT_INTC	0x26
 #define PCIE_MSG_CODE_DEASSERT_INTD	0x27
 
+/* Format of TLP; PCIe r5.0, sec 2.2.1 */
+#define PCIE_TLP_FMT_3DW_NO_DATA	0x00 /* 3DW header, no data */
+#define PCIE_TLP_FMT_4DW_NO_DATA	0x01 /* 4DW header, no data */
+#define PCIE_TLP_FMT_3DW_DATA		0x02 /* 3DW header, with data */
+#define PCIE_TLP_FMT_4DW_DATA		0x03 /* 4DW header, with data */
+
+/* Type of TLP; PCIe r5.0, sec 2.2.1 */
+#define PCIE_TLP_TYPE_CFG0_RD		0x04 /* Config Type 0 Read Request */
+#define PCIE_TLP_TYPE_CFG0_WR		0x04 /* Config Type 0 Write Request */
+#define PCIE_TLP_TYPE_CFG1_RD		0x05 /* Config Type 1 Read Request */
+#define PCIE_TLP_TYPE_CFG1_WR		0x05 /* Config Type 1 Write Request */
+
 extern const unsigned char pcie_link_speed[];
 extern bool pci_early_dump;
 
-- 
2.43.0



From jacky_chou at aspeedtech.com  Sun Aug 31 22:59:21 2025
From: jacky_chou at aspeedtech.com (Jacky Chou)
Date: Mon, 1 Sep 2025 13:59:21 +0800
Subject: [PATCH v3 09/10] PCI: aspeed: Add ASPEED PCIe RC driver
In-Reply-To: <20250901055922.1553550-1-jacky_chou@aspeedtech.com>
References: <20250901055922.1553550-1-jacky_chou@aspeedtech.com>
Message-ID: <20250901055922.1553550-10-jacky_chou@aspeedtech.com>

Introduce PCIe Root Complex driver for ASPEED SoCs. Support RC
initialization, reset, clock, IRQ domain, and MSI domain setup.
Implement platform-specific setup and register configuration for
ASPEED. And provide PCI config space read/write and INTx/MSI
interrupt handling.

Signed-off-by: Jacky Chou <jacky_chou at aspeedtech.com>
---
 drivers/pci/controller/Kconfig       |   16 +
 drivers/pci/controller/Makefile      |    1 +
 drivers/pci/controller/pcie-aspeed.c | 1137 ++++++++++++++++++++++++++
 3 files changed, 1154 insertions(+)
 create mode 100644 drivers/pci/controller/pcie-aspeed.c

diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index 41748d083b93..bd0fb96f9dbd 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -58,6 +58,22 @@ config PCI_VERSATILE
 	bool "ARM Versatile PB PCI controller"
 	depends on ARCH_VERSATILE || COMPILE_TEST
 
+config PCIE_ASPEED
+	bool "ASPEED PCIe controller"
+	depends on ARCH_ASPEED || COMPILE_TEST
+	depends on OF
+	depends on PCI_MSI
+	select IRQ_MSI_LIB
+	help
+	  Enable this option to add support for the PCIe controller
+	  found on ASPEED SoCs.
+
+	  This driver provides initialization and management for PCIe
+	  Root Complex functionality, including interrupt and MSI support.
+
+	  Select Y if your platform uses an ASPEED SoC and requires PCIe
+	  connectivity.
+
 config PCIE_BRCMSTB
 	tristate "Broadcom Brcmstb PCIe controller"
 	depends on ARCH_BRCMSTB || ARCH_BCM2835 || ARCH_BCMBCA || \
diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
index 038ccbd9e3ba..1339f88e153d 100644
--- a/drivers/pci/controller/Makefile
+++ b/drivers/pci/controller/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_PCI_LOONGSON) += pci-loongson.o
 obj-$(CONFIG_PCIE_HISI_ERR) += pcie-hisi-error.o
 obj-$(CONFIG_PCIE_APPLE) += pcie-apple.o
 obj-$(CONFIG_PCIE_MT7621) += pcie-mt7621.o
+obj-$(CONFIG_PCIE_ASPEED) += pcie-aspeed.o
 
 # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW
 obj-y				+= dwc/
diff --git a/drivers/pci/controller/pcie-aspeed.c b/drivers/pci/controller/pcie-aspeed.c
new file mode 100644
index 000000000000..3f684c09aa6c
--- /dev/null
+++ b/drivers/pci/controller/pcie-aspeed.c
@@ -0,0 +1,1137 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2025 Aspeed Technology Inc.
+ */
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqchip/irq-msi-lib.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/msi.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/of_pci.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/phy/pcie.h>
+#include <linux/phy/phy.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+
+#include "../pci.h"
+
+#define MAX_MSI_HOST_IRQS	64
+#define ASPEED_RESET_CONFIG_RC_WAIT_MS	10
+
+/* AST2600 AHBC Registers */
+#define AHBC_KEY		0x00
+#define  AHBC_UNLOCK_KEY		0xaeed1a03
+#define  AHBC_UNLOCK			0x01
+#define AHBC_ADDR_MAPPING	0x8c
+#define  PCIE_RC_MEMORY_EN		BIT(5)
+
+/* AST2600 H2X Controller Registers */
+#define H2X_INT_STS		0x08
+#define  PCIE_TX_IDLE_CLEAR		BIT(0)
+#define  PCIE_INTX_STS			GENMASK(3, 0)
+#define H2X_TX_DESC0		0x10
+#define H2X_TX_DESC1		0x14
+#define H2X_TX_DESC2		0x18
+#define H2X_TX_DESC3		0x1c
+#define H2X_TX_DESC_DATA	0x20
+#define H2X_STS			0x24
+#define  PCIE_TX_IDLE			BIT(31)
+#define  PCIE_STATUS_OF_TX		GENMASK(25, 24)
+#define	 PCIE_RC_L_TX_COMPLETE		BIT(24)
+#define	 PCIE_RC_H_TX_COMPLETE		BIT(25)
+#define  PCIE_TRIGGER_TX		BIT(0)
+#define H2X_AHB_ADDR_CONFIG0	0x60
+#define  AHB_REMAP_LO_ADDR(x)		FIELD_PREP(GENMASK(15, 4), x)
+#define  AHB_MASK_LO_ADDR(x)		FIELD_PREP(GENMASK(31, 20), x)
+#define H2X_AHB_ADDR_CONFIG1	0x64
+#define  AHB_REMAP_HI_ADDR(x)		(x)
+#define H2X_AHB_ADDR_CONFIG2	0x68
+#define  AHB_MASK_HI_ADDR(x)		(x)
+#define H2X_DEV_CTRL		0xc0
+#define  PCIE_RX_DMA_EN			BIT(9)
+#define  PCIE_RX_LINEAR			BIT(8)
+#define  PCIE_RX_MSI_SEL		BIT(7)
+#define  PCIE_RX_MSI_EN			BIT(6)
+#define  PCIE_UNLOCK_RX_BUFF		BIT(4)
+#define  PCIE_WAIT_RX_TLP_CLR		BIT(2)
+#define  PCIE_RC_RX_ENABLE		BIT(1)
+#define  PCIE_RC_ENABLE			BIT(0)
+#define H2X_DEV_STS		0xc8
+#define  PCIE_RC_RX_DONE_ISR		BIT(4)
+#define H2X_DEV_RX_DESC_DATA	0xcc
+#define H2X_DEV_RX_DESC1	0xd4
+#define H2X_DEV_TX_TAG		0xfc
+
+/* AST2700 H2X */
+#define H2X_CTRL		0x00
+#define  H2X_BRIDGE_EN			BIT(0)
+#define  H2X_BRIDGE_DIRECT_EN		BIT(1)
+#define H2X_CFGE_INT_STS	0x08
+#define  CFGE_TX_IDLE			BIT(0)
+#define  CFGE_RX_BUSY			BIT(1)
+#define H2X_CFGI_TLP		0x20
+#define  CFGI_BYTE_EN_MASK		GENMASK(19, 16)
+#define  CFGI_BYTE_EN(x)		FIELD_PREP(CFGI_BYTE_EN_MASK, (x))
+#define H2X_CFGI_WR_DATA	0x24
+#define  CFGI_WRITE			BIT(20)
+#define H2X_CFGI_CTRL		0x28
+#define  CFGI_TLP_FIRE			BIT(0)
+#define H2X_CFGI_RET_DATA	0x2c
+#define H2X_CFGE_TLP_1ST	0x30
+#define H2X_CFGE_TLP_NEXT	0x34
+#define H2X_CFGE_CTRL		0x38
+#define  CFGE_TLP_FIRE			BIT(0)
+#define H2X_CFGE_RET_DATA	0x3c
+#define H2X_REMAP_PREF_ADDR	0x70
+#define  REMAP_PREF_ADDR_63_32(x)	(x)
+#define H2X_REMAP_DIRECT_ADDR	0x78
+#define  REMAP_BAR_BASE(x)		(x)
+
+/* AST2700 SCU */
+#define SCU_60			0x60
+#define  RC_E2M_PATH_EN			BIT(0)
+#define  RC_H2XS_PATH_EN		BIT(16)
+#define  RC_H2XD_PATH_EN		BIT(17)
+#define  RC_H2XX_PATH_EN		BIT(18)
+#define  RC_UPSTREAM_MEM_EN		BIT(19)
+#define SCU_64			0x64
+#define  RC0_DECODE_DMA_BASE(x)		FIELD_PREP(GENMASK(7, 0), x)
+#define  RC0_DECODE_DMA_LIMIT(x)	FIELD_PREP(GENMASK(15, 8), x)
+#define  RC1_DECODE_DMA_BASE(x)		FIELD_PREP(GENMASK(23, 16), x)
+#define  RC1_DECODE_DMA_LIMIT(x)	FIELD_PREP(GENMASK(31, 24), x)
+#define SCU_70			0x70
+#define  DISABLE_EP_FUNC		0
+
+/* Macro to combine Fmt and Type into the 8-bit field */
+#define ASPEED_TLP_FMT_TYPE(fmt, type)	(((fmt) << 5) | ((type) & 0x1F))
+#define ASPEED_TLP_COMMON_FIELDS	GENMASK(31, 24)
+
+/* TLP configuration type 0 and type 1 */
+#define CRG0_READ_FMTTYPE                                        \
+	FIELD_PREP(ASPEED_TLP_COMMON_FIELDS,                     \
+		   ASPEED_TLP_FMT_TYPE(PCIE_TLP_FMT_3DW_NO_DATA, \
+				       PCIE_TLP_TYPE_CFG0_RD))
+#define CRG0_WRITE_FMTTYPE                                    \
+	FIELD_PREP(ASPEED_TLP_COMMON_FIELDS,                  \
+		   ASPEED_TLP_FMT_TYPE(PCIE_TLP_FMT_3DW_DATA, \
+				       PCIE_TLP_TYPE_CFG0_WR))
+#define CRG1_READ_FMTTYPE                                        \
+	FIELD_PREP(ASPEED_TLP_COMMON_FIELDS,                     \
+		   ASPEED_TLP_FMT_TYPE(PCIE_TLP_FMT_3DW_NO_DATA, \
+				       PCIE_TLP_TYPE_CFG1_RD))
+#define CRG1_WRITE_FMTTYPE                                    \
+	FIELD_PREP(ASPEED_TLP_COMMON_FIELDS,                  \
+		   ASPEED_TLP_FMT_TYPE(PCIE_TLP_FMT_3DW_DATA, \
+				       PCIE_TLP_TYPE_CFG1_WR))
+#define CRG_PAYLOAD_SIZE		0x01 /* 1 DWORD */
+#define TLP_HEADER_BYTE_EN(x, y)	((GENMASK((x) - 1, 0) << ((y) % 4)))
+#define TLP_GET_VALUE(x, y, z)	\
+	(((x) >> ((((z) % 4)) * 8)) & GENMASK((8 * (y)) - 1, 0))
+#define TLP_SET_VALUE(x, y, z)	\
+	((((x) & GENMASK((8 * (y)) - 1, 0)) << ((((z) % 4)) * 8)))
+#define AST2600_TX_DESC1_VALUE		0x00002000
+#define AST2700_TX_DESC1_VALUE		0x00401000
+
+/**
+ * struct aspeed_pcie_port - PCIe port information
+ * @list: port list
+ * @pcie: pointer to PCIe host info
+ * @clk: pointer to the port clock gate
+ * @phy: pointer to PCIe PHY
+ * @perst: pointer to port reset control
+ * @slot: port slot
+ */
+struct aspeed_pcie_port {
+	struct list_head list;
+	struct aspeed_pcie *pcie;
+	struct clk *clk;
+	struct phy *phy;
+	struct reset_control *perst;
+	u32 slot;
+};
+
+/**
+ * struct aspeed_pcie - PCIe RC information
+ * @host: pointer to PCIe host bridge
+ * @dev: pointer to device structure
+ * @reg: PCIe host register base address
+ * @ahbc: pointer to AHHC register map
+ * @cfg: pointer to Aspeed PCIe configuration register map
+ * @platform: platform specific information
+ * @ports: list of PCIe ports
+ * @domain: PCI domain number
+ * @tx_tag: current TX tag for the port
+ * @host_bus_num: bus number of the host bridge
+ * @h2xrst: pointer to H2X reset control
+ * @intx_domain: IRQ domain for INTx interrupts
+ * @msi_domain: IRQ domain for MSI interrupts
+ * @lock: mutex to protect MSI bitmap variable
+ * @msi_irq_in_use: bitmap to track used MSI host IRQs
+ */
+struct aspeed_pcie {
+	struct pci_host_bridge *host;
+	struct device *dev;
+	void __iomem *reg;
+	struct regmap *ahbc;
+	struct regmap *cfg;
+	const struct aspeed_pcie_rc_platform *platform;
+	struct list_head ports;
+
+	int domain;
+	u8 tx_tag;
+	int host_bus_num;
+
+	struct reset_control *h2xrst;
+
+	struct irq_domain *intx_domain;
+	struct irq_domain *msi_domain;
+	struct mutex lock;		/* Protect MSI bitmap variable */
+	DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_HOST_IRQS);
+};
+
+/**
+ * struct aspeed_pcie_rc_platform - Platform information
+ * @setup: initialization function
+ * @reg_intx_en: INTx enable register offset
+ * @reg_intx_sts: INTx status register offset
+ * @reg_msi_en: MSI enable register offset
+ * @reg_msi_sts: MSI enable register offset
+ * @msi_address: HW fixed MSI address
+ */
+struct aspeed_pcie_rc_platform {
+	int (*setup)(struct platform_device *pdev);
+	int reg_intx_en;
+	int reg_intx_sts;
+	int reg_msi_en;
+	int reg_msi_sts;
+	int msi_address;
+};
+
+static void aspeed_pcie_intx_irq_ack(struct irq_data *d)
+{
+	struct aspeed_pcie *pcie = irq_data_get_irq_chip_data(d);
+	int intx_en = pcie->platform->reg_intx_en;
+	u32 en;
+
+	en = readl(pcie->reg + intx_en);
+	en |= BIT(d->hwirq);
+	writel(en, pcie->reg + intx_en);
+}
+
+static void aspeed_pcie_intx_irq_mask(struct irq_data *d)
+{
+	struct aspeed_pcie *pcie = irq_data_get_irq_chip_data(d);
+	int intx_en = pcie->platform->reg_intx_en;
+	u32 en;
+
+	en = readl(pcie->reg + intx_en);
+	en &= ~BIT(d->hwirq);
+	writel(en, pcie->reg + intx_en);
+}
+
+static void aspeed_pcie_intx_irq_unmask(struct irq_data *d)
+{
+	struct aspeed_pcie *pcie = irq_data_get_irq_chip_data(d);
+	int intx_en = pcie->platform->reg_intx_en;
+	u32 en;
+
+	en = readl(pcie->reg + intx_en);
+	en |= BIT(d->hwirq);
+	writel(en, pcie->reg + intx_en);
+}
+
+static struct irq_chip aspeed_intx_irq_chip = {
+	.name = "INTx",
+	.irq_ack = aspeed_pcie_intx_irq_ack,
+	.irq_mask = aspeed_pcie_intx_irq_mask,
+	.irq_unmask = aspeed_pcie_intx_irq_unmask,
+};
+
+static int aspeed_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
+				irq_hw_number_t hwirq)
+{
+	irq_set_chip_and_handler(irq, &aspeed_intx_irq_chip, handle_level_irq);
+	irq_set_chip_data(irq, domain->host_data);
+	irq_set_status_flags(irq, IRQ_LEVEL);
+
+	return 0;
+}
+
+static const struct irq_domain_ops aspeed_intx_domain_ops = {
+	.map = aspeed_pcie_intx_map,
+};
+
+static irqreturn_t aspeed_pcie_intr_handler(int irq, void *dev_id)
+{
+	struct aspeed_pcie *pcie = dev_id;
+	const struct aspeed_pcie_rc_platform *platform = pcie->platform;
+	unsigned long status;
+	unsigned long intx;
+	u32 bit;
+	int i;
+
+	intx = FIELD_GET(PCIE_INTX_STS,
+			 readl(pcie->reg + platform->reg_intx_sts));
+	for_each_set_bit(bit, &intx, PCI_NUM_INTX)
+		generic_handle_domain_irq(pcie->intx_domain, bit);
+
+	if (IS_ENABLED(CONFIG_PCI_MSI)) {
+		for (i = 0; i < 2; i++) {
+			int msi_sts_reg = platform->reg_msi_sts + (i * 4);
+
+			status = readl(pcie->reg + msi_sts_reg);
+			writel(status, pcie->reg + msi_sts_reg);
+
+			/*
+			 * AST2700 A1 workaround:
+			 * The MSI status needs to clear one more time.
+			 */
+			if (of_device_is_compatible(pcie->dev->of_node,
+						    "aspeed,ast2700-pcie"))
+				writel(status, pcie->reg + msi_sts_reg);
+
+			for_each_set_bit(bit, &status, 32) {
+				bit += (i * 32);
+				generic_handle_domain_irq(pcie->msi_domain,
+							  bit);
+			}
+		}
+	}
+
+	return IRQ_HANDLED;
+}
+
+static u32 aspeed_pcie_get_bdf_offset(struct pci_bus *bus, unsigned int devfn,
+				      int where)
+{
+	return ((bus->number) << 24) | (PCI_SLOT(devfn) << 19) |
+		(PCI_FUNC(devfn) << 16) | (where & ~3);
+}
+
+static int aspeed_ast2600_conf(struct pci_bus *bus, unsigned int devfn,
+			       int where, int size, u32 *val, u32 fmt_type,
+			       bool write)
+{
+	struct aspeed_pcie *pcie = bus->sysdata;
+	u32 bdf_offset, cfg_val, isr;
+	int ret;
+
+	bdf_offset = aspeed_pcie_get_bdf_offset(bus, devfn, where);
+
+	/* Driver may set unlock RX buffer before triggering next TX config */
+	writel(PCIE_UNLOCK_RX_BUFF | readl(pcie->reg + H2X_DEV_CTRL),
+	       pcie->reg + H2X_DEV_CTRL);
+
+	cfg_val = fmt_type | CRG_PAYLOAD_SIZE;
+	writel(cfg_val, pcie->reg + H2X_TX_DESC0);
+
+	cfg_val = AST2600_TX_DESC1_VALUE |
+		  FIELD_PREP(GENMASK(11, 8), pcie->tx_tag) |
+		  TLP_HEADER_BYTE_EN(size, where);
+	writel(cfg_val, pcie->reg + H2X_TX_DESC1);
+
+	writel(bdf_offset, pcie->reg + H2X_TX_DESC2);
+	writel(0, pcie->reg + H2X_TX_DESC3);
+	if (write)
+		writel(TLP_SET_VALUE(*val, size, where),
+		       pcie->reg + H2X_TX_DESC_DATA);
+
+	cfg_val = readl(pcie->reg + H2X_STS);
+	cfg_val |= PCIE_TRIGGER_TX;
+	writel(cfg_val, pcie->reg + H2X_STS);
+
+	ret = readl_poll_timeout(pcie->reg + H2X_STS, cfg_val,
+				 (cfg_val & PCIE_TX_IDLE), 0, 50);
+	if (ret) {
+		dev_err(pcie->dev,
+			"%04x:%02x:%02x.%d CR tx timeout sts: 0x%08x\n",
+			pcie->domain, bus->number, PCI_SLOT(devfn),
+			PCI_FUNC(devfn), cfg_val);
+		ret = PCIBIOS_SET_FAILED;
+		PCI_SET_ERROR_RESPONSE(val);
+		goto out;
+	}
+
+	cfg_val = readl(pcie->reg + H2X_INT_STS);
+	cfg_val |= PCIE_TX_IDLE_CLEAR;
+	writel(cfg_val, pcie->reg + H2X_INT_STS);
+
+	cfg_val = readl(pcie->reg + H2X_STS);
+	switch (cfg_val & PCIE_STATUS_OF_TX) {
+	case PCIE_RC_L_TX_COMPLETE:
+	case PCIE_RC_H_TX_COMPLETE:
+		ret = readl_poll_timeout(pcie->reg + H2X_DEV_STS, isr,
+					 (isr & PCIE_RC_RX_DONE_ISR), 0, 50);
+		if (ret) {
+			dev_err(pcie->dev,
+				"%04x:%02x:%02x.%d CR rx timeout sts: 0x%08x\n",
+				pcie->domain, bus->number, PCI_SLOT(devfn),
+				PCI_FUNC(devfn), isr);
+			ret = PCIBIOS_SET_FAILED;
+			PCI_SET_ERROR_RESPONSE(val);
+			goto out;
+		}
+		if (!write) {
+			if (readl(pcie->reg + H2X_DEV_RX_DESC1) & BIT(13)) {
+				ret = PCIBIOS_SET_FAILED;
+				PCI_SET_ERROR_RESPONSE(val);
+				goto out;
+			} else {
+				*val = readl(pcie->reg + H2X_DEV_RX_DESC_DATA);
+			}
+		}
+		break;
+	case PCIE_STATUS_OF_TX:
+		ret = PCIBIOS_SET_FAILED;
+		PCI_SET_ERROR_RESPONSE(val);
+		goto out;
+	default:
+		*val = readl(pcie->reg + H2X_DEV_RX_DESC_DATA);
+		break;
+	}
+
+	writel(PCIE_UNLOCK_RX_BUFF | readl(pcie->reg + H2X_DEV_CTRL),
+	       pcie->reg + H2X_DEV_CTRL);
+
+	*val = TLP_GET_VALUE(*val, size, where);
+
+	ret = PCIBIOS_SUCCESSFUL;
+out:
+	writel(readl(pcie->reg + H2X_DEV_STS), pcie->reg + H2X_DEV_STS);
+	pcie->tx_tag = (pcie->tx_tag + 1) % 0x8;
+	return ret;
+}
+
+static int aspeed_ast2600_rd_conf(struct pci_bus *bus, unsigned int devfn,
+				  int where, int size, u32 *val)
+{
+	int slot = PCI_SLOT(devfn);
+
+	/*
+	 * AST2600 has only one host on dev 0 and one root port on dev
+	 * 8 in root bus.
+	 */
+	if (slot != 0 && slot != 8)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return aspeed_ast2600_conf(bus, devfn, where, size, val,
+				   CRG0_READ_FMTTYPE, false);
+}
+
+static int aspeed_ast2600_child_rd_conf(struct pci_bus *bus, unsigned int devfn,
+					int where, int size, u32 *val)
+{
+	return aspeed_ast2600_conf(bus, devfn, where, size, val,
+				   CRG1_READ_FMTTYPE, false);
+}
+
+static int aspeed_ast2600_wr_conf(struct pci_bus *bus, unsigned int devfn,
+				  int where, int size, u32 val)
+{
+	int slot = PCI_SLOT(devfn);
+
+	/*
+	 * AST2600 has only one host on dev 0 and one root port on dev
+	 * 8 in root bus.
+	 */
+	if (slot != 0 && slot != 8)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return aspeed_ast2600_conf(bus, devfn, where, size, &val,
+				   CRG0_WRITE_FMTTYPE, true);
+}
+
+static int aspeed_ast2600_child_wr_conf(struct pci_bus *bus, unsigned int devfn,
+					int where, int size, u32 val)
+{
+	return aspeed_ast2600_conf(bus, devfn, where, size, &val,
+				   CRG1_WRITE_FMTTYPE, true);
+}
+
+static int aspeed_ast2700_config(struct pci_bus *bus, unsigned int devfn,
+				 int where, int size, u32 *val, bool write)
+{
+	struct aspeed_pcie *pcie = bus->sysdata;
+	u32 cfg_val;
+
+	cfg_val = CFGI_BYTE_EN(TLP_HEADER_BYTE_EN(size, where)) | (where & ~3);
+	if (write)
+		cfg_val |= CFGI_WRITE;
+	writel(cfg_val, pcie->reg + H2X_CFGI_TLP);
+
+	writel(TLP_SET_VALUE(*val, size, where), pcie->reg + H2X_CFGI_WR_DATA);
+	writel(CFGI_TLP_FIRE, pcie->reg + H2X_CFGI_CTRL);
+	*val = readl(pcie->reg + H2X_CFGI_RET_DATA);
+	*val = TLP_GET_VALUE(*val, size, where);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int aspeed_ast2700_child_config(struct pci_bus *bus, unsigned int devfn,
+				       int where, int size, u32 *val,
+				       bool write)
+{
+	struct aspeed_pcie *pcie = bus->sysdata;
+	u32 bdf_offset, status, cfg_val;
+	int ret;
+
+	bdf_offset = aspeed_pcie_get_bdf_offset(bus, devfn, where);
+
+	cfg_val = CRG_PAYLOAD_SIZE;
+	if (write)
+		cfg_val |= (bus->number == (pcie->host_bus_num + 1)) ?
+				   CRG0_WRITE_FMTTYPE :
+				   CRG1_WRITE_FMTTYPE;
+	else
+		cfg_val |= (bus->number == (pcie->host_bus_num + 1)) ?
+				   CRG0_READ_FMTTYPE :
+				   CRG1_READ_FMTTYPE;
+	writel(cfg_val, pcie->reg + H2X_CFGE_TLP_1ST);
+
+	cfg_val = AST2700_TX_DESC1_VALUE |
+		  FIELD_PREP(GENMASK(11, 8), pcie->tx_tag) |
+		  TLP_HEADER_BYTE_EN(size, where);
+	writel(cfg_val, pcie->reg + H2X_CFGE_TLP_NEXT);
+
+	writel(bdf_offset, pcie->reg + H2X_CFGE_TLP_NEXT);
+	if (write)
+		writel(TLP_SET_VALUE(*val, size, where),
+		       pcie->reg + H2X_CFGE_TLP_NEXT);
+	writel(CFGE_TX_IDLE | CFGE_RX_BUSY, pcie->reg + H2X_CFGE_INT_STS);
+	writel(CFGE_TLP_FIRE, pcie->reg + H2X_CFGE_CTRL);
+
+	ret = readl_poll_timeout(pcie->reg + H2X_CFGE_INT_STS, status,
+				 (status & CFGE_TX_IDLE), 0, 50);
+	if (ret) {
+		dev_err(pcie->dev,
+			"%04x:%02x:%02x.%d CR tx timeout sts: 0x%08x\n",
+			pcie->domain, bus->number, PCI_SLOT(devfn),
+			PCI_FUNC(devfn), status);
+		ret = PCIBIOS_SET_FAILED;
+		PCI_SET_ERROR_RESPONSE(val);
+		goto out;
+	}
+
+	ret = readl_poll_timeout(pcie->reg + H2X_CFGE_INT_STS, status,
+				 (status & CFGE_RX_BUSY), 0, 50);
+	if (ret) {
+		dev_err(pcie->dev,
+			"%04x:%02x:%02x.%d CR rx timeoutsts: 0x%08x\n",
+			pcie->domain, bus->number, PCI_SLOT(devfn),
+			PCI_FUNC(devfn), status);
+		ret = PCIBIOS_SET_FAILED;
+		PCI_SET_ERROR_RESPONSE(val);
+		goto out;
+	}
+	*val = readl(pcie->reg + H2X_CFGE_RET_DATA);
+	*val = TLP_GET_VALUE(*val, size, where);
+
+	ret = PCIBIOS_SUCCESSFUL;
+out:
+	writel(status, pcie->reg + H2X_CFGE_INT_STS);
+	pcie->tx_tag = (pcie->tx_tag + 1) % 0xf;
+	return ret;
+}
+
+static int aspeed_ast2700_rd_conf(struct pci_bus *bus, unsigned int devfn,
+				  int where, int size, u32 *val)
+{
+	/*
+	 * AST2700 has only one root port on dev 0 in root bus.
+	 */
+	if (devfn != 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return aspeed_ast2700_config(bus, devfn, where, size, val, false);
+}
+
+static int aspeed_ast2700_child_rd_conf(struct pci_bus *bus, unsigned int devfn,
+					int where, int size, u32 *val)
+{
+	return aspeed_ast2700_child_config(bus, devfn, where, size, val, false);
+}
+
+static int aspeed_ast2700_wr_conf(struct pci_bus *bus, unsigned int devfn,
+				  int where, int size, u32 val)
+{
+	/*
+	 * AST2700 has only one root port on dev 0 in root bus.
+	 */
+	if (devfn != 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return aspeed_ast2700_config(bus, devfn, where, size, &val, true);
+}
+
+static int aspeed_ast2700_child_wr_conf(struct pci_bus *bus, unsigned int devfn,
+					int where, int size, u32 val)
+{
+	return aspeed_ast2700_child_config(bus, devfn, where, size, &val, true);
+}
+
+static struct pci_ops aspeed_ast2600_pcie_ops = {
+	.read = aspeed_ast2600_rd_conf,
+	.write = aspeed_ast2600_wr_conf,
+};
+
+static struct pci_ops aspeed_ast2600_pcie_child_ops = {
+	.read = aspeed_ast2600_child_rd_conf,
+	.write = aspeed_ast2600_child_wr_conf,
+};
+
+static struct pci_ops aspeed_ast2700_pcie_ops = {
+	.read = aspeed_ast2700_rd_conf,
+	.write = aspeed_ast2700_wr_conf,
+};
+
+static struct pci_ops aspeed_ast2700_pcie_child_ops = {
+	.read = aspeed_ast2700_child_rd_conf,
+	.write = aspeed_ast2700_child_wr_conf,
+};
+
+#ifdef CONFIG_PCI_MSI
+static void aspeed_msi_compose_msi_msg(struct irq_data *data,
+				       struct msi_msg *msg)
+{
+	struct aspeed_pcie *pcie = irq_data_get_irq_chip_data(data);
+
+	msg->address_hi = 0;
+	msg->address_lo = pcie->platform->msi_address;
+	msg->data = data->hwirq;
+}
+
+static int aspeed_msi_set_affinity(struct irq_data *irq_data,
+				   const struct cpumask *mask, bool force)
+{
+	return -EINVAL;
+}
+
+static struct irq_chip aspeed_msi_bottom_irq_chip = {
+	.name = "ASPEED MSI",
+	.irq_compose_msi_msg = aspeed_msi_compose_msi_msg,
+	.irq_set_affinity = aspeed_msi_set_affinity,
+};
+
+static int aspeed_irq_msi_domain_alloc(struct irq_domain *domain,
+				       unsigned int virq, unsigned int nr_irqs,
+				       void *args)
+{
+	struct aspeed_pcie *pcie = domain->host_data;
+	int bit;
+	int i;
+
+	guard(mutex)(&pcie->lock);
+
+	bit = bitmap_find_free_region(pcie->msi_irq_in_use, MAX_MSI_HOST_IRQS,
+				      get_count_order(nr_irqs));
+
+	if (bit < 0)
+		return -ENOSPC;
+
+	for (i = 0; i < nr_irqs; i++) {
+		irq_domain_set_info(domain, virq + i, bit + i,
+				    &aspeed_msi_bottom_irq_chip,
+				    domain->host_data, handle_simple_irq, NULL,
+				    NULL);
+	}
+
+	return 0;
+}
+
+static void aspeed_irq_msi_domain_free(struct irq_domain *domain,
+				       unsigned int virq, unsigned int nr_irqs)
+{
+	struct irq_data *data = irq_domain_get_irq_data(domain, virq);
+	struct aspeed_pcie *pcie = irq_data_get_irq_chip_data(data);
+
+	mutex_lock(&pcie->lock);
+
+	bitmap_release_region(pcie->msi_irq_in_use, data->hwirq,
+			      get_count_order(nr_irqs));
+
+	mutex_unlock(&pcie->lock);
+}
+
+static const struct irq_domain_ops aspeed_msi_domain_ops = {
+	.alloc = aspeed_irq_msi_domain_alloc,
+	.free = aspeed_irq_msi_domain_free,
+};
+
+#define ASPEED_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS	| \
+				  MSI_FLAG_USE_DEF_CHIP_OPS	| \
+				  MSI_FLAG_NO_AFFINITY)
+
+#define ASPEED_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK	| \
+				   MSI_FLAG_MULTI_PCI_MSI	| \
+				   MSI_FLAG_PCI_MSIX)
+
+static const struct msi_parent_ops aspeed_msi_parent_ops = {
+	.required_flags		= ASPEED_MSI_FLAGS_REQUIRED,
+	.supported_flags	= ASPEED_MSI_FLAGS_SUPPORTED,
+	.bus_select_token	= DOMAIN_BUS_PCI_MSI,
+	.chip_flags		= MSI_CHIP_FLAG_SET_ACK,
+	.prefix			= "ASPEED-",
+	.init_dev_msi_info	= msi_lib_init_dev_msi_info,
+};
+
+static int aspeed_pcie_msi_init(struct aspeed_pcie *pcie)
+{
+	int ret = 0;
+
+	writel(~0, pcie->reg + pcie->platform->reg_msi_en);
+	writel(~0, pcie->reg + pcie->platform->reg_msi_en + 0x04);
+	writel(~0, pcie->reg + pcie->platform->reg_msi_sts);
+	writel(~0, pcie->reg + pcie->platform->reg_msi_sts + 0x04);
+
+	struct irq_domain_info info = {
+		.fwnode		= dev_fwnode(pcie->dev),
+		.ops		= &aspeed_msi_domain_ops,
+		.host_data	= pcie,
+		.size		= MAX_MSI_HOST_IRQS,
+	};
+
+	pcie->msi_domain = msi_create_parent_irq_domain(&info,
+							&aspeed_msi_parent_ops);
+	if (!pcie->msi_domain)
+		return dev_err_probe(pcie->dev, -ENOMEM,
+				     "failed to create MSI domain\n");
+
+	return ret;
+}
+
+static void aspeed_pcie_msi_free(struct aspeed_pcie *pcie)
+{
+	if (pcie->msi_domain) {
+		irq_domain_remove(pcie->msi_domain);
+		pcie->msi_domain = NULL;
+	}
+}
+#else
+static int aspeed_pcie_msi_init(struct aspeed_pcie *pcie)
+{
+	return 0;
+}
+
+static void aspeed_pcie_msi_free(struct aspeed_pcie *pcie) {}
+#endif
+
+static void aspeed_pcie_irq_domain_free(void *d)
+{
+	struct aspeed_pcie *pcie = d;
+
+	if (pcie->intx_domain) {
+		irq_domain_remove(pcie->intx_domain);
+		pcie->intx_domain = NULL;
+	}
+	aspeed_pcie_msi_free(pcie);
+}
+
+static int aspeed_pcie_init_irq_domain(struct aspeed_pcie *pcie)
+{
+	struct device *dev = pcie->dev;
+	struct device_node *node = dev->of_node;
+	struct device_node *pcie_intc_node;
+	int ret;
+
+	pcie_intc_node = of_get_next_child(node, NULL);
+	if (!pcie_intc_node)
+		return dev_err_probe(dev, -ENODEV, "No PCIe INTc node found\n");
+
+	pcie->intx_domain = irq_domain_add_linear(pcie_intc_node,
+						  PCI_NUM_INTX,
+						  &aspeed_intx_domain_ops,
+						  pcie);
+	of_node_put(pcie_intc_node);
+	if (!pcie->intx_domain) {
+		ret = dev_err_probe(dev, -ENOMEM,
+				    "failed to get INTx IRQ domain\n");
+		goto err;
+	}
+
+	writel(0, pcie->reg + pcie->platform->reg_intx_en);
+	writel(~0, pcie->reg + pcie->platform->reg_intx_sts);
+
+	ret = aspeed_pcie_msi_init(pcie);
+	if (ret)
+		goto err;
+
+	return 0;
+err:
+	aspeed_pcie_irq_domain_free(pcie);
+	return ret;
+}
+
+static int aspeed_pcie_port_init(struct aspeed_pcie_port *port)
+{
+	struct aspeed_pcie *pcie = port->pcie;
+	struct device *dev = pcie->dev;
+	int ret;
+
+	ret = clk_prepare_enable(port->clk);
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to enable clk pcie%d\n",
+				     port->slot);
+
+	ret = phy_init(port->phy);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "failed to initialize phy pcie%d\n",
+				     port->slot);
+
+	ret = phy_set_mode_ext(port->phy, PHY_MODE_PCIE, PHY_MODE_PCIE_RC);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "failed to set phy pcie%d\n", port->slot);
+
+	reset_control_deassert(port->perst);
+	mdelay(PCIE_RESET_CONFIG_WAIT_MS);
+
+	return 0;
+}
+
+static int aspeed_pcie_init_ports(struct aspeed_pcie *pcie)
+{
+	struct aspeed_pcie_port *port, *tmp;
+	u8 num_enabled = 0;
+
+	list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
+		int ret;
+
+		ret = aspeed_pcie_port_init(port);
+		if (ret)
+			list_del(&port->list);
+		else
+			num_enabled++;
+	}
+
+	return (num_enabled > 0) ? 0 : -ENODEV;
+}
+
+static void aspeed_host_reset(struct aspeed_pcie *pcie)
+{
+	reset_control_assert(pcie->h2xrst);
+	mdelay(ASPEED_RESET_CONFIG_RC_WAIT_MS);
+	reset_control_deassert(pcie->h2xrst);
+}
+
+static int aspeed_ast2600_setup(struct platform_device *pdev)
+{
+	struct aspeed_pcie *pcie = platform_get_drvdata(pdev);
+	struct device *dev = pcie->dev;
+
+	if (pcie->host_bus_num != 0x80)
+		return dev_err_probe(dev, -EINVAL,
+				     "The host bus must be 0x80\n");
+
+	pcie->ahbc = syscon_regmap_lookup_by_phandle(dev->of_node,
+						     "aspeed,ahbc");
+	if (IS_ERR(pcie->ahbc))
+		return dev_err_probe(dev, PTR_ERR(pcie->ahbc),
+				     "failed to map ahbc base\n");
+
+	aspeed_host_reset(pcie);
+
+	regmap_write(pcie->ahbc, AHBC_KEY, AHBC_UNLOCK_KEY);
+	regmap_update_bits(pcie->ahbc, AHBC_ADDR_MAPPING, PCIE_RC_MEMORY_EN,
+			   PCIE_RC_MEMORY_EN);
+	regmap_write(pcie->ahbc, AHBC_KEY, AHBC_UNLOCK);
+
+	writel(AHB_REMAP_LO_ADDR(0x600) | AHB_MASK_LO_ADDR(0xe00),
+	       pcie->reg + H2X_AHB_ADDR_CONFIG0);
+	writel(AHB_REMAP_HI_ADDR(0), pcie->reg + H2X_AHB_ADDR_CONFIG1);
+	writel(AHB_MASK_HI_ADDR(~0), pcie->reg + H2X_AHB_ADDR_CONFIG2);
+	writel(H2X_BRIDGE_EN, pcie->reg + H2X_CTRL);
+
+	writel(PCIE_RX_DMA_EN | PCIE_RX_LINEAR | PCIE_RX_MSI_SEL |
+	       PCIE_RX_MSI_EN | PCIE_WAIT_RX_TLP_CLR |
+	       PCIE_RC_RX_ENABLE | PCIE_RC_ENABLE,
+	       pcie->reg + H2X_DEV_CTRL);
+
+	writel(0x28, pcie->reg + H2X_DEV_TX_TAG);
+
+	pcie->host->ops = &aspeed_ast2600_pcie_ops;
+	pcie->host->child_ops = &aspeed_ast2600_pcie_child_ops;
+
+	return 0;
+}
+
+static int aspeed_ast2700_bar_assign(struct aspeed_pcie *pcie)
+{
+	struct resource_entry *win, *tmp;
+	struct pci_host_bridge *bridge = pcie->host;
+
+	resource_list_for_each_entry_safe(win, tmp, &bridge->windows) {
+		struct resource *res = win->res;
+
+		if (resource_type(res) == IORESOURCE_MEM &&
+		    !(res->flags & IORESOURCE_MEM_64)) {
+			writel(REMAP_BAR_BASE(res->start),
+			       pcie->reg + H2X_REMAP_DIRECT_ADDR);
+			return 0;
+		}
+	}
+
+	return -ENODEV;
+}
+
+static int aspeed_ast2700_setup(struct platform_device *pdev)
+{
+	struct aspeed_pcie *pcie = platform_get_drvdata(pdev);
+	struct device *dev = pcie->dev;
+	int ret;
+
+	pcie->cfg = syscon_regmap_lookup_by_phandle(dev->of_node,
+						    "aspeed,pciecfg");
+	if (IS_ERR(pcie->cfg))
+		return dev_err_probe(dev, PTR_ERR(pcie->cfg),
+				     "failed to map pciecfg base\n");
+
+	regmap_update_bits(pcie->cfg, SCU_60,
+			   RC_E2M_PATH_EN | RC_H2XS_PATH_EN | RC_H2XD_PATH_EN |
+			   RC_H2XX_PATH_EN | RC_UPSTREAM_MEM_EN,
+			   RC_E2M_PATH_EN | RC_H2XS_PATH_EN | RC_H2XD_PATH_EN |
+			   RC_H2XX_PATH_EN | RC_UPSTREAM_MEM_EN);
+	regmap_write(pcie->cfg, SCU_64,
+		     RC0_DECODE_DMA_BASE(0) | RC0_DECODE_DMA_LIMIT(0xff) |
+		     RC1_DECODE_DMA_BASE(0) | RC1_DECODE_DMA_LIMIT(0xff));
+	regmap_write(pcie->cfg, SCU_70, DISABLE_EP_FUNC);
+
+	aspeed_host_reset(pcie);
+
+	writel(0, pcie->reg + H2X_CTRL);
+	writel(H2X_BRIDGE_EN | H2X_BRIDGE_DIRECT_EN, pcie->reg + H2X_CTRL);
+
+	ret = aspeed_ast2700_bar_assign(pcie);
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to assign BAR\n");
+
+	/* Prepare for 64-bit BAR pref */
+	writel(REMAP_PREF_ADDR_63_32(0x3), pcie->reg + H2X_REMAP_PREF_ADDR);
+
+	pcie->host->ops = &aspeed_ast2700_pcie_ops;
+	pcie->host->child_ops = &aspeed_ast2700_pcie_child_ops;
+
+	return 0;
+}
+
+static void aspeed_pcie_reset_release(void *d)
+{
+	struct reset_control *perst = d;
+
+	if (!perst)
+		return;
+
+	reset_control_put(perst);
+}
+
+static int aspeed_pcie_parse_port(struct aspeed_pcie *pcie,
+				  struct device_node *node,
+				  int slot)
+{
+	struct aspeed_pcie_port *port;
+	struct device *dev = pcie->dev;
+	int ret;
+
+	port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
+	if (!port)
+		return -ENOMEM;
+
+	port->clk = devm_get_clk_from_child(dev, node, NULL);
+	if (IS_ERR(port->clk))
+		return dev_err_probe(dev, PTR_ERR(port->clk),
+				     "failed to get pcie%d clock\n", slot);
+
+	port->phy = devm_of_phy_get(dev, node, NULL);
+	if (IS_ERR(port->phy))
+		return dev_err_probe(dev, PTR_ERR(port->phy),
+				     "failed to get phy pcie%d\n",
+				     port->slot);
+
+	port->perst = of_reset_control_get_exclusive(node, "perst");
+	if (IS_ERR(port->perst))
+		return dev_err_probe(dev, PTR_ERR(port->perst),
+				     "failed to get pcie%d reset control\n",
+				     slot);
+	ret = devm_add_action_or_reset(dev, aspeed_pcie_reset_release,
+				       port->perst);
+	if (ret)
+		return ret;
+	reset_control_assert(port->perst);
+
+	port->slot = slot;
+	port->pcie = pcie;
+
+	INIT_LIST_HEAD(&port->list);
+	list_add_tail(&port->list, &pcie->ports);
+
+	return 0;
+}
+
+static int aspeed_pcie_parse_dt(struct aspeed_pcie *pcie)
+{
+	struct device *dev = pcie->dev;
+	struct device_node *node = dev->of_node;
+	int ret;
+
+	for_each_available_child_of_node_scoped(node, child) {
+		int slot;
+		const char *type;
+
+		ret = of_property_read_string(child, "device_type", &type);
+		if (ret || strcmp(type, "pci"))
+			continue;
+
+		ret = of_pci_get_devfn(child);
+		if (ret < 0)
+			return dev_err_probe(dev, ret,
+					     "failed to parse devfn\n");
+
+		slot = PCI_SLOT(ret);
+
+		ret = aspeed_pcie_parse_port(pcie, child, slot);
+		if (ret)
+			return ret;
+	}
+
+	if (list_empty(&pcie->ports))
+		return dev_err_probe(dev, -ENODEV,
+				     "No PCIe port found in DT\n");
+
+	return 0;
+}
+
+static int aspeed_pcie_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct pci_host_bridge *host;
+	struct aspeed_pcie *pcie;
+	struct device_node *node = dev->of_node;
+	const struct aspeed_pcie_rc_platform *md;
+	u32 bus_range[2];
+	int irq, ret;
+
+	md = of_device_get_match_data(dev);
+	if (!md)
+		return -ENODEV;
+
+	host = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
+	if (!host)
+		return -ENOMEM;
+
+	pcie = pci_host_bridge_priv(host);
+	pcie->dev = dev;
+	pcie->tx_tag = 0;
+	platform_set_drvdata(pdev, pcie);
+
+	pcie->platform = md;
+	pcie->host = host;
+	INIT_LIST_HEAD(&pcie->ports);
+
+	ret = of_property_read_u32_array(node, "bus-range", bus_range,
+					 ARRAY_SIZE(bus_range));
+	if (ret) {
+		dev_warn(dev, "failed to get bus range, assuming bus is 0\n");
+		pcie->host_bus_num = 0;
+	}
+	pcie->host_bus_num = bus_range[0];
+
+	pcie->reg = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(pcie->reg))
+		return PTR_ERR(pcie->reg);
+
+	pcie->domain = of_get_pci_domain_nr(node);
+
+	pcie->h2xrst = devm_reset_control_get_exclusive(dev, "h2x");
+	if (IS_ERR(pcie->h2xrst))
+		return dev_err_probe(dev, PTR_ERR(pcie->h2xrst),
+				     "failed to get h2x reset\n");
+
+	ret = devm_mutex_init(dev, &pcie->lock);
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to init mutex\n");
+
+	ret = pcie->platform->setup(pdev);
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to setup PCIe RC\n");
+
+	ret = aspeed_pcie_parse_dt(pcie);
+	if (ret)
+		return ret;
+
+	ret = aspeed_pcie_init_ports(pcie);
+	if (ret)
+		return ret;
+
+	host->sysdata = pcie;
+
+	ret = aspeed_pcie_init_irq_domain(pcie);
+	if (ret)
+		return ret;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
+
+	ret = devm_add_action_or_reset(dev, aspeed_pcie_irq_domain_free, pcie);
+	if (ret)
+		return ret;
+
+	ret = devm_request_irq(dev, irq, aspeed_pcie_intr_handler, IRQF_SHARED,
+			       dev_name(dev), pcie);
+	if (ret)
+		return ret;
+
+	ret = pci_host_probe(host);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+const struct aspeed_pcie_rc_platform pcie_rc_ast2600 = {
+	.setup = aspeed_ast2600_setup,
+	.reg_intx_en = 0xc4,
+	.reg_intx_sts = 0xc8,
+	.reg_msi_en = 0xe0,
+	.reg_msi_sts = 0xe8,
+	.msi_address = 0x1e77005c,
+};
+
+const struct aspeed_pcie_rc_platform pcie_rc_ast2700 = {
+	.setup = aspeed_ast2700_setup,
+	.reg_intx_en = 0x40,
+	.reg_intx_sts = 0x48,
+	.reg_msi_en = 0x50,
+	.reg_msi_sts = 0x58,
+	.msi_address = 0x000000f0,
+};
+
+static const struct of_device_id aspeed_pcie_of_match[] = {
+	{ .compatible = "aspeed,ast2600-pcie", .data = &pcie_rc_ast2600 },
+	{ .compatible = "aspeed,ast2700-pcie", .data = &pcie_rc_ast2700 },
+	{}
+};
+
+static struct platform_driver aspeed_pcie_driver = {
+	.driver = {
+		.name = "aspeed-pcie",
+		.of_match_table = aspeed_pcie_of_match,
+	},
+	.probe = aspeed_pcie_probe,
+};
+
+module_platform_driver(aspeed_pcie_driver);
+
+MODULE_AUTHOR("Jacky Chou <jacky_chou at aspeedtech.com>");
+MODULE_DESCRIPTION("ASPEED PCIe Root Complex");
+MODULE_LICENSE("GPL");
-- 
2.43.0



From jacky_chou at aspeedtech.com  Sun Aug 31 22:59:22 2025
From: jacky_chou at aspeedtech.com (Jacky Chou)
Date: Mon, 1 Sep 2025 13:59:22 +0800
Subject: [PATCH v3 10/10] MAINTAINERS: Add ASPEED PCIe RC driver
In-Reply-To: <20250901055922.1553550-1-jacky_chou@aspeedtech.com>
References: <20250901055922.1553550-1-jacky_chou@aspeedtech.com>
Message-ID: <20250901055922.1553550-11-jacky_chou@aspeedtech.com>

Add maintainer for ASPEED PCIe RC driver.

Signed-off-by: Jacky Chou <jacky_chou at aspeedtech.com>
---
 MAINTAINERS | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 6dcfbd11efef..178bfe82880d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3791,6 +3791,17 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/media/aspeed,video-engine.yaml
 F:	drivers/media/platform/aspeed/
 
+ASPEED PCIE CONTROLLER DRIVER
+M:	Jacky Chou <jacky_chou at aspeedtech.com>
+L:	linux-aspeed at lists.ozlabs.org (moderated for non-subscribers)
+L:	linux-pci at vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/pci/aspeed,ast2600-pcie.yaml
+F:	Documentation/devicetree/bindings/phy/aspeed,ast2600-pcie-phy.yaml
+F:	Documentation/devicetree/bindings/soc/aspeed/aspeed,ast2700-pcie-cfg.yaml
+F:	drivers/pci/controller/pcie-aspeed.c
+F:	drivers/phy/aspeed/pcie-phy-aspeed.c
+
 ASUS EC HARDWARE MONITOR DRIVER
 M:	Eugene Shalygin <eugene.shalygin at gmail.com>
 L:	linux-hwmon at vger.kernel.org
-- 
2.43.0



From vkoul at kernel.org  Wed Aug 20 10:03:01 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 20 Aug 2025 17:03:01 -0000
Subject: (subset) [PATCH 00/21] treewide: remove unneeded 'fast_io'
 parameter in regmap_config
In-Reply-To: <20250813161517.4746-1-wsa+renesas@sang-engineering.com>
References: <20250813161517.4746-1-wsa+renesas@sang-engineering.com>
Message-ID: <175570934550.66459.15951444863822303407.b4-ty@kernel.org>


On Wed, 13 Aug 2025 18:14:46 +0200, Wolfram Sang wrote:
> While working on a driver using regmap with MMIO, I wondered if I need
> to set 'fast_io' in the config. Turned out I don't need to, so I added
> documentation for it with commit ffc72771ff6e ("regmap: Annotate that
> MMIO implies fast IO").
> 
> This series fixes the existing users in the tree which needlessly set
> the flag. They have been found using this coccinelle script:
> 
> [...]

Applied, thanks!

[12/21] phy: remove unneeded 'fast_io' parameter in regmap_config
        commit: e1e1e77f7df7cbee959ba024e5475907fe561c98

Best regards,
-- 
~Vinod




