* [PATCH v2 2/5] phy: rockchip: inno-usb2: Simplify rockchip,usbgrf handling
From: Heiko Stuebner @ 2026-05-05 17:04 UTC (permalink / raw)
To: vkoul
Cc: neil.armstrong, robh, krzk+dt, conor+dt, heiko, linux-phy,
devicetree, linux-arm-kernel, linux-rockchip, linux-kernel, jonas
In-Reply-To: <20260505170410.3265305-1-heiko@sntech.de>
From: Jonas Karlman <jonas@kwiboo.se>
The logic to decide if usbgrf or grf should be used is more complex than
it needs to be. For RK3568, RV1108 and soon RK3528 we can assign the
rockchip,usbgrf regmap directly to grf instead of doing a usbgrf and grf
dance.
Simplify the code to only use the grf regmap and handle the logic of
what regmap should be used in driver probe instead.
The only expected change from this is that RK3528 can be supported
because of an addition of a of_property_present() check.
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 68 +++++--------------
1 file changed, 18 insertions(+), 50 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
index 8f4c08e599aa..7cec45192393 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
@@ -228,7 +228,6 @@ struct rockchip_usb2phy_port {
* struct rockchip_usb2phy - usb2.0 phy driver data.
* @dev: pointer to device.
* @grf: General Register Files regmap.
- * @usbgrf: USB General Register Files regmap.
* @clks: array of phy input clocks.
* @clk480m: clock struct of phy output clk.
* @clk480m_hw: clock struct of phy output clk management.
@@ -246,7 +245,6 @@ struct rockchip_usb2phy_port {
struct rockchip_usb2phy {
struct device *dev;
struct regmap *grf;
- struct regmap *usbgrf;
struct clk_bulk_data *clks;
struct clk *clk480m;
struct clk_hw clk480m_hw;
@@ -261,11 +259,6 @@ struct rockchip_usb2phy {
struct rockchip_usb2phy_port ports[USB2PHY_NUM_PORTS];
};
-static inline struct regmap *get_reg_base(struct rockchip_usb2phy *rphy)
-{
- return rphy->usbgrf == NULL ? rphy->grf : rphy->usbgrf;
-}
-
static inline int property_enable(struct regmap *base,
const struct usb2phy_reg *reg, bool en)
{
@@ -323,12 +316,11 @@ static int rockchip_usb2phy_clk480m_prepare(struct clk_hw *hw)
{
struct rockchip_usb2phy *rphy =
container_of(hw, struct rockchip_usb2phy, clk480m_hw);
- struct regmap *base = get_reg_base(rphy);
int ret;
/* turn on 480m clk output if it is off */
- if (!property_enabled(base, &rphy->phy_cfg->clkout_ctl)) {
- ret = property_enable(base, &rphy->phy_cfg->clkout_ctl, true);
+ if (!property_enabled(rphy->grf, &rphy->phy_cfg->clkout_ctl)) {
+ ret = property_enable(rphy->grf, &rphy->phy_cfg->clkout_ctl, true);
if (ret)
return ret;
@@ -343,19 +335,17 @@ static void rockchip_usb2phy_clk480m_unprepare(struct clk_hw *hw)
{
struct rockchip_usb2phy *rphy =
container_of(hw, struct rockchip_usb2phy, clk480m_hw);
- struct regmap *base = get_reg_base(rphy);
/* turn off 480m clk output */
- property_enable(base, &rphy->phy_cfg->clkout_ctl, false);
+ property_enable(rphy->grf, &rphy->phy_cfg->clkout_ctl, false);
}
static int rockchip_usb2phy_clk480m_prepared(struct clk_hw *hw)
{
struct rockchip_usb2phy *rphy =
container_of(hw, struct rockchip_usb2phy, clk480m_hw);
- struct regmap *base = get_reg_base(rphy);
- return property_enabled(base, &rphy->phy_cfg->clkout_ctl);
+ return property_enabled(rphy->grf, &rphy->phy_cfg->clkout_ctl);
}
static unsigned long
@@ -574,7 +564,6 @@ static int rockchip_usb2phy_power_on(struct phy *phy)
{
struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);
- struct regmap *base = get_reg_base(rphy);
int ret;
dev_dbg(&rport->phy->dev, "port power on\n");
@@ -586,7 +575,7 @@ static int rockchip_usb2phy_power_on(struct phy *phy)
if (ret)
return ret;
- ret = property_enable(base, &rport->port_cfg->phy_sus, false);
+ ret = property_enable(rphy->grf, &rport->port_cfg->phy_sus, false);
if (ret) {
clk_disable_unprepare(rphy->clk480m);
return ret;
@@ -615,7 +604,6 @@ static int rockchip_usb2phy_power_off(struct phy *phy)
{
struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);
- struct regmap *base = get_reg_base(rphy);
int ret;
dev_dbg(&rport->phy->dev, "port power off\n");
@@ -623,7 +611,7 @@ static int rockchip_usb2phy_power_off(struct phy *phy)
if (rport->suspended)
return 0;
- ret = property_enable(base, &rport->port_cfg->phy_sus, true);
+ ret = property_enable(rphy->grf, &rport->port_cfg->phy_sus, true);
if (ret)
return ret;
@@ -787,28 +775,22 @@ static const char *chg_to_string(enum power_supply_type chg_type)
static void rockchip_chg_enable_dcd(struct rockchip_usb2phy *rphy,
bool en)
{
- struct regmap *base = get_reg_base(rphy);
-
- property_enable(base, &rphy->phy_cfg->chg_det.rdm_pdwn_en, en);
- property_enable(base, &rphy->phy_cfg->chg_det.idp_src_en, en);
+ property_enable(rphy->grf, &rphy->phy_cfg->chg_det.rdm_pdwn_en, en);
+ property_enable(rphy->grf, &rphy->phy_cfg->chg_det.idp_src_en, en);
}
static void rockchip_chg_enable_primary_det(struct rockchip_usb2phy *rphy,
bool en)
{
- struct regmap *base = get_reg_base(rphy);
-
- property_enable(base, &rphy->phy_cfg->chg_det.vdp_src_en, en);
- property_enable(base, &rphy->phy_cfg->chg_det.idm_sink_en, en);
+ property_enable(rphy->grf, &rphy->phy_cfg->chg_det.vdp_src_en, en);
+ property_enable(rphy->grf, &rphy->phy_cfg->chg_det.idm_sink_en, en);
}
static void rockchip_chg_enable_secondary_det(struct rockchip_usb2phy *rphy,
bool en)
{
- struct regmap *base = get_reg_base(rphy);
-
- property_enable(base, &rphy->phy_cfg->chg_det.vdm_src_en, en);
- property_enable(base, &rphy->phy_cfg->chg_det.idp_sink_en, en);
+ property_enable(rphy->grf, &rphy->phy_cfg->chg_det.vdm_src_en, en);
+ property_enable(rphy->grf, &rphy->phy_cfg->chg_det.idp_sink_en, en);
}
#define CHG_DCD_POLL_TIME (100 * HZ / 1000)
@@ -820,7 +802,6 @@ static void rockchip_chg_detect_work(struct work_struct *work)
struct rockchip_usb2phy_port *rport =
container_of(work, struct rockchip_usb2phy_port, chg_work.work);
struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
- struct regmap *base = get_reg_base(rphy);
bool is_dcd, tmout, vout, vbus_attach;
unsigned long delay;
@@ -834,7 +815,7 @@ static void rockchip_chg_detect_work(struct work_struct *work)
rockchip_usb2phy_power_off(rport->phy);
/* put the controller in non-driving mode */
if (!vbus_attach)
- property_enable(base, &rphy->phy_cfg->chg_det.opmode, false);
+ property_enable(rphy->grf, &rphy->phy_cfg->chg_det.opmode, false);
/* Start DCD processing stage 1 */
rockchip_chg_enable_dcd(rphy, true);
rphy->chg_state = USB_CHG_STATE_WAIT_FOR_DCD;
@@ -898,7 +879,7 @@ static void rockchip_chg_detect_work(struct work_struct *work)
case USB_CHG_STATE_DETECTED:
/* put the controller in normal mode */
if (!vbus_attach)
- property_enable(base, &rphy->phy_cfg->chg_det.opmode, true);
+ property_enable(rphy->grf, &rphy->phy_cfg->chg_det.opmode, true);
rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work);
dev_dbg(&rport->phy->dev, "charger = %s\n",
chg_to_string(rphy->chg_type));
@@ -1353,27 +1334,14 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
if (!rphy)
return -ENOMEM;
- if (!dev->parent || !dev->parent->of_node) {
+ if (!dev->parent || !dev->parent->of_node ||
+ of_property_present(np, "rockchip,usbgrf")) {
rphy->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,usbgrf");
- if (IS_ERR(rphy->grf)) {
- dev_err(dev, "failed to locate usbgrf\n");
- return PTR_ERR(rphy->grf);
- }
} else {
rphy->grf = syscon_node_to_regmap(dev->parent->of_node);
- if (IS_ERR(rphy->grf))
- return PTR_ERR(rphy->grf);
- }
-
- if (of_device_is_compatible(np, "rockchip,rv1108-usb2phy")) {
- rphy->usbgrf =
- syscon_regmap_lookup_by_phandle(dev->of_node,
- "rockchip,usbgrf");
- if (IS_ERR(rphy->usbgrf))
- return PTR_ERR(rphy->usbgrf);
- } else {
- rphy->usbgrf = NULL;
}
+ if (IS_ERR(rphy->grf))
+ return PTR_ERR(rphy->grf);
if (of_property_read_u32_index(np, "reg", 0, ®)) {
dev_err(dev, "the reg property is not assigned in %pOFn node\n", np);
--
2.47.3
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v2 3/5] dt-bindings: phy: rockchip,inno-usb2phy: Add compatible for RK3528
From: Heiko Stuebner @ 2026-05-05 17:04 UTC (permalink / raw)
To: vkoul
Cc: neil.armstrong, robh, krzk+dt, conor+dt, heiko, linux-phy,
devicetree, linux-arm-kernel, linux-rockchip, linux-kernel, jonas
In-Reply-To: <20260505170410.3265305-1-heiko@sntech.de>
From: Jonas Karlman <jonas@kwiboo.se>
The embedded USB2 PHY on RK3528 is very similar to the one in RK3568,
the main difference being that it only uses two clocks instead of three.
Add compatible to support the USB2 PHY in RK3528.
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
.../bindings/phy/rockchip,inno-usb2phy.yaml | 30 ++++++++++++++++---
1 file changed, 26 insertions(+), 4 deletions(-)
diff --git a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
index b95c9e3e44fe..f50fc69fbbe4 100644
--- a/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
+++ b/Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml
@@ -20,6 +20,7 @@ properties:
- rockchip,rk3328-usb2phy
- rockchip,rk3366-usb2phy
- rockchip,rk3399-usb2phy
+ - rockchip,rk3528-usb2phy
- rockchip,rk3562-usb2phy
- rockchip,rk3568-usb2phy
- rockchip,rk3576-usb2phy
@@ -41,11 +42,15 @@ properties:
maxItems: 3
clock-names:
- minItems: 1
- items:
+ oneOf:
- const: phyclk
- - const: aclk
- - const: aclk_slv
+ - items:
+ - const: phyclk
+ - const: pclk
+ - items:
+ - const: phyclk
+ - const: aclk
+ - const: aclk_slv
assigned-clocks:
description:
@@ -65,6 +70,9 @@ properties:
description: Muxed interrupt for both ports
maxItems: 1
+ power-domains:
+ maxItems: 1
+
resets:
maxItems: 2
@@ -150,6 +158,7 @@ allOf:
compatible:
contains:
enum:
+ - rockchip,rk3528-usb2phy
- rockchip,rk3568-usb2phy
- rockchip,rv1108-usb2phy
then:
@@ -218,6 +227,19 @@ allOf:
clock-names:
maxItems: 1
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - rockchip,rk3528-usb2phy
+ then:
+ properties:
+ clocks:
+ minItems: 2
+ clock-names:
+ minItems: 2
+
- if:
properties:
compatible:
--
2.47.3
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* Re: [PATCH v5 5/6] phy: realtek: usb2: add support for RTL9607C USB2 PHY
From: Rustam Adilov @ 2026-05-05 18:10 UTC (permalink / raw)
To: Vladimir Oltean
Cc: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Stanley Chang, linux-phy, devicetree, linux-kernel,
Michael Zavertkin
In-Reply-To: <20260505113001.idgj7ssikjgcypa2@skbuf>
On 2026-05-05 11:30, Vladimir Oltean wrote:
> On Tue, Apr 21, 2026 at 12:19:40AM +0500, Rustam Adilov wrote:
>> Add support for the usb2 phy of RTL9607C series based SoCs.
>> Add the macros and phy config struct for rtl9607.
>>
>> RTL9607C requires to clear a "force host disconnect" bit in the
>> specific register (which is at an offset from reg_wrap_vstatus)
>> before proceeding with phy parameter writes. Since it belongs into
>> the vstatus register region, it doesn't need bytes swapping.
>>
>> Add the bool variable to the driver data struct and hide this whole
>> procedure under the if statement that checks this new variable.
>>
>> Add the appropriate little endian read and write functions for rtl9607
>> and assign them to its phy config struct.
>>
>> As mentioned earlier, the readl/writel are native endian on MIPS arch
>> if SWAP_IO_SPACE is not enabled. Since enabling SWAP_IO_SPACE results
>> in boot hang on RTL9607C machine, wrapping le32 around readl/writel
>> should be a good compromise, but swab32 could be also work.
>>
>> Co-developed-by: Michael Zavertkin <misha.zavertkin@mail.ru>
>> Signed-off-by: Michael Zavertkin <misha.zavertkin@mail.ru>
>> Signed-off-by: Rustam Adilov <adilov@disroot.org>
>> ---
>
> Have you considered ioread32() instead of wrapping le32 around readl()?
I think you meant ioread32be() and yes i have considered it. If this is what
it takes to get rid of le32 warning you mentioned from an earlier email then
so be it.
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v5 0/6] phy: realtek: usb2: support for RTL9607C USB2 PHY
From: Rustam Adilov @ 2026-05-05 18:39 UTC (permalink / raw)
To: Vladimir Oltean
Cc: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Stanley Chang, linux-phy, devicetree, linux-kernel
In-Reply-To: <20260505113721.ur4qd4udu7jas473@skbuf>
On 2026-05-05 11:37, Vladimir Oltean wrote:
> On Tue, Apr 21, 2026 at 12:19:35AM +0500, Rustam Adilov wrote:
>> This patch series for Realtek USB2 PHY driver adds support for RTL9607C
>> USB2 PHY.
>>
>> RTL9607C is a big endian MIPS CPU which is quite far from RTD series SoCs
>> supported by realtek usb2 phy driver, but the phy initilization is found
>> to be very indentical in most areas.
>>
>> Most of the code was based on the Realtek's usb driver from the GPL tarball
>> in [1] and adjusted to fit into the realtek usb2 phy driver code format.
>>
>> The patch series was split into smaller patches that add/change something
>> in the driver that are not exactly related to RTL9607C and that also
>> helps for easier review. That also means, patch 5 depends on all the prior
>> patches that come before it.
>>
>> USB2 PHY on RTL9607C is primarly used for its internal OHCI/EHCI controllers.
>>
>> [1] - https://github.com/jameywine/GPL-for-GP3000/blob/main/linux-5.10.x/arch/mips/rtl9607c/usb.c
>>
>> ---
>
> Could you go through Patchwork and reply inline to the issues found,
> stating whether you are or are not going to resolve them?
> https://patchwork.kernel.org/project/linux-phy/list/?series=1083475
Yeah, sure thing. However i do expect a good bit of refactoring of this patch series
once we get SWAP_IO_SPACE working. It just turned out that some of the realtek drivers
from various subsystems use readl/ioread32 for native endian (which is big endian for
rtl9607c and others under MACH_REALTEK_RTL) and enabling SWAP_IO_SPACE makes them
function in little endian which breaks those things. So that's what we are dealing with
at this moment.
> All of the WARNING: line length of XX exceeds 80 columns
I can resolve them just fine.
> WARNING: msleep < 20ms can sleep for up to 20ms; see function description of msleep().
> #88: FILE: drivers/phy/realtek/phy-rtk-usb2.c:629:
> + msleep(10);
I can resolve it by changing it to usleep_range like i did with reset controller one.
> ../drivers/phy/realtek/phy-rtk-usb2.c:158:16: warning: cast to restricted __le32
> ../drivers/phy/realtek/phy-rtk-usb2.c:163:19: warning: incorrect type in initializer (different base types)
> ../drivers/phy/realtek/phy-rtk-usb2.c:163:19: expected unsigned int [usertype] tmp
> ../drivers/phy/realtek/phy-rtk-usb2.c:163:19: got restricted __le32 [usertype]
That should be fixed by using ioread32be.
> 1 maintainers not CCed: p.zabel@pengutronix.de
When i run scripts/get_maintainer.pl, it doesn't print it out at all but I can include it.
> Detected inline keyword in C files
> +static inline int utmi_wait_register(u32 (*read)(void __iomem *reg), void __iomem *reg, u32 mask,
Even though it was not introduced by this patch series, i think it is relevant as
i am directly modifying its property to include read function to it. Something along
like "While we are here, remove inline from utmi_wait_register"
I believe that is every issue from Checks list apart from Sashiko reviews.
Best,
Rustam
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v5 5/6] phy: realtek: usb2: add support for RTL9607C USB2 PHY
From: Vladimir Oltean @ 2026-05-05 19:25 UTC (permalink / raw)
To: Rustam Adilov
Cc: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Stanley Chang, linux-phy, devicetree, linux-kernel,
Michael Zavertkin
In-Reply-To: <9de0dcc209eab02d2a4e5fcec25e7711@disroot.org>
On Tue, May 05, 2026 at 06:10:42PM +0000, Rustam Adilov wrote:
> On 2026-05-05 11:30, Vladimir Oltean wrote:
> > On Tue, Apr 21, 2026 at 12:19:40AM +0500, Rustam Adilov wrote:
> >> Add support for the usb2 phy of RTL9607C series based SoCs.
> >> Add the macros and phy config struct for rtl9607.
> >>
> >> RTL9607C requires to clear a "force host disconnect" bit in the
> >> specific register (which is at an offset from reg_wrap_vstatus)
> >> before proceeding with phy parameter writes. Since it belongs into
> >> the vstatus register region, it doesn't need bytes swapping.
> >>
> >> Add the bool variable to the driver data struct and hide this whole
> >> procedure under the if statement that checks this new variable.
> >>
> >> Add the appropriate little endian read and write functions for rtl9607
> >> and assign them to its phy config struct.
> >>
> >> As mentioned earlier, the readl/writel are native endian on MIPS arch
> >> if SWAP_IO_SPACE is not enabled. Since enabling SWAP_IO_SPACE results
> >> in boot hang on RTL9607C machine, wrapping le32 around readl/writel
> >> should be a good compromise, but swab32 could be also work.
> >>
> >> Co-developed-by: Michael Zavertkin <misha.zavertkin@mail.ru>
> >> Signed-off-by: Michael Zavertkin <misha.zavertkin@mail.ru>
> >> Signed-off-by: Rustam Adilov <adilov@disroot.org>
> >> ---
> >
> > Have you considered ioread32() instead of wrapping le32 around readl()?
>
> I think you meant ioread32be() and yes i have considered it. If this is what
> it takes to get rid of le32 warning you mentioned from an earlier email then
> so be it.
No, I meant ioread32(). When I read Documentation/driver-api/device-io.rst,
it says ioread32() is for a little endian peripheral and ioread32be()
for big endian peripherals. You have a little endian peripheral (relevant)
and a big endian CPU (not relevant) so I don't see why ioread32() wouldn't
be the correct accessor to use.
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH v3 00/15] clk: introduce clk_determine_rate_noop() and update drivers to use it
From: Brian Masney @ 2026-05-06 0:48 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Brian Masney
Cc: linux-clk, linux-kernel, Peng Fan, Abel Vesa, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam, imx,
linux-arm-kernel, Anson Huang, Bjorn Andersson,
Geert Uytterhoeven, Andrea della Porta, Tudor Ambarus,
Krzysztof Kozlowski, Sylwester Nawrocki, Chanwoo Choi,
Alim Akhtar, Sudeep Holla, Cristian Marussi, Orson Zhai,
Baolin Wang, Chunyan Zhang, Chun-Kuang Hu, Philipp Zabel,
Chunfeng Yun, Vinod Koul, Neil Armstrong, Matthias Brugger,
AngeloGioacchino Del Regno, Ulf Hansson, linux-arm-msm,
linux-renesas-soc, linux-samsung-soc, arm-scmi, dri-devel,
linux-mediatek, linux-phy, linux-pm
There are some clocks where the determine_rate clk op is just an empty
function that returns 0. This can be either because the rounding is
managed by the firmware/hardware, or the clock is capable of any rate.
Let's add a new new shared function to clk.c named
clk_determine_rate_noop(), and update all of the drivers that have an
empty determine_rate() ops to use this new shared function.
The first patch in this series also includes a minor cleanup to
drivers/clk/imx/clk-scu.c. I included it as the first patch so it
doesn't get buried in the middle of this series. I change this same
driver later in the series to use clk_determine_rate_noop().
Changes since v2:
https://lore.kernel.org/all/20260309-clk-det-rate-fw-managed-v2-0-c48ef5a3100a@redhat.com/
- Dropped the NOOP flag and just use a dedicated noop function.
Merge Strategy
--------------
All of this needs to be directly merged by Stephen as one series into
his tree. Subsystem maintainers: please leave a Reviewed-by or Acked-by
for Stephen. To reduce the noise, I am only CCing people on their
respective drivers.
Since there's only 3 drivers outside of drivers/clk that need to be
updated, I included them in this same series for completeness. These
should go through Stephen's tree as well.
Signed-off-by: Brian Masney <bmasney@redhat.com>
---
Brian Masney (15):
clk: imx: scu: drop redundant init.ops variable assignment
clk: add clk_determine_rate_noop()
clk: hisilicon: hi3660-stub: use clk_determine_rate_noop()
clk: imx: scu: use clk_determine_rate_noop()
clk: qcom: rpm: use clk_determine_rate_noop()
clk: qcom: rpmh: use clk_determine_rate_noop()
clk: qcom: smd-rpm: use clk_determine_rate_noop()
clk: renesas: rzg2l-cpg: use clk_determine_rate_noop()
clk: rp1: use clk_determine_rate_noop()
clk: samsung: acpm: use clk_determine_rate_noop()
clk: scpi: use clk_determine_rate_noop()
clk: sprd: use clk_determine_rate_noop()
phy: mediatek: phy-mtk-hdmi-mt2701: use clk_determine_rate_noop()
pmdomain: mediatek: airoha: use clk_determine_rate_noop()
pmdomain: mediatek: mtk-mfg: use clk_determine_rate_noop()
drivers/clk/clk-rp1.c | 8 +-------
drivers/clk/clk-scpi.c | 14 +-------------
drivers/clk/clk.c | 18 ++++++++++++++++++
drivers/clk/hisilicon/clk-hi3660-stub.c | 12 +-----------
drivers/clk/imx/clk-scu.c | 24 +++---------------------
drivers/clk/qcom/clk-rpm.c | 15 ++-------------
drivers/clk/qcom/clk-rpmh.c | 8 +-------
drivers/clk/qcom/clk-smd-rpm.c | 13 +------------
drivers/clk/renesas/rzg2l-cpg.c | 8 +-------
drivers/clk/samsung/clk-acpm.c | 14 +-------------
drivers/clk/sprd/pll.c | 8 +-------
drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c | 8 +-------
drivers/pmdomain/mediatek/airoha-cpu-pmdomain.c | 8 +-------
drivers/pmdomain/mediatek/mtk-mfg-pmdomain.c | 23 ++---------------------
include/linux/clk-provider.h | 1 +
15 files changed, 36 insertions(+), 146 deletions(-)
---
base-commit: 4cd074ae20bbcc293bbbce9163abe99d68ae6ae0
change-id: 20260505-clk-determine-rate-noop-17a544f78018
Best regards,
--
Brian Masney <bmasney@redhat.com>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH v3 02/15] clk: add clk_determine_rate_noop()
From: Brian Masney @ 2026-05-06 0:48 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Brian Masney
Cc: linux-clk, linux-kernel, Abel Vesa, Peng Fan, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam, Anson Huang,
Bjorn Andersson, Geert Uytterhoeven, Andrea della Porta,
Tudor Ambarus, Krzysztof Kozlowski, Sylwester Nawrocki,
Chanwoo Choi, Alim Akhtar, Sudeep Holla, Cristian Marussi,
Orson Zhai, Baolin Wang, Chunyan Zhang, Chun-Kuang Hu,
Philipp Zabel, Chunfeng Yun, Vinod Koul, Neil Armstrong,
Matthias Brugger, AngeloGioacchino Del Regno, Ulf Hansson, imx,
linux-arm-kernel, linux-arm-msm, linux-renesas-soc,
linux-samsung-soc, arm-scmi, dri-devel, linux-mediatek, linux-phy,
linux-pm
In-Reply-To: <20260505-clk-determine-rate-noop-v3-0-f3f829fbacdf@redhat.com>
Add a new helper clk_determine_rate_noop() that's for clocks where the
rate rounding is handled by the firmware/hardware, or the clock is
capable of any rate. The requested rate is passed through unchanged,
and the actual rate will be learned via recalc_rate() after the rate
is set.
This shared helper will be used to get rid of the driver-specific empty
determine rate implementations that are present in the tree.
Signed-off-by: Brian Masney <bmasney@redhat.com>
---
To: Michael Turquette <mturquette@baylibre.com>
To: Stephen Boyd <sboyd@kernel.org>
To: Brian Masney <bmasney@redhat.com>
To: Abel Vesa <abelvesa@kernel.org>
To: Peng Fan <peng.fan@nxp.com>
To: Frank Li <Frank.Li@nxp.com>
To: Sascha Hauer <s.hauer@pengutronix.de>
To: Pengutronix Kernel Team <kernel@pengutronix.de>
To: Fabio Estevam <festevam@gmail.com>
To: Anson Huang <anson.huang@nxp.com>
To: Bjorn Andersson <andersson@kernel.org>
To: Geert Uytterhoeven <geert+renesas@glider.be>
To: Andrea della Porta <andrea.porta@suse.com>
To: Tudor Ambarus <tudor.ambarus@linaro.org>
To: Krzysztof Kozlowski <krzk@kernel.org>
To: Sylwester Nawrocki <s.nawrocki@samsung.com>
To: Chanwoo Choi <cw00.choi@samsung.com>
To: Alim Akhtar <alim.akhtar@samsung.com>
To: Sudeep Holla <sudeep.holla@kernel.org>
To: Cristian Marussi <cristian.marussi@arm.com>
To: Orson Zhai <orsonzhai@gmail.com>
To: Baolin Wang <baolin.wang@linux.alibaba.com>
To: Chunyan Zhang <zhang.lyra@gmail.com>
To: Chun-Kuang Hu <chunkuang.hu@kernel.org>
To: Philipp Zabel <p.zabel@pengutronix.de>
To: Chunfeng Yun <chunfeng.yun@mediatek.com>
To: Vinod Koul <vkoul@kernel.org>
To: Neil Armstrong <neil.armstrong@linaro.org>
To: Matthias Brugger <matthias.bgg@gmail.com>
To: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
To: Ulf Hansson <ulfh@kernel.org>
Cc: linux-clk@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-arm-msm@vger.kernel.org
Cc: linux-renesas-soc@vger.kernel.org
Cc: linux-samsung-soc@vger.kernel.org
Cc: arm-scmi@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: linux-mediatek@lists.infradead.org
Cc: linux-phy@lists.infradead.org
Cc: linux-pm@vger.kernel.org
---
drivers/clk/clk.c | 18 ++++++++++++++++++
include/linux/clk-provider.h | 1 +
2 files changed, 19 insertions(+)
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 048adfa86a5d..956e147f4d4e 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -882,6 +882,24 @@ int clk_hw_determine_rate_no_reparent(struct clk_hw *hw,
}
EXPORT_SYMBOL_GPL(clk_hw_determine_rate_no_reparent);
+/**
+ * clk_determine_rate_noop - clk_ops::determine_rate noop implementation
+ * @hw: clk to determine rate on
+ * @req: rate request
+ *
+ * Noop determine rate for clocks where the rate rounding is handled by the
+ * firmware/hardware, or the clock is capable of any rate. The requested rate is
+ * passed through unchanged, and the actual rate will be learned via
+ * recalc_rate() after the rate is set.
+ *
+ * Returns: 0 always
+ */
+int clk_determine_rate_noop(struct clk_hw *hw, struct clk_rate_request *req)
+{
+ return 0;
+}
+EXPORT_SYMBOL_GPL(clk_determine_rate_noop);
+
/*** clk api ***/
static void clk_core_rate_unprotect(struct clk_core *core)
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index b01a38fef8cf..334b9211a157 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -1431,6 +1431,7 @@ int clk_mux_determine_rate_flags(struct clk_hw *hw,
unsigned long flags);
int clk_hw_determine_rate_no_reparent(struct clk_hw *hw,
struct clk_rate_request *req);
+int clk_determine_rate_noop(struct clk_hw *hw, struct clk_rate_request *req);
void clk_hw_reparent(struct clk_hw *hw, struct clk_hw *new_parent);
void clk_hw_get_rate_range(struct clk_hw *hw, unsigned long *min_rate,
unsigned long *max_rate);
--
2.54.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v3 13/15] phy: mediatek: phy-mtk-hdmi-mt2701: use clk_determine_rate_noop()
From: Brian Masney @ 2026-05-06 0:49 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Brian Masney
Cc: linux-clk, linux-kernel, Chun-Kuang Hu, Philipp Zabel,
Chunfeng Yun, Vinod Koul, Matthias Brugger,
AngeloGioacchino Del Regno, Neil Armstrong, dri-devel,
linux-mediatek, linux-arm-kernel, linux-phy
In-Reply-To: <20260505-clk-determine-rate-noop-v3-0-f3f829fbacdf@redhat.com>
Drop the driver-specific empty determine_rate() function and use the new
shared clk_determine_rate_noop() helper.
Signed-off-by: Brian Masney <bmasney@redhat.com>
---
To: Chun-Kuang Hu <chunkuang.hu@kernel.org>
To: Philipp Zabel <p.zabel@pengutronix.de>
To: Chunfeng Yun <chunfeng.yun@mediatek.com>
To: Vinod Koul <vkoul@kernel.org>
To: Matthias Brugger <matthias.bgg@gmail.com>
To: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
To: Michael Turquette <mturquette@baylibre.com>
To: Stephen Boyd <sboyd@kernel.org>
To: Brian Masney <bmasney@redhat.com>
Cc: linux-clk@vger.kernel.org
Cc: Neil Armstrong <neil.armstrong@linaro.org>
Cc: dri-devel@lists.freedesktop.org
Cc: linux-mediatek@lists.infradead.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-phy@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
---
drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c b/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c
index b0b6497e7eed..c9a1f20e939b 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c
+++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c
@@ -90,12 +90,6 @@ static void mtk_hdmi_pll_unprepare(struct clk_hw *hw)
usleep_range(80, 100);
}
-static int mtk_hdmi_pll_determine_rate(struct clk_hw *hw,
- struct clk_rate_request *req)
-{
- return 0;
-}
-
static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
@@ -170,7 +164,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,
- .determine_rate = mtk_hdmi_pll_determine_rate,
+ .determine_rate = clk_determine_rate_noop,
.recalc_rate = mtk_hdmi_pll_recalc_rate,
};
--
2.54.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* Re: [PATCH 1/4] dt-bindings: phy: qcom,sc8280xp-qmp-usb43dp-phy: Add Hawi QMP PHY
From: Rob Herring (Arm) @ 2026-05-06 1:19 UTC (permalink / raw)
To: Ronak Raheja
Cc: linux-usb, dmitry.baryshkov, abel.vesa, krzysztof.kozlowski,
linux-kernel, vkoul, linux-phy, devicetree, gregkh, conor+dt,
konrad.dybcio, wesley.cheng, linux-arm-msm, krzk+dt,
neil.armstrong
In-Reply-To: <20260427214217.2735240-2-ronak.raheja@oss.qualcomm.com>
On Mon, 27 Apr 2026 14:42:14 -0700, Ronak Raheja wrote:
> Document the Hawi compatible string for the QMP combo PHY.
>
> Hawi uses a new QSERDES V10 register layout with a new COM AON module
> and hardware-specific PHY init sequences compared to previous targets,
> requiring a dedicated compatible string.
>
> Signed-off-by: Ronak Raheja <ronak.raheja@oss.qualcomm.com>
> ---
> .../devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml | 2 ++
> 1 file changed, 2 insertions(+)
>
Acked-by: Rob Herring (Arm) <robh@kernel.org>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v7 phy-next 15/27] phy: move provider API out of public <linux/phy/phy.h>
From: Vladimir Oltean @ 2026-05-05 9:30 UTC (permalink / raw)
To: linux-phy
Cc: Vinod Koul, Neil Armstrong, dri-devel, freedreno,
linux-arm-kernel, linux-arm-msm, linux-can, linux-gpio, linux-ide,
linux-kernel, linux-media, linux-pci, linux-renesas-soc,
linux-riscv, linux-rockchip, linux-samsung-soc, linux-scsi,
linux-sunxi, linux-tegra, linux-usb, netdev, spacemit,
UNGLinuxDriver, Dmitry Baryshkov, Abhinav Kumar,
Alexandre Belloni, André Draszik, Andrew Lunn, Andrzej Hajda,
Andy Yan, Bjorn Helgaas, Chanho Park, Chen-Yu Tsai,
Claudiu Beznea, Damien Le Moal, Daniel Machon, David Airlie,
David S. Miller, Dmitry Baryshkov, Eric Dumazet, Fabio Estevam,
Frank Li, Geert Uytterhoeven, Greg Kroah-Hartman,
Heiko Stübner, Inki Dae, Jagan Teki, Jakub Kicinski,
James E.J. Bottomley, JC Kuo, Jernej Skrabec, Jessica Zhang,
Joe Perches, Johan Hovold, Jonas Karlman, Jonathan Hunter,
Kevin Xie, Krzysztof Kozlowski, Krzysztof Wilczyński,
Laurent Pinchart, Linus Walleij, Lorenzo Pieralisi,
Maarten Lankhorst, Magnus Damm, Manivannan Sadhasivam,
Marc Kleine-Budde, Marek Szyprowski, Marijn Suijten,
Markus Schneider-Pargmann, Martin K. Petersen, Mathias Nyman,
Mauro Carvalho Chehab, Maxime Ripard, Michael Dege, Nicolas Ferre,
Niklas Cassel, Nitin Rawat, Paolo Abeni, Pengutronix Kernel Team,
Peter Chen, Peter Griffin, Rob Clark, Robert Foss, Rob Herring,
Russell King (Oracle), Samuel Holland, Sandy Huang, Sascha Hauer,
Sean Paul, Sebastian Reichel, Shawn Guo, Shawn Lin, Simona Vetter,
Steen Hegelund, Thierry Reding, Thinh Nguyen, Thomas Zimmermann,
Tudor Ambarus, Vincent Mailhol, Yixun Lan, Yoshihiro Shimoda
In-Reply-To: <20260430110652.558622-16-vladimir.oltean@nxp.com>
Sashiko says:
> commit 65f3c7aba94024fd51e12abfeeb5cdaae7e123cd
> Author: Vladimir Oltean <vladimir.oltean@nxp.com>
> phy: move provider API out of public <linux/phy/phy.h>
>
> The major goal is to hide the contents of struct phy from consumer
> drivers by moving the provider API out of the public linux/phy/phy.h
> header and into drivers/phy/phy-provider.h. For temporary compatibility,
> the consumer header currently includes the provider header via a relative
> path.
>
> > diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
> > index 21aaf2f76e53e..a1aff00fba7c5 100644
> > --- a/drivers/phy/phy-core.c
> > +++ b/drivers/phy/phy-core.c
> [ ... ]
> > @@ -606,6 +622,24 @@ int phy_validate(struct phy *phy, enum phy_mode mode, int submode,
> > }
> > EXPORT_SYMBOL_GPL(phy_validate);
> >
> > +enum phy_mode phy_get_mode(struct phy *phy)
> > +{
> > + return phy->attrs.mode;
>
> The PHY framework supports optional PHYs (represented as NULL pointers via
> devm_phy_optional_get()). Does this unconditional dereference cause a NULL
> pointer dereference if called with an optional PHY?
>
> I noticed this was also the case in the previous inline implementation, and
> that a fix is provided later in the series in the commit "phy: make
> phy_get_mode(), phy_(get|set)_bus_width() NULL tolerant".
>
> > +}
> > +EXPORT_SYMBOL_GPL(phy_get_mode);
> > +
> > +int phy_get_bus_width(struct phy *phy)
> > +{
> > + return phy->attrs.bus_width;
>
> Can this also cause a NULL pointer dereference when called with an optional
> PHY?
>
> > +}
> > +EXPORT_SYMBOL_GPL(phy_get_bus_width);
> > +
> > +void phy_set_bus_width(struct phy *phy, int bus_width)
> > +{
> > + phy->attrs.bus_width = bus_width;
>
> Can this also cause a NULL pointer dereference when called with an optional
> PHY?
It was a conscious decision to move code first and then to start fixing
it up later, so that more context is present in 'git blame'. So I will
ignore these comments for issues that are resolved later in the series.
> > +}
> > +EXPORT_SYMBOL_GPL(phy_set_bus_width);
> [ ... ]
> > diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
> > index ea47975e288ae..f208edd25afee 100644
> > --- a/include/linux/phy/phy.h
> > +++ b/include/linux/phy/phy.h
> > @@ -1,246 +1,38 @@
> > /* SPDX-License-Identifier: GPL-2.0-or-later */
> > /*
> > - * phy.h -- generic phy header file
> > + * phy.h -- Generic PHY consumer API
> [ ... ]
> > -#include <linux/phy/phy-mipi-dphy.h>
> > +#include <linux/phy/phy-props.h>
> >
> > +#include "../../../drivers/phy/phy-provider.h"
>
> Does this relative include of a private driver header break out-of-tree
> module builds?
>
> Out-of-tree modules compile against kernel headers packages that typically do
> not contain the private drivers/ directory tree, which would cause
> compilation to fail with a missing file error.
>
> I note this is resolved later in the series in the commit "phy: remove
> temporary provider compatibility from consumer header".
Yes, out of tree building will temporarily be broken but resolved by the
end of the series for PHY consumers (but remains broken for PHY providers).
My understanding is that support for out of tree modules is best effort,
and I don't see how breakage could be avoided, given Vinod's request to
have phy-provider.h be a non-public header.
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH v8 phy-next 30/31] phy: remove temporary provider compatibility from consumer header
From: Vladimir Oltean @ 2026-05-05 10:05 UTC (permalink / raw)
To: linux-phy
Cc: Vinod Koul, Neil Armstrong, dri-devel, freedreno,
linux-arm-kernel, linux-arm-msm, linux-can, linux-gpio, linux-ide,
linux-kernel, linux-media, linux-pci, linux-renesas-soc,
linux-riscv, linux-rockchip, linux-samsung-soc, linux-scsi,
linux-sunxi, linux-tegra, linux-usb, netdev, spacemit,
UNGLinuxDriver, Dmitry Baryshkov, Abhinav Kumar,
Alexandre Belloni, André Draszik, Andrew Lunn, Andrzej Hajda,
Andy Yan, Bjorn Helgaas, Chanho Park, Chen-Yu Tsai,
Claudiu Beznea, Damien Le Moal, Daniel Machon, David Airlie,
David S. Miller, Dmitry Baryshkov, Eric Dumazet, Fabio Estevam,
Frank Li, Geert Uytterhoeven, Greg Kroah-Hartman,
Heiko Stübner, Inki Dae, Jagan Teki, Jakub Kicinski,
James E.J. Bottomley, JC Kuo, Jernej Skrabec, Jessica Zhang,
Joe Perches, Johan Hovold, Jonas Karlman, Jonathan Hunter,
Kevin Xie, Krzysztof Kozlowski, Krzysztof Wilczyński,
Laurent Pinchart, Linus Walleij, Lorenzo Pieralisi,
Maarten Lankhorst, Magnus Damm, Manivannan Sadhasivam,
Marc Kleine-Budde, Marek Szyprowski, Marijn Suijten,
Markus Schneider-Pargmann, Martin K. Petersen, Mathias Nyman,
Mauro Carvalho Chehab, Maxime Ripard, Michael Dege, Nicolas Ferre,
Niklas Cassel, Nitin Rawat, Paolo Abeni, Pengutronix Kernel Team,
Peter Chen, Peter Griffin, Rob Clark, Robert Foss, Rob Herring,
Russell King (Oracle), Samuel Holland, Sandy Huang, Sascha Hauer,
Sean Paul, Sebastian Reichel, Shawn Guo, Shawn Lin, Simona Vetter,
Steen Hegelund, Thierry Reding, Thinh Nguyen, Thomas Zimmermann,
Tudor Ambarus, Vincent Mailhol, Yixun Lan, Yoshihiro Shimoda
In-Reply-To: <20260505100523.1922388-1-vladimir.oltean@nxp.com>
Now that all consumers have been updated to no longer dereference fields
inside struct phy, we can hide its definition altogether from public view.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
Cc: Abhinav Kumar <abhinav.kumar@linux.dev>
Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
Cc: "André Draszik" <andre.draszik@linaro.org>
Cc: Andrew Lunn <andrew+netdev@lunn.ch>
Cc: Andrzej Hajda <andrzej.hajda@intel.com>
Cc: Andy Yan <andy.yan@rock-chips.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Chanho Park <chanho61.park@samsung.com>
Cc: Chen-Yu Tsai <wens@kernel.org>
Cc: Claudiu Beznea <claudiu.beznea@tuxon.dev>
Cc: Damien Le Moal <dlemoal@kernel.org>
Cc: Daniel Machon <daniel.machon@microchip.com>
Cc: David Airlie <airlied@gmail.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Dmitry Baryshkov <lumag@kernel.org>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Frank Li <Frank.Li@nxp.com>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Heiko Stübner" <heiko@sntech.de>
Cc: Inki Dae <inki.dae@samsung.com>
Cc: Jagan Teki <jagan@amarulasolutions.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
Cc: JC Kuo <jckuo@nvidia.com>
Cc: Jernej Skrabec <jernej.skrabec@gmail.com>
Cc: Jessica Zhang <jesszhan0024@gmail.com>
Cc: Joe Perches <joe@perches.com>
Cc: Johan Hovold <johan+linaro@kernel.org>
Cc: Jonas Karlman <jonas@kwiboo.se>
Cc: Jonathan Hunter <jonathanh@nvidia.com>
Cc: Kevin Xie <kevin.xie@starfivetech.com>
Cc: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Cc: "Krzysztof Wilczyński" <kwilczynski@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Linus Walleij <linusw@kernel.org>
Cc: Lorenzo Pieralisi <lpieralisi@kernel.org>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Magnus Damm <magnus.damm@gmail.com>
Cc: Manivannan Sadhasivam <mani@kernel.org>
Cc: Marc Kleine-Budde <mkl@pengutronix.de>
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Cc: Marijn Suijten <marijn.suijten@somainline.org>
Cc: Markus Schneider-Pargmann <msp@baylibre.com>
Cc: "Martin K. Petersen" <martin.petersen@oracle.com>
Cc: Mathias Nyman <mathias.nyman@intel.com>
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: Maxime Ripard <mripard@kernel.org>
Cc: Michael Dege <michael.dege@renesas.com>
Cc: Neil Armstrong <neil.armstrong@linaro.org>
Cc: Nicolas Ferre <nicolas.ferre@microchip.com>
Cc: Niklas Cassel <cassel@kernel.org>
Cc: Nitin Rawat <quic_nitirawa@quicinc.com>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Peter Chen <peter.chen@kernel.org>
Cc: Peter Griffin <peter.griffin@linaro.org>
Cc: Rob Clark <robin.clark@oss.qualcomm.com>
Cc: Robert Foss <rfoss@kernel.org>
Cc: Rob Herring <robh@kernel.org>
Cc: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
Cc: Samuel Holland <samuel@sholland.org>
Cc: Sandy Huang <hjc@rock-chips.com>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Sean Paul <sean@poorly.run>
Cc: Sebastian Reichel <sre@kernel.org>
Cc: Shawn Guo <shawn.guo@linaro.org>
Cc: Shawn Lin <shawn.lin@rock-chips.com>
Cc: Simona Vetter <simona@ffwll.ch>
Cc: Steen Hegelund <Steen.Hegelund@microchip.com>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Tudor Ambarus <tudor.ambarus@linaro.org>
Cc: Vincent Mailhol <mailhol@kernel.org>
Cc: Yixun Lan <dlan@kernel.org>
Cc: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
v2->v8: none
v1->v2: collect tag
---
include/linux/phy/phy.h | 2 --
1 file changed, 2 deletions(-)
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index e65865b4acfe..ccf7e83f103a 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -12,8 +12,6 @@
#include <linux/phy/phy-props.h>
-#include "../../../drivers/phy/phy-provider.h"
-
struct device;
struct device_node;
struct phy;
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v8 phy-next 00/31] Split Generic PHY consumer and provider API
From: Vladimir Oltean @ 2026-05-05 10:04 UTC (permalink / raw)
To: linux-phy
Cc: Vinod Koul, Neil Armstrong, dri-devel, freedreno,
linux-arm-kernel, linux-arm-msm, linux-can, linux-gpio, linux-ide,
linux-kernel, linux-media, linux-pci, linux-renesas-soc,
linux-riscv, linux-rockchip, linux-samsung-soc, linux-scsi,
linux-sunxi, linux-tegra, linux-usb, netdev, spacemit,
UNGLinuxDriver, Abhinav Kumar, Alexandre Belloni, Alim Akhtar,
André Draszik, Andrew Lunn, Andrzej Hajda, Andy Yan,
Bart Van Assche, Bjorn Helgaas, Can Guo, Chanho Park,
Chen-Yu Tsai, Claudiu Beznea, Damien Le Moal, Daniel Machon,
David Airlie, David S. Miller, Dmitry Baryshkov, Eric Dumazet,
Fabio Estevam, Frank Li, Geert Uytterhoeven, Greg Kroah-Hartman,
Heiko Stübner, Inki Dae, Jagan Teki, Jakub Kicinski,
James E.J. Bottomley, JC Kuo, Jernej Skrabec, Jessica Zhang,
Joe Perches, Johan Hovold, Jonas Karlman, Jonathan Hunter,
Kevin Xie, Krzysztof Kozlowski, Krzysztof Wilczyński,
Laurent Pinchart, Linus Walleij, Lorenzo Pieralisi,
Maarten Lankhorst, Magnus Damm, Manivannan Sadhasivam,
Marc Kleine-Budde, Marek Szyprowski, Marijn Suijten,
Markus Schneider-Pargmann, Martin K. Petersen, Mathias Nyman,
Mauro Carvalho Chehab, Maxime Ripard, Michael Dege, Nicolas Ferre,
Niklas Cassel, Nitin Rawat, Paolo Abeni, Pengutronix Kernel Team,
Peter Chen, Peter Griffin, Rob Clark, Robert Foss, Rob Herring,
Russell King (Oracle), Samuel Holland, Sandy Huang, Sascha Hauer,
Sean Paul, Sebastian Reichel, Shawn Guo, Shawn Lin, Simona Vetter,
Steen Hegelund, Thierry Reding, Thinh Nguyen, Thomas Zimmermann,
Tudor Ambarus, Vincent Mailhol, Xu Yang, Yixun Lan,
Yoshihiro Shimoda
The biggest problem requiring this split is the fact that consumer
drivers poke around in struct phy, accessing fields which shouldn't be
visible to them. Follow the example of mux, gpio, iio, spi offload,
pwrsec, pinctrl and regulator, which each expose separate headers for
consumers and providers.
Some off-list discussions were had with Vinod Koul regarding the 3 PHY
providers outside the drivers/phy/ subsystem. It was agreed that it is
desirable to relocate them to drivers/phy/, rather than to publish
phy-provider.h to include/linux/phy/ for liberal use. Only phy.h and
(new) phy-props.h - consumer-facing headers - stay there.
The hope is that developers get a hint when they need to include the
wrong header to get their job done.
If that fails, patch 31/31 adds a regex in the MAINTAINERS entry that
ensures linux-phy is copied on all Generic PHY patches, for an extra set
of eyes.
Requested merge strategy, I hope this works for everyone:
- Subsystem maintainers ACK their affected portions
- Entire series goes through linux-phy/next (v7.1-rc1)
- linux-phy provides stable tag
- (optionally, but recommended) Said tag is merged back into affected
subsystem 'next' branches. Those who strongly prefer can handle merge
conflicts when they send their PR. But this series unexports a lot of
stuff from <linux/phy/phy.h> which may cause breakage if still used
later, directly or not, in other subsystems.
Detailed change log in patches, summary below.
v7->v8:
- new "[PATCH v8 phy-next 01/31] PCI: cadence: Preserve all error codes
in cdns_plat_pcie_probe()" to fix pre-existing issue found by Sashiko
- bring commit message details more in line with actual code changes
(reported by Sashiko)
- completely rewrote Exynos UFS patch (10/31), introducing new
phy_request_bus_width() consumer API (also updated regex pattern in
MAINTAINERS). Issues with previous approach
reported by Sashiko.
- completely rewrote Qualcomm UFS patches, included 3 untested changes
previously sent to Manivannan Sadhasivam during v5
- move ulpi_phy.h from include/linux/phy/ to drivers/phy/
- make "struct phy *" argument const for new phy_get_max_link_rate() API
function, but not for existing API functions. From Geert Uytterhoeven.
- updated all patches to clarify that phy_set_bus_width() is intended as
a provider-only function.
- Bug fixes pointed out by Sashiko in Tegra XUDC and XUSB drivers
- expanded CC list coverage for UFS changes
v6->v7:
- "[PATCH v6 phy-next 15/28] drm/msm/dp: remove debugging prints with
internal struct phy state" merged separately:
https://lore.kernel.org/linux-phy/okmmblz53sdgjwduiszsyo5l2hcqnxm3xq5yojbi6uxp7kmojm@jaz2a34av7ww/#t
- rebase onto v7.1-rc1
- fix new fallout in drivers/usb/dwc3/dwc3-imx.c (patch 04/31) due to
crossing paths with new driver
v5->v6:
- new patch 14/31 to avoid build breakage in ufs-qcom.c for armv7
- expanded CC list coverage
v4->v5:
- fix additional compilation breakage caught by better build coverage.
PCI patch 02/27 received an extra change for pcie-spacemit-k1.c,
patch 10/27 (for ufs-qcom.c) is new, so are 12/27 and 13/27 for Tegra
USB (host and gadget)
v3->v4:
- fix build breakage in drivers/phy/qualcomm/phy-qcom-ipq806x-sata.c and
include/linux/phy/tegra/xusb.h added by patch 22/24
v2->v3:
- remove unused variable in PCI after device link removal
- update MAINTAINERS regex pattern to escape forward slashes
- add more people to CC list
- provide conflict resolution
v1->v2:
- split "phy: include PHY provider header" into smaller chunks to work
around mailing list moderation due to patch size
- improve MAINTAINERS regex pattern
- make all PHY attribute helpers NULL-tolerant. Not just the new
phy_get_bus_width(), but also retroactively, the existing ones.
- fixed the temporary include path from <linux/phy/phy.h> to
"phy-provider.h", removed anyway by the end of the series
- logical bug fixes in the PCI controller <-> PHY device link removal
and Exynos UFS PHY API rework
In case anyone wants to test the series, here it is on top of linux-phy/next:
https://github.com/vladimiroltean/linux/tree/phy-split-consumer-provider-v8
v7 at:
https://lore.kernel.org/linux-phy/20260430110652.558622-1-vladimir.oltean@nxp.com/
v6 at:
https://lore.kernel.org/linux-phy/20260327184706.1600329-1-vladimir.oltean@nxp.com/
v5 at:
https://lore.kernel.org/linux-phy/20260319223241.1351137-1-vladimir.oltean@nxp.com/
v4 at:
https://lore.kernel.org/linux-phy/20260317230500.2056077-1-vladimir.oltean@nxp.com/
v3 at:
https://lore.kernel.org/linux-phy/20260309190842.927634-1-vladimir.oltean@nxp.com/
v2 at:
https://lore.kernel.org/linux-phy/20260308114009.2546587-1-vladimir.oltean@nxp.com/
v1 at:
https://lore.kernel.org/linux-phy/20260304175735.2660419-13-vladimir.oltean@nxp.com/
Cc: Abhinav Kumar <abhinav.kumar@linux.dev>
Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
Cc: Alim Akhtar <alim.akhtar@samsung.com>
Cc: "André Draszik" <andre.draszik@linaro.org>
Cc: Andrew Lunn <andrew+netdev@lunn.ch>
Cc: Andrzej Hajda <andrzej.hajda@intel.com>
Cc: Andy Yan <andy.yan@rock-chips.com>
Cc: Bart Van Assche <bvanassche@acm.org>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Can Guo <quic_cang@quicinc.com>
Cc: Chanho Park <chanho61.park@samsung.com>
Cc: Chen-Yu Tsai <wens@kernel.org>
Cc: Claudiu Beznea <claudiu.beznea@tuxon.dev>
Cc: Damien Le Moal <dlemoal@kernel.org>
Cc: Daniel Machon <daniel.machon@microchip.com>
Cc: David Airlie <airlied@gmail.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Dmitry Baryshkov <lumag@kernel.org>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Frank Li <Frank.Li@nxp.com>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Heiko Stübner" <heiko@sntech.de>
Cc: Inki Dae <inki.dae@samsung.com>
Cc: Jagan Teki <jagan@amarulasolutions.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
Cc: JC Kuo <jckuo@nvidia.com>
Cc: Jernej Skrabec <jernej.skrabec@gmail.com>
Cc: Jessica Zhang <jesszhan0024@gmail.com>
Cc: Joe Perches <joe@perches.com>
Cc: Johan Hovold <johan+linaro@kernel.org>
Cc: Jonas Karlman <jonas@kwiboo.se>
Cc: Jonathan Hunter <jonathanh@nvidia.com>
Cc: Kevin Xie <kevin.xie@starfivetech.com>
Cc: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Cc: "Krzysztof Wilczyński" <kwilczynski@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Linus Walleij <linusw@kernel.org>
Cc: Lorenzo Pieralisi <lpieralisi@kernel.org>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Magnus Damm <magnus.damm@gmail.com>
Cc: Manivannan Sadhasivam <mani@kernel.org>
Cc: Marc Kleine-Budde <mkl@pengutronix.de>
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Cc: Marijn Suijten <marijn.suijten@somainline.org>
Cc: Markus Schneider-Pargmann <msp@baylibre.com>
Cc: "Martin K. Petersen" <martin.petersen@oracle.com>
Cc: Mathias Nyman <mathias.nyman@intel.com>
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: Maxime Ripard <mripard@kernel.org>
Cc: Michael Dege <michael.dege@renesas.com>
Cc: Neil Armstrong <neil.armstrong@linaro.org>
Cc: Nicolas Ferre <nicolas.ferre@microchip.com>
Cc: Niklas Cassel <cassel@kernel.org>
Cc: Nitin Rawat <quic_nitirawa@quicinc.com>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Peter Chen <peter.chen@kernel.org>
Cc: Peter Griffin <peter.griffin@linaro.org>
Cc: Rob Clark <robin.clark@oss.qualcomm.com>
Cc: Robert Foss <rfoss@kernel.org>
Cc: Rob Herring <robh@kernel.org>
Cc: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
Cc: Samuel Holland <samuel@sholland.org>
Cc: Sandy Huang <hjc@rock-chips.com>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Sean Paul <sean@poorly.run>
Cc: Sebastian Reichel <sre@kernel.org>
Cc: Shawn Guo <shawn.guo@linaro.org>
Cc: Shawn Lin <shawn.lin@rock-chips.com>
Cc: Simona Vetter <simona@ffwll.ch>
Cc: Steen Hegelund <Steen.Hegelund@microchip.com>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Tudor Ambarus <tudor.ambarus@linaro.org>
Cc: Vincent Mailhol <mailhol@kernel.org>
Cc: Xu Yang <xu.yang_2@nxp.com>
Cc: Yixun Lan <dlan@kernel.org>
Cc: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Vladimir Oltean (31):
PCI: cadence: Preserve all error codes in cdns_plat_pcie_probe()
ata: add <linux/pm_runtime.h> where missing
PCI: Add missing headers transitively included by <linux/phy/phy.h>
usb: add missing headers transitively included by <linux/phy/phy.h>
drm: add <linux/pm_runtime.h> where missing
phy: add <linux/pm_runtime.h> where missing
phy: spacemit: include missing <linux/phy/phy.h>
net: lan969x: include missing <linux/of.h>
PCI: Remove device links to PHY
scsi: ufs: exynos: use dedicated API for updating PHY bus width
scsi: ufs: qcom: call phy_init() before phy_power_on()
scsi: ufs: qcom: make use of QMP PHY dynamic gear switching ability
scsi: ufs: qcom: keep separate track of PHY power state
scsi: ufs: qcom: include missing <linux/interrupt.h>
drm/rockchip: dw_hdmi: avoid direct dereference of phy->dev.of_node
usb: host: tegra: avoid direct dereference of phy->dev.of_node
usb: gadget: tegra-xudc: avoid direct dereference of phy->dev.of_node
phy: move provider API out of public <linux/phy/phy.h>
phy: make phy_get_mode(), phy_get_bus_width() NULL tolerant
phy: introduce phy_get_max_link_rate() helper for consumers
drm/rockchip: dsi: include PHY provider header
drm: bridge: cdns-mhdp8546: use consumer API for getting PHY bus width
media: sunxi: a83-mips-csi2: include PHY provider header
net: renesas: rswitch: include PHY provider header
pinctrl: tegra-xusb: include PHY provider header
power: supply: cpcap-charger: include missing <linux/property.h>
phy: move ulpi_phy.h from include/linux/phy/ to drivers/phy/
phy: include PHY provider header (1/2)
phy: include PHY provider header (2/2)
phy: remove temporary provider compatibility from consumer header
MAINTAINERS: add regexes for linux-phy
MAINTAINERS | 12 +
drivers/ata/ahci.c | 1 +
drivers/ata/ahci_brcm.c | 1 +
drivers/ata/ahci_ceva.c | 1 +
drivers/ata/ahci_qoriq.c | 1 +
drivers/ata/libahci.c | 1 +
.../drm/bridge/analogix/analogix_dp_core.c | 1 +
.../drm/bridge/cadence/cdns-mhdp8546-core.c | 7 +-
drivers/gpu/drm/bridge/nwl-dsi.c | 1 +
drivers/gpu/drm/bridge/samsung-dsim.c | 1 +
drivers/gpu/drm/bridge/synopsys/dw-dp.c | 2 +-
drivers/gpu/drm/msm/dp/dp_aux.c | 1 +
drivers/gpu/drm/rockchip/cdn-dp-core.c | 1 +
.../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 1 +
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 25 +-
.../sun8i-a83t-mipi-csi2/sun8i_a83t_dphy.c | 2 +-
drivers/net/can/at91_can.c | 3 +-
drivers/net/can/flexcan/flexcan-core.c | 3 +-
drivers/net/can/m_can/m_can_platform.c | 3 +-
drivers/net/can/rcar/rcar_canfd.c | 3 +-
.../microchip/sparx5/lan969x/lan969x_rgmii.c | 1 +
drivers/net/ethernet/renesas/rswitch_main.c | 1 +
.../controller/cadence/pcie-cadence-plat.c | 6 +-
drivers/pci/controller/cadence/pcie-cadence.c | 16 +-
drivers/pci/controller/cadence/pcie-cadence.h | 2 -
drivers/pci/controller/dwc/pci-dra7xx.c | 16 -
drivers/pci/controller/dwc/pci-keystone.c | 32 +-
drivers/pci/controller/dwc/pcie-dw-rockchip.c | 1 +
drivers/pci/controller/dwc/pcie-histb.c | 1 +
drivers/pci/controller/dwc/pcie-qcom-ep.c | 1 +
drivers/pci/controller/dwc/pcie-spacemit-k1.c | 3 +
drivers/pci/controller/dwc/pcie-tegra194.c | 1 +
drivers/pci/controller/pci-tegra.c | 1 +
drivers/pci/controller/pcie-rockchip-host.c | 1 +
drivers/pci/controller/plda/pcie-starfive.c | 1 +
drivers/phy/allwinner/phy-sun4i-usb.c | 3 +-
drivers/phy/allwinner/phy-sun50i-usb3.c | 3 +-
drivers/phy/allwinner/phy-sun6i-mipi-dphy.c | 4 +-
drivers/phy/allwinner/phy-sun9i-usb.c | 3 +-
drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c | 2 +
.../amlogic/phy-meson-axg-mipi-pcie-analog.c | 3 +-
drivers/phy/amlogic/phy-meson-axg-pcie.c | 2 +
.../amlogic/phy-meson-g12a-mipi-dphy-analog.c | 3 +-
drivers/phy/amlogic/phy-meson-g12a-usb2.c | 3 +-
.../phy/amlogic/phy-meson-g12a-usb3-pcie.c | 3 +-
drivers/phy/amlogic/phy-meson-gxl-usb2.c | 3 +-
drivers/phy/amlogic/phy-meson8-hdmi-tx.c | 3 +-
drivers/phy/amlogic/phy-meson8b-usb2.c | 3 +-
drivers/phy/apple/atc.c | 3 +-
drivers/phy/broadcom/phy-bcm-cygnus-pcie.c | 3 +-
drivers/phy/broadcom/phy-bcm-kona-usb2.c | 3 +-
drivers/phy/broadcom/phy-bcm-ns-usb2.c | 3 +-
drivers/phy/broadcom/phy-bcm-ns-usb3.c | 3 +-
drivers/phy/broadcom/phy-bcm-ns2-pcie.c | 3 +-
drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c | 3 +-
drivers/phy/broadcom/phy-bcm-sr-pcie.c | 3 +-
drivers/phy/broadcom/phy-bcm-sr-usb.c | 3 +-
drivers/phy/broadcom/phy-bcm63xx-usbh.c | 3 +-
drivers/phy/broadcom/phy-brcm-sata.c | 3 +-
drivers/phy/broadcom/phy-brcm-usb.c | 2 +-
drivers/phy/cadence/cdns-dphy-rx.c | 3 +-
drivers/phy/cadence/cdns-dphy.c | 4 +-
drivers/phy/cadence/phy-cadence-salvo.c | 3 +-
drivers/phy/cadence/phy-cadence-sierra.c | 3 +-
drivers/phy/cadence/phy-cadence-torrent.c | 3 +-
drivers/phy/canaan/phy-k230-usb.c | 3 +-
drivers/phy/eswin/phy-eic7700-sata.c | 3 +-
.../phy/freescale/phy-fsl-imx8-mipi-dphy.c | 3 +-
drivers/phy/freescale/phy-fsl-imx8m-pcie.c | 4 +-
drivers/phy/freescale/phy-fsl-imx8mq-usb.c | 3 +-
drivers/phy/freescale/phy-fsl-imx8qm-hsio.c | 6 +-
.../phy/freescale/phy-fsl-imx8qm-lvds-phy.c | 3 +-
drivers/phy/freescale/phy-fsl-lynx-28g.c | 3 +-
drivers/phy/hisilicon/phy-hi3660-usb3.c | 3 +-
drivers/phy/hisilicon/phy-hi3670-pcie.c | 3 +-
drivers/phy/hisilicon/phy-hi3670-usb3.c | 3 +-
drivers/phy/hisilicon/phy-hi6220-usb.c | 3 +-
drivers/phy/hisilicon/phy-hisi-inno-usb2.c | 3 +-
drivers/phy/hisilicon/phy-histb-combphy.c | 3 +-
drivers/phy/hisilicon/phy-hix5hd2-sata.c | 3 +-
drivers/phy/ingenic/phy-ingenic-usb.c | 3 +-
drivers/phy/intel/phy-intel-keembay-emmc.c | 3 +-
drivers/phy/intel/phy-intel-keembay-usb.c | 3 +-
drivers/phy/intel/phy-intel-lgm-combo.c | 4 +-
drivers/phy/intel/phy-intel-lgm-emmc.c | 3 +-
drivers/phy/lantiq/phy-lantiq-rcu-usb2.c | 3 +-
drivers/phy/lantiq/phy-lantiq-vrx200-pcie.c | 4 +-
drivers/phy/marvell/phy-armada375-usb2.c | 3 +-
drivers/phy/marvell/phy-armada38x-comphy.c | 3 +-
drivers/phy/marvell/phy-berlin-sata.c | 3 +-
drivers/phy/marvell/phy-berlin-usb.c | 3 +-
drivers/phy/marvell/phy-mmp3-hsic.c | 3 +-
drivers/phy/marvell/phy-mmp3-usb.c | 3 +-
drivers/phy/marvell/phy-mvebu-a3700-comphy.c | 3 +-
drivers/phy/marvell/phy-mvebu-a3700-utmi.c | 3 +-
drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 3 +-
drivers/phy/marvell/phy-mvebu-cp110-utmi.c | 3 +-
drivers/phy/marvell/phy-mvebu-sata.c | 3 +-
drivers/phy/marvell/phy-pxa-28nm-hsic.c | 3 +-
drivers/phy/marvell/phy-pxa-28nm-usb2.c | 3 +-
drivers/phy/marvell/phy-pxa-usb.c | 3 +-
drivers/phy/mediatek/phy-mtk-dp.c | 3 +-
drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c | 1 -
drivers/phy/mediatek/phy-mtk-hdmi.h | 3 +-
drivers/phy/mediatek/phy-mtk-mipi-csi-0-5.c | 2 +-
drivers/phy/mediatek/phy-mtk-mipi-dsi.h | 3 +-
drivers/phy/mediatek/phy-mtk-pcie.c | 2 +-
drivers/phy/mediatek/phy-mtk-tphy.c | 2 +-
drivers/phy/mediatek/phy-mtk-ufs.c | 2 +-
drivers/phy/mediatek/phy-mtk-xfi-tphy.c | 2 +-
drivers/phy/mediatek/phy-mtk-xsphy.c | 2 +-
drivers/phy/microchip/lan966x_serdes.c | 4 +-
drivers/phy/microchip/sparx5_serdes.c | 2 +-
drivers/phy/motorola/phy-cpcap-usb.c | 3 +-
drivers/phy/motorola/phy-mapphone-mdm6600.c | 5 +-
drivers/phy/mscc/phy-ocelot-serdes.c | 3 +-
drivers/phy/nuvoton/phy-ma35d1-usb2.c | 3 +-
drivers/phy/phy-airoha-pcie.c | 2 +-
drivers/phy/phy-can-transceiver.c | 3 +-
drivers/phy/phy-core-mipi-dphy.c | 4 +-
drivers/phy/phy-core.c | 80 +++
drivers/phy/phy-google-usb.c | 4 +-
drivers/phy/phy-lpc18xx-usb-otg.c | 3 +-
drivers/phy/phy-nxp-ptn3222.c | 3 +-
drivers/phy/phy-pistachio-usb.c | 4 +-
drivers/phy/phy-provider.h | 263 +++++++++
drivers/phy/phy-snps-eusb2.c | 2 +
drivers/phy/phy-xgene.c | 3 +-
drivers/phy/qualcomm/phy-ath79-usb.c | 3 +-
drivers/phy/qualcomm/phy-qcom-apq8064-sata.c | 3 +-
drivers/phy/qualcomm/phy-qcom-edp.c | 3 +-
.../phy/qualcomm/phy-qcom-eusb2-repeater.c | 3 +-
drivers/phy/qualcomm/phy-qcom-ipq4019-usb.c | 3 +-
drivers/phy/qualcomm/phy-qcom-ipq806x-sata.c | 3 +-
drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c | 3 +-
drivers/phy/qualcomm/phy-qcom-m31-eusb2.c | 2 +
drivers/phy/qualcomm/phy-qcom-m31.c | 3 +-
drivers/phy/qualcomm/phy-qcom-pcie2.c | 3 +-
drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 4 +-
.../phy/qualcomm/phy-qcom-qmp-pcie-msm8996.c | 3 +-
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 3 +-
drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 9 +-
.../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 +-
drivers/phy/qualcomm/phy-qcom-qusb2.c | 5 +-
drivers/phy/qualcomm/phy-qcom-sgmii-eth.c | 3 +-
drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c | 4 +-
.../phy/qualcomm/phy-qcom-uniphy-pcie-28lp.c | 3 +-
drivers/phy/qualcomm/phy-qcom-usb-hs-28nm.c | 3 +-
drivers/phy/qualcomm/phy-qcom-usb-hs.c | 3 +-
drivers/phy/qualcomm/phy-qcom-usb-hsic.c | 3 +-
drivers/phy/qualcomm/phy-qcom-usb-ss.c | 3 +-
drivers/phy/ralink/phy-mt7621-pci.c | 3 +-
drivers/phy/ralink/phy-ralink-usb.c | 3 +-
drivers/phy/realtek/phy-rtk-usb2.c | 3 +-
drivers/phy/realtek/phy-rtk-usb3.c | 3 +-
drivers/phy/renesas/phy-rcar-gen2.c | 3 +-
drivers/phy/renesas/phy-rcar-gen3-pcie.c | 4 +-
drivers/phy/renesas/phy-rcar-gen3-usb2.c | 3 +-
drivers/phy/renesas/phy-rcar-gen3-usb3.c | 3 +-
drivers/phy/renesas/phy-rzg3e-usb3.c | 3 +-
drivers/phy/renesas/r8a779f0-ether-serdes.c | 4 +-
drivers/phy/rockchip/phy-rockchip-dp.c | 3 +-
drivers/phy/rockchip/phy-rockchip-dphy-rx0.c | 3 +-
drivers/phy/rockchip/phy-rockchip-emmc.c | 3 +-
.../phy/rockchip/phy-rockchip-inno-csidphy.c | 3 +-
.../phy/rockchip/phy-rockchip-inno-dsidphy.c | 4 +-
drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 4 +-
drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 3 +-
.../rockchip/phy-rockchip-naneng-combphy.c | 3 +-
drivers/phy/rockchip/phy-rockchip-pcie.c | 2 +-
.../phy/rockchip/phy-rockchip-samsung-dcphy.c | 3 +-
.../phy/rockchip/phy-rockchip-samsung-hdptx.c | 4 +-
.../phy/rockchip/phy-rockchip-snps-pcie3.c | 3 +-
drivers/phy/rockchip/phy-rockchip-typec.c | 5 +-
drivers/phy/rockchip/phy-rockchip-usb.c | 3 +-
drivers/phy/rockchip/phy-rockchip-usbdp.c | 3 +-
drivers/phy/samsung/phy-exynos-dp-video.c | 3 +-
drivers/phy/samsung/phy-exynos-mipi-video.c | 3 +-
drivers/phy/samsung/phy-exynos-pcie.c | 3 +-
drivers/phy/samsung/phy-exynos4210-usb2.c | 3 +-
drivers/phy/samsung/phy-exynos4x12-usb2.c | 3 +-
drivers/phy/samsung/phy-exynos5-usbdrd.c | 2 +
drivers/phy/samsung/phy-exynos5250-sata.c | 3 +-
drivers/phy/samsung/phy-exynos5250-usb2.c | 3 +-
drivers/phy/samsung/phy-s5pv210-usb2.c | 3 +-
drivers/phy/samsung/phy-samsung-ufs.c | 29 +-
drivers/phy/samsung/phy-samsung-ufs.h | 3 +-
drivers/phy/samsung/phy-samsung-usb2.c | 3 +-
drivers/phy/samsung/phy-samsung-usb2.h | 3 +-
drivers/phy/socionext/phy-uniphier-ahci.c | 3 +-
drivers/phy/socionext/phy-uniphier-pcie.c | 3 +-
drivers/phy/socionext/phy-uniphier-usb2.c | 3 +-
drivers/phy/socionext/phy-uniphier-usb3hs.c | 3 +-
drivers/phy/socionext/phy-uniphier-usb3ss.c | 3 +-
drivers/phy/sophgo/phy-cv1800-usb2.c | 3 +-
drivers/phy/spacemit/phy-k1-pcie.c | 4 +-
drivers/phy/spacemit/phy-k1-usb2.c | 2 +
drivers/phy/st/phy-miphy28lp.c | 4 +-
drivers/phy/st/phy-spear1310-miphy.c | 3 +-
drivers/phy/st/phy-spear1340-miphy.c | 3 +-
drivers/phy/st/phy-stih407-usb.c | 3 +-
drivers/phy/st/phy-stm32-combophy.c | 3 +-
drivers/phy/st/phy-stm32-usbphyc.c | 3 +-
drivers/phy/starfive/phy-jh7110-dphy-rx.c | 3 +-
drivers/phy/starfive/phy-jh7110-dphy-tx.c | 3 +-
drivers/phy/starfive/phy-jh7110-pcie.c | 3 +-
drivers/phy/starfive/phy-jh7110-usb.c | 3 +-
drivers/phy/sunplus/phy-sunplus-usb2.c | 3 +-
drivers/phy/tegra/phy-tegra194-p2u.c | 3 +-
drivers/phy/tegra/xusb-tegra124.c | 2 +-
drivers/phy/tegra/xusb-tegra186.c | 2 +-
drivers/phy/tegra/xusb-tegra210.c | 2 +-
drivers/phy/tegra/xusb.c | 2 +-
drivers/phy/ti/phy-am654-serdes.c | 3 +-
drivers/phy/ti/phy-da8xx-usb.c | 3 +-
drivers/phy/ti/phy-dm816x-usb.c | 3 +-
drivers/phy/ti/phy-gmii-sel.c | 3 +-
drivers/phy/ti/phy-omap-usb2.c | 3 +-
drivers/phy/ti/phy-ti-pipe3.c | 3 +-
drivers/phy/ti/phy-tusb1210.c | 4 +-
drivers/phy/ti/phy-twl4030-usb.c | 3 +-
{include/linux => drivers}/phy/ulpi_phy.h | 2 +-
drivers/phy/xilinx/phy-zynqmp.c | 4 +-
drivers/pinctrl/tegra/pinctrl-tegra-xusb.c | 2 +-
drivers/power/supply/cpcap-charger.c | 1 +
drivers/ufs/host/ufs-exynos.c | 114 ++--
drivers/ufs/host/ufs-exynos.h | 1 +
drivers/ufs/host/ufs-qcom.c | 99 ++--
drivers/ufs/host/ufs-qcom.h | 1 +
drivers/usb/chipidea/ci_hdrc_imx.c | 1 +
drivers/usb/core/hcd.c | 1 +
drivers/usb/dwc3/dwc3-generic-plat.c | 1 +
drivers/usb/dwc3/dwc3-imx.c | 1 +
drivers/usb/dwc3/gadget.c | 1 +
drivers/usb/gadget/udc/tegra-xudc.c | 43 +-
drivers/usb/host/xhci-tegra.c | 43 +-
include/linux/phy/phy-props.h | 75 +++
include/linux/phy/phy-sun4i-usb.h | 2 +-
include/linux/phy/phy.h | 497 ++++--------------
include/linux/phy/tegra/xusb.h | 1 +
242 files changed, 1188 insertions(+), 799 deletions(-)
create mode 100644 drivers/phy/phy-provider.h
rename {include/linux => drivers}/phy/ulpi_phy.h (96%)
create mode 100644 include/linux/phy/phy-props.h
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH v8 phy-next 18/31] phy: move provider API out of public <linux/phy/phy.h>
From: Vladimir Oltean @ 2026-05-05 10:05 UTC (permalink / raw)
To: linux-phy
Cc: Vinod Koul, Neil Armstrong, dri-devel, freedreno,
linux-arm-kernel, linux-arm-msm, linux-can, linux-gpio, linux-ide,
linux-kernel, linux-media, linux-pci, linux-renesas-soc,
linux-riscv, linux-rockchip, linux-samsung-soc, linux-scsi,
linux-sunxi, linux-tegra, linux-usb, netdev, spacemit,
UNGLinuxDriver, Dmitry Baryshkov, Abhinav Kumar,
Alexandre Belloni, André Draszik, Andrew Lunn, Andrzej Hajda,
Andy Yan, Bjorn Helgaas, Chanho Park, Chen-Yu Tsai,
Claudiu Beznea, Damien Le Moal, Daniel Machon, David Airlie,
David S. Miller, Dmitry Baryshkov, Eric Dumazet, Fabio Estevam,
Frank Li, Geert Uytterhoeven, Greg Kroah-Hartman,
Heiko Stübner, Inki Dae, Jagan Teki, Jakub Kicinski,
James E.J. Bottomley, JC Kuo, Jernej Skrabec, Jessica Zhang,
Joe Perches, Johan Hovold, Jonas Karlman, Jonathan Hunter,
Kevin Xie, Krzysztof Kozlowski, Krzysztof Wilczyński,
Laurent Pinchart, Linus Walleij, Lorenzo Pieralisi,
Maarten Lankhorst, Magnus Damm, Manivannan Sadhasivam,
Marc Kleine-Budde, Marek Szyprowski, Marijn Suijten,
Markus Schneider-Pargmann, Martin K. Petersen, Mathias Nyman,
Mauro Carvalho Chehab, Maxime Ripard, Michael Dege, Nicolas Ferre,
Niklas Cassel, Nitin Rawat, Paolo Abeni, Pengutronix Kernel Team,
Peter Chen, Peter Griffin, Rob Clark, Robert Foss, Rob Herring,
Russell King (Oracle), Samuel Holland, Sandy Huang, Sascha Hauer,
Sean Paul, Sebastian Reichel, Shawn Guo, Shawn Lin, Simona Vetter,
Steen Hegelund, Thierry Reding, Thinh Nguyen, Thomas Zimmermann,
Tudor Ambarus, Vincent Mailhol, Yixun Lan, Yoshihiro Shimoda
In-Reply-To: <20260505100523.1922388-1-vladimir.oltean@nxp.com>
The major goal is to hide the contents of struct phy from consumer
drivers.
The idea with "phy-props.h" is that both consumers and providers make
use of some data types. So both headers include "phy-props.h".
Some slight points of contention.
1. phy-provider.h should go to include/linux/phy/ or to drivers/phy/?
We do have 3 PHY providers outside of drivers/phy/:
drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_dphy.c
drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
drivers/pinctrl/tegra/pinctrl-tegra-xusb.c
but the practice is not encouraged, and with time, these should be
moved to the subsystem. This is not something that I can do now.
2. We can no longer tolerate static inline helpers. Allowing these would
make it impossible to hide the struct phy definition from consumers.
I've made phy_get_mode(), phy_get_bus_width() exported symbols in
drivers/phy/phy-core.c.
3. This is not a change without side effects. In the transition we are
no longer providing <linux/pm_runtime.h> at all, and
<linux/regulator/consumer.h> to PHY consumer drivers. However, the
in-tree dependencies should all have been resolved. Also, the
movement of phy-provider.h to drivers/phy/ is at least "interesting"
for out of tree PHY provider drivers (this header is not deployed by
make headers_install). However, it seems to be what Vinod is looking
to see.
For temporary compatibility, keep including the provider header. This
will be removed when abuses are all gotten rid of.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
Cc: Abhinav Kumar <abhinav.kumar@linux.dev>
Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
Cc: "André Draszik" <andre.draszik@linaro.org>
Cc: Andrew Lunn <andrew+netdev@lunn.ch>
Cc: Andrzej Hajda <andrzej.hajda@intel.com>
Cc: Andy Yan <andy.yan@rock-chips.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Chanho Park <chanho61.park@samsung.com>
Cc: Chen-Yu Tsai <wens@kernel.org>
Cc: Claudiu Beznea <claudiu.beznea@tuxon.dev>
Cc: Damien Le Moal <dlemoal@kernel.org>
Cc: Daniel Machon <daniel.machon@microchip.com>
Cc: David Airlie <airlied@gmail.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Dmitry Baryshkov <lumag@kernel.org>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Frank Li <Frank.Li@nxp.com>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Heiko Stübner" <heiko@sntech.de>
Cc: Inki Dae <inki.dae@samsung.com>
Cc: Jagan Teki <jagan@amarulasolutions.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
Cc: JC Kuo <jckuo@nvidia.com>
Cc: Jernej Skrabec <jernej.skrabec@gmail.com>
Cc: Jessica Zhang <jesszhan0024@gmail.com>
Cc: Joe Perches <joe@perches.com>
Cc: Johan Hovold <johan+linaro@kernel.org>
Cc: Jonas Karlman <jonas@kwiboo.se>
Cc: Jonathan Hunter <jonathanh@nvidia.com>
Cc: Kevin Xie <kevin.xie@starfivetech.com>
Cc: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Cc: "Krzysztof Wilczyński" <kwilczynski@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Linus Walleij <linusw@kernel.org>
Cc: Lorenzo Pieralisi <lpieralisi@kernel.org>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Magnus Damm <magnus.damm@gmail.com>
Cc: Manivannan Sadhasivam <mani@kernel.org>
Cc: Marc Kleine-Budde <mkl@pengutronix.de>
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Cc: Marijn Suijten <marijn.suijten@somainline.org>
Cc: Markus Schneider-Pargmann <msp@baylibre.com>
Cc: "Martin K. Petersen" <martin.petersen@oracle.com>
Cc: Mathias Nyman <mathias.nyman@intel.com>
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: Maxime Ripard <mripard@kernel.org>
Cc: Michael Dege <michael.dege@renesas.com>
Cc: Neil Armstrong <neil.armstrong@linaro.org>
Cc: Nicolas Ferre <nicolas.ferre@microchip.com>
Cc: Niklas Cassel <cassel@kernel.org>
Cc: Nitin Rawat <quic_nitirawa@quicinc.com>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Peter Chen <peter.chen@kernel.org>
Cc: Peter Griffin <peter.griffin@linaro.org>
Cc: Rob Clark <robin.clark@oss.qualcomm.com>
Cc: Robert Foss <rfoss@kernel.org>
Cc: Rob Herring <robh@kernel.org>
Cc: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
Cc: Samuel Holland <samuel@sholland.org>
Cc: Sandy Huang <hjc@rock-chips.com>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Sean Paul <sean@poorly.run>
Cc: Sebastian Reichel <sre@kernel.org>
Cc: Shawn Guo <shawn.guo@linaro.org>
Cc: Shawn Lin <shawn.lin@rock-chips.com>
Cc: Simona Vetter <simona@ffwll.ch>
Cc: Steen Hegelund <Steen.Hegelund@microchip.com>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Tudor Ambarus <tudor.ambarus@linaro.org>
Cc: Vincent Mailhol <mailhol@kernel.org>
Cc: Yixun Lan <dlan@kernel.org>
Cc: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
v7->v8:
- phy_set_bus_width() is now considered a provider function; the new
consumer function is phy_request_bus_width()
v2->v7: none
v1->v2:
- collect tag
- fix path to phy-provider.h
- update commit message with the 4th point of contention
---
drivers/phy/phy-core.c | 28 ++
drivers/phy/phy-provider.h | 263 ++++++++++++++++++
include/linux/phy/phy-props.h | 75 +++++
include/linux/phy/phy.h | 504 ++++++----------------------------
4 files changed, 457 insertions(+), 413 deletions(-)
create mode 100644 drivers/phy/phy-provider.h
create mode 100644 include/linux/phy/phy-props.h
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index 634ac07fd1f3..fe933629286b 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -20,6 +20,22 @@
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
+#define to_phy(a) (container_of((a), struct phy, dev))
+
+/**
+ * struct phy_lookup - PHY association in list of phys managed by the phy driver
+ * @node: list node
+ * @dev_id: the device of the association
+ * @con_id: connection ID string on device
+ * @phy: the phy of the association
+ */
+struct phy_lookup {
+ struct list_head node;
+ const char *dev_id;
+ const char *con_id;
+ struct phy *phy;
+};
+
static void phy_release(struct device *dev);
static const struct class phy_class = {
.name = "phy",
@@ -606,6 +622,18 @@ int phy_validate(struct phy *phy, enum phy_mode mode, int submode,
}
EXPORT_SYMBOL_GPL(phy_validate);
+enum phy_mode phy_get_mode(struct phy *phy)
+{
+ return phy->attrs.mode;
+}
+EXPORT_SYMBOL_GPL(phy_get_mode);
+
+int phy_get_bus_width(struct phy *phy)
+{
+ return phy->attrs.bus_width;
+}
+EXPORT_SYMBOL_GPL(phy_get_bus_width);
+
/**
* phy_request_bus_width() - request PHY to change its bus width
* @phy: the phy returned by phy_get()
diff --git a/drivers/phy/phy-provider.h b/drivers/phy/phy-provider.h
new file mode 100644
index 000000000000..c76dd8cf5f32
--- /dev/null
+++ b/drivers/phy/phy-provider.h
@@ -0,0 +1,263 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * phy-provider.h -- Generic PHY provider API
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Author: Kishon Vijay Abraham I <kishon@ti.com>
+ */
+#ifndef __PHY_PROVIDER_H
+#define __PHY_PROVIDER_H
+
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/phy/phy-props.h>
+
+struct phy;
+
+/**
+ * struct phy_ops - set of function pointers for performing phy operations
+ * @init: operation to be performed for initializing phy
+ * @exit: operation to be performed while exiting
+ * @power_on: powering on the phy
+ * @power_off: powering off the phy
+ * @set_mode: set the mode of the phy
+ * @set_media: set the media type of the phy (optional)
+ * @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
+ * @request_bus_width: request a different bus width for the phy
+ * @release: ops to be performed while the consumer relinquishes the PHY
+ * @owner: the module owner containing the ops
+ */
+struct phy_ops {
+ int (*init)(struct phy *phy);
+ int (*exit)(struct phy *phy);
+ int (*power_on)(struct phy *phy);
+ int (*power_off)(struct phy *phy);
+ int (*set_mode)(struct phy *phy, enum phy_mode mode, int submode);
+ int (*set_media)(struct phy *phy, enum phy_media media);
+ int (*set_speed)(struct phy *phy, int speed);
+
+ /**
+ * @configure:
+ *
+ * Optional.
+ *
+ * Used to change the PHY parameters. phy_init() must have
+ * been called on the phy.
+ *
+ * Returns: 0 if successful, an negative error code otherwise
+ */
+ int (*configure)(struct phy *phy, union phy_configure_opts *opts);
+
+ /**
+ * @validate:
+ *
+ * Optional.
+ *
+ * Used to check that the current set of parameters can be
+ * handled by the phy. Implementations are free to tune the
+ * parameters passed as arguments if needed by some
+ * implementation detail or constraints. It must not change
+ * any actual configuration of the PHY, so calling it as many
+ * times as deemed fit by the consumer must have no side
+ * effect.
+ *
+ * Returns: 0 if the configuration can be applied, an negative
+ * error code otherwise
+ */
+ int (*validate)(struct phy *phy, enum phy_mode mode, int submode,
+ union phy_configure_opts *opts);
+ int (*reset)(struct phy *phy);
+ int (*calibrate)(struct phy *phy);
+
+ /* notify phy connect status change */
+ int (*connect)(struct phy *phy, int port);
+ int (*disconnect)(struct phy *phy, int port);
+
+ int (*notify_phystate)(struct phy *phy, union phy_notify state);
+ int (*request_bus_width)(struct phy *phy, int bus_width);
+ void (*release)(struct phy *phy);
+ struct module *owner;
+};
+
+/**
+ * struct phy_attrs - represents phy attributes
+ * @bus_width: Data path width implemented by PHY
+ * @max_link_rate: Maximum link rate supported by PHY (units to be decided by producer and consumer)
+ * @mode: PHY mode
+ */
+struct phy_attrs {
+ u32 bus_width;
+ u32 max_link_rate;
+ enum phy_mode mode;
+};
+
+/**
+ * struct phy - represents the phy device
+ * @dev: phy device
+ * @id: id of the phy device
+ * @ops: function pointers for performing phy operations
+ * @mutex: mutex to protect phy_ops
+ * @lockdep_key: lockdep information for this mutex
+ * @init_count: used to protect when the PHY is used by multiple consumers
+ * @power_count: used to protect when the PHY is used by multiple consumers
+ * @attrs: used to specify PHY specific attributes
+ * @pwr: power regulator associated with the phy
+ * @debugfs: debugfs directory
+ */
+struct phy {
+ struct device dev;
+ int id;
+ const struct phy_ops *ops;
+ struct mutex mutex;
+ struct lock_class_key lockdep_key;
+ int init_count;
+ int power_count;
+ struct phy_attrs attrs;
+ struct regulator *pwr;
+ struct dentry *debugfs;
+};
+
+/**
+ * struct phy_provider - represents the phy provider
+ * @dev: phy provider device
+ * @children: can be used to override the default (dev->of_node) child node
+ * @owner: the module owner having of_xlate
+ * @list: to maintain a linked list of PHY providers
+ * @of_xlate: function pointer to obtain phy instance from phy pointer
+ */
+struct phy_provider {
+ struct device *dev;
+ struct device_node *children;
+ struct module *owner;
+ struct list_head list;
+ struct phy *(*of_xlate)(struct device *dev,
+ const struct of_phandle_args *args);
+};
+
+#define of_phy_provider_register(dev, xlate) \
+ __of_phy_provider_register((dev), NULL, THIS_MODULE, (xlate))
+
+#define devm_of_phy_provider_register(dev, xlate) \
+ __devm_of_phy_provider_register((dev), NULL, THIS_MODULE, (xlate))
+
+#define of_phy_provider_register_full(dev, children, xlate) \
+ __of_phy_provider_register(dev, children, THIS_MODULE, xlate)
+
+#define devm_of_phy_provider_register_full(dev, children, xlate) \
+ __devm_of_phy_provider_register(dev, children, THIS_MODULE, xlate)
+
+static inline void phy_set_drvdata(struct phy *phy, void *data)
+{
+ dev_set_drvdata(&phy->dev, data);
+}
+
+static inline void *phy_get_drvdata(struct phy *phy)
+{
+ return dev_get_drvdata(&phy->dev);
+}
+
+static inline void phy_set_bus_width(struct phy *phy, int bus_width)
+{
+ phy->attrs.bus_width = bus_width;
+}
+
+#if IS_ENABLED(CONFIG_GENERIC_PHY)
+struct phy *phy_create(struct device *dev, struct device_node *node,
+ const struct phy_ops *ops);
+struct phy *devm_phy_create(struct device *dev, struct device_node *node,
+ const struct phy_ops *ops);
+void phy_destroy(struct phy *phy);
+void devm_phy_destroy(struct device *dev, struct phy *phy);
+
+struct phy_provider *
+__of_phy_provider_register(struct device *dev, struct device_node *children,
+ struct module *owner,
+ struct phy *(*of_xlate)(struct device *dev,
+ const struct of_phandle_args *args));
+struct phy_provider *
+__devm_of_phy_provider_register(struct device *dev, struct device_node *children,
+ struct module *owner,
+ struct phy *(*of_xlate)(struct device *dev,
+ const struct of_phandle_args *args));
+void of_phy_provider_unregister(struct phy_provider *phy_provider);
+void devm_of_phy_provider_unregister(struct device *dev,
+ struct phy_provider *phy_provider);
+int phy_create_lookup(struct phy *phy, const char *con_id, const char *dev_id);
+void phy_remove_lookup(struct phy *phy, const char *con_id, const char *dev_id);
+struct phy *of_phy_simple_xlate(struct device *dev,
+ const struct of_phandle_args *args);
+#else
+static inline struct phy *phy_create(struct device *dev,
+ struct device_node *node,
+ const struct phy_ops *ops)
+{
+ return ERR_PTR(-ENOSYS);
+}
+
+static inline struct phy *devm_phy_create(struct device *dev,
+ struct device_node *node,
+ const struct phy_ops *ops)
+{
+ return ERR_PTR(-ENOSYS);
+}
+
+static inline void phy_destroy(struct phy *phy)
+{
+}
+
+static inline void devm_phy_destroy(struct device *dev, struct phy *phy)
+{
+}
+
+static inline struct phy_provider *
+__of_phy_provider_register(struct device *dev, struct device_node *children,
+ struct module *owner,
+ struct phy *(*of_xlate)(struct device *dev,
+ const struct of_phandle_args *args))
+{
+ return ERR_PTR(-ENOSYS);
+}
+
+static inline struct phy_provider *
+__devm_of_phy_provider_register(struct device *dev, struct device_node *children,
+ struct module *owner,
+ struct phy *(*of_xlate)(struct device *dev,
+ const struct of_phandle_args *args))
+{
+ return ERR_PTR(-ENOSYS);
+}
+
+static inline void of_phy_provider_unregister(struct phy_provider *phy_provider)
+{
+}
+
+static inline void devm_of_phy_provider_unregister(struct device *dev,
+ struct phy_provider *phy_provider)
+{
+}
+
+static inline int phy_create_lookup(struct phy *phy, const char *con_id,
+ const char *dev_id)
+{
+ return 0;
+}
+
+static inline void phy_remove_lookup(struct phy *phy, const char *con_id,
+ const char *dev_id)
+{
+}
+
+static inline struct phy *of_phy_simple_xlate(struct device *dev,
+ const struct of_phandle_args *args)
+{
+ return ERR_PTR(-ENOSYS);
+}
+#endif /* IS_ENABLED(CONFIG_GENERIC_PHY) */
+
+#endif /* __PHY_PROVIDER_H */
diff --git a/include/linux/phy/phy-props.h b/include/linux/phy/phy-props.h
new file mode 100644
index 000000000000..11f36738165f
--- /dev/null
+++ b/include/linux/phy/phy-props.h
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * phy-provider.h -- Generic PHY properties
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Author: Kishon Vijay Abraham I <kishon@ti.com>
+ */
+#ifndef __PHY_PROPS_H
+#define __PHY_PROPS_H
+
+#include <linux/phy/phy-dp.h>
+#include <linux/phy/phy-hdmi.h>
+#include <linux/phy/phy-lvds.h>
+#include <linux/phy/phy-mipi-dphy.h>
+
+enum phy_mode {
+ PHY_MODE_INVALID,
+ PHY_MODE_USB_HOST,
+ PHY_MODE_USB_HOST_LS,
+ PHY_MODE_USB_HOST_FS,
+ PHY_MODE_USB_HOST_HS,
+ PHY_MODE_USB_HOST_SS,
+ PHY_MODE_USB_DEVICE,
+ PHY_MODE_USB_DEVICE_LS,
+ PHY_MODE_USB_DEVICE_FS,
+ PHY_MODE_USB_DEVICE_HS,
+ PHY_MODE_USB_DEVICE_SS,
+ PHY_MODE_USB_OTG,
+ PHY_MODE_UFS_HS_A,
+ PHY_MODE_UFS_HS_B,
+ PHY_MODE_PCIE,
+ PHY_MODE_ETHERNET,
+ PHY_MODE_MIPI_DPHY,
+ PHY_MODE_SATA,
+ PHY_MODE_LVDS,
+ PHY_MODE_DP,
+ PHY_MODE_HDMI,
+};
+
+enum phy_media {
+ PHY_MEDIA_DEFAULT,
+ PHY_MEDIA_SR,
+ 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
+ *
+ * @mipi_dphy: Configuration set applicable for phys supporting
+ * the MIPI_DPHY phy mode.
+ * @dp: Configuration set applicable for phys supporting
+ * the DisplayPort protocol.
+ * @lvds: Configuration set applicable for phys supporting
+ * the LVDS phy mode.
+ * @hdmi: Configuration set applicable for phys supporting
+ * the HDMI phy mode.
+ */
+union phy_configure_opts {
+ struct phy_configure_opts_mipi_dphy mipi_dphy;
+ struct phy_configure_opts_dp dp;
+ struct phy_configure_opts_lvds lvds;
+ struct phy_configure_opts_hdmi hdmi;
+};
+
+#endif /* __PHY_PROPS_H */
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index 01af84f97608..d716e5e0584c 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -1,248 +1,38 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
- * phy.h -- generic phy header file
+ * phy.h -- Generic PHY consumer API
*
* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
*
* Author: Kishon Vijay Abraham I <kishon@ti.com>
*/
-#ifndef __DRIVERS_PHY_H
-#define __DRIVERS_PHY_H
+#ifndef __PHY_CONSUMER_H
+#define __PHY_CONSUMER_H
-#include <linux/err.h>
-#include <linux/of.h>
-#include <linux/device.h>
-#include <linux/pm_runtime.h>
-#include <linux/regulator/consumer.h>
+#include <linux/phy/phy-props.h>
-#include <linux/phy/phy-dp.h>
-#include <linux/phy/phy-hdmi.h>
-#include <linux/phy/phy-lvds.h>
-#include <linux/phy/phy-mipi-dphy.h>
+#include "../../../drivers/phy/phy-provider.h"
+struct device;
+struct device_node;
struct phy;
-enum phy_mode {
- PHY_MODE_INVALID,
- PHY_MODE_USB_HOST,
- PHY_MODE_USB_HOST_LS,
- PHY_MODE_USB_HOST_FS,
- PHY_MODE_USB_HOST_HS,
- PHY_MODE_USB_HOST_SS,
- PHY_MODE_USB_DEVICE,
- PHY_MODE_USB_DEVICE_LS,
- PHY_MODE_USB_DEVICE_FS,
- PHY_MODE_USB_DEVICE_HS,
- PHY_MODE_USB_DEVICE_SS,
- PHY_MODE_USB_OTG,
- PHY_MODE_UFS_HS_A,
- PHY_MODE_UFS_HS_B,
- PHY_MODE_PCIE,
- PHY_MODE_ETHERNET,
- PHY_MODE_MIPI_DPHY,
- PHY_MODE_SATA,
- PHY_MODE_LVDS,
- PHY_MODE_DP,
- PHY_MODE_HDMI,
-};
-
-enum phy_media {
- PHY_MEDIA_DEFAULT,
- PHY_MEDIA_SR,
- 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
- *
- * @mipi_dphy: Configuration set applicable for phys supporting
- * the MIPI_DPHY phy mode.
- * @dp: Configuration set applicable for phys supporting
- * the DisplayPort protocol.
- * @lvds: Configuration set applicable for phys supporting
- * the LVDS phy mode.
- * @hdmi: Configuration set applicable for phys supporting
- * the HDMI phy mode.
- */
-union phy_configure_opts {
- struct phy_configure_opts_mipi_dphy mipi_dphy;
- struct phy_configure_opts_dp dp;
- struct phy_configure_opts_lvds lvds;
- struct phy_configure_opts_hdmi hdmi;
-};
-
-/**
- * struct phy_ops - set of function pointers for performing phy operations
- * @init: operation to be performed for initializing phy
- * @exit: operation to be performed while exiting
- * @power_on: powering on the phy
- * @power_off: powering off the phy
- * @set_mode: set the mode of the phy
- * @set_media: set the media type of the phy (optional)
- * @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
- * @request_bus_width: request a different bus width for the phy
- * @release: ops to be performed while the consumer relinquishes the PHY
- * @owner: the module owner containing the ops
- */
-struct phy_ops {
- int (*init)(struct phy *phy);
- int (*exit)(struct phy *phy);
- int (*power_on)(struct phy *phy);
- int (*power_off)(struct phy *phy);
- int (*set_mode)(struct phy *phy, enum phy_mode mode, int submode);
- int (*set_media)(struct phy *phy, enum phy_media media);
- int (*set_speed)(struct phy *phy, int speed);
-
- /**
- * @configure:
- *
- * Optional.
- *
- * Used to change the PHY parameters. phy_init() must have
- * been called on the phy.
- *
- * Returns: 0 if successful, an negative error code otherwise
- */
- int (*configure)(struct phy *phy, union phy_configure_opts *opts);
-
- /**
- * @validate:
- *
- * Optional.
- *
- * Used to check that the current set of parameters can be
- * handled by the phy. Implementations are free to tune the
- * parameters passed as arguments if needed by some
- * implementation detail or constraints. It must not change
- * any actual configuration of the PHY, so calling it as many
- * times as deemed fit by the consumer must have no side
- * effect.
- *
- * Returns: 0 if the configuration can be applied, an negative
- * error code otherwise
- */
- int (*validate)(struct phy *phy, enum phy_mode mode, int submode,
- union phy_configure_opts *opts);
- int (*reset)(struct phy *phy);
- int (*calibrate)(struct phy *phy);
-
- /* notify phy connect status change */
- int (*connect)(struct phy *phy, int port);
- int (*disconnect)(struct phy *phy, int port);
-
- int (*notify_phystate)(struct phy *phy, union phy_notify state);
- int (*request_bus_width)(struct phy *phy, int bus_width);
- void (*release)(struct phy *phy);
- struct module *owner;
-};
-
-/**
- * struct phy_attrs - represents phy attributes
- * @bus_width: Data path width implemented by PHY
- * @max_link_rate: Maximum link rate supported by PHY (units to be decided by producer and consumer)
- * @mode: PHY mode
- */
-struct phy_attrs {
- u32 bus_width;
- u32 max_link_rate;
- enum phy_mode mode;
-};
-
-/**
- * struct phy - represents the phy device
- * @dev: phy device
- * @id: id of the phy device
- * @ops: function pointers for performing phy operations
- * @mutex: mutex to protect phy_ops
- * @lockdep_key: lockdep information for this mutex
- * @init_count: used to protect when the PHY is used by multiple consumers
- * @power_count: used to protect when the PHY is used by multiple consumers
- * @attrs: used to specify PHY specific attributes
- * @pwr: power regulator associated with the phy
- * @debugfs: debugfs directory
- */
-struct phy {
- struct device dev;
- int id;
- const struct phy_ops *ops;
- struct mutex mutex;
- struct lock_class_key lockdep_key;
- int init_count;
- int power_count;
- struct phy_attrs attrs;
- struct regulator *pwr;
- struct dentry *debugfs;
-};
-
-/**
- * struct phy_provider - represents the phy provider
- * @dev: phy provider device
- * @children: can be used to override the default (dev->of_node) child node
- * @owner: the module owner having of_xlate
- * @list: to maintain a linked list of PHY providers
- * @of_xlate: function pointer to obtain phy instance from phy pointer
- */
-struct phy_provider {
- struct device *dev;
- struct device_node *children;
- struct module *owner;
- struct list_head list;
- struct phy * (*of_xlate)(struct device *dev,
- const struct of_phandle_args *args);
-};
-
-/**
- * struct phy_lookup - PHY association in list of phys managed by the phy driver
- * @node: list node
- * @dev_id: the device of the association
- * @con_id: connection ID string on device
- * @phy: the phy of the association
- */
-struct phy_lookup {
- struct list_head node;
- const char *dev_id;
- const char *con_id;
- struct phy *phy;
-};
-
-#define to_phy(a) (container_of((a), struct phy, dev))
-
-#define of_phy_provider_register(dev, xlate) \
- __of_phy_provider_register((dev), NULL, THIS_MODULE, (xlate))
-
-#define devm_of_phy_provider_register(dev, xlate) \
- __devm_of_phy_provider_register((dev), NULL, THIS_MODULE, (xlate))
-
-#define of_phy_provider_register_full(dev, children, xlate) \
- __of_phy_provider_register(dev, children, THIS_MODULE, xlate)
-
-#define devm_of_phy_provider_register_full(dev, children, xlate) \
- __devm_of_phy_provider_register(dev, children, THIS_MODULE, xlate)
-
-static inline void phy_set_drvdata(struct phy *phy, void *data)
-{
- dev_set_drvdata(&phy->dev, data);
-}
-
-static inline void *phy_get_drvdata(struct phy *phy)
-{
- return dev_get_drvdata(&phy->dev);
-}
-
#if IS_ENABLED(CONFIG_GENERIC_PHY)
+struct phy *phy_get(struct device *dev, const char *string);
+struct phy *devm_phy_get(struct device *dev, const char *string);
+struct phy *devm_phy_optional_get(struct device *dev, const char *string);
+struct phy *devm_of_phy_get(struct device *dev, struct device_node *np,
+ const char *con_id);
+struct phy *devm_of_phy_optional_get(struct device *dev, struct device_node *np,
+ const char *con_id);
+struct phy *devm_of_phy_get_by_index(struct device *dev, struct device_node *np,
+ int index);
+void of_phy_put(struct phy *phy);
+void phy_put(struct device *dev, struct phy *phy);
+void devm_phy_put(struct device *dev, struct phy *phy);
+struct phy *of_phy_get(struct device_node *np, const char *con_id);
+
int phy_pm_runtime_get(struct phy *phy);
int phy_pm_runtime_get_sync(struct phy *phy);
void phy_pm_runtime_put(struct phy *phy);
@@ -259,60 +49,69 @@ int phy_set_speed(struct phy *phy, int speed);
int phy_configure(struct phy *phy, union phy_configure_opts *opts);
int phy_validate(struct phy *phy, enum phy_mode mode, int submode,
union phy_configure_opts *opts);
-
-static inline enum phy_mode phy_get_mode(struct phy *phy)
-{
- return phy->attrs.mode;
-}
+enum phy_mode phy_get_mode(struct phy *phy);
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)
+int phy_get_bus_width(struct phy *phy);
+int phy_request_bus_width(struct phy *phy, int bus_width);
+#else
+static inline struct phy *phy_get(struct device *dev, const char *string)
{
- return phy->attrs.bus_width;
+ return ERR_PTR(-ENOSYS);
}
-static inline void phy_set_bus_width(struct phy *phy, int bus_width)
+
+static inline struct phy *devm_phy_get(struct device *dev, const char *string)
{
- phy->attrs.bus_width = bus_width;
+ return ERR_PTR(-ENOSYS);
}
-int phy_request_bus_width(struct phy *phy, int bus_width);
-struct phy *phy_get(struct device *dev, const char *string);
-struct phy *devm_phy_get(struct device *dev, const char *string);
-struct phy *devm_phy_optional_get(struct device *dev, const char *string);
-struct phy *devm_of_phy_get(struct device *dev, struct device_node *np,
- const char *con_id);
-struct phy *devm_of_phy_optional_get(struct device *dev, struct device_node *np,
- const char *con_id);
-struct phy *devm_of_phy_get_by_index(struct device *dev, struct device_node *np,
- int index);
-void of_phy_put(struct phy *phy);
-void phy_put(struct device *dev, struct phy *phy);
-void devm_phy_put(struct device *dev, struct phy *phy);
-struct phy *of_phy_get(struct device_node *np, const char *con_id);
-struct phy *of_phy_simple_xlate(struct device *dev,
- const struct of_phandle_args *args);
-struct phy *phy_create(struct device *dev, struct device_node *node,
- const struct phy_ops *ops);
-struct phy *devm_phy_create(struct device *dev, struct device_node *node,
- const struct phy_ops *ops);
-void phy_destroy(struct phy *phy);
-void devm_phy_destroy(struct device *dev, struct phy *phy);
-struct phy_provider *__of_phy_provider_register(struct device *dev,
- struct device_node *children, struct module *owner,
- struct phy * (*of_xlate)(struct device *dev,
- const struct of_phandle_args *args));
-struct phy_provider *__devm_of_phy_provider_register(struct device *dev,
- struct device_node *children, struct module *owner,
- struct phy * (*of_xlate)(struct device *dev,
- const struct of_phandle_args *args));
-void of_phy_provider_unregister(struct phy_provider *phy_provider);
-void devm_of_phy_provider_unregister(struct device *dev,
- struct phy_provider *phy_provider);
-int phy_create_lookup(struct phy *phy, const char *con_id, const char *dev_id);
-void phy_remove_lookup(struct phy *phy, const char *con_id, const char *dev_id);
-#else
+
+static inline struct phy *devm_phy_optional_get(struct device *dev,
+ const char *string)
+{
+ return NULL;
+}
+
+static inline struct phy *devm_of_phy_get(struct device *dev,
+ struct device_node *np,
+ const char *con_id)
+{
+ return ERR_PTR(-ENOSYS);
+}
+
+static inline struct phy *devm_of_phy_optional_get(struct device *dev,
+ struct device_node *np,
+ const char *con_id)
+{
+ return NULL;
+}
+
+static inline struct phy *devm_of_phy_get_by_index(struct device *dev,
+ struct device_node *np,
+ int index)
+{
+ return ERR_PTR(-ENOSYS);
+}
+
+static inline void of_phy_put(struct phy *phy)
+{
+}
+
+static inline void phy_put(struct device *dev, struct phy *phy)
+{
+}
+
+static inline void devm_phy_put(struct device *dev, struct phy *phy)
+{
+}
+
+static inline struct phy *of_phy_get(struct device_node *np, const char *con_id)
+{
+ return ERR_PTR(-ENOSYS);
+}
+
static inline int phy_pm_runtime_get(struct phy *phy)
{
if (!phy)
@@ -391,61 +190,59 @@ static inline int phy_set_speed(struct phy *phy, int speed)
return -ENODEV;
}
-static inline enum phy_mode phy_get_mode(struct phy *phy)
-{
- return PHY_MODE_INVALID;
-}
-
-static inline int phy_reset(struct phy *phy)
+static inline int phy_configure(struct phy *phy,
+ union phy_configure_opts *opts)
{
if (!phy)
return 0;
return -ENOSYS;
}
-static inline int phy_calibrate(struct phy *phy)
+static inline int phy_validate(struct phy *phy, enum phy_mode mode, int submode,
+ union phy_configure_opts *opts)
{
if (!phy)
return 0;
return -ENOSYS;
}
-static inline int phy_notify_connect(struct phy *phy, int index)
+static inline enum phy_mode phy_get_mode(struct phy *phy)
+{
+ return PHY_MODE_INVALID;
+}
+
+static inline int phy_reset(struct phy *phy)
{
if (!phy)
return 0;
return -ENOSYS;
}
-static inline int phy_notify_disconnect(struct phy *phy, int index)
+static inline int phy_calibrate(struct phy *phy)
{
if (!phy)
return 0;
return -ENOSYS;
}
-static inline int phy_notify_state(struct phy *phy, union phy_notify state)
+static inline int phy_notify_connect(struct phy *phy, int index)
{
if (!phy)
return 0;
return -ENOSYS;
}
-static inline int phy_configure(struct phy *phy,
- union phy_configure_opts *opts)
+static inline int phy_notify_disconnect(struct phy *phy, int index)
{
if (!phy)
return 0;
-
return -ENOSYS;
}
-static inline int phy_validate(struct phy *phy, enum phy_mode mode, int submode,
- union phy_configure_opts *opts)
+static inline int phy_notify_state(struct phy *phy, union phy_notify state)
{
if (!phy)
return 0;
-
return -ENOSYS;
}
@@ -454,11 +251,6 @@ static inline int phy_get_bus_width(struct phy *phy)
return -ENOSYS;
}
-static inline void phy_set_bus_width(struct phy *phy, int bus_width)
-{
- return;
-}
-
static inline int phy_request_bus_width(struct phy *phy, int bus_width)
{
if (!phy)
@@ -466,120 +258,6 @@ static inline int phy_request_bus_width(struct phy *phy, int bus_width)
return -ENOSYS;
}
+#endif /* IS_ENABLED(CONFIG_GENERIC_PHY) */
-static inline struct phy *phy_get(struct device *dev, const char *string)
-{
- return ERR_PTR(-ENOSYS);
-}
-
-static inline struct phy *devm_phy_get(struct device *dev, const char *string)
-{
- return ERR_PTR(-ENOSYS);
-}
-
-static inline struct phy *devm_phy_optional_get(struct device *dev,
- const char *string)
-{
- return NULL;
-}
-
-static inline struct phy *devm_of_phy_get(struct device *dev,
- struct device_node *np,
- const char *con_id)
-{
- return ERR_PTR(-ENOSYS);
-}
-
-static inline struct phy *devm_of_phy_optional_get(struct device *dev,
- struct device_node *np,
- const char *con_id)
-{
- return NULL;
-}
-
-static inline struct phy *devm_of_phy_get_by_index(struct device *dev,
- struct device_node *np,
- int index)
-{
- return ERR_PTR(-ENOSYS);
-}
-
-static inline void of_phy_put(struct phy *phy)
-{
-}
-
-static inline void phy_put(struct device *dev, struct phy *phy)
-{
-}
-
-static inline void devm_phy_put(struct device *dev, struct phy *phy)
-{
-}
-
-static inline struct phy *of_phy_get(struct device_node *np, const char *con_id)
-{
- return ERR_PTR(-ENOSYS);
-}
-
-static inline struct phy *of_phy_simple_xlate(struct device *dev,
- const struct of_phandle_args *args)
-{
- return ERR_PTR(-ENOSYS);
-}
-
-static inline struct phy *phy_create(struct device *dev,
- struct device_node *node,
- const struct phy_ops *ops)
-{
- return ERR_PTR(-ENOSYS);
-}
-
-static inline struct phy *devm_phy_create(struct device *dev,
- struct device_node *node,
- const struct phy_ops *ops)
-{
- return ERR_PTR(-ENOSYS);
-}
-
-static inline void phy_destroy(struct phy *phy)
-{
-}
-
-static inline void devm_phy_destroy(struct device *dev, struct phy *phy)
-{
-}
-
-static inline struct phy_provider *__of_phy_provider_register(
- struct device *dev, struct device_node *children, struct module *owner,
- struct phy * (*of_xlate)(struct device *dev,
- const struct of_phandle_args *args))
-{
- return ERR_PTR(-ENOSYS);
-}
-
-static inline struct phy_provider *__devm_of_phy_provider_register(struct device
- *dev, struct device_node *children, struct module *owner,
- struct phy * (*of_xlate)(struct device *dev,
- const struct of_phandle_args *args))
-{
- return ERR_PTR(-ENOSYS);
-}
-
-static inline void of_phy_provider_unregister(struct phy_provider *phy_provider)
-{
-}
-
-static inline void devm_of_phy_provider_unregister(struct device *dev,
- struct phy_provider *phy_provider)
-{
-}
-static inline int
-phy_create_lookup(struct phy *phy, const char *con_id, const char *dev_id)
-{
- return 0;
-}
-static inline void phy_remove_lookup(struct phy *phy, const char *con_id,
- const char *dev_id) { }
-#endif
-
-#endif /* __DRIVERS_PHY_H */
+#endif /* __PHY_CONSUMER_H */
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* Re: [PATCH v2 2/5] phy: rockchip: inno-usb2: Simplify rockchip,usbgrf handling
From: neil.armstrong @ 2026-05-06 14:42 UTC (permalink / raw)
To: Heiko Stuebner, vkoul
Cc: robh, krzk+dt, conor+dt, linux-phy, devicetree, linux-arm-kernel,
linux-rockchip, linux-kernel, jonas
In-Reply-To: <20260505170410.3265305-3-heiko@sntech.de>
On 5/5/26 19:04, Heiko Stuebner wrote:
> From: Jonas Karlman <jonas@kwiboo.se>
>
> The logic to decide if usbgrf or grf should be used is more complex than
> it needs to be. For RK3568, RV1108 and soon RK3528 we can assign the
> rockchip,usbgrf regmap directly to grf instead of doing a usbgrf and grf
> dance.
>
> Simplify the code to only use the grf regmap and handle the logic of
> what regmap should be used in driver probe instead.
>
> The only expected change from this is that RK3528 can be supported
> because of an addition of a of_property_present() check.
>
> Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
> Signed-off-by: Heiko Stuebner <heiko@sntech.de>
> ---
> drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 68 +++++--------------
> 1 file changed, 18 insertions(+), 50 deletions(-)
>
> diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> index 8f4c08e599aa..7cec45192393 100644
> --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> @@ -228,7 +228,6 @@ struct rockchip_usb2phy_port {
> * struct rockchip_usb2phy - usb2.0 phy driver data.
> * @dev: pointer to device.
> * @grf: General Register Files regmap.
> - * @usbgrf: USB General Register Files regmap.
> * @clks: array of phy input clocks.
> * @clk480m: clock struct of phy output clk.
> * @clk480m_hw: clock struct of phy output clk management.
> @@ -246,7 +245,6 @@ struct rockchip_usb2phy_port {
> struct rockchip_usb2phy {
> struct device *dev;
> struct regmap *grf;
> - struct regmap *usbgrf;
> struct clk_bulk_data *clks;
> struct clk *clk480m;
> struct clk_hw clk480m_hw;
> @@ -261,11 +259,6 @@ struct rockchip_usb2phy {
> struct rockchip_usb2phy_port ports[USB2PHY_NUM_PORTS];
> };
>
> -static inline struct regmap *get_reg_base(struct rockchip_usb2phy *rphy)
> -{
> - return rphy->usbgrf == NULL ? rphy->grf : rphy->usbgrf;
> -}
> -
> static inline int property_enable(struct regmap *base,
> const struct usb2phy_reg *reg, bool en)
> {
> @@ -323,12 +316,11 @@ static int rockchip_usb2phy_clk480m_prepare(struct clk_hw *hw)
> {
> struct rockchip_usb2phy *rphy =
> container_of(hw, struct rockchip_usb2phy, clk480m_hw);
> - struct regmap *base = get_reg_base(rphy);
> int ret;
>
> /* turn on 480m clk output if it is off */
> - if (!property_enabled(base, &rphy->phy_cfg->clkout_ctl)) {
> - ret = property_enable(base, &rphy->phy_cfg->clkout_ctl, true);
> + if (!property_enabled(rphy->grf, &rphy->phy_cfg->clkout_ctl)) {
> + ret = property_enable(rphy->grf, &rphy->phy_cfg->clkout_ctl, true);
> if (ret)
> return ret;
>
> @@ -343,19 +335,17 @@ static void rockchip_usb2phy_clk480m_unprepare(struct clk_hw *hw)
> {
> struct rockchip_usb2phy *rphy =
> container_of(hw, struct rockchip_usb2phy, clk480m_hw);
> - struct regmap *base = get_reg_base(rphy);
>
> /* turn off 480m clk output */
> - property_enable(base, &rphy->phy_cfg->clkout_ctl, false);
> + property_enable(rphy->grf, &rphy->phy_cfg->clkout_ctl, false);
> }
>
> static int rockchip_usb2phy_clk480m_prepared(struct clk_hw *hw)
> {
> struct rockchip_usb2phy *rphy =
> container_of(hw, struct rockchip_usb2phy, clk480m_hw);
> - struct regmap *base = get_reg_base(rphy);
>
> - return property_enabled(base, &rphy->phy_cfg->clkout_ctl);
> + return property_enabled(rphy->grf, &rphy->phy_cfg->clkout_ctl);
> }
>
> static unsigned long
> @@ -574,7 +564,6 @@ static int rockchip_usb2phy_power_on(struct phy *phy)
> {
> struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
> struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);
> - struct regmap *base = get_reg_base(rphy);
> int ret;
>
> dev_dbg(&rport->phy->dev, "port power on\n");
> @@ -586,7 +575,7 @@ static int rockchip_usb2phy_power_on(struct phy *phy)
> if (ret)
> return ret;
>
> - ret = property_enable(base, &rport->port_cfg->phy_sus, false);
> + ret = property_enable(rphy->grf, &rport->port_cfg->phy_sus, false);
> if (ret) {
> clk_disable_unprepare(rphy->clk480m);
> return ret;
> @@ -615,7 +604,6 @@ static int rockchip_usb2phy_power_off(struct phy *phy)
> {
> struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
> struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);
> - struct regmap *base = get_reg_base(rphy);
> int ret;
>
> dev_dbg(&rport->phy->dev, "port power off\n");
> @@ -623,7 +611,7 @@ static int rockchip_usb2phy_power_off(struct phy *phy)
> if (rport->suspended)
> return 0;
>
> - ret = property_enable(base, &rport->port_cfg->phy_sus, true);
> + ret = property_enable(rphy->grf, &rport->port_cfg->phy_sus, true);
> if (ret)
> return ret;
>
> @@ -787,28 +775,22 @@ static const char *chg_to_string(enum power_supply_type chg_type)
> static void rockchip_chg_enable_dcd(struct rockchip_usb2phy *rphy,
> bool en)
> {
> - struct regmap *base = get_reg_base(rphy);
> -
> - property_enable(base, &rphy->phy_cfg->chg_det.rdm_pdwn_en, en);
> - property_enable(base, &rphy->phy_cfg->chg_det.idp_src_en, en);
> + property_enable(rphy->grf, &rphy->phy_cfg->chg_det.rdm_pdwn_en, en);
> + property_enable(rphy->grf, &rphy->phy_cfg->chg_det.idp_src_en, en);
> }
>
> static void rockchip_chg_enable_primary_det(struct rockchip_usb2phy *rphy,
> bool en)
> {
> - struct regmap *base = get_reg_base(rphy);
> -
> - property_enable(base, &rphy->phy_cfg->chg_det.vdp_src_en, en);
> - property_enable(base, &rphy->phy_cfg->chg_det.idm_sink_en, en);
> + property_enable(rphy->grf, &rphy->phy_cfg->chg_det.vdp_src_en, en);
> + property_enable(rphy->grf, &rphy->phy_cfg->chg_det.idm_sink_en, en);
> }
>
> static void rockchip_chg_enable_secondary_det(struct rockchip_usb2phy *rphy,
> bool en)
> {
> - struct regmap *base = get_reg_base(rphy);
> -
> - property_enable(base, &rphy->phy_cfg->chg_det.vdm_src_en, en);
> - property_enable(base, &rphy->phy_cfg->chg_det.idp_sink_en, en);
> + property_enable(rphy->grf, &rphy->phy_cfg->chg_det.vdm_src_en, en);
> + property_enable(rphy->grf, &rphy->phy_cfg->chg_det.idp_sink_en, en);
> }
>
> #define CHG_DCD_POLL_TIME (100 * HZ / 1000)
> @@ -820,7 +802,6 @@ static void rockchip_chg_detect_work(struct work_struct *work)
> struct rockchip_usb2phy_port *rport =
> container_of(work, struct rockchip_usb2phy_port, chg_work.work);
> struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
> - struct regmap *base = get_reg_base(rphy);
> bool is_dcd, tmout, vout, vbus_attach;
> unsigned long delay;
>
> @@ -834,7 +815,7 @@ static void rockchip_chg_detect_work(struct work_struct *work)
> rockchip_usb2phy_power_off(rport->phy);
> /* put the controller in non-driving mode */
> if (!vbus_attach)
> - property_enable(base, &rphy->phy_cfg->chg_det.opmode, false);
> + property_enable(rphy->grf, &rphy->phy_cfg->chg_det.opmode, false);
> /* Start DCD processing stage 1 */
> rockchip_chg_enable_dcd(rphy, true);
> rphy->chg_state = USB_CHG_STATE_WAIT_FOR_DCD;
> @@ -898,7 +879,7 @@ static void rockchip_chg_detect_work(struct work_struct *work)
> case USB_CHG_STATE_DETECTED:
> /* put the controller in normal mode */
> if (!vbus_attach)
> - property_enable(base, &rphy->phy_cfg->chg_det.opmode, true);
> + property_enable(rphy->grf, &rphy->phy_cfg->chg_det.opmode, true);
> rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work);
> dev_dbg(&rport->phy->dev, "charger = %s\n",
> chg_to_string(rphy->chg_type));
> @@ -1353,27 +1334,14 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
> if (!rphy)
> return -ENOMEM;
>
> - if (!dev->parent || !dev->parent->of_node) {
> + if (!dev->parent || !dev->parent->of_node ||
> + of_property_present(np, "rockchip,usbgrf")) {
> rphy->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,usbgrf");
> - if (IS_ERR(rphy->grf)) {
> - dev_err(dev, "failed to locate usbgrf\n");
> - return PTR_ERR(rphy->grf);
> - }
> } else {
> rphy->grf = syscon_node_to_regmap(dev->parent->of_node);
> - if (IS_ERR(rphy->grf))
> - return PTR_ERR(rphy->grf);
> - }
> -
> - if (of_device_is_compatible(np, "rockchip,rv1108-usb2phy")) {
> - rphy->usbgrf =
> - syscon_regmap_lookup_by_phandle(dev->of_node,
> - "rockchip,usbgrf");
> - if (IS_ERR(rphy->usbgrf))
> - return PTR_ERR(rphy->usbgrf);
> - } else {
> - rphy->usbgrf = NULL;
> }
> + if (IS_ERR(rphy->grf))
> + return PTR_ERR(rphy->grf);
>
> if (of_property_read_u32_index(np, "reg", 0, ®)) {
> dev_err(dev, "the reg property is not assigned in %pOFn node\n", np);
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v2 4/5] phy: rockchip: inno-usb2: Add clkout_ctl_phy support
From: neil.armstrong @ 2026-05-06 14:45 UTC (permalink / raw)
To: Heiko Stuebner, vkoul
Cc: robh, krzk+dt, conor+dt, linux-phy, devicetree, linux-arm-kernel,
linux-rockchip, linux-kernel, jonas
In-Reply-To: <20260505170410.3265305-5-heiko@sntech.de>
On 5/5/26 19:04, Heiko Stuebner wrote:
> From: Jonas Karlman <jonas@kwiboo.se>
>
> The 480m clk is controlled using regs in the PHY address space and not
> in the USB GRF address space on e.g. RK3528 and RK3506.
>
> Add a clkout_ctl_phy usb2phy_reg to handle enable/disable of the 480m
> clk on these SoCs.
>
> Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
> Signed-off-by: Heiko Stuebner <heiko@sntech.de>
> ---
> drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 47 +++++++++++++++----
> 1 file changed, 38 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> index 7cec45192393..d8879fcd4291 100644
> --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> @@ -179,6 +179,7 @@ struct rockchip_usb2phy_cfg {
> unsigned int num_ports;
> int (*phy_tuning)(struct rockchip_usb2phy *rphy);
> struct usb2phy_reg clkout_ctl;
> + struct usb2phy_reg clkout_ctl_phy;
> const struct rockchip_usb2phy_port_cfg port_cfgs[USB2PHY_NUM_PORTS];
> const struct rockchip_chg_det_reg chg_det;
> };
> @@ -228,6 +229,7 @@ struct rockchip_usb2phy_port {
> * struct rockchip_usb2phy - usb2.0 phy driver data.
> * @dev: pointer to device.
> * @grf: General Register Files regmap.
> + * @phy_base: USB PHY regmap.
> * @clks: array of phy input clocks.
> * @clk480m: clock struct of phy output clk.
> * @clk480m_hw: clock struct of phy output clk management.
> @@ -245,6 +247,7 @@ struct rockchip_usb2phy_port {
> struct rockchip_usb2phy {
> struct device *dev;
> struct regmap *grf;
> + struct regmap *phy_base;
> struct clk_bulk_data *clks;
> struct clk *clk480m;
> struct clk_hw clk480m_hw;
> @@ -312,15 +315,33 @@ static void rockchip_usb2phy_clk_bulk_disable(void *data)
> clk_bulk_disable_unprepare(rphy->num_clks, rphy->clks);
> }
>
> -static int rockchip_usb2phy_clk480m_prepare(struct clk_hw *hw)
> +static void
> +rockchip_usb2phy_clk480m_clkout_ctl(struct clk_hw *hw, struct regmap **base,
> + const struct usb2phy_reg **clkout_ctl)
> {
> struct rockchip_usb2phy *rphy =
> container_of(hw, struct rockchip_usb2phy, clk480m_hw);
> +
> + if (rphy->phy_cfg->clkout_ctl_phy.enable) {
> + *base = rphy->phy_base;
> + *clkout_ctl = &rphy->phy_cfg->clkout_ctl_phy;
> + } else {
> + *base = rphy->grf;
> + *clkout_ctl = &rphy->phy_cfg->clkout_ctl;
> + }
> +}
> +
> +static int rockchip_usb2phy_clk480m_prepare(struct clk_hw *hw)
> +{
> + const struct usb2phy_reg *clkout_ctl;
> + struct regmap *base;
> int ret;
>
> + rockchip_usb2phy_clk480m_clkout_ctl(hw, &base, &clkout_ctl);
> +
> /* turn on 480m clk output if it is off */
> - if (!property_enabled(rphy->grf, &rphy->phy_cfg->clkout_ctl)) {
> - ret = property_enable(rphy->grf, &rphy->phy_cfg->clkout_ctl, true);
> + if (!property_enabled(base, clkout_ctl)) {
> + ret = property_enable(base, clkout_ctl, true);
> if (ret)
> return ret;
>
> @@ -333,19 +354,23 @@ static int rockchip_usb2phy_clk480m_prepare(struct clk_hw *hw)
>
> static void rockchip_usb2phy_clk480m_unprepare(struct clk_hw *hw)
> {
> - struct rockchip_usb2phy *rphy =
> - container_of(hw, struct rockchip_usb2phy, clk480m_hw);
> + const struct usb2phy_reg *clkout_ctl;
> + struct regmap *base;
> +
> + rockchip_usb2phy_clk480m_clkout_ctl(hw, &base, &clkout_ctl);
>
> /* turn off 480m clk output */
> - property_enable(rphy->grf, &rphy->phy_cfg->clkout_ctl, false);
> + property_enable(base, clkout_ctl, false);
> }
>
> static int rockchip_usb2phy_clk480m_prepared(struct clk_hw *hw)
> {
> - struct rockchip_usb2phy *rphy =
> - container_of(hw, struct rockchip_usb2phy, clk480m_hw);
> + const struct usb2phy_reg *clkout_ctl;
> + struct regmap *base;
> +
> + rockchip_usb2phy_clk480m_clkout_ctl(hw, &base, &clkout_ctl);
>
> - return property_enabled(rphy->grf, &rphy->phy_cfg->clkout_ctl);
> + return property_enabled(base, clkout_ctl);
> }
>
> static unsigned long
> @@ -1336,9 +1361,13 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
>
> if (!dev->parent || !dev->parent->of_node ||
> of_property_present(np, "rockchip,usbgrf")) {
> + rphy->phy_base = device_node_to_regmap(np);
> + if (IS_ERR(rphy->phy_base))
> + return PTR_ERR(rphy->phy_base);
> rphy->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,usbgrf");
> } else {
> rphy->grf = syscon_node_to_regmap(dev->parent->of_node);
> + rphy->phy_base = rphy->grf;
> }
> if (IS_ERR(rphy->grf))
> return PTR_ERR(rphy->grf);
The logic is not easy to follow, but it looks right.
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v2 5/5] phy: rockchip: inno-usb2: Add support for RK3528
From: neil.armstrong @ 2026-05-06 14:45 UTC (permalink / raw)
To: Heiko Stuebner, vkoul
Cc: robh, krzk+dt, conor+dt, linux-phy, devicetree, linux-arm-kernel,
linux-rockchip, linux-kernel, jonas, Jianwei Zheng
In-Reply-To: <20260505170410.3265305-6-heiko@sntech.de>
On 5/5/26 19:04, Heiko Stuebner wrote:
> From: Jianwei Zheng <jianwei.zheng@rock-chips.com>
>
> 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.
>
> Undocumented magic-values are based on the linux-stan-6.1-rkr5 tag of
> the vendor-kernel.
>
> Signed-off-by: Jianwei Zheng <jianwei.zheng@rock-chips.com>
> Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
> Signed-off-by: Heiko Stuebner <heiko@sntech.de>
> ---
> drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 84 +++++++++++++++++++
> 1 file changed, 84 insertions(+)
>
> diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> index d8879fcd4291..133cfd6624e8 100644
> --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> @@ -1511,6 +1511,38 @@ 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;
> +
> + /* Turn off otg port differential receiver in suspend mode */
> + ret = regmap_write(rphy->phy_base, 0x30, BIT(18) | 0x0000);
> + if (ret)
> + return ret;
> +
> + /* Turn off host port differential receiver in suspend mode */
> + ret = regmap_write(rphy->phy_base, 0x430, BIT(18) | 0x0000);
> + if (ret)
> + return ret;
> +
> + /* Set otg port HS eye height to 400mv (default is 450mv) */
> + ret = regmap_write(rphy->phy_base, 0x30, GENMASK(22, 20) | 0x0000);
> + if (ret)
> + return ret;
> +
> + /* Set host port HS eye height to 400mv (default is 450mv) */
> + ret = regmap_write(rphy->phy_base, 0x430, GENMASK(22, 20) | 0x0000);
> + if (ret)
> + return ret;
> +
> + /* 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);
> + if (ret)
> + return ret;
> +
> + return 0;
> +}
> +
> static int rk3576_usb2phy_tuning(struct rockchip_usb2phy *rphy)
> {
> int ret;
> @@ -1924,6 +1956,57 @@ static const struct rockchip_usb2phy_cfg rk3399_phy_cfgs[] = {
> { /* sentinel */ }
> };
>
> +static const struct rockchip_usb2phy_cfg rk3528_phy_cfgs[] = {
> + {
> + .reg = 0xffdf0000,
> + .num_ports = 2,
> + .phy_tuning = rk3528_usb2phy_tuning,
> + .clkout_ctl_phy = { 0x041c, 7, 2, 0, 0x27 },
> + .port_cfgs = {
> + [USB2PHY_PORT_OTG] = {
> + .phy_sus = { 0x004c, 8, 0, 0, 0x1d1 },
> + .bvalid_det_en = { 0x0074, 3, 2, 0, 3 },
> + .bvalid_det_st = { 0x0078, 3, 2, 0, 3 },
> + .bvalid_det_clr = { 0x007c, 3, 2, 0, 3 },
> + .idfall_det_en = { 0x0074, 5, 5, 0, 1 },
> + .idfall_det_st = { 0x0078, 5, 5, 0, 1 },
> + .idfall_det_clr = { 0x007c, 5, 5, 0, 1 },
> + .idrise_det_en = { 0x0074, 4, 4, 0, 1 },
> + .idrise_det_st = { 0x0078, 4, 4, 0, 1 },
> + .idrise_det_clr = { 0x007c, 4, 4, 0, 1 },
> + .ls_det_en = { 0x0074, 0, 0, 0, 1 },
> + .ls_det_st = { 0x0078, 0, 0, 0, 1 },
> + .ls_det_clr = { 0x007c, 0, 0, 0, 1 },
> + .utmi_avalid = { 0x006c, 1, 1, 0, 1 },
> + .utmi_bvalid = { 0x006c, 0, 0, 0, 1 },
> + .utmi_id = { 0x006c, 6, 6, 0, 1 },
> + .utmi_ls = { 0x006c, 5, 4, 0, 1 },
> + },
> + [USB2PHY_PORT_HOST] = {
> + .phy_sus = { 0x005c, 8, 0, 0x1d2, 0x1d1 },
> + .ls_det_en = { 0x0090, 0, 0, 0, 1 },
> + .ls_det_st = { 0x0094, 0, 0, 0, 1 },
> + .ls_det_clr = { 0x0098, 0, 0, 0, 1 },
> + .utmi_ls = { 0x006c, 13, 12, 0, 1 },
> + .utmi_hstdet = { 0x006c, 15, 15, 0, 1 },
> + }
> + },
> + .chg_det = {
> + .opmode = { 0x004c, 3, 0, 5, 1 },
> + .cp_det = { 0x006c, 19, 19, 0, 1 },
> + .dcp_det = { 0x006c, 18, 18, 0, 1 },
> + .dp_det = { 0x006c, 20, 20, 0, 1 },
> + .idm_sink_en = { 0x0058, 1, 1, 0, 1 },
> + .idp_sink_en = { 0x0058, 0, 0, 0, 1 },
> + .idp_src_en = { 0x0058, 2, 2, 0, 1 },
> + .rdm_pdwn_en = { 0x0058, 3, 3, 0, 1 },
> + .vdm_src_en = { 0x0058, 5, 5, 0, 1 },
> + .vdp_src_en = { 0x0058, 4, 4, 0, 1 },
> + },
> + },
> + { /* sentinel */ }
> +};
> +
> static const struct rockchip_usb2phy_cfg rk3562_phy_cfgs[] = {
> {
> .reg = 0xff740000,
> @@ -2291,6 +2374,7 @@ static const struct of_device_id rockchip_usb2phy_dt_match[] = {
> { .compatible = "rockchip,rk3328-usb2phy", .data = &rk3328_phy_cfgs },
> { .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs },
> { .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs },
> + { .compatible = "rockchip,rk3528-usb2phy", .data = &rk3528_phy_cfgs },
> { .compatible = "rockchip,rk3562-usb2phy", .data = &rk3562_phy_cfgs },
> { .compatible = "rockchip,rk3568-usb2phy", .data = &rk3568_phy_cfgs },
> { .compatible = "rockchip,rk3576-usb2phy", .data = &rk3576_phy_cfgs },
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v4 02/16] phy: rockchip: usbdp: Do not loose USB3 PHY status
From: Neil Armstrong @ 2026-05-06 14:47 UTC (permalink / raw)
To: Sebastian Reichel, Vinod Koul, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree
In-Reply-To: <20260428-rockchip-usbdp-cleanup-v4-2-7775671ece22@collabora.com>
On 4/28/26 18:13, Sebastian Reichel wrote:
> By default (i.e. without manually enabling runtime PM) DWC3 requests the
> USB3 PHY once and keeps it enabled all the time. When DisplayPort is
> being requested later on, a mode change is needed. This re-initializes
> the PHY. During re-initialization the status variable has incorrectly
> been cleared, which means the tracking information for USB3 ist lost.
--------------------------------------------------------------/\ is
>
> This is not an immediate problem, since the DP side keeps the PHY
> enabled. But once DP is toggled off, the whole PHY will be disabled.
> This is a problem, because the USB side still needs it powered.
>
> Fix things by not clearing the status flags.
>
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> ---
> drivers/phy/rockchip/phy-rockchip-usbdp.c | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
> index fba35510d88c..744cc7c642f4 100644
> --- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
> +++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
> @@ -1009,7 +1009,6 @@ static int rk_udphy_power_on(struct rk_udphy *udphy, u8 mode)
> rk_udphy_u3_port_disable(udphy, false);
> } else if (udphy->mode_change) {
> udphy->mode_change = false;
> - udphy->status = UDPHY_MODE_NONE;
> if (udphy->mode == UDPHY_MODE_DP)
> rk_udphy_u3_port_disable(udphy, true);
>
>
Looks good, but any fixes tag ?
Neil
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v4 03/16] phy: rockchip: usbdp: Keep clocks running on PHY re-init
From: Neil Armstrong @ 2026-05-06 14:49 UTC (permalink / raw)
To: Sebastian Reichel, Vinod Koul, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree
In-Reply-To: <20260428-rockchip-usbdp-cleanup-v4-3-7775671ece22@collabora.com>
On 4/28/26 18:13, Sebastian Reichel wrote:
> When a mode change is required rk_udphy_power_on() disables
> the clocks and then calls rk_udphy_setup(), which then enables
> all the clocks again before continuing with rk_udphy_init().
>
> Considering that rk_udphy_init() does assert the reset lines,
> re-enabling the clocks is just delaying things. Avoid it by
> directly calling rk_udphy_init().
>
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> ---
> drivers/phy/rockchip/phy-rockchip-usbdp.c | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
> index 744cc7c642f4..98562a888b42 100644
> --- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
> +++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
> @@ -1012,8 +1012,7 @@ static int rk_udphy_power_on(struct rk_udphy *udphy, u8 mode)
> if (udphy->mode == UDPHY_MODE_DP)
> rk_udphy_u3_port_disable(udphy, true);
>
> - rk_udphy_disable(udphy);
> - ret = rk_udphy_setup(udphy);
> + ret = rk_udphy_init(udphy);
> if (ret)
> return ret;
> }
>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v4 04/16] phy: rockchip: usbdp: Amend SSC modulation deviation
From: Neil Armstrong @ 2026-05-06 14:49 UTC (permalink / raw)
To: Sebastian Reichel, Vinod Koul, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree
In-Reply-To: <20260428-rockchip-usbdp-cleanup-v4-4-7775671ece22@collabora.com>
On 4/28/26 18:13, Sebastian Reichel wrote:
> From: Frank Wang <frank.wang@rock-chips.com>
>
> Move SSC modulation deviation into private config of clock
>
> - 24M: 0x00d4[5:0] = 0x30
> - 26M: 0x00d4[5:0] = 0x33
>
> Signed-off-by: Frank Wang <frank.wang@rock-chips.com>
> [Taken over from rockchip's kernel tree; register 0x00d4 is not
> described in the TRM]
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> ---
> drivers/phy/rockchip/phy-rockchip-usbdp.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
> index 98562a888b42..1f686844c337 100644
> --- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
> +++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
> @@ -350,7 +350,8 @@ static const struct reg_sequence rk_udphy_24m_refclk_cfg[] = {
> {0x0a64, 0xa8}, {0x1a3c, 0xd0},
> {0x1a44, 0xd0}, {0x1a48, 0x01},
> {0x1a4c, 0x0d}, {0x1a54, 0xe0},
> - {0x1a5c, 0xe0}, {0x1a64, 0xa8}
> + {0x1a5c, 0xe0}, {0x1a64, 0xa8},
> + {0x00d4, 0x30}
> };
>
> static const struct reg_sequence rk_udphy_26m_refclk_cfg[] = {
> @@ -377,7 +378,7 @@ static const struct reg_sequence rk_udphy_26m_refclk_cfg[] = {
> {0x0c30, 0x0e}, {0x0c48, 0x06},
> {0x1c30, 0x0e}, {0x1c48, 0x06},
> {0x028c, 0x18}, {0x0af0, 0x00},
> - {0x1af0, 0x00}
> + {0x1af0, 0x00}, {0x00d4, 0x33}
> };
>
> static const struct reg_sequence rk_udphy_init_sequence[] = {
> @@ -412,8 +413,7 @@ static const struct reg_sequence rk_udphy_init_sequence[] = {
> {0x0070, 0x7d}, {0x0074, 0x68},
> {0x0af4, 0x1a}, {0x1af4, 0x1a},
> {0x0440, 0x3f}, {0x10d4, 0x08},
> - {0x20d4, 0x08}, {0x00d4, 0x30},
> - {0x0024, 0x6e},
> + {0x20d4, 0x08}, {0x0024, 0x6e}
> };
>
> static inline int rk_udphy_grfreg_write(struct regmap *base,
>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v4 05/16] phy: rockchip: usbdp: Fix LFPS detect threshold control
From: Neil Armstrong @ 2026-05-06 14:49 UTC (permalink / raw)
To: Sebastian Reichel, Vinod Koul, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree, William Wu
In-Reply-To: <20260428-rockchip-usbdp-cleanup-v4-5-7775671ece22@collabora.com>
On 4/28/26 18:13, Sebastian Reichel wrote:
> From: William Wu <william.wu@rock-chips.com>
>
> According to the LFPS Tx Low Power/LFPS Rx Detect Threshold [1],
> the device under test(DUT) must not respond if LFPS below the
> minimum LFPS Rx Detect Threshold 100mV. Test fail on Rockchip
> platforms, because the default LFPS detect threshold is set to
> 65mV.
>
> The USBDP PHY LFPS detect threshold voltage could be set to
> 30mV ~ 140mV, and since there could be 10-20% PVT variation,
> we set LFPS detect threshold voltage to 110mV.
>
> [1] https://compliance.usb.org/resources/LFPS_Rx_Tx_Low_Power_Compliance_Update_Rev5.pdf
>
> Signed-off-by: William Wu <william.wu@rock-chips.com>
> [Taken over from rockchip's kernel tree; the registers are not described
> in the TRM]
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> ---
> drivers/phy/rockchip/phy-rockchip-usbdp.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
> index 1f686844c337..97e53b933225 100644
> --- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
> +++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
> @@ -413,7 +413,8 @@ static const struct reg_sequence rk_udphy_init_sequence[] = {
> {0x0070, 0x7d}, {0x0074, 0x68},
> {0x0af4, 0x1a}, {0x1af4, 0x1a},
> {0x0440, 0x3f}, {0x10d4, 0x08},
> - {0x20d4, 0x08}, {0x0024, 0x6e}
> + {0x20d4, 0x08}, {0x0024, 0x6e},
> + {0x09c0, 0x0a}, {0x19c0, 0x0a}
> };
>
> static inline int rk_udphy_grfreg_write(struct regmap *base,
>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v4 06/16] phy: rockchip: usbdp: Add missing mode_change update
From: Neil Armstrong @ 2026-05-06 14:50 UTC (permalink / raw)
To: Sebastian Reichel, Vinod Koul, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree
In-Reply-To: <20260428-rockchip-usbdp-cleanup-v4-6-7775671ece22@collabora.com>
On 4/28/26 18:13, Sebastian Reichel wrote:
> rk_udphy_set_typec_default_mapping() updates the available modes,
> but does not set the mode_change as required. This results in
> missing re-initialization and thus non-working DisplayPort.
>
> Fix this issue by introducing a new helper to update the available
> modes.
>
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> ---
> drivers/phy/rockchip/phy-rockchip-usbdp.c | 16 +++++++++++-----
> 1 file changed, 11 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
> index 97e53b933225..febc148a754e 100644
> --- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
> +++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
> @@ -619,6 +619,15 @@ static void rk_udphy_dp_hpd_event_trigger(struct rk_udphy *udphy, bool hpd)
> rk_udphy_grfreg_write(udphy->vogrf, &cfg->vogrfcfg[udphy->id].hpd_trigger, hpd);
> }
>
> +static void rk_udphy_mode_set(struct rk_udphy *udphy, u8 mode)
> +{
> + if (udphy->mode == mode)
> + return;
> +
> + udphy->mode_change = true;
> + udphy->mode = mode;
> +}
> +
> static void rk_udphy_set_typec_default_mapping(struct rk_udphy *udphy)
> {
> if (udphy->flip) {
> @@ -649,7 +658,7 @@ static void rk_udphy_set_typec_default_mapping(struct rk_udphy *udphy)
> gpiod_set_value_cansleep(udphy->sbu2_dc_gpio, 1);
> }
>
> - udphy->mode = UDPHY_MODE_DP_USB;
> + rk_udphy_mode_set(udphy, UDPHY_MODE_DP_USB);
> }
>
> static int rk_udphy_orien_sw_set(struct typec_switch_dev *sw,
> @@ -1385,10 +1394,7 @@ static int rk_udphy_typec_mux_set(struct typec_mux_dev *mux,
> usleep_range(750, 800);
> rk_udphy_dp_hpd_event_trigger(udphy, true);
> } else if (data->status & DP_STATUS_HPD_STATE) {
> - if (udphy->mode != mode) {
> - udphy->mode = mode;
> - udphy->mode_change = true;
> - }
> + rk_udphy_mode_set(udphy, mode);
> rk_udphy_dp_hpd_event_trigger(udphy, true);
> } else {
> rk_udphy_dp_hpd_event_trigger(udphy, false);
>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v4 07/16] phy: rockchip: usbdp: Support single-lane DP
From: Neil Armstrong @ 2026-05-06 14:53 UTC (permalink / raw)
To: Sebastian Reichel, Vinod Koul, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree
In-Reply-To: <20260428-rockchip-usbdp-cleanup-v4-7-7775671ece22@collabora.com>
On 4/28/26 18:13, Sebastian Reichel wrote:
> From: Zhang Yubing <yubing.zhang@rock-chips.com>
>
> Implement support for using just a single DisplayPort line.
>
> Signed-off-by: Zhang Yubing <yubing.zhang@rock-chips.com>
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> ---
> drivers/phy/rockchip/phy-rockchip-usbdp.c | 61 +++++++++++++------------------
> 1 file changed, 25 insertions(+), 36 deletions(-)
>
> diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
> index febc148a754e..bf8394174294 100644
> --- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
> +++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
> @@ -193,6 +193,7 @@ struct rk_udphy {
> int id;
>
> bool dp_in_use;
> + int dp_lanes;
>
> /* PHY const config */
> const struct rk_udphy_cfg *cfgs;
> @@ -537,6 +538,13 @@ static void rk_udphy_usb_bvalid_enable(struct rk_udphy *udphy, u8 enable)
> * <0 1> dpln0 dpln1 usbrx usbtx
> * <2 3> usbrx usbtx dpln0 dpln1
> * ---------------------------------------------------------------------------
> + * if 1 lane for dp function, 2 lane for usb function, define rockchip,dp-lane-mux = <x>;
> + * sample as follow:
> + * ---------------------------------------------------------------------------
> + * B11-B10 A2-A3 A11-A10 B2-B3
> + * rockchip,dp-lane-mux ln0(tx/rx) ln1(tx) ln2(tx/rx) ln3(tx)
> + * <0> dpln0 \ usbrx usbtx
> + * ---------------------------------------------------------------------------
> */
>
> static void rk_udphy_dplane_select(struct rk_udphy *udphy)
> @@ -544,18 +552,18 @@ static void rk_udphy_dplane_select(struct rk_udphy *udphy)
> const struct rk_udphy_cfg *cfg = udphy->cfgs;
> u32 value = 0;
>
> - switch (udphy->mode) {
> - case UDPHY_MODE_DP:
> - value |= 2 << udphy->dp_lane_sel[2] * 2;
> + switch (udphy->dp_lanes) {
> + case 4:
> value |= 3 << udphy->dp_lane_sel[3] * 2;
> + value |= 2 << udphy->dp_lane_sel[2] * 2;
> fallthrough;
>
> - case UDPHY_MODE_DP_USB:
> - value |= 0 << udphy->dp_lane_sel[0] * 2;
> + case 2:
> value |= 1 << udphy->dp_lane_sel[1] * 2;
> - break;
> + fallthrough;
>
> - case UDPHY_MODE_USB:
> + case 1:
> + value |= 0 << udphy->dp_lane_sel[0] * 2;
What's the point of keeping this no-op calculation ?
> break;
>
> default:
> @@ -568,28 +576,6 @@ static void rk_udphy_dplane_select(struct rk_udphy *udphy)
> FIELD_PREP(DP_AUX_DOUT_SEL, udphy->dp_aux_dout_sel) | value);
> }
>
> -static int rk_udphy_dplane_get(struct rk_udphy *udphy)
> -{
> - int dp_lanes;
> -
> - switch (udphy->mode) {
> - case UDPHY_MODE_DP:
> - dp_lanes = 4;
> - break;
> -
> - case UDPHY_MODE_DP_USB:
> - dp_lanes = 2;
> - break;
> -
> - case UDPHY_MODE_USB:
> - default:
> - dp_lanes = 0;
> - break;
> - }
> -
> - return dp_lanes;
> -}
> -
> static void rk_udphy_dplane_enable(struct rk_udphy *udphy, int dp_lanes)
> {
> u32 val = 0;
> @@ -659,6 +645,7 @@ static void rk_udphy_set_typec_default_mapping(struct rk_udphy *udphy)
> }
>
> rk_udphy_mode_set(udphy, UDPHY_MODE_DP_USB);
> + udphy->dp_lanes = 2;
> }
>
> static int rk_udphy_orien_sw_set(struct typec_switch_dev *sw,
> @@ -897,7 +884,7 @@ static int rk_udphy_parse_lane_mux_data(struct rk_udphy *udphy)
> return 0;
> }
>
> - if (num_lanes != 2 && num_lanes != 4)
> + if (num_lanes != 1 && num_lanes != 2 && num_lanes != 4)
> return dev_err_probe(udphy->dev, -EINVAL,
> "invalid number of lane mux\n");
>
> @@ -923,7 +910,8 @@ static int rk_udphy_parse_lane_mux_data(struct rk_udphy *udphy)
> }
>
> udphy->mode = UDPHY_MODE_DP;
> - if (num_lanes == 2) {
> + udphy->dp_lanes = num_lanes;
> + if (num_lanes == 1 || num_lanes == 2) {
> udphy->mode |= UDPHY_MODE_USB;
> udphy->flip = (udphy->lane_mux_sel[0] == PHY_LANE_MUX_DP);
> }
> @@ -1074,18 +1062,17 @@ static int rk_udphy_dp_phy_exit(struct phy *phy)
> static int rk_udphy_dp_phy_power_on(struct phy *phy)
> {
> struct rk_udphy *udphy = phy_get_drvdata(phy);
> - int ret, dp_lanes;
> + int ret;
>
> mutex_lock(&udphy->mutex);
>
> - dp_lanes = rk_udphy_dplane_get(udphy);
> - phy_set_bus_width(phy, dp_lanes);
> + phy_set_bus_width(phy, udphy->dp_lanes);
>
> ret = rk_udphy_power_on(udphy, UDPHY_MODE_DP);
> if (ret)
> goto unlock;
>
> - rk_udphy_dplane_enable(udphy, dp_lanes);
> + rk_udphy_dplane_enable(udphy, udphy->dp_lanes);
>
> rk_udphy_dplane_select(udphy);
>
> @@ -1365,6 +1352,7 @@ static int rk_udphy_typec_mux_set(struct typec_mux_dev *mux,
> udphy->lane_mux_sel[2] = PHY_LANE_MUX_DP;
> udphy->lane_mux_sel[3] = PHY_LANE_MUX_DP;
> mode = UDPHY_MODE_DP;
> + udphy->dp_lanes = 4;
> break;
>
> case TYPEC_DP_STATE_D:
> @@ -1381,6 +1369,7 @@ static int rk_udphy_typec_mux_set(struct typec_mux_dev *mux,
> udphy->lane_mux_sel[3] = PHY_LANE_MUX_DP;
> }
> mode = UDPHY_MODE_DP_USB;
> + udphy->dp_lanes = 2;
> break;
> }
>
> @@ -1529,7 +1518,7 @@ static int rk_udphy_probe(struct platform_device *pdev)
> ret = PTR_ERR(udphy->phy_dp);
> return dev_err_probe(dev, ret, "failed to create DP phy\n");
> }
> - phy_set_bus_width(udphy->phy_dp, rk_udphy_dplane_get(udphy));
> + phy_set_bus_width(udphy->phy_dp, udphy->dp_lanes);
> udphy->phy_dp->attrs.max_link_rate = 8100;
> phy_set_drvdata(udphy->phy_dp, udphy);
>
>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v4 08/16] phy: rockchip: usbdp: Rename DP lane functions
From: Neil Armstrong @ 2026-05-06 14:53 UTC (permalink / raw)
To: Sebastian Reichel, Vinod Koul, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree
In-Reply-To: <20260428-rockchip-usbdp-cleanup-v4-8-7775671ece22@collabora.com>
On 4/28/26 18:13, Sebastian Reichel wrote:
> The common prefix for DisplayPort related functions is rk_udphy_dp_
> (with a final _), so update the two DP lane functions to follow that
> scheme.
>
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> ---
> drivers/phy/rockchip/phy-rockchip-usbdp.c | 10 +++++-----
> 1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
> index bf8394174294..6d7ca11b308e 100644
> --- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
> +++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
> @@ -547,7 +547,7 @@ static void rk_udphy_usb_bvalid_enable(struct rk_udphy *udphy, u8 enable)
> * ---------------------------------------------------------------------------
> */
>
> -static void rk_udphy_dplane_select(struct rk_udphy *udphy)
> +static void rk_udphy_dp_lane_select(struct rk_udphy *udphy)
> {
> const struct rk_udphy_cfg *cfg = udphy->cfgs;
> u32 value = 0;
> @@ -576,7 +576,7 @@ static void rk_udphy_dplane_select(struct rk_udphy *udphy)
> FIELD_PREP(DP_AUX_DOUT_SEL, udphy->dp_aux_dout_sel) | value);
> }
>
> -static void rk_udphy_dplane_enable(struct rk_udphy *udphy, int dp_lanes)
> +static void rk_udphy_dp_lane_enable(struct rk_udphy *udphy, int dp_lanes)
> {
> u32 val = 0;
> int i;
> @@ -1072,9 +1072,9 @@ static int rk_udphy_dp_phy_power_on(struct phy *phy)
> if (ret)
> goto unlock;
>
> - rk_udphy_dplane_enable(udphy, udphy->dp_lanes);
> + rk_udphy_dp_lane_enable(udphy, udphy->dp_lanes);
>
> - rk_udphy_dplane_select(udphy);
> + rk_udphy_dp_lane_select(udphy);
>
> unlock:
> mutex_unlock(&udphy->mutex);
> @@ -1092,7 +1092,7 @@ static int rk_udphy_dp_phy_power_off(struct phy *phy)
> struct rk_udphy *udphy = phy_get_drvdata(phy);
>
> mutex_lock(&udphy->mutex);
> - rk_udphy_dplane_enable(udphy, 0);
> + rk_udphy_dp_lane_enable(udphy, 0);
> rk_udphy_power_off(udphy, UDPHY_MODE_DP);
> mutex_unlock(&udphy->mutex);
>
>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v4 09/16] phy: rockchip: usbdp: Use FIELD_PREP_WM16_CONST
From: Neil Armstrong @ 2026-05-06 14:54 UTC (permalink / raw)
To: Sebastian Reichel, Vinod Koul, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree
In-Reply-To: <20260428-rockchip-usbdp-cleanup-v4-9-7775671ece22@collabora.com>
On 4/28/26 18:13, Sebastian Reichel wrote:
> Cleanup code by replacing open-coded version of FIELD_PREP_WM16_CONST
> with the existing helper macro.
>
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> ---
> drivers/phy/rockchip/phy-rockchip-usbdp.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
> index 6d7ca11b308e..1bfc365e2b2c 100644
> --- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
> +++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
> @@ -12,6 +12,7 @@
> #include <linux/clk.h>
> #include <linux/delay.h>
> #include <linux/gpio.h>
> +#include <linux/hw_bitfield.h>
> #include <linux/mfd/syscon.h>
> #include <linux/mod_devicetable.h>
> #include <linux/module.h>
> @@ -75,7 +76,6 @@
> #define TRSV_LN2_MON_RX_CDR_DONE_OFFSET 0x1b84 /* trsv_reg06E1 */
> #define TRSV_LN2_MON_RX_CDR_LOCK_DONE BIT(0)
>
> -#define BIT_WRITEABLE_SHIFT 16
> #define PHY_AUX_DP_DATA_POL_NORMAL 0
> #define PHY_AUX_DP_DATA_POL_INVERT 1
> #define PHY_LANE_MUX_USB 0
> @@ -104,8 +104,8 @@ struct rk_udphy_grf_reg {
> #define _RK_UDPHY_GEN_GRF_REG(offset, mask, disable, enable) \
> {\
> offset, \
> - FIELD_PREP_CONST(mask, disable) | (mask << BIT_WRITEABLE_SHIFT), \
> - FIELD_PREP_CONST(mask, enable) | (mask << BIT_WRITEABLE_SHIFT), \
> + FIELD_PREP_WM16_CONST(mask, disable), \
> + FIELD_PREP_WM16_CONST(mask, enable), \
> }
>
> #define RK_UDPHY_GEN_GRF_REG(offset, bitend, bitstart, disable, enable) \
>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v4 10/16] phy: rockchip: usbdp: Cleanup DP lane selection function
From: Neil Armstrong @ 2026-05-06 14:55 UTC (permalink / raw)
To: Sebastian Reichel, Vinod Koul, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree
In-Reply-To: <20260428-rockchip-usbdp-cleanup-v4-10-7775671ece22@collabora.com>
On 4/28/26 18:13, Sebastian Reichel wrote:
> Use FIELD_PREP_WM16() helpers to simplify the DP lane selection
> logic.
>
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> ---
> drivers/phy/rockchip/phy-rockchip-usbdp.c | 28 +++++++---------------------
> 1 file changed, 7 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
> index 1bfc365e2b2c..beab20e4c512 100644
> --- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
> +++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
> @@ -550,30 +550,16 @@ static void rk_udphy_usb_bvalid_enable(struct rk_udphy *udphy, u8 enable)
> static void rk_udphy_dp_lane_select(struct rk_udphy *udphy)
> {
> const struct rk_udphy_cfg *cfg = udphy->cfgs;
> - u32 value = 0;
> -
> - switch (udphy->dp_lanes) {
> - case 4:
> - value |= 3 << udphy->dp_lane_sel[3] * 2;
> - value |= 2 << udphy->dp_lane_sel[2] * 2;
> - fallthrough;
> -
> - case 2:
> - value |= 1 << udphy->dp_lane_sel[1] * 2;
> - fallthrough;
> + u32 value = FIELD_PREP_WM16(DP_LANE_SEL_ALL, 0);
> + int i;
>
> - case 1:
> - value |= 0 << udphy->dp_lane_sel[0] * 2;
> - break;
> + for (i = 0; i < udphy->dp_lanes; i++)
> + value |= field_prep(DP_LANE_SEL_N(udphy->dp_lane_sel[i]), i);
>
> - default:
> - break;
> - }
> + value |= FIELD_PREP_WM16(DP_AUX_DIN_SEL, udphy->dp_aux_din_sel);
> + value |= FIELD_PREP_WM16(DP_AUX_DOUT_SEL, udphy->dp_aux_dout_sel);
>
> - regmap_write(udphy->vogrf, cfg->vogrfcfg[udphy->id].dp_lane_reg,
> - ((DP_AUX_DIN_SEL | DP_AUX_DOUT_SEL | DP_LANE_SEL_ALL) << 16) |
> - FIELD_PREP(DP_AUX_DIN_SEL, udphy->dp_aux_din_sel) |
> - FIELD_PREP(DP_AUX_DOUT_SEL, udphy->dp_aux_dout_sel) | value);
> + regmap_write(udphy->vogrf, cfg->vogrfcfg[udphy->id].dp_lane_reg, value);
> }
>
> static void rk_udphy_dp_lane_enable(struct rk_udphy *udphy, int dp_lanes)
>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox