lynx_28g_validate() suffers from the following shortcomings:
- Changing the protocol should not be possible if the source protocol of
the lane is unsupported. This is because lynx_28g_proto_conf[] only
covers the register deltas between any pair of supported lane modes,
but that delta is probably incomplete if the source protocol is, say,
PCIe (which is currently assimilated by the driver to
LANE_MODE_UNKNOWN).
lynx_28g_proto_conf() does refuse changing the protocol if the current
one is unsupported, but we shouldn't advertise it via phy_validate()
at all.
The phy_set_mode_ext() call should perform the exact same
verifications as phy_validate() did, in case the caller bypassed
phy_validate(). So we need to centralize the logic into a common
validation. But lynx_28g_set_mode() later needs the lane_mode that
this validation needs to compute anyway, so name the common helper
lynx_phy_mode_to_lane_mode() and let it return that lane_mode.
- Future core sanity checks on phy_validate() will want to differentiate
the case where this optional method is not implemented from the case
where the mode/submode is really not supported. So we shouldn't return
-EOPNOTSUPP from lynx_28g_validate(), but -EINVAL to signal that we do
implement the operation:
https://lore.kernel.org/linux-phy/aY2lFTIALH7qEJmM@shell.armlinux.org.uk/
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Link: https://patch.msgid.link/20260610151952.2141019-14-vladimir.oltean@nxp.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
It is unnecessary to rewrite a register if the masked field already
contains the desired value upon reading. The hardware behaviour does not
depend upon register writes with identical values.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Link: https://patch.msgid.link/20260610151952.2141019-13-vladimir.oltean@nxp.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Some 10G Lynx SerDes blocks are big endian and require byte swapping
because the CPUs are little endian armv8 (LS1046A). Parse the
"big-endian" device tree property, and modify the base lynx_read() and
lynx_write() accessors to test this property before issuing either the
ioread32() or ioread32be() variants (as per
Documentation/driver-api/device-io.rst).
All other accessors - lynx_rmw(), lynx_lane_read(), lynx_lane_write(),
lynx_lane_rmw(), lynx_pll_read() - need to go through these endian-aware
helpers.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Link: https://patch.msgid.link/20260610151952.2141019-12-vladimir.oltean@nxp.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Factor the device-agnostic logic from lynx_28g_probe() and
lynx_28g_remove() into lynx_probe() and lynx_remove() inside
phy-fsl-lynx-core.c. These will be shared with the 10G Lynx driver.
Since the PLL configuration, lane configuration and CDR lock detection
procedure are going to be different, introduce lynx_info function
pointers so that this code remains in the 28G Lynx driver.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Link: https://patch.msgid.link/20260610151952.2141019-11-vladimir.oltean@nxp.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
In a future change, lynx_28g_pll_read_configuration() and
lynx_28g_lane_read_configuration() will be made methods of struct
lynx_info.
There is no functional reason, but lynx_28g_lane_read_configuration() is
called per lane and lynx_28g_pll_read_configuration() iterates over PLLs
internally. So the API exported by the lynx_info structure would not be
uniform. Change lynx_28g_pll_read_configuration() to also permit reading
the PLL configuration individually, and move the for loop at the call
site.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Link: https://patch.msgid.link/20260610151952.2141019-10-vladimir.oltean@nxp.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
We need to be able to reference more function pointers in upcoming
patches. The struct lynx_info definitions are currently placed a bit up
in lynx-28g.c in order to be able to do that without function prototype
forward declarations, so move them downward to avoid that situation.
No functional change intended.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Link: https://patch.msgid.link/20260610151952.2141019-9-vladimir.oltean@nxp.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
For the 28G Lynx, there are situations where a protocol is not supported
on a lane despite there being a PCCR register and protocol converter
available:
- LX2160A SerDes 1: reference manual documents PCCD fields E25GC_CFG and
E25GD_CFG and protocol converter registers E25GCCR1..E25GCCR3 /
E25GDCR1..E25GDCR3, but nonetheless, Table 289. SerDes 1 protocol
mapping shows no RCW[SRDS_PRTCL_S1] value for which lanes C and D
support 25G
- when using the "fsl,lynx-28g" fallback compatible string, we don't
want to offer 25GbE because we don't know if the lane supports it,
even though we know how to reach the PCCR and protocol converter
registers for it.
But for the upcoming 10G Lynx SerDes, the above situations don't exist.
There, if we know how to reach the PCCR and protocol converter
registers on a lane, we implicitly know that the protocol is supported
there, so implementing priv->info->lane_supports_mode() would be
redundant.
Implement lynx_lane_supports_mode_default() which decides whether a lane
mode is supported just based on priv->info->get_pccr() and
priv->info->get_pcvt_offset().
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Link: https://patch.msgid.link/20260610151952.2141019-8-vladimir.oltean@nxp.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
The protocol converters on the 10G Lynx are architecturally similar, but
different in layout from the 28G Lynx ones.
Move lynx_pccr_read(), lynx_pccr_write(), lynx_pcvt_read() and
lynx_pcvt_write() from the 28G Lynx driver to the common module, and
permit each SerDes driver to provide just its own bits in order to use
this common API.
Currently, that just means that the direct calls to
lynx_28g_get_pcvt_offset() are modified to go through the
lynx->info->get_pcvt_offset() indirect function call, and similarly,
lynx_28g_get_pccr() through lynx->info->get_pccr().
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Link: https://patch.msgid.link/20260610151952.2141019-7-vladimir.oltean@nxp.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
The logic should be absolutely unchanged in the new 10G Lynx SerDes
driver, so let's move this to phy-fsl-lynx-core.c and update the 28G
Lynx driver to use the common variant.
While at it, update the call site, lynx_28g_lane_remap_pll(), to use the
new data structures, and refactor the NULL pll pointer check (the
current form triggers a checkpatch CHECK).
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Link: https://patch.msgid.link/20260610151952.2141019-6-vladimir.oltean@nxp.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
The goal is to avoid duplicating the core data structures when
introducing the new lynx-10g driver.
We move the following to phy-fsl-lynx-core:
- struct lynx_28g_pll -> struct lynx_pll. This has some
hardware-specific register fields which need to become hardware
agnostic (the PLL register layout is different for Lynx 10G), So:
- PLLnRSTCTL_DIS(pll->rstctl) becomes !pll->enabled
- PLLnRSTCTL_LOCK(pll->rstctl) becomes pll->locked
- FIELD_GET(PLLnCR1_FRATE_SEL, pll->cr1) becomes pll->frate_sel
- FIELD_GET(PLLnCR0_REFCLK_SEL, pll->cr0) becomes pll->refclk_sel
- struct lynx_28g_lane -> struct lynx_lane
- struct lynx_28g_priv -> struct lynx_priv
- field lane[LYNX_28G_NUM_LANE] has to be dynamically allocated. Not
all Lynx 10G SerDes blocks have 8 lanes.
- LYNX_28G_NUM_PLL -> LYNX_NUM_PLL. This is an architectural constant
which is the same for Lynx 10G as well.
To avoid major noise in the lynx-28g driver, we keep compatibility shims
(for now) where the old lynx_28g names are preserved, but translate to
the common data structures.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Link: https://patch.msgid.link/20260610151952.2141019-5-vladimir.oltean@nxp.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Do some preparation work for the introduction of the lynx-10g driver,
which will share a common backbone with the 28G Lynx SerDes.
This is just trivial stuff which can be moved without any surgery, and
is easy to follow but otherwise pollutes more serious changes.
The lane modes themselves are exported to a public header, because on
the 10G Lynx, the hardware requires implementing a procedure called
"RCW override". This requires coordination with drivers/soc/fsl/guts.c
to tell it that a SerDes lane needs to be switched to a different
protocol (enum lynx_lane_mode).
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Link: https://patch.msgid.link/20260610151952.2141019-4-vladimir.oltean@nxp.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
It is possible to bind the lynx-28g driver to an arbitrary device with
an OF node, using the driver_override mechanism that is available for
the platform bus, and trigger a crash this way:
$ echo 1ea0000.serdes > /sys/bus/platform/drivers/lynx-10g/unbind
$ echo lynx-28g > /sys/bus/platform/devices/1ea0000.serdes/driver_override
$ echo 1ea0000.serdes > /sys/bus/platform/drivers/lynx-28g/bind
Internal error: Oops: 0000000096000004 [#1] SMP
Hardware name: LS1028A RDB Board (DT)
pc : lynx_probe+0x118/0x4fc
lr : lynx_probe+0x110/0x4fc
Call trace:
lynx_probe+0x118/0x4fc (P)
lynx_28g_probe+0x54/0x7c
platform_probe+0x68/0xa4
really_probe+0x14c/0x2ec
__driver_probe_device+0xc8/0x170
device_driver_attach+0x58/0xa8
bind_store+0xd8/0x118
drv_attr_store+0x24/0x38
The crash is caused by the fact that of_device_get_match_data() returns
NULL (the bound device has a different compatible string) and this is
not checked.
There was a previous attempt to avoid this in commit c9d80e8610 ("phy:
lynx-28g: require an OF node to probe"), but the mechanism was not fully
understood and it only covered the case where the driver was bound to a
device with no OF node.
The issue was found during Sashiko review. Elevated privilege is
required to override the driver for a device, so the real life impact of
the issue should not be very high.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Link: https://patch.msgid.link/20260610151952.2141019-3-vladimir.oltean@nxp.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Sashiko points out that _of_phy_get() does not support a NULL returned
output from phy_provider->of_xlate(), just a valid pointer or a
pointer-encoded error.
When lynx_28g_probe() -> for_each_available_child_of_node() skips
over lanes which have OF nodes with status = "disabled", the
priv->lane[idx].phy pointer will remain NULL.
This NULL pointer may be propagated to lynx_28g_xlate() if the device
tree contains a phandle to the disabled lane AND fw_devlink did not
block probing for the consumer. In that case, the PHY core will crash
when trying to dereference the NULL phy pointer.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Link: https://patch.msgid.link/20260610151952.2141019-2-vladimir.oltean@nxp.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Add QMP PCIe PHY support for the Eliza SoC. Introduce a new Gen3x1 PHY
configuration with Eliza-specific initialization tables, and reuse the
existing sm8550 Gen3x2 configuration for the Gen3x2 PHY instance.
Also add the missing QPHY_PCIE_V6_PCS_PCIE_INT_AUX_CLK_CONFIG1 register
definition to the PCIe V6 PCS header.
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
Link: https://patch.msgid.link/20260608-eliza-v3-3-9bdeb7434b28@oss.qualcomm.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
While being less compact, using named initializers allows to more easily
see which members of the structs are assigned which value without having
to lookup the declaration of the struct. And it's also more robust
against changes to the struct definition.
This patch doesn't modify the compiled arrays, only their representation
in source form benefits. The former was confirmed with x86 and arm64
builds.
Signed-off-by: Uwe Kleine-König (The Capable Hub) <u.kleine-koenig@baylibre.com>
Link: https://patch.msgid.link/20260519151957.1593214-2-u.kleine-koenig@baylibre.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Neither of the two Gen4x4 PHYs found on Purwa supports bifurcation.
The PHY is however physically laid out as if it were to, since there
are two separate ports (A/B).
Split out a new if-then block to un-require the bifurcation register
handle to squash this warning:
purwa-iot-evk.dtb: phy@1bd4000 (qcom,x1p42100-qmp-gen4x4-pcie-phy): 'qcom,4ln-config-sel' is a required property
Fixes: 2e1ffd4c18 ("dt-bindings: phy: qcom,qmp-pcie: Add X1P42100 PCIe Gen4x4 PHY")
Reported-by: Rob Herring <robh@kernel.org>
Closes: https://lore.kernel.org/linux-arm-msm/176857775469.1631885.16133311938753588148.robh@kernel.org/
Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Acked-by: Rob Herring (Arm) <robh@kernel.org>
Link: https://patch.msgid.link/20260610-topic-purwa_phy_shutup_warning-v2-1-951c1fbfe9b2@oss.qualcomm.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Currently the code enqueue work items using {queue|mod}_delayed_work(),
using system_long_wq. This workqueue should be used when long works are
expected and it is a per-cpu workqueue.
The function(s) end up calling __queue_delayed_work(), which set a global
timer that could fire anywhere, enqueuing the work where the timer fired.
Unbound works could benefit from scheduler task placement, to optimize
performance and power consumption. Long work shouldn't stick to a single
CPU.
Recently, a new unbound workqueue specific for long running work has
been added:
c116737e972e ("workqueue: Add system_dfl_long_wq for long unbound works")
Since the workqueue work doesn't rely on per-cpu variables, there is no
obvious reason that justify the use of a per-cpu workqueue. So change
system_long_wq with system_dfl_long_wq so that the work may benefit from
scheduler task placement.
Signed-off-by: Marco Crivellari <marco.crivellari@suse.com>
Link: https://patch.msgid.link/20260507131439.264906-1-marco.crivellari@suse.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
I volunteered to maintain the phy-zynqmp driver as part of my work on
the ZynqMP DPSUB driver. Now that Tomi has taken over the DPSUB, it
makes sense for him to handle the phy-zynqmp driver as well.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Acked-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
Link: https://patch.msgid.link/20260519082253.40142-1-laurent.pinchart@ideasonboard.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Add a generic PHY driver for the TI DS125DF111 Multi-Protocol
Dual-Channel Retimer. The driver currently supports only 10G and 1G link
speeds but it can easily extended to also cover other usecases.
Since the available datasheet (https://www.ti.com/lit/gpn/DS125DF111)
does not name the registers, the name for the macros were determined by
their usage pattern.
A PHY device is created for each of the two channels present on the
retimer. This allows for independent configuration of the two channels.
This capability is especially important on retimers which have more than
2 channels that can be, depending on the board design, connected in
multiple different ways to the SerDes lanes.
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
Link: https://patch.msgid.link/20260518142026.3098496-4-ioana.ciornei@nxp.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
The PCIe SSC configuration for the RK3588 and RK3576 SoCs required
additional tuning which is missing. When adding these same SSC
configurations for both of these two SoCs, as well as upcoming
platforms, it's obvious the SSC setup code was largely duplicated
across the platform-specific configuration functions. This becomes
harder to maintain as more platforms are added.
So extract the common SSC logic into a shared helper function,
rk_combphy_common_cfg_ssc(). This cleans up the per-platform drivers
and centralizes the standard configuration as possible.
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
Link: https://patch.msgid.link/1777251433-110466-1-git-send-email-shawn.lin@rock-chips.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Keep the USB pipe clock working when the phy is in DP-only mode, because
the dwc controller still needs it for USB 2.0 over the same Type-C port.
Tested with the BenQ RD280UA monitor which has a downstream-facing port
for data passthrough that's manually switchable between USB 2 and 3,
corresponding to 4-lane and 2-lane DP respectively.
Note: the suspend/resume callbacks were already gating the enable/disable
of this clock only on init_count and not usb_init_count!
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Val Packett <val@packett.cool>
Link: https://patch.msgid.link/20260304190827.176988-1-val@packett.cool
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Instead of kzalloc and kcalloc, we can use a flex array to reduce to a
single allocation.
Also added __counted_by() for extra possible analysis.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
Reviewed-by: Gustavo A. R. Silva <gustavoars@kernel.org>
Link: https://patch.msgid.link/20260304043420.14151-1-rosenp@gmail.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Introduce support for EcoNet PCIe PHY controllers found in EN751221
and EN7528 SoCs, these SoCs are not identical but are similar, each
having one Gen1 port, and one Gen1/Gen2 port.
Co-developed-by: Ahmed Naseef <naseefkm@gmail.com>
Signed-off-by: Ahmed Naseef <naseefkm@gmail.com>
[cjd@cjdns.fr: add EN751221 support and refactor for clarity]
Signed-off-by: Caleb James DeLisle <cjd@cjdns.fr>
Link: https://patch.msgid.link/20260425173642.406089-3-cjd@cjdns.fr
Signed-off-by: Vinod Koul <vkoul@kernel.org>
EN751221 and EN7528 SoCs have two PCIe slots, and each one has a PHY
which behaves slightly differently because one slot is Gen1/Gen2 while
the other is Gen1 only.
Signed-off-by: Caleb James DeLisle <cjd@cjdns.fr>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Link: https://patch.msgid.link/20260425173642.406089-2-cjd@cjdns.fr
Signed-off-by: Vinod Koul <vkoul@kernel.org>
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>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Link: https://patch.msgid.link/20260505170410.3265305-6-heiko@sntech.de
Signed-off-by: Vinod Koul <vkoul@kernel.org>
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>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Link: https://patch.msgid.link/20260505170410.3265305-5-heiko@sntech.de
Signed-off-by: Vinod Koul <vkoul@kernel.org>
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>
Link: https://patch.msgid.link/20260505170410.3265305-4-heiko@sntech.de
Signed-off-by: Vinod Koul <vkoul@kernel.org>
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>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Link: https://patch.msgid.link/20260505170410.3265305-3-heiko@sntech.de
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Typically these Rockchip USB2 PHYs are fully contained within a single
GRF. However, for RK3568 and RV1108 regs to control the USB2 PHY is
located in a different GRF compared to the base address.
Update this binding to require rockchip,usbgrf for RK3568 and RV1108 to
properly reflect that the USB GRF is required to control the USB2 PHYs
on these variants. Also disable use of rockchip,usbgrf for variants
where it is not required.
This should not introduce any breakage as the affected usb2phy nodes for
RK3568 and RV1108 were added together with a rockchip,usbgrf phandle in
their initial commit.
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
Acked-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Link: https://patch.msgid.link/20260505170410.3265305-2-heiko@sntech.de
Signed-off-by: Vinod Koul <vkoul@kernel.org>
This file does not use the symbols from the legacy
<linux/gpio.h> header, so let's drop it.
Reviewed-by: Josua Mayer <josua@solid-run.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://patch.msgid.link/20260513220336.369628-7-andriy.shevchenko@linux.intel.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
The code like
int foo = X;
...
if (bar)
foo = Y;
is prone to subtle mistakes and hence harder to maintain as the foo value
may be changed inadvertently while code in '...' grown in lines. On top
it's harder to navigate to understand the possible values of foo when branch
is not taken (requires to look somewhere else in the code, far from the piece
at hand).
Besides that in case of taken branch the foo will be rewritten, which is
not a problem per se, just an unneeded operation.
Decouple assignment and definition to use if-else to address the inconveniences
described above.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://patch.msgid.link/20260513220336.369628-6-andriy.shevchenko@linux.intel.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Instead of checking for the specific error codes (that can be considered
a layering violation to some extent) check for the property existence first
and then either parse it, or apply a default value.
With that, return an error when parsing of the existing property fails.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://patch.msgid.link/20260513220336.369628-5-andriy.shevchenko@linux.intel.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
There is no code that uses ID table directly, except the
struct device_driver at the end of the file. Hence, move
table closer to its user. It's always possible to access
them via a pointer.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://patch.msgid.link/20260513220336.369628-4-andriy.shevchenko@linux.intel.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Use the generic firmware node interface for retrieving
device match data instead of the OF-specific one.
While at it, drop unneeded argument to devm_phy_create() which
extracts device node from the given device by default.
Reviewed-by: Josua Mayer <josua@solid-run.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://patch.msgid.link/20260513220336.369628-3-andriy.shevchenko@linux.intel.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Every platform driver can be forced to match a device that doesn't
match its list of device IDs because of device_match_driver_override()
so platform drivers that rely on the existence of a device's driver
data need to verify its presence.
Accordingly, add requisite match and driver data checks against NULL
to the driver where they are missing.
Fixes: a4a86d273f ("phy: phy-can-transceiver: Add support for generic CAN transceiver driver")
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://patch.msgid.link/20260513220336.369628-2-andriy.shevchenko@linux.intel.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Add support for 25GBASE-R in the Lynx 28G SerDes PHY driver. This will
be used by the dpaa2-mac consumer on LX2160A with:
- phy_validate(phy, PHY_MODE_ETHERNET, PHY_INTERFACE_MODE_25GBASER) to
detect support.
- phy_set_mode_ext(phy, PHY_MODE_ETHERNET, PHY_INTERFACE_MODE_25GBASER)
to reconfigure the lane for this protocol.
The intended use case for dynamic protocol switching to 25GBase-R is
with SFP28 modules, and protocol switching is triggered by the SFP
module insertion. There also exists a 25GBase-KR use case, where the
protocol switching is covered by IEEE 802.3 clause 73 auto-negotiation.
However, that is not handled here; it merely needs the support added
here as basic ground work.
The lane frequency for 25GbE is sourced from a clock net frequency of
12.890625 GHz, as produced by PLLF or PLLS, further multiplied by the
lane by 2. The clock net frequencies produced by the PLLs are treated as
read-only by the driver, so the absence of a PLL provisioned for the
right clock net frequency implies absence of 25GbE support, even though
a lane might have the appropriate protocol converter for it.
In terms of implementation, the change consists of:
- determining at probe time if any PLL was preconfigured for the
required clock net frequency for 25GbE
- adding the default lane parameters for reconfiguring a lane to 25GbE
irrespective of the original protocol
- allowing this operating mode only on supported lanes, i.e. all lanes
of LX2162A SerDes #1, and LX2160A SerDes lanes 0-1, 4-7.
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Tested-by: Josua Mayer <josua@solid-run.com>
Link: https://patch.msgid.link/20260511150023.1903577-6-vladimir.oltean@nxp.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Add driver support for probing on the new, per-instance and per-SoC
bindings, which provide the main benefit that they allow rejecting
unsupported protocols per lane (10GbE on SerDes 2 lanes 0-5), but they
also allow avoiding the creation of PHYs for lanes that don't exist
(LX2162A lanes 0-3).
For old device trees with just "fsl,lynx-28g", the only things that
change are:
- a probe time warning/encouragement to update the device tree. This is
warranted by the fact that using "fsl,lynx-28g" may already provide
incorrect behaviour (undetected absent 10GbE support on LX2160A
SerDes 2 lanes 0-5). But we retain bug compatibility nonetheless.
- the feature set is frozen in time (e.g. no 25GbE). Since we cannot
guarantee that this protocol will work on a lane, just err on the safe
side and don't offer it (and require a device tree update to get it).
In terms of code, the lynx_28g_supports_lane_mode() function prototype
changes. It was a SerDes-global function and now becomes per lane, to
reflect the specific capabilities each instance may have. The
implementation goes through priv->info->lane_supports_mode().
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Tested-by: Josua Mayer <josua@solid-run.com>
Link: https://patch.msgid.link/20260511150023.1903577-5-vladimir.oltean@nxp.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
The driver will gain support for variants in an upcoming change, and
will use of_device_get_match_data() to deduce the running variant from
the compatible string.
Currently, the driver expects the schema at phy/fsl,lynx-28g.yaml, and
OF-based consumers, but doesn't enforce this. And it is possible for
user space to force-bind the driver to a device without OF node using
the driver_override sysfs.
To avoid future surprise crashes for an unsupported configuration,
explicitly test for the presence of an OF node and fail probing if
found.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Tested-by: Josua Mayer <josua@solid-run.com>
Link: https://patch.msgid.link/20260511150023.1903577-4-vladimir.oltean@nxp.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
The SerDes 1 of LX2162A has fewer lanes than all other instances, and
strangely, their indices are not 0-3, but 4-7.
This is a best-effort constraint, since we can only impose it when using
per-SoC compatible string and per-lane OF nodes.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Tested-by: Josua Mayer <josua@solid-run.com>
Link: https://patch.msgid.link/20260511150023.1903577-3-vladimir.oltean@nxp.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
The 28G Lynx SerDes is instantiated 3 times in the NXP LX2160A SoC and
twice in the NXP LX2162A. All these instances share the same register
map, but the number of lanes and the protocols supported by each lane
differs in a way that isn't detectable by the programming model.
For example, not all lanes of all SerDes block instantiations support
25GbE.
So, using a generic "fsl,lynx-28g" compatible string and expecting all
SerDes instantiations to use it was a mistake that needs to be fixed.
The option chosen is to encode the SoC and the SerDes instance in the
compatible string, with everything else being the responsibility of the
driver to derive.
An alternative considered but dismissed was to add sufficient device
tree properties to describe the per-lane differences (implying:
supported protocols), as well as the different lane count.
Any decision made for the 28G Lynx should be consistent with the
decisions taken for the yet-to-be-introduced 10G Lynx SerDes (older
generation for older SoCs), because of how similar they are.
I've seen the alternative at play in this unmerged patch set for the 10G
Lynx here, and I didn't like it:
https://lore.kernel.org/linux-phy/20230413160607.4128315-3-sean.anderson@seco.com/
This is because there, we have a higher degree of variability in the
PCCR register values that need to be written per protocol. This makes
that approach more drawn-out and more prone to errors, compared to the
compatible strings which are more succinct and obviously correct.
NXP SoC reference manuals clearly document the SerDes instantiations as
not identical, and refers to them as such (SerDes 1, 2, etc).
The per-SoC compatible string is prepended to the "fsl,lynx-28g" generic
compatible, which is left there for compatibility with old kernels. An
exception would be LX2160A SerDes #3, which at the time of writing is
not described in fsl-lx2160a.dtsi. As "fsl,lx2160a-serdes3" implies it
is a 28G Lynx SerDes, it makes "fsl,lynx-28g" redundant so we don't
accept it.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Tested-by: Josua Mayer <josua@solid-run.com>
Link: https://patch.msgid.link/20260511150023.1903577-2-vladimir.oltean@nxp.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
This driver uses multiple regmaps, which will causes name conflicts
in debugfs like:
debugfs: '5f1a0000.phy' already exists in 'regmap'
Fix this by using a dedicated regmap config for each resource, each
having a dedicated regmap name.
Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260211144949.1128122-1-alexander.stein@ew.tq-group.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
There's nothing special here to prevent compilation on non ARM hosts.
Matches every other st phy driver.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>
Link: https://patch.msgid.link/20260306222457.8400-2-rosenp@gmail.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
EyeQ5 embeds a system-controller called OLB. It features many unrelated
registers, and some of those are registers used to configure the
integration of the RGMII/SGMII Cadence PHY used by MACB/GEM instances.
Wrap in a neat generic PHY provider, exposing two PHYs with standard
phy_init() / phy_set_mode() / phy_power_on() operations.
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
Link: https://patch.msgid.link/20260309-macb-phy-v9-1-5afd87d9db43@bootlin.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Fix a malformed MODULE_AUTHOR macro in the RZ/G3E USB3.0 PHY driver where
the author's name and opening angle bracket were missing, leaving only the
email address with a stray closing >. Correct it to the standard Name
<email> format.
Reported-by: Pavel Machek <pavel@nabladev.com>
Closes: https://lore.kernel.org/all/abp4KprlYyU+jMPu@duo.ucw.cz/
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Link: https://patch.msgid.link/20260319063211.5056-1-biju.das.jz@bp.renesas.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>