* [PATCH v9 00/10] phy: Add support for Lynx 10G SerDes
@ 2022-12-30 0:01 Sean Anderson
2022-12-30 0:01 ` [PATCH v9 02/10] dt-bindings: phy: Add Lynx 10G phy binding Sean Anderson
` (3 more replies)
0 siblings, 4 replies; 13+ messages in thread
From: Sean Anderson @ 2022-12-30 0:01 UTC (permalink / raw)
To: Vinod Koul, Kishon Vijay Abraham I, linux-phy
Cc: linux-arm-kernel, Camelia Alexandra Groza, Madalin Bucur,
Bagas Sanjaya, Rob Herring, Ioana Ciornei, linuxppc-dev,
devicetree, Krzysztof Kozlowski, Sean Anderson, Jonathan Corbet,
Li Yang, Michael Turquette, Shawn Guo, Stephen Boyd, linux-clk,
linux-doc
This adds support for the Lynx 10G SerDes found on the QorIQ T-series
and Layerscape series. Due to limited time and hardware, only support
for the LS1046ARDB and LS1088ARDB is added in this initial series.
This series is based on phy/next, but it requires phylink support. This
is already present for the LS1088A, and it was recently added for the
LS1046A in net-next/master.
Major reconfiguration of baud rate (e.g. 1G->10G) does not work. From my
testing, SerDes register settings appear identical. The issue appears to
be between the PCS and the MAC. The link itself comes up at both ends,
and a mac loopback succeeds. However, a PCS loopback results in dropped
packets. Perhaps there is some undocumented register in the PCS?
I suspect this driver is around 95% complete, but I don't have the
documentation to make it work completely. At the very least it is useful
for two cases:
- Although this is untested, it should support 2.5G SGMII as well as
1000BASE-KX. The latter needs MAC and PCS support, but the former
should work out of the box.
- It allows for clock configurations not supported by the RCW. This is
very useful if you want to use e.g. SRDS_PRTCL_S1=0x3333 and =0x1133
on the same board. This is because the former setting will use PLL1
as the 1G reference, but the latter will use PLL1 as the 10G
reference. Because we can reconfigure the PLLs, it is possible to
always use PLL1 as the 1G reference.
The final patch in this series depends on [1].
[1] https://lore.kernel.org/netdev/20221227230918.2440351-1-sean.anderson@seco.com/
Changes in v9:
- Add fsl,unused-lanes-reserved to allow for a gradual transition
between firmware and Linux control of the SerDes
- Change phy-type back to fsl,type, as I was getting the error
'#phy-cells' is a dependency of 'phy-type'
- Convert some u32s to unsigned long to match arguments
- Switch from round_rate to determine_rate
- Drop explicit reference to reference clock
- Use .parent_names when requesting parents
- Use devm_clk_hw_get_clk to pass clocks back to serdes
- Fix indentation
- Split off clock "driver" into its own patch to allow for better
review.
- Add ability to defer lane initialization to phy_init. This allows
for easier transitioning between firmware-managed serdes and Linux-
managed serdes, as the consumer (such as dpaa2, which knows what the
firmware is doing) has the last say on who gets control.
- Fix name of phy mode node
- Add fsl,unused-lanes-reserved to allow a gradual transition, depending
on the mac link type.
- Remove unused clocks
- Fix some phy mode node names
Changes in v8:
- Remove unused variable from lynx_ls_mode_init
- Rename serdes phy handles to use _A, _B, etc. instead of _0, _1, etc.
This should help remind readers that the numbering corresponds to the
physical layout of the registers, and not the lane (pin) number.
- Prevent PCSs from probing as phys
- Rename serdes phy handles like the LS1046A
- Add SFP slot binding
- Fix incorrect lane ordering (it's backwards on the LS1088A just like it is in
the LS1046A).
- Fix duplicated lane 2 (it should have been lane 3).
- Fix incorrectly-documented value for XFI1.
- Remove interrupt for aquantia phy. It never fired for whatever reason,
preventing the link from coming up.
- Add GPIOs for QIXIS FPGA.
- Enable MAC1 PCS
- Remove si5341 binding
Changes in v7:
- Use double quotes everywhere in yaml
- Break out call order into generic documentation
- Refuse to switch "major" protocols
- Update Kconfig to reflect restrictions
- Remove set/clear of "pcs reset" bit, since it doesn't seem to fix
anything.
Changes in v6:
- Bump PHY_TYPE_2500BASEX to 13, since PHY_TYPE_USXGMII was added in the
meantime
- fsl,type -> phy-type
- frequence -> frequency
- Update MAINTAINERS to include new files
- Include bitfield.h and slab.h to allow compilation on non-arm64
arches.
- Depend on COMMON_CLK and either layerscape/ppc
- XGI.9 -> XFI.9
Changes in v5:
- Update commit description
- Dual id header
- Remove references to PHY_INTERFACE_MODE_1000BASEKX to allow this
series to be applied directly to linux/master.
- Add fsl,lynx-10g.h to MAINTAINERS
Changes in v4:
- Add 2500BASE-X and 10GBASE-R phy types
- Use subnodes to describe lane configuration, instead of describing
PCCRs. This is the same style used by phy-cadence-sierra et al.
- Add ids for Lynx 10g PLLs
- Rework all debug statements to remove use of __func__. Additional
information has been provided as necessary.
- Consider alternative parent rates in round_rate and not in set_rate.
Trying to modify out parent's rate in set_rate will deadlock.
- Explicitly perform a stop/reset sequence in set_rate. This way we
always ensure that the PLL is properly stopped.
- Set the power-down bit when disabling the PLL. We can do this now that
enable/disable aren't abused during the set rate sequence.
- Fix typos in QSGMII_OFFSET and XFI_OFFSET
- Rename LNmTECR0_TEQ_TYPE_PRE to LNmTECR0_TEQ_TYPE_POST to better
reflect its function (adding post-cursor equalization).
- Use of_clk_hw_onecell_get instead of a custom function.
- Return struct clks from lynx_clks_init instead of embedding lynx_clk
in lynx_priv.
- Rework PCCR helper functions; T-series SoCs differ from Layerscape SoCs
primarily in the layout and offset of the PCCRs. This will help bring a
cleaner abstraction layer. The caps have been removed, since this handles the
only current usage.
- Convert to use new binding format. As a result of this, we no longer need to
have protocols for PCIe or SATA. Additionally, modes now live in lynx_group
instead of lynx_priv.
- Remove teq from lynx_proto_params, since it can be determined from
preq_ratio/postq_ratio.
- Fix an early return from lynx_set_mode not releasing serdes->lock.
- Rename lynx_priv.conf to .cfg, since I kept mistyping it.
Changes in v3:
- Manually expand yaml references
- Add mode configuration to device tree
- Rename remaining references to QorIQ SerDes to Lynx 10G
- Fix PLL enable sequence by waiting for our reset request to be cleared
before continuing. Do the same for the lock, even though it isn't as
critical. Because we will delay for 1.5ms on average, use prepare
instead of enable so we can sleep.
- Document the status of each protocol
- Fix offset of several bitfields in RECR0
- Take into account PLLRST_B, SDRST_B, and SDEN when considering whether
a PLL is "enabled."
- Only power off unused lanes.
- Split mode lane mask into first/last lane (like group)
- Read modes from device tree
- Use caps to determine whether KX/KR are supported
- Move modes to lynx_priv
- Ensure that the protocol controller is not already in-use when we try
to configure a new mode. This should only occur if the device tree is
misconfigured (e.g. when QSGMII is selected on two lanes but there is
only one QSGMII controller).
- Split PLL drivers off into their own file
- Add clock for "ext_dly" instead of writing the bit directly (and
racing with any clock code).
- Use kasprintf instead of open-coding the snprintf dance
- Support 1000BASE-KX in lynx_lookup_proto. This still requires PCS
support, so nothing is truly "enabled" yet.
- Describe modes in device tree
- ls1088a: Add serdes bindings
Changes in v2:
- Rename to fsl,lynx-10g.yaml
- Refer to the device in the documentation, rather than the binding
- Move compatible first
- Document phy cells in the description
- Allow a value of 1 for phy-cells. This allows for compatibility with
the similar (but according to Ioana Ciornei different enough) lynx-28g
binding.
- Remove minItems
- Use list for clock-names
- Fix example binding having too many cells in regs
- Add #clock-cells. This will allow using assigned-clocks* to configure
the PLLs.
- Document the structure of the compatible strings
- Rename driver to Lynx 10G (etc.)
- Fix not clearing group->pll after disabling it
- Support 1 and 2 phy-cells
- Power off lanes during probe
- Clear SGMIIaCR1_PCS_EN during probe
- Rename LYNX_PROTO_UNKNOWN to LYNX_PROTO_NONE
- Handle 1000BASE-KX in lynx_proto_mode_prep
- Use one phy cell for SerDes1, since no lanes can be grouped
- Disable SerDes by default to prevent breaking boards inadvertently.
Sean Anderson (10):
dt-bindings: phy: Add 2500BASE-X and 10GBASE-R
dt-bindings: phy: Add Lynx 10G phy binding
dt-bindings: clock: Add ids for Lynx 10g PLLs
clk: Add Lynx 10G SerDes PLL driver
phy: fsl: Add Lynx 10G SerDes driver
arm64: dts: ls1046a: Add serdes bindings
arm64: dts: ls1046ardb: Add serdes bindings
arm64: dts: ls1088a: Add serdes bindings
arm64: dts: ls1088a: Prevent PCSs from probing as phys
arm64: dts: ls1088ardb: Add serdes bindings
.../devicetree/bindings/phy/fsl,lynx-10g.yaml | 248 ++++
Documentation/driver-api/phy/index.rst | 1 +
Documentation/driver-api/phy/lynx_10g.rst | 58 +
MAINTAINERS | 9 +
.../boot/dts/freescale/fsl-ls1046a-rdb.dts | 112 ++
.../arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 18 +
.../boot/dts/freescale/fsl-ls1088a-rdb.dts | 162 ++-
.../arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 48 +-
drivers/clk/Makefile | 1 +
drivers/clk/clk-fsl-lynx-10g.c | 509 +++++++
drivers/phy/freescale/Kconfig | 23 +
drivers/phy/freescale/Makefile | 1 +
drivers/phy/freescale/phy-fsl-lynx-10g.c | 1224 +++++++++++++++++
include/dt-bindings/clock/fsl,lynx-10g.h | 14 +
include/dt-bindings/phy/phy.h | 2 +
include/linux/phy/lynx-10g.h | 16 +
16 files changed, 2434 insertions(+), 12 deletions(-)
create mode 100644 Documentation/devicetree/bindings/phy/fsl,lynx-10g.yaml
create mode 100644 Documentation/driver-api/phy/lynx_10g.rst
create mode 100644 drivers/clk/clk-fsl-lynx-10g.c
create mode 100644 drivers/phy/freescale/phy-fsl-lynx-10g.c
create mode 100644 include/dt-bindings/clock/fsl,lynx-10g.h
create mode 100644 include/linux/phy/lynx-10g.h
--
2.35.1.1320.gc452695387.dirty
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v9 02/10] dt-bindings: phy: Add Lynx 10G phy binding
2022-12-30 0:01 [PATCH v9 00/10] phy: Add support for Lynx 10G SerDes Sean Anderson
@ 2022-12-30 0:01 ` Sean Anderson
2023-01-12 20:37 ` Rob Herring
2022-12-30 0:01 ` [PATCH v9 03/10] dt-bindings: clock: Add ids for Lynx 10g PLLs Sean Anderson
` (2 subsequent siblings)
3 siblings, 1 reply; 13+ messages in thread
From: Sean Anderson @ 2022-12-30 0:01 UTC (permalink / raw)
To: Vinod Koul, Kishon Vijay Abraham I, linux-phy
Cc: linux-arm-kernel, Camelia Alexandra Groza, Madalin Bucur,
Bagas Sanjaya, Rob Herring, Ioana Ciornei, linuxppc-dev,
devicetree, Krzysztof Kozlowski, Sean Anderson, Michael Turquette,
Stephen Boyd, linux-clk
This adds a binding for the SerDes module found on QorIQ processors.
Each phy is a subnode of the top-level device, possibly supporting
multiple lanes and protocols. This "thick" #phy-cells is used due to
allow for better organization of parameters. Note that the particular
parameters necessary to select a protocol-controller/lane combination
vary across different SoCs, and even within different SerDes on the same
SoC.
The driver is designed to be able to completely reconfigure lanes at
runtime. Generally, the phy consumer can select the appropriate
protocol using set_mode.
There are two PLLs, each of which can be used as the master clock for
each lane. Each PLL has its own reference. For the moment they are
required, because it simplifies the driver implementation. Absent
reference clocks can be modeled by a fixed-clock with a rate of 0.
Signed-off-by: Sean Anderson <sean.anderson@seco.com>
---
Changes in v9:
- Add fsl,unused-lanes-reserved to allow for a gradual transition
between firmware and Linux control of the SerDes
- Change phy-type back to fsl,type, as I was getting the error
'#phy-cells' is a dependency of 'phy-type'
Changes in v7:
- Use double quotes everywhere in yaml
Changes in v6:
- fsl,type -> phy-type
Changes in v4:
- Use subnodes to describe lane configuration, instead of describing
PCCRs. This is the same style used by phy-cadence-sierra et al.
Changes in v3:
- Manually expand yaml references
- Add mode configuration to device tree
Changes in v2:
- Rename to fsl,lynx-10g.yaml
- Refer to the device in the documentation, rather than the binding
- Move compatible first
- Document phy cells in the description
- Allow a value of 1 for phy-cells. This allows for compatibility with
the similar (but according to Ioana Ciornei different enough) lynx-28g
binding.
- Remove minItems
- Use list for clock-names
- Fix example binding having too many cells in regs
- Add #clock-cells. This will allow using assigned-clocks* to configure
the PLLs.
- Document the structure of the compatible strings
.../devicetree/bindings/phy/fsl,lynx-10g.yaml | 248 ++++++++++++++++++
1 file changed, 248 insertions(+)
create mode 100644 Documentation/devicetree/bindings/phy/fsl,lynx-10g.yaml
diff --git a/Documentation/devicetree/bindings/phy/fsl,lynx-10g.yaml b/Documentation/devicetree/bindings/phy/fsl,lynx-10g.yaml
new file mode 100644
index 000000000000..7c364f7de85c
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/fsl,lynx-10g.yaml
@@ -0,0 +1,248 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/fsl,lynx-10g.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP Lynx 10G SerDes
+
+maintainers:
+ - Sean Anderson <sean.anderson@seco.com>
+
+description: |
+ These Lynx "SerDes" devices are found in NXP's QorIQ line of processors. The
+ SerDes provides up to eight lanes. Each lane may be configured individually,
+ or may be combined with adjacent lanes for a multi-lane protocol. The SerDes
+ supports a variety of protocols, including up to 10G Ethernet, PCIe, SATA, and
+ others. The specific protocols supported for each lane depend on the
+ particular SoC.
+
+properties:
+ compatible:
+ items:
+ - enum:
+ - fsl,ls1046a-serdes
+ - fsl,ls1088a-serdes
+ - const: fsl,lynx-10g
+
+ "#address-cells":
+ const: 1
+
+ "#size-cells":
+ const: 0
+
+ "#clock-cells":
+ const: 1
+ description: |
+ The cell contains an ID as described in dt-bindings/clock/fsl,lynx-10g.h.
+ Note that when assigning a rate to a PLL, the PLL's rate is divided by
+ 1000 to avoid overflow. A rate of 5000000 corresponds to 5GHz.
+
+ clocks:
+ maxItems: 2
+ description: |
+ Clock for each PLL reference clock input.
+
+ clock-names:
+ minItems: 2
+ maxItems: 2
+ items:
+ enum:
+ - ref0
+ - ref1
+
+ fsl,unused-lanes-reserved:
+ $ref: /schemas/types.yaml#/definitions/flag
+ description: |
+ Unused lanes are reserved for firmware use, and should not be disabled.
+ Normally, groups containing unused lanes may be reconfigured or disabled
+ to save power. However, when this property is present, unused lanes will
+ not be touched until they are used by another driver. This allows
+ migrating from firmware control of lanes to driver control.
+
+ Lanes not present in any group will never be modified, regardless of the
+ presence of this property.
+
+ reg:
+ maxItems: 1
+
+patternProperties:
+ "^phy@":
+ type: object
+
+ description: |
+ A contiguous group of lanes which will be configured together. Each group
+ corresponds to one phy device. Lanes not described by any group will be
+ left as-is.
+
+ properties:
+ "#phy-cells":
+ const: 0
+
+ reg:
+ minItems: 1
+ maxItems: 8
+ description:
+ The lanes in the group. These must be listed in order. The first lane
+ will have the FIRST_LANE bit set in GCR0. The order of lanes also
+ determines the reset order (TRSTDIR).
+
+ patternProperties:
+ "^(q?sgmii|xfi)":
+ type: object
+
+ description: |
+ A protocol controller which may control the group of lanes. Each
+ controller is selected through the PCCRs. In addition to protocols
+ desired for use by the OS, protocols which may have been configured
+ by the bootloader must also be described. This ensures that only one
+ protocol controller is attached to a group of lanes at once.
+
+ properties:
+ fsl,pccr:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ The index of the PCCR which configures this protocol controller.
+ This is the same as the register name suffix. For example, PCCR8
+ would use a value of 8 for an offset of 0x220 (0x200 + 4 * 8).
+
+ fsl,index:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ The index of the protocol controller. This corresponds to the
+ suffix in the documentation. For example, PEXa would be 0, PEXb
+ 1, etc. Generally, higher fields occupy lower bits.
+
+ fsl,cfg:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 1
+ description: |
+ The configuration value to program into the protocol controller
+ field.
+
+ fsl,type:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum:
+ - 8 # PHY_TYPE_SGMII
+ - 9 # PHY_TYPE_QSGMII
+ - 13 # PHY_TYPE_2500BASEX
+ - 14 # PHY_TYPE_10GBASER
+ description: |
+ The category of protocols supported by this controller. See
+ "dt-bindings/phy/phy.h" for the relevant definitions. Individual
+ protocols are selected by the phy consumer. The availability of
+ 1000BASE-KX and 10GBASE-KR depends on the SoC.
+
+ - PHY_TYPE_SGMII: 1000BASE-X, SGMII, and 1000BASE-KX
+ - PHY_TYPE_2500BASEX: 2500BASE-X, 1000BASE-X, SGMII, and
+ 1000BASE-KX
+ - PHY_TYPE_QSGMII: QSGMII
+ - PHY_TYPE_10GBASER: 10GBASE-R and 10GBASE-KR
+
+ required:
+ - fsl,pccr
+ - fsl,index
+ - fsl,cfg
+ - fsl,type
+
+ additionalProperties: false
+
+ required:
+ - "#phy-cells"
+ - reg
+
+ additionalProperties: false
+
+required:
+ - "#address-cells"
+ - "#clock-cells"
+ - "#size-cells"
+ - compatible
+ - clocks
+ - clock-names
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/phy/phy.h>
+
+ serdes1: serdes@1ea0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #clock-cells = <1>;
+ compatible = "fsl,ls1046a-serdes", "fsl,lynx-10g";
+ reg = <0x1ea0000 0x2000>;
+ clocks = <&clk_100mhz>, <&clk_156mhz>;
+ clock-names = "ref0", "ref1";
+
+ serdes1_0: phy@0 {
+ #phy-cells = <0>;
+ reg = <0>;
+
+ /* SGMII.6 */
+ sgmii-0 {
+ fsl,pccr = <0x8>;
+ fsl,index = <0>;
+ fsl,cfg = <0x1>;
+ fsl,type = <PHY_TYPE_SGMII>;
+ };
+ };
+
+ serdes1_1: phy@1 {
+ #phy-cells = <0>;
+ reg = <1>;
+
+ /* SGMII.5 */
+ sgmii-1 {
+ fsl,pccr = <0x8>;
+ fsl,index = <1>;
+ fsl,cfg = <0x1>;
+ fsl,type = <PHY_TYPE_2500BASEX>;
+ };
+ };
+
+ serdes1_2: phy@2 {
+ #phy-cells = <0>;
+ reg = <2>;
+
+ /* SGMII.10 */
+ sgmii-2 {
+ fsl,pccr = <0x8>;
+ fsl,index = <2>;
+ fsl,cfg = <0x1>;
+ fsl,type = <PHY_TYPE_2500BASEX>;
+ };
+
+ /* XFI.10 */
+ xfi-0 {
+ fsl,pccr = <0xb>;
+ fsl,index = <0>;
+ fsl,cfg = <0x2>;
+ fsl,type = <PHY_TYPE_10GBASER>;
+ };
+ };
+
+ serdes1_3: phy@3 {
+ #phy-cells = <0>;
+ reg = <3>;
+
+ /* SGMII.9 */
+ sgmii-3 {
+ fsl,pccr = <0x8>;
+ fsl,index = <3>;
+ fsl,cfg = <0x1>;
+ fsl,type = <PHY_TYPE_2500BASEX>;
+ };
+
+ /* XFI.9 */
+ xfi-1 {
+ fsl,pccr = <0xb>;
+ fsl,index = <1>;
+ fsl,cfg = <0x1>;
+ fsl,type = <PHY_TYPE_10GBASER>;
+ };
+ };
+ };
+...
--
2.35.1.1320.gc452695387.dirty
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v9 03/10] dt-bindings: clock: Add ids for Lynx 10g PLLs
2022-12-30 0:01 [PATCH v9 00/10] phy: Add support for Lynx 10G SerDes Sean Anderson
2022-12-30 0:01 ` [PATCH v9 02/10] dt-bindings: phy: Add Lynx 10G phy binding Sean Anderson
@ 2022-12-30 0:01 ` Sean Anderson
2022-12-30 0:01 ` [PATCH v9 04/10] clk: Add Lynx 10G SerDes PLL driver Sean Anderson
2023-01-17 16:46 ` [PATCH v9 00/10] phy: Add support for Lynx 10G SerDes Sean Anderson
3 siblings, 0 replies; 13+ messages in thread
From: Sean Anderson @ 2022-12-30 0:01 UTC (permalink / raw)
To: Vinod Koul, Kishon Vijay Abraham I, linux-phy
Cc: linux-arm-kernel, Camelia Alexandra Groza, Madalin Bucur,
Bagas Sanjaya, Rob Herring, Ioana Ciornei, linuxppc-dev,
devicetree, Krzysztof Kozlowski, Sean Anderson, Rob Herring,
Michael Turquette, Stephen Boyd, linux-clk
This adds ids for the Lynx 10g SerDes's internal PLLs. These may be used
with assigned-clock* to specify a particular frequency to use. For
example, to set the second PLL (at offset 0x20)'s frequency, use
LYNX10G_PLLa(1). These are for use only in the device tree, and are not
otherwise used by the driver.
Signed-off-by: Sean Anderson <sean.anderson@seco.com>
Acked-by: Rob Herring <robh@kernel.org>
---
(no changes since v6)
Changes in v6:
- frequence -> frequency
Changes in v5:
- Update commit description
- Dual id header
Changes in v4:
- New
include/dt-bindings/clock/fsl,lynx-10g.h | 14 ++++++++++++++
1 file changed, 14 insertions(+)
create mode 100644 include/dt-bindings/clock/fsl,lynx-10g.h
diff --git a/include/dt-bindings/clock/fsl,lynx-10g.h b/include/dt-bindings/clock/fsl,lynx-10g.h
new file mode 100644
index 000000000000..15362ae85304
--- /dev/null
+++ b/include/dt-bindings/clock/fsl,lynx-10g.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
+/*
+ * Copyright (C) 2022 Sean Anderson <sean.anderson@seco.com>
+ */
+
+#ifndef __DT_BINDINGS_CLK_LYNX_10G_H
+#define __DT_BINDINGS_CLK_LYNX_10G_H
+
+#define LYNX10G_CLKS_PER_PLL 2
+
+#define LYNX10G_PLLa(a) ((a) * LYNX10G_CLKS_PER_PLL)
+#define LYNX10G_PLLa_EX_DLY(a) ((a) * LYNX10G_CLKS_PER_PLL + 1)
+
+#endif /* __DT_BINDINGS_CLK_LYNX_10G_H */
--
2.35.1.1320.gc452695387.dirty
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v9 04/10] clk: Add Lynx 10G SerDes PLL driver
2022-12-30 0:01 [PATCH v9 00/10] phy: Add support for Lynx 10G SerDes Sean Anderson
2022-12-30 0:01 ` [PATCH v9 02/10] dt-bindings: phy: Add Lynx 10G phy binding Sean Anderson
2022-12-30 0:01 ` [PATCH v9 03/10] dt-bindings: clock: Add ids for Lynx 10g PLLs Sean Anderson
@ 2022-12-30 0:01 ` Sean Anderson
2023-01-27 20:59 ` Stephen Boyd
2023-01-17 16:46 ` [PATCH v9 00/10] phy: Add support for Lynx 10G SerDes Sean Anderson
3 siblings, 1 reply; 13+ messages in thread
From: Sean Anderson @ 2022-12-30 0:01 UTC (permalink / raw)
To: Vinod Koul, Kishon Vijay Abraham I, linux-phy
Cc: linux-arm-kernel, Camelia Alexandra Groza, Madalin Bucur,
Bagas Sanjaya, Rob Herring, Ioana Ciornei, linuxppc-dev,
devicetree, Krzysztof Kozlowski, Sean Anderson, Michael Turquette,
Stephen Boyd, linux-clk
This adds support for the PLLs found in Lynx 10G "SerDes" devices found on
various NXP QorIQ SoCs. There are two PLLs in each SerDes. This driver has
been split from the main PHY driver to allow for better review, even though
these PLLs are not present anywhere else besides the SerDes. An auxiliary
device is not used as it offers no benefits over a function call (and there
is no need to have a separate device).
The PLLs are modeled as clocks proper to let us take advantage of the
existing clock infrastructure. I have not given the same treatment to the
per-lane clocks because they need to be programmed in-concert with the rest
of the lane settings. One tricky thing is that the VCO (PLL) rate exceeds
2^32 (maxing out at around 5GHz). This will be a problem on 32-bit
platforms, since clock rates are stored as unsigned longs. To work around
this, the pll clock rate is generally treated in units of kHz.
The PLLs are configured rather interestingly. Instead of the usual direct
programming of the appropriate divisors, the input and output clock rates
are selected directly. Generally, the only restriction is that the input
and output must be integer multiples of each other. This suggests some kind
of internal look-up table. The datasheets generally list out the supported
combinations explicitly, and not all input/output combinations are
documented. I'm not sure if this is due to lack of support, or due to an
oversight. If this becomes an issue, then some combinations can be
blacklisted (or whitelisted). This may also be necessary for other SoCs
which have more stringent clock requirements.
Signed-off-by: Sean Anderson <sean.anderson@seco.com>
---
Changes in v9:
- Convert some u32s to unsigned long to match arguments
- Switch from round_rate to determine_rate
- Drop explicit reference to reference clock
- Use .parent_names when requesting parents
- Use devm_clk_hw_get_clk to pass clocks back to serdes
- Fix indentation
- Split off from following patch to allow for better review
MAINTAINERS | 7 +
drivers/clk/Makefile | 1 +
drivers/clk/clk-fsl-lynx-10g.c | 509 +++++++++++++++++++++++++++++++++
drivers/phy/freescale/Kconfig | 6 +
include/linux/phy/lynx-10g.h | 16 ++
5 files changed, 539 insertions(+)
create mode 100644 drivers/clk/clk-fsl-lynx-10g.c
create mode 100644 include/linux/phy/lynx-10g.h
diff --git a/MAINTAINERS b/MAINTAINERS
index f61eb221415b..c2802d4e61a6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12274,6 +12274,13 @@ S: Maintained
W: http://linux-test-project.github.io/
T: git https://github.com/linux-test-project/ltp.git
+LYNX 10G SERDES DRIVER
+M: Sean Anderson <sean.anderson@seco.com>
+S: Maintained
+F: drivers/clk/clk-fsl-lynx-10g.c
+F: include/dt-bindings/clock/fsl,lynx-10g.h
+F: include/linux/phy/lynx-10g.h
+
LYNX 28G SERDES PHY DRIVER
M: Ioana Ciornei <ioana.ciornei@nxp.com>
L: netdev@vger.kernel.org
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index e3ca0d058a25..eebed69f6c58 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_ARCH_SPARX5) += clk-sparx5.o
obj-$(CONFIG_COMMON_CLK_EN7523) += clk-en7523.o
obj-$(CONFIG_COMMON_CLK_FIXED_MMIO) += clk-fixed-mmio.o
obj-$(CONFIG_COMMON_CLK_FSL_FLEXSPI) += clk-fsl-flexspi.o
+obj-$(CONFIG_PHY_FSL_LYNX_10G) += clk-fsl-lynx-10g.o
obj-$(CONFIG_COMMON_CLK_FSL_SAI) += clk-fsl-sai.o
obj-$(CONFIG_COMMON_CLK_GEMINI) += clk-gemini.o
obj-$(CONFIG_COMMON_CLK_ASPEED) += clk-aspeed.o
diff --git a/drivers/clk/clk-fsl-lynx-10g.c b/drivers/clk/clk-fsl-lynx-10g.c
new file mode 100644
index 000000000000..61f68b5ae675
--- /dev/null
+++ b/drivers/clk/clk-fsl-lynx-10g.c
@@ -0,0 +1,509 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 Sean Anderson <sean.anderson@seco.com>
+ *
+ * This file contains the implementation for the PLLs found on Lynx 10G phys.
+ *
+ * XXX: The VCO rate of the PLLs can exceed ~4GHz, which is the maximum rate
+ * expressable in an unsigned long. To work around this, rates are specified in
+ * kHz. This is as if there was a division by 1000 in the PLL.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/device.h>
+#include <linux/bitfield.h>
+#include <linux/math64.h>
+#include <linux/phy/lynx-10g.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/units.h>
+#include <dt-bindings/clock/fsl,lynx-10g.h>
+
+#define PLL_STRIDE 0x20
+#define PLLa(a, off) ((a) * PLL_STRIDE + (off))
+#define PLLaRSTCTL(a) PLLa(a, 0x00)
+#define PLLaCR0(a) PLLa(a, 0x04)
+
+#define PLLaRSTCTL_RSTREQ BIT(31)
+#define PLLaRSTCTL_RST_DONE BIT(30)
+#define PLLaRSTCTL_RST_ERR BIT(29)
+#define PLLaRSTCTL_PLLRST_B BIT(7)
+#define PLLaRSTCTL_SDRST_B BIT(6)
+#define PLLaRSTCTL_SDEN BIT(5)
+
+#define PLLaRSTCTL_ENABLE_SET (PLLaRSTCTL_RST_DONE | PLLaRSTCTL_PLLRST_B | \
+ PLLaRSTCTL_SDRST_B | PLLaRSTCTL_SDEN)
+#define PLLaRSTCTL_ENABLE_MASK (PLLaRSTCTL_ENABLE_SET | PLLaRSTCTL_RST_ERR)
+
+#define PLLaCR0_POFF BIT(31)
+#define PLLaCR0_RFCLK_SEL GENMASK(30, 28)
+#define PLLaCR0_PLL_LCK BIT(23)
+#define PLLaCR0_FRATE_SEL GENMASK(19, 16)
+#define PLLaCR0_DLYDIV_SEL GENMASK(1, 0)
+
+#define PLLaCR0_DLYDIV_SEL_16 0b01
+
+/**
+ * struct lynx_clk - Driver data for the PLLs
+ * @pll: The PLL clock
+ * @ex_dly: The "PLLa_ex_dly_clk" clock
+ * @dev: The serdes device
+ * @regmap: Our registers
+ * @idx: Which PLL this clock is for
+ */
+struct lynx_clk {
+ struct clk_hw pll, ex_dly;
+ struct device *dev;
+ struct regmap *regmap;
+ unsigned int idx;
+};
+
+static u32 lynx_read(struct lynx_clk *clk, u32 reg)
+{
+ unsigned int ret = 0;
+
+ WARN_ON_ONCE(regmap_read(clk->regmap, reg, &ret));
+ return ret;
+}
+
+static void lynx_write(struct lynx_clk *clk, u32 val, u32 reg)
+{
+ WARN_ON_ONCE(regmap_write(clk->regmap, reg, val));
+}
+
+static struct lynx_clk *lynx_pll_to_clk(struct clk_hw *hw)
+{
+ return container_of(hw, struct lynx_clk, pll);
+}
+
+static struct lynx_clk *lynx_ex_dly_to_clk(struct clk_hw *hw)
+{
+ return container_of(hw, struct lynx_clk, ex_dly);
+}
+
+static void lynx_pll_stop(struct lynx_clk *clk)
+{
+ u32 rstctl;
+
+ rstctl = lynx_read(clk, PLLaRSTCTL(clk->idx));
+ rstctl &= ~PLLaRSTCTL_SDRST_B;
+ lynx_write(clk, rstctl, PLLaRSTCTL(clk->idx));
+
+ ndelay(50);
+
+ rstctl = lynx_read(clk, PLLaRSTCTL(clk->idx));
+ rstctl &= ~(PLLaRSTCTL_SDEN | PLLaRSTCTL_PLLRST_B);
+ lynx_write(clk, rstctl, PLLaRSTCTL(clk->idx));
+
+ ndelay(100);
+}
+
+static void lynx_pll_disable(struct clk_hw *hw)
+{
+ struct lynx_clk *clk = lynx_pll_to_clk(hw);
+ u32 cr0;
+
+ dev_dbg(clk->dev, "disable pll%d\n", clk->idx);
+
+ lynx_pll_stop(clk);
+
+ cr0 = lynx_read(clk, PLLaCR0(clk->idx));
+ cr0 |= PLLaCR0_POFF;
+ lynx_write(clk, cr0, PLLaCR0(clk->idx));
+}
+
+static int lynx_pll_reset(struct lynx_clk *clk)
+{
+ int ret;
+ u32 rstctl = lynx_read(clk, PLLaRSTCTL(clk->idx));
+
+ rstctl |= PLLaRSTCTL_RSTREQ;
+ lynx_write(clk, rstctl, PLLaRSTCTL(clk->idx));
+ ret = read_poll_timeout(lynx_read, rstctl,
+ rstctl & (PLLaRSTCTL_RST_DONE | PLLaRSTCTL_RST_ERR),
+ 100, 5000, true, clk, PLLaRSTCTL(clk->idx));
+ if (rstctl & PLLaRSTCTL_RST_ERR)
+ ret = -EIO;
+ if (ret) {
+ dev_err(clk->dev, "pll%d reset failed\n", clk->idx);
+ return ret;
+ }
+
+ rstctl |= PLLaRSTCTL_SDEN | PLLaRSTCTL_PLLRST_B | PLLaRSTCTL_SDRST_B;
+ lynx_write(clk, rstctl, PLLaRSTCTL(clk->idx));
+ return 0;
+}
+
+static int lynx_pll_prepare(struct clk_hw *hw)
+{
+ struct lynx_clk *clk = lynx_pll_to_clk(hw);
+ u32 rstctl = lynx_read(clk, PLLaRSTCTL(clk->idx));
+ u32 cr0 = lynx_read(clk, PLLaCR0(clk->idx));
+
+ /*
+ * "Enabling" the PLL involves resetting it (and all attached lanes).
+ * Avoid doing this if we are already enabled.
+ */
+ if (!(cr0 & PLLaCR0_POFF) &&
+ (rstctl & PLLaRSTCTL_ENABLE_MASK) == PLLaRSTCTL_ENABLE_SET) {
+ dev_dbg(clk->dev, "pll%d already prepared\n", clk->idx);
+ return 0;
+ }
+
+ dev_dbg(clk->dev, "prepare pll%d\n", clk->idx);
+
+ cr0 &= ~PLLaCR0_POFF;
+ lynx_write(clk, cr0, PLLaCR0(clk->idx));
+
+ return lynx_pll_reset(clk);
+}
+
+static int lynx_pll_is_enabled(struct clk_hw *hw)
+{
+ struct lynx_clk *clk = lynx_pll_to_clk(hw);
+ u32 cr0 = lynx_read(clk, PLLaCR0(clk->idx));
+ bool enabled = !(cr0 & PLLaCR0_POFF);
+
+ dev_dbg(clk->dev, "pll%d %s enabled\n", clk->idx,
+ enabled ? "is" : "is not");
+
+ return enabled;
+}
+
+static const unsigned long rfclk_sel_map[8] = {
+ [0b000] = 100000000,
+ [0b001] = 125000000,
+ [0b010] = 156250000,
+ [0b011] = 150000000,
+};
+
+/**
+ * lynx_rfclk_to_sel() - Convert a reference clock rate to a selector
+ * @rate: The reference clock rate
+ *
+ * To allow for some variation in the reference clock rate, up to 100ppm of
+ * error is allowed.
+ *
+ * Return: An appropriate selector for @rate, or -%EINVAL.
+ */
+static int lynx_rfclk_to_sel(unsigned long rate)
+{
+ int ret;
+
+ for (ret = 0; ret < ARRAY_SIZE(rfclk_sel_map); ret++) {
+ unsigned long rfclk_rate = rfclk_sel_map[ret];
+ /* Allow an error of 100ppm */
+ unsigned long error = rfclk_rate / 10000;
+
+ if (abs(rate - rfclk_rate) < error)
+ return ret;
+ }
+
+ return -EINVAL;
+}
+
+static const unsigned long frate_sel_map[16] = {
+ [0b0000] = 5000000,
+ [0b0101] = 3750000,
+ [0b0110] = 5156250,
+ [0b0111] = 4000000,
+ [0b1001] = 3125000,
+ [0b1010] = 3000000,
+};
+
+/**
+ * lynx_frate_to_sel() - Convert a VCO clock rate to a selector
+ * @rate_khz: The VCO frequency, in kHz
+ *
+ * Return: An appropriate selector for @rate_khz, or -%EINVAL.
+ */
+static int lynx_frate_to_sel(unsigned long rate_khz)
+{
+ int ret;
+
+ for (ret = 0; ret < ARRAY_SIZE(frate_sel_map); ret++)
+ if (frate_sel_map[ret] == rate_khz)
+ return ret;
+
+ return -EINVAL;
+}
+
+static u32 lynx_pll_ratio(u32 frate_sel, u32 rfclk_sel)
+{
+ u64 frate;
+ u32 rfclk, error, ratio;
+
+ frate = frate_sel_map[frate_sel] * (u64)HZ_PER_KHZ;
+ rfclk = rfclk_sel_map[rfclk_sel];
+
+ if (!frate || !rfclk)
+ return 0;
+
+ ratio = div_u64_rem(frate, rfclk, &error);
+ if (!error)
+ return ratio;
+ return 0;
+}
+
+static unsigned long lynx_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct lynx_clk *clk = lynx_pll_to_clk(hw);
+ u32 cr0 = lynx_read(clk, PLLaCR0(clk->idx));
+ u32 frate_sel = FIELD_GET(PLLaCR0_FRATE_SEL, cr0);
+ u32 rfclk_sel = FIELD_GET(PLLaCR0_RFCLK_SEL, cr0);
+ u32 ratio = lynx_pll_ratio(frate_sel, rfclk_sel);
+ unsigned long ret;
+
+ /* Ensure that the parent matches our rfclk selector */
+ if (rfclk_sel == lynx_rfclk_to_sel(parent_rate))
+ ret = mult_frac(parent_rate, ratio, HZ_PER_KHZ);
+ else
+ ret = 0;
+
+ dev_dbg(clk->dev, "recalc pll%d new=%llu parent=%lu\n", clk->idx,
+ (u64)ret * HZ_PER_KHZ, parent_rate);
+ return ret;
+}
+
+static int lynx_pll_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+{
+ int frate_sel, rfclk_sel;
+ struct lynx_clk *clk = lynx_pll_to_clk(hw);
+ u32 ratio;
+
+ dev_dbg(clk->dev, "round pll%d new=%llu parent=%lu\n", clk->idx,
+ (u64)req->rate * HZ_PER_KHZ, req->best_parent_rate);
+
+ frate_sel = lynx_frate_to_sel(req->rate);
+ if (frate_sel < 0)
+ return frate_sel;
+
+ /* Try the current parent rate */
+ rfclk_sel = lynx_rfclk_to_sel(req->best_parent_rate);
+ if (rfclk_sel >= 0) {
+ ratio = lynx_pll_ratio(frate_sel, rfclk_sel);
+ if (ratio) {
+ req->rate = mult_frac(req->best_parent_rate, ratio,
+ HZ_PER_KHZ);
+ return 0;
+ }
+ }
+
+ /* Try all possible parent rates */
+ for (rfclk_sel = 0;
+ rfclk_sel < ARRAY_SIZE(rfclk_sel_map);
+ rfclk_sel++) {
+ unsigned long new_parent_rate;
+
+ ratio = lynx_pll_ratio(frate_sel, rfclk_sel);
+ if (!ratio)
+ continue;
+
+ /* Ensure the reference clock can produce this rate */
+ new_parent_rate = rfclk_sel_map[rfclk_sel];
+ new_parent_rate = clk_hw_round_rate(req->best_parent_hw,
+ new_parent_rate);
+ if (rfclk_sel != lynx_rfclk_to_sel(new_parent_rate))
+ continue;
+
+ req->rate = mult_frac(new_parent_rate, ratio, HZ_PER_KHZ);
+ req->best_parent_rate = new_parent_rate;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int lynx_pll_set_rate(struct clk_hw *hw, unsigned long rate_khz,
+ unsigned long parent_rate)
+{
+ int frate_sel, rfclk_sel;
+ struct lynx_clk *clk = lynx_pll_to_clk(hw);
+ u32 ratio, cr0 = lynx_read(clk, PLLaCR0(clk->idx));
+
+ dev_dbg(clk->dev, "set rate pll%d new=%llu parent=%lu\n", clk->idx,
+ (u64)rate_khz * HZ_PER_KHZ, parent_rate);
+
+ frate_sel = lynx_frate_to_sel(rate_khz);
+ if (frate_sel < 0)
+ return frate_sel;
+
+ rfclk_sel = lynx_rfclk_to_sel(parent_rate);
+ if (rfclk_sel < 0)
+ return rfclk_sel;
+
+ ratio = lynx_pll_ratio(frate_sel, rfclk_sel);
+ if (!ratio)
+ return -EINVAL;
+
+ lynx_pll_stop(clk);
+ cr0 &= ~(PLLaCR0_RFCLK_SEL | PLLaCR0_FRATE_SEL);
+ cr0 |= FIELD_PREP(PLLaCR0_RFCLK_SEL, rfclk_sel);
+ cr0 |= FIELD_PREP(PLLaCR0_FRATE_SEL, frate_sel);
+ lynx_write(clk, cr0, PLLaCR0(clk->idx));
+ /* Don't bother resetting if it's off */
+ if (cr0 & PLLaCR0_POFF)
+ return 0;
+ return lynx_pll_reset(clk);
+}
+
+static const struct clk_ops lynx_pll_clk_ops = {
+ .prepare = lynx_pll_prepare,
+ .disable = lynx_pll_disable,
+ .is_enabled = lynx_pll_is_enabled,
+ .recalc_rate = lynx_pll_recalc_rate,
+ .determine_rate = lynx_pll_determine_rate,
+ .set_rate = lynx_pll_set_rate,
+};
+
+static void lynx_ex_dly_disable(struct clk_hw *hw)
+{
+ struct lynx_clk *clk = lynx_ex_dly_to_clk(hw);
+ u32 cr0 = lynx_read(clk, PLLaCR0(clk->idx));
+
+ cr0 &= ~PLLaCR0_DLYDIV_SEL;
+ lynx_write(clk, PLLaCR0(clk->idx), cr0);
+}
+
+static int lynx_ex_dly_enable(struct clk_hw *hw)
+{
+ struct lynx_clk *clk = lynx_ex_dly_to_clk(hw);
+ u32 cr0 = lynx_read(clk, PLLaCR0(clk->idx));
+
+ cr0 &= ~PLLaCR0_DLYDIV_SEL;
+ cr0 |= FIELD_PREP(PLLaCR0_DLYDIV_SEL, PLLaCR0_DLYDIV_SEL_16);
+ lynx_write(clk, PLLaCR0(clk->idx), cr0);
+ return 0;
+}
+
+static int lynx_ex_dly_is_enabled(struct clk_hw *hw)
+{
+ struct lynx_clk *clk = lynx_ex_dly_to_clk(hw);
+
+ return lynx_read(clk, PLLaCR0(clk->idx)) & PLLaCR0_DLYDIV_SEL;
+}
+
+static unsigned long lynx_ex_dly_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ return parent_rate / 16;
+}
+
+static const struct clk_ops lynx_ex_dly_clk_ops = {
+ .enable = lynx_ex_dly_enable,
+ .disable = lynx_ex_dly_disable,
+ .is_enabled = lynx_ex_dly_is_enabled,
+ .recalc_rate = lynx_ex_dly_recalc_rate,
+};
+
+static int lynx_clk_init(struct clk_hw_onecell_data *hw_data,
+ struct device *dev, struct regmap *regmap,
+ unsigned int index)
+{
+ const struct clk_hw *ex_dly_parents;
+ struct clk_parent_data pll_parents[1] = { };
+ struct clk_init_data pll_init = {
+ .ops = &lynx_pll_clk_ops,
+ .parent_data = pll_parents,
+ .num_parents = 1,
+ .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT |
+ CLK_OPS_PARENT_ENABLE,
+ };
+ struct clk_init_data ex_dly_init = {
+ .ops = &lynx_ex_dly_clk_ops,
+ .parent_hws = &ex_dly_parents,
+ .num_parents = 1,
+ };
+ struct lynx_clk *clk;
+ int ret;
+
+ clk = devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL);
+ if (!clk)
+ return -ENOMEM;
+
+ clk->dev = dev;
+ clk->regmap = regmap;
+ clk->idx = index;
+
+ pll_parents[0].fw_name = kasprintf(GFP_KERNEL, "ref%d", index);
+ pll_init.name = kasprintf(GFP_KERNEL, "%s.pll%d_khz", dev_name(dev),
+ index);
+ ex_dly_init.name = kasprintf(GFP_KERNEL, "%s.pll%d_ex_dly_khz",
+ dev_name(dev), index);
+ if (!pll_parents[0].fw_name || !pll_init.name || !ex_dly_init.name) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ clk->pll.init = &pll_init;
+ ret = devm_clk_hw_register(dev, &clk->pll);
+ if (ret) {
+ dev_err_probe(dev, ret, "could not register %s\n",
+ pll_init.name);
+ goto out;
+ }
+
+ ex_dly_parents = &clk->pll;
+ clk->ex_dly.init = &ex_dly_init;
+ ret = devm_clk_hw_register(dev, &clk->ex_dly);
+ if (ret)
+ dev_err_probe(dev, ret, "could not register %s\n",
+ ex_dly_init.name);
+
+ hw_data->hws[LYNX10G_PLLa(index)] = &clk->pll;
+ hw_data->hws[LYNX10G_PLLa_EX_DLY(index)] = &clk->ex_dly;
+
+out:
+ kfree(pll_parents[0].fw_name);
+ kfree(pll_init.name);
+ kfree(ex_dly_init.name);
+ return ret;
+}
+
+#define NUM_PLLS 2
+#define NUM_CLKS (NUM_PLLS * LYNX10G_CLKS_PER_PLL)
+
+int lynx_clks_init(struct device *dev, struct regmap *regmap,
+ struct clk *plls[2], struct clk *ex_dlys[2])
+{
+ int ret, i;
+ struct clk_hw_onecell_data *hw_data;
+
+ hw_data = devm_kzalloc(dev, struct_size(hw_data, hws, NUM_CLKS),
+ GFP_KERNEL);
+ if (!hw_data)
+ return -ENOMEM;
+ hw_data->num = NUM_CLKS;
+
+ for (i = 0; i < NUM_PLLS; i++) {
+ ret = lynx_clk_init(hw_data, dev, regmap, i);
+ if (ret)
+ return ret;
+
+ plls[i] = devm_clk_hw_get_clk(dev,
+ hw_data->hws[LYNX10G_PLLa(i)],
+ NULL);
+ if (IS_ERR(plls[i]))
+ return PTR_ERR(plls[i]);
+
+ ex_dlys[i] = devm_clk_hw_get_clk(dev,
+ hw_data->hws[LYNX10G_PLLa_EX_DLY(i)],
+ NULL);
+ if (IS_ERR(ex_dlys[i]))
+ return PTR_ERR(plls[i]);
+ }
+
+ ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, hw_data);
+ if (ret)
+ dev_err_probe(dev, ret, "could not register clock provider\n");
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(lynx_clks_init);
+
+MODULE_AUTHOR("Sean Anderson <sean.anderson@seco.com>");
+MODULE_DESCRIPTION("Lynx 10G PLL driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig
index 853958fb2c06..5d461232276f 100644
--- a/drivers/phy/freescale/Kconfig
+++ b/drivers/phy/freescale/Kconfig
@@ -47,3 +47,9 @@ config PHY_FSL_LYNX_28G
found on NXP's Layerscape platforms such as LX2160A.
Used to change the protocol running on SerDes lanes at runtime.
Only useful for a restricted set of Ethernet protocols.
+
+config PHY_FSL_LYNX_10G
+ tristate
+ depends on COMMON_CLK
+ depends on ARCH_LAYERSCAPE || PPC || COMPILE_TEST
+ select REGMAP_MMIO
diff --git a/include/linux/phy/lynx-10g.h b/include/linux/phy/lynx-10g.h
new file mode 100644
index 000000000000..75d9353a867b
--- /dev/null
+++ b/include/linux/phy/lynx-10g.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2022 Sean Anderson <sean.anderson@seco.com>
+ */
+
+#ifndef LYNX_10G
+#define LYNX_10G
+
+struct clk;
+struct device;
+struct regmap;
+
+int lynx_clks_init(struct device *dev, struct regmap *regmap,
+ struct clk *plls[2], struct clk *ex_dlys[2]);
+
+#endif /* LYNX 10G */
--
2.35.1.1320.gc452695387.dirty
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v9 02/10] dt-bindings: phy: Add Lynx 10G phy binding
2022-12-30 0:01 ` [PATCH v9 02/10] dt-bindings: phy: Add Lynx 10G phy binding Sean Anderson
@ 2023-01-12 20:37 ` Rob Herring
0 siblings, 0 replies; 13+ messages in thread
From: Rob Herring @ 2023-01-12 20:37 UTC (permalink / raw)
To: Sean Anderson
Cc: Madalin Bucur, Stephen Boyd, Rob Herring, linuxppc-dev,
devicetree, Ioana Ciornei, Kishon Vijay Abraham I, linux-clk,
Vinod Koul, Krzysztof Kozlowski, Michael Turquette, linux-phy,
Camelia Alexandra Groza, linux-arm-kernel, Bagas Sanjaya
On Thu, 29 Dec 2022 19:01:31 -0500, Sean Anderson wrote:
> This adds a binding for the SerDes module found on QorIQ processors.
> Each phy is a subnode of the top-level device, possibly supporting
> multiple lanes and protocols. This "thick" #phy-cells is used due to
> allow for better organization of parameters. Note that the particular
> parameters necessary to select a protocol-controller/lane combination
> vary across different SoCs, and even within different SerDes on the same
> SoC.
>
> The driver is designed to be able to completely reconfigure lanes at
> runtime. Generally, the phy consumer can select the appropriate
> protocol using set_mode.
>
> There are two PLLs, each of which can be used as the master clock for
> each lane. Each PLL has its own reference. For the moment they are
> required, because it simplifies the driver implementation. Absent
> reference clocks can be modeled by a fixed-clock with a rate of 0.
>
> Signed-off-by: Sean Anderson <sean.anderson@seco.com>
> ---
>
> Changes in v9:
> - Add fsl,unused-lanes-reserved to allow for a gradual transition
> between firmware and Linux control of the SerDes
> - Change phy-type back to fsl,type, as I was getting the error
> '#phy-cells' is a dependency of 'phy-type'
>
> Changes in v7:
> - Use double quotes everywhere in yaml
>
> Changes in v6:
> - fsl,type -> phy-type
>
> Changes in v4:
> - Use subnodes to describe lane configuration, instead of describing
> PCCRs. This is the same style used by phy-cadence-sierra et al.
>
> Changes in v3:
> - Manually expand yaml references
> - Add mode configuration to device tree
>
> Changes in v2:
> - Rename to fsl,lynx-10g.yaml
> - Refer to the device in the documentation, rather than the binding
> - Move compatible first
> - Document phy cells in the description
> - Allow a value of 1 for phy-cells. This allows for compatibility with
> the similar (but according to Ioana Ciornei different enough) lynx-28g
> binding.
> - Remove minItems
> - Use list for clock-names
> - Fix example binding having too many cells in regs
> - Add #clock-cells. This will allow using assigned-clocks* to configure
> the PLLs.
> - Document the structure of the compatible strings
>
> .../devicetree/bindings/phy/fsl,lynx-10g.yaml | 248 ++++++++++++++++++
> 1 file changed, 248 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/phy/fsl,lynx-10g.yaml
>
Reviewed-by: Rob Herring <robh@kernel.org>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v9 00/10] phy: Add support for Lynx 10G SerDes
2022-12-30 0:01 [PATCH v9 00/10] phy: Add support for Lynx 10G SerDes Sean Anderson
` (2 preceding siblings ...)
2022-12-30 0:01 ` [PATCH v9 04/10] clk: Add Lynx 10G SerDes PLL driver Sean Anderson
@ 2023-01-17 16:46 ` Sean Anderson
2023-01-18 16:54 ` Vinod Koul
3 siblings, 1 reply; 13+ messages in thread
From: Sean Anderson @ 2023-01-17 16:46 UTC (permalink / raw)
To: Vinod Koul, Kishon Vijay Abraham I, linux-phy
Cc: linux-arm-kernel, Camelia Alexandra Groza, Madalin Bucur,
Bagas Sanjaya, Rob Herring, Ioana Ciornei, linuxppc-dev,
devicetree, Krzysztof Kozlowski, Jonathan Corbet, Li Yang,
Michael Turquette, Shawn Guo, Stephen Boyd, linux-clk, linux-doc
On 12/29/22 19:01, Sean Anderson wrote:
> This adds support for the Lynx 10G SerDes found on the QorIQ T-series
> and Layerscape series. Due to limited time and hardware, only support
> for the LS1046ARDB and LS1088ARDB is added in this initial series.
>
> This series is based on phy/next, but it requires phylink support. This
> is already present for the LS1088A, and it was recently added for the
> LS1046A in net-next/master.
>
> Major reconfiguration of baud rate (e.g. 1G->10G) does not work. From my
> testing, SerDes register settings appear identical. The issue appears to
> be between the PCS and the MAC. The link itself comes up at both ends,
> and a mac loopback succeeds. However, a PCS loopback results in dropped
> packets. Perhaps there is some undocumented register in the PCS?
>
> I suspect this driver is around 95% complete, but I don't have the
> documentation to make it work completely. At the very least it is useful
> for two cases:
>
> - Although this is untested, it should support 2.5G SGMII as well as
> 1000BASE-KX. The latter needs MAC and PCS support, but the former
> should work out of the box.
> - It allows for clock configurations not supported by the RCW. This is
> very useful if you want to use e.g. SRDS_PRTCL_S1=0x3333 and =0x1133
> on the same board. This is because the former setting will use PLL1
> as the 1G reference, but the latter will use PLL1 as the 10G
> reference. Because we can reconfigure the PLLs, it is possible to
> always use PLL1 as the 1G reference.
>
> The final patch in this series depends on [1].
>
> [1] https://lore.kernel.org/netdev/20221227230918.2440351-1-sean.anderson@seco.com/
>
> Changes in v9:
> - Add fsl,unused-lanes-reserved to allow for a gradual transition
> between firmware and Linux control of the SerDes
> - Change phy-type back to fsl,type, as I was getting the error
> '#phy-cells' is a dependency of 'phy-type'
> - Convert some u32s to unsigned long to match arguments
> - Switch from round_rate to determine_rate
> - Drop explicit reference to reference clock
> - Use .parent_names when requesting parents
> - Use devm_clk_hw_get_clk to pass clocks back to serdes
> - Fix indentation
> - Split off clock "driver" into its own patch to allow for better
> review.
> - Add ability to defer lane initialization to phy_init. This allows
> for easier transitioning between firmware-managed serdes and Linux-
> managed serdes, as the consumer (such as dpaa2, which knows what the
> firmware is doing) has the last say on who gets control.
> - Fix name of phy mode node
> - Add fsl,unused-lanes-reserved to allow a gradual transition, depending
> on the mac link type.
> - Remove unused clocks
> - Fix some phy mode node names
>
> Changes in v8:
> - Remove unused variable from lynx_ls_mode_init
> - Rename serdes phy handles to use _A, _B, etc. instead of _0, _1, etc.
> This should help remind readers that the numbering corresponds to the
> physical layout of the registers, and not the lane (pin) number.
> - Prevent PCSs from probing as phys
> - Rename serdes phy handles like the LS1046A
> - Add SFP slot binding
> - Fix incorrect lane ordering (it's backwards on the LS1088A just like it is in
> the LS1046A).
> - Fix duplicated lane 2 (it should have been lane 3).
> - Fix incorrectly-documented value for XFI1.
> - Remove interrupt for aquantia phy. It never fired for whatever reason,
> preventing the link from coming up.
> - Add GPIOs for QIXIS FPGA.
> - Enable MAC1 PCS
> - Remove si5341 binding
>
> Changes in v7:
> - Use double quotes everywhere in yaml
> - Break out call order into generic documentation
> - Refuse to switch "major" protocols
> - Update Kconfig to reflect restrictions
> - Remove set/clear of "pcs reset" bit, since it doesn't seem to fix
> anything.
>
> Changes in v6:
> - Bump PHY_TYPE_2500BASEX to 13, since PHY_TYPE_USXGMII was added in the
> meantime
> - fsl,type -> phy-type
> - frequence -> frequency
> - Update MAINTAINERS to include new files
> - Include bitfield.h and slab.h to allow compilation on non-arm64
> arches.
> - Depend on COMMON_CLK and either layerscape/ppc
> - XGI.9 -> XFI.9
>
> Changes in v5:
> - Update commit description
> - Dual id header
> - Remove references to PHY_INTERFACE_MODE_1000BASEKX to allow this
> series to be applied directly to linux/master.
> - Add fsl,lynx-10g.h to MAINTAINERS
>
> Changes in v4:
> - Add 2500BASE-X and 10GBASE-R phy types
> - Use subnodes to describe lane configuration, instead of describing
> PCCRs. This is the same style used by phy-cadence-sierra et al.
> - Add ids for Lynx 10g PLLs
> - Rework all debug statements to remove use of __func__. Additional
> information has been provided as necessary.
> - Consider alternative parent rates in round_rate and not in set_rate.
> Trying to modify out parent's rate in set_rate will deadlock.
> - Explicitly perform a stop/reset sequence in set_rate. This way we
> always ensure that the PLL is properly stopped.
> - Set the power-down bit when disabling the PLL. We can do this now that
> enable/disable aren't abused during the set rate sequence.
> - Fix typos in QSGMII_OFFSET and XFI_OFFSET
> - Rename LNmTECR0_TEQ_TYPE_PRE to LNmTECR0_TEQ_TYPE_POST to better
> reflect its function (adding post-cursor equalization).
> - Use of_clk_hw_onecell_get instead of a custom function.
> - Return struct clks from lynx_clks_init instead of embedding lynx_clk
> in lynx_priv.
> - Rework PCCR helper functions; T-series SoCs differ from Layerscape SoCs
> primarily in the layout and offset of the PCCRs. This will help bring a
> cleaner abstraction layer. The caps have been removed, since this handles the
> only current usage.
> - Convert to use new binding format. As a result of this, we no longer need to
> have protocols for PCIe or SATA. Additionally, modes now live in lynx_group
> instead of lynx_priv.
> - Remove teq from lynx_proto_params, since it can be determined from
> preq_ratio/postq_ratio.
> - Fix an early return from lynx_set_mode not releasing serdes->lock.
> - Rename lynx_priv.conf to .cfg, since I kept mistyping it.
>
> Changes in v3:
> - Manually expand yaml references
> - Add mode configuration to device tree
> - Rename remaining references to QorIQ SerDes to Lynx 10G
> - Fix PLL enable sequence by waiting for our reset request to be cleared
> before continuing. Do the same for the lock, even though it isn't as
> critical. Because we will delay for 1.5ms on average, use prepare
> instead of enable so we can sleep.
> - Document the status of each protocol
> - Fix offset of several bitfields in RECR0
> - Take into account PLLRST_B, SDRST_B, and SDEN when considering whether
> a PLL is "enabled."
> - Only power off unused lanes.
> - Split mode lane mask into first/last lane (like group)
> - Read modes from device tree
> - Use caps to determine whether KX/KR are supported
> - Move modes to lynx_priv
> - Ensure that the protocol controller is not already in-use when we try
> to configure a new mode. This should only occur if the device tree is
> misconfigured (e.g. when QSGMII is selected on two lanes but there is
> only one QSGMII controller).
> - Split PLL drivers off into their own file
> - Add clock for "ext_dly" instead of writing the bit directly (and
> racing with any clock code).
> - Use kasprintf instead of open-coding the snprintf dance
> - Support 1000BASE-KX in lynx_lookup_proto. This still requires PCS
> support, so nothing is truly "enabled" yet.
> - Describe modes in device tree
> - ls1088a: Add serdes bindings
>
> Changes in v2:
> - Rename to fsl,lynx-10g.yaml
> - Refer to the device in the documentation, rather than the binding
> - Move compatible first
> - Document phy cells in the description
> - Allow a value of 1 for phy-cells. This allows for compatibility with
> the similar (but according to Ioana Ciornei different enough) lynx-28g
> binding.
> - Remove minItems
> - Use list for clock-names
> - Fix example binding having too many cells in regs
> - Add #clock-cells. This will allow using assigned-clocks* to configure
> the PLLs.
> - Document the structure of the compatible strings
> - Rename driver to Lynx 10G (etc.)
> - Fix not clearing group->pll after disabling it
> - Support 1 and 2 phy-cells
> - Power off lanes during probe
> - Clear SGMIIaCR1_PCS_EN during probe
> - Rename LYNX_PROTO_UNKNOWN to LYNX_PROTO_NONE
> - Handle 1000BASE-KX in lynx_proto_mode_prep
> - Use one phy cell for SerDes1, since no lanes can be grouped
> - Disable SerDes by default to prevent breaking boards inadvertently.
>
> Sean Anderson (10):
> dt-bindings: phy: Add 2500BASE-X and 10GBASE-R
> dt-bindings: phy: Add Lynx 10G phy binding
> dt-bindings: clock: Add ids for Lynx 10g PLLs
> clk: Add Lynx 10G SerDes PLL driver
> phy: fsl: Add Lynx 10G SerDes driver
> arm64: dts: ls1046a: Add serdes bindings
> arm64: dts: ls1046ardb: Add serdes bindings
> arm64: dts: ls1088a: Add serdes bindings
> arm64: dts: ls1088a: Prevent PCSs from probing as phys
> arm64: dts: ls1088ardb: Add serdes bindings
>
> .../devicetree/bindings/phy/fsl,lynx-10g.yaml | 248 ++++
> Documentation/driver-api/phy/index.rst | 1 +
> Documentation/driver-api/phy/lynx_10g.rst | 58 +
> MAINTAINERS | 9 +
> .../boot/dts/freescale/fsl-ls1046a-rdb.dts | 112 ++
> .../arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 18 +
> .../boot/dts/freescale/fsl-ls1088a-rdb.dts | 162 ++-
> .../arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 48 +-
> drivers/clk/Makefile | 1 +
> drivers/clk/clk-fsl-lynx-10g.c | 509 +++++++
> drivers/phy/freescale/Kconfig | 23 +
> drivers/phy/freescale/Makefile | 1 +
> drivers/phy/freescale/phy-fsl-lynx-10g.c | 1224 +++++++++++++++++
> include/dt-bindings/clock/fsl,lynx-10g.h | 14 +
> include/dt-bindings/phy/phy.h | 2 +
> include/linux/phy/lynx-10g.h | 16 +
> 16 files changed, 2434 insertions(+), 12 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/phy/fsl,lynx-10g.yaml
> create mode 100644 Documentation/driver-api/phy/lynx_10g.rst
> create mode 100644 drivers/clk/clk-fsl-lynx-10g.c
> create mode 100644 drivers/phy/freescale/phy-fsl-lynx-10g.c
> create mode 100644 include/dt-bindings/clock/fsl,lynx-10g.h
> create mode 100644 include/linux/phy/lynx-10g.h
>
I noticed that this series is marked "changes requested" on patchwork.
However, I have received only automated feedback. I have done my best
effort to address feedback I have received on prior revisions. I would
appreciate getting another round of review before resending this series.
--Sean
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v9 00/10] phy: Add support for Lynx 10G SerDes
2023-01-17 16:46 ` [PATCH v9 00/10] phy: Add support for Lynx 10G SerDes Sean Anderson
@ 2023-01-18 16:54 ` Vinod Koul
2023-01-19 16:22 ` Sean Anderson
0 siblings, 1 reply; 13+ messages in thread
From: Vinod Koul @ 2023-01-18 16:54 UTC (permalink / raw)
To: Sean Anderson
Cc: Kishon Vijay Abraham I, linux-phy, linux-arm-kernel,
Camelia Alexandra Groza, Madalin Bucur, Bagas Sanjaya,
Rob Herring, Ioana Ciornei, linuxppc-dev, devicetree,
Krzysztof Kozlowski, Jonathan Corbet, Li Yang, Michael Turquette,
Shawn Guo, Stephen Boyd, linux-clk, linux-doc
On 17-01-23, 11:46, Sean Anderson wrote:
>
> I noticed that this series is marked "changes requested" on patchwork.
> However, I have received only automated feedback. I have done my best
> effort to address feedback I have received on prior revisions. I would
> appreciate getting another round of review before resending this series.
Looking at the series, looks like kernel-bot sent some warnings on the
series so I was expecting an updated series for review
--
~Vinod
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v9 00/10] phy: Add support for Lynx 10G SerDes
2023-01-18 16:54 ` Vinod Koul
@ 2023-01-19 16:22 ` Sean Anderson
2023-01-20 8:06 ` Vinod Koul
0 siblings, 1 reply; 13+ messages in thread
From: Sean Anderson @ 2023-01-19 16:22 UTC (permalink / raw)
To: Vinod Koul
Cc: Kishon Vijay Abraham I, linux-phy, linux-arm-kernel,
Camelia Alexandra Groza, Madalin Bucur, Bagas Sanjaya,
Rob Herring, Ioana Ciornei, linuxppc-dev, devicetree,
Krzysztof Kozlowski, Jonathan Corbet, Li Yang, Michael Turquette,
Shawn Guo, Stephen Boyd, linux-clk, linux-doc
On 1/18/23 11:54, Vinod Koul wrote:
> On 17-01-23, 11:46, Sean Anderson wrote:
>>
>> I noticed that this series is marked "changes requested" on patchwork.
>> However, I have received only automated feedback. I have done my best
>> effort to address feedback I have received on prior revisions. I would
>> appreciate getting another round of review before resending this series.
>
> Looking at the series, looks like kernel-bot sent some warnings on the
> series so I was expecting an updated series for review
>
Generally, multiple reviewers will comment on a patch, even if another
reviewer finds something which needs to be changed. This is a one-line
fix, so I would appreciate getting more substantial feedback before
respinning. Every time I send a new series I have to rebase and test on
hardware. It's work that I would rather do when there is something to be
gained.
--Sean
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v9 00/10] phy: Add support for Lynx 10G SerDes
2023-01-19 16:22 ` Sean Anderson
@ 2023-01-20 8:06 ` Vinod Koul
2023-01-20 16:43 ` Sean Anderson
0 siblings, 1 reply; 13+ messages in thread
From: Vinod Koul @ 2023-01-20 8:06 UTC (permalink / raw)
To: Sean Anderson
Cc: Kishon Vijay Abraham I, linux-phy, linux-arm-kernel,
Camelia Alexandra Groza, Madalin Bucur, Bagas Sanjaya,
Rob Herring, Ioana Ciornei, linuxppc-dev, devicetree,
Krzysztof Kozlowski, Jonathan Corbet, Li Yang, Michael Turquette,
Shawn Guo, Stephen Boyd, linux-clk, linux-doc
On 19-01-23, 11:22, Sean Anderson wrote:
> On 1/18/23 11:54, Vinod Koul wrote:
> > On 17-01-23, 11:46, Sean Anderson wrote:
> >>
> >> I noticed that this series is marked "changes requested" on patchwork.
> >> However, I have received only automated feedback. I have done my best
> >> effort to address feedback I have received on prior revisions. I would
> >> appreciate getting another round of review before resending this series.
> >
> > Looking at the series, looks like kernel-bot sent some warnings on the
> > series so I was expecting an updated series for review
> >
>
> Generally, multiple reviewers will comment on a patch, even if another
> reviewer finds something which needs to be changed. This is a one-line
> fix, so I would appreciate getting more substantial feedback before
> respinning. Every time I send a new series I have to rebase and test on
> hardware. It's work that I would rather do when there is something to be
> gained.
I review to apply, if I can apply, I would typically skip this
--
~Vinod
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v9 00/10] phy: Add support for Lynx 10G SerDes
2023-01-20 8:06 ` Vinod Koul
@ 2023-01-20 16:43 ` Sean Anderson
0 siblings, 0 replies; 13+ messages in thread
From: Sean Anderson @ 2023-01-20 16:43 UTC (permalink / raw)
To: Vinod Koul
Cc: Kishon Vijay Abraham I, linux-phy, linux-arm-kernel,
Camelia Alexandra Groza, Madalin Bucur, Bagas Sanjaya,
Rob Herring, Ioana Ciornei, linuxppc-dev, devicetree,
Krzysztof Kozlowski, Jonathan Corbet, Li Yang, Michael Turquette,
Shawn Guo, Stephen Boyd, linux-clk, linux-doc
On 1/20/23 03:06, Vinod Koul wrote:
> On 19-01-23, 11:22, Sean Anderson wrote:
>> On 1/18/23 11:54, Vinod Koul wrote:
>> > On 17-01-23, 11:46, Sean Anderson wrote:
>> >>
>> >> I noticed that this series is marked "changes requested" on patchwork.
>> >> However, I have received only automated feedback. I have done my best
>> >> effort to address feedback I have received on prior revisions. I would
>> >> appreciate getting another round of review before resending this series.
>> >
>> > Looking at the series, looks like kernel-bot sent some warnings on the
>> > series so I was expecting an updated series for review
>> >
>>
>> Generally, multiple reviewers will comment on a patch, even if another
>> reviewer finds something which needs to be changed. This is a one-line
>> fix, so I would appreciate getting more substantial feedback before
>> respinning. Every time I send a new series I have to rebase and test on
>> hardware. It's work that I would rather do when there is something to be
>> gained.
>
> I review to apply, if I can apply, I would typically skip this
>
It is much more efficient to conduct reviews in parallel. So e.g. the
bindings can be reviewed at the same time as the driver, at the same
time as the device tree changes. This way, I can get a series applied
after max(N, M, ...) revisions, where I would otherwise need N revisions
to get the bindings ready, M revisions to get the driver ready, etc.
But what's happening is that I have to make N + M + ... revisions! I am
very frustrated by your refusal to review anything until there are no
other comments, since it unnecessarily extends the process of getting a
series applied. I have been trying to get this series applied since
June, with nine revisions, and you have reviewed it *twice*! I think the
driver is in a good state and is ready to be applied (aside from the one
known issue), but I have no idea if you agree with that assessment.
--Sean
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v9 04/10] clk: Add Lynx 10G SerDes PLL driver
2022-12-30 0:01 ` [PATCH v9 04/10] clk: Add Lynx 10G SerDes PLL driver Sean Anderson
@ 2023-01-27 20:59 ` Stephen Boyd
2023-01-27 21:51 ` Sean Anderson
0 siblings, 1 reply; 13+ messages in thread
From: Stephen Boyd @ 2023-01-27 20:59 UTC (permalink / raw)
To: Kishon Vijay Abraham I, Sean Anderson, Vinod Koul, linux-phy
Cc: linux-arm-kernel, Camelia Alexandra Groza, Madalin Bucur,
Bagas Sanjaya, Rob Herring, Ioana Ciornei, linuxppc-dev,
devicetree, Krzysztof Kozlowski, Sean Anderson, Michael Turquette,
linux-clk
Quoting Sean Anderson (2022-12-29 16:01:33)
> This adds support for the PLLs found in Lynx 10G "SerDes" devices found on
> various NXP QorIQ SoCs. There are two PLLs in each SerDes. This driver has
> been split from the main PHY driver to allow for better review, even though
> these PLLs are not present anywhere else besides the SerDes. An auxiliary
> device is not used as it offers no benefits over a function call (and there
> is no need to have a separate device).
>
> The PLLs are modeled as clocks proper to let us take advantage of the
> existing clock infrastructure.
What advantage do we gain?
> I have not given the same treatment to the
> per-lane clocks because they need to be programmed in-concert with the rest
> of the lane settings. One tricky thing is that the VCO (PLL) rate exceeds
> 2^32 (maxing out at around 5GHz). This will be a problem on 32-bit
> platforms, since clock rates are stored as unsigned longs. To work around
> this, the pll clock rate is generally treated in units of kHz.
This looks like a disadvantage. Are we reporting the frequency in kHz to
the clk framework?
>
> The PLLs are configured rather interestingly. Instead of the usual direct
> programming of the appropriate divisors, the input and output clock rates
> are selected directly. Generally, the only restriction is that the input
> and output must be integer multiples of each other. This suggests some kind
> of internal look-up table. The datasheets generally list out the supported
> combinations explicitly, and not all input/output combinations are
> documented. I'm not sure if this is due to lack of support, or due to an
> oversight. If this becomes an issue, then some combinations can be
> blacklisted (or whitelisted). This may also be necessary for other SoCs
> which have more stringent clock requirements.
I'm wondering if a clk provider should be created at all here. Who is
the consumer of the clk? The phy driver itself? Does the clk provided
need to interact with other clks in the system? Or is the clk tree
wholly self-contained?
Can the phy consumer configure the output frequency directly via
phy_configure() or when the phy is enabled? I'm thinking the phy driver
can call clk_set_rate() on the parent 'rfclk' before or after setting
the bits to control the output rate, and use clk_round_rate() to figure
out what input frequencies are supported for the output frequency
desired. This would avoid kHz overflowing 32-bits, and the big clk lock
getting blocked on some other clk in the system changing rates.
BTW, what sort of phy is this? Some networking device?
>
> diff --git a/drivers/clk/clk-fsl-lynx-10g.c b/drivers/clk/clk-fsl-lynx-10g.c
> new file mode 100644
> index 000000000000..61f68b5ae675
> --- /dev/null
> +++ b/drivers/clk/clk-fsl-lynx-10g.c
> @@ -0,0 +1,509 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2022 Sean Anderson <sean.anderson@seco.com>
> + *
> + * This file contains the implementation for the PLLs found on Lynx 10G phys.
> + *
> + * XXX: The VCO rate of the PLLs can exceed ~4GHz, which is the maximum rate
> + * expressable in an unsigned long. To work around this, rates are specified in
> + * kHz. This is as if there was a division by 1000 in the PLL.
> + */
> +
> +#include <linux/clk.h>
Is this include used? If not, please remove.
> +#include <linux/clk-provider.h>
> +#include <linux/device.h>
> +#include <linux/bitfield.h>
> +#include <linux/math64.h>
> +#include <linux/phy/lynx-10g.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +#include <linux/units.h>
> +#include <dt-bindings/clock/fsl,lynx-10g.h>
> +
> +#define PLL_STRIDE 0x20
> +#define PLLa(a, off) ((a) * PLL_STRIDE + (off))
> +#define PLLaRSTCTL(a) PLLa(a, 0x00)
> +#define PLLaCR0(a) PLLa(a, 0x04)
> +
> +#define PLLaRSTCTL_RSTREQ BIT(31)
> +#define PLLaRSTCTL_RST_DONE BIT(30)
> +#define PLLaRSTCTL_RST_ERR BIT(29)
[...]
> +
> +static int lynx_clk_init(struct clk_hw_onecell_data *hw_data,
> + struct device *dev, struct regmap *regmap,
> + unsigned int index)
> +{
> + const struct clk_hw *ex_dly_parents;
> + struct clk_parent_data pll_parents[1] = { };
> + struct clk_init_data pll_init = {
> + .ops = &lynx_pll_clk_ops,
> + .parent_data = pll_parents,
> + .num_parents = 1,
> + .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT |
Why is the nocache flag used?
> + CLK_OPS_PARENT_ENABLE,
> + };
> + struct clk_init_data ex_dly_init = {
> + .ops = &lynx_ex_dly_clk_ops,
> + .parent_hws = &ex_dly_parents,
> + .num_parents = 1,
> + };
> + struct lynx_clk *clk;
> + int ret;
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v9 04/10] clk: Add Lynx 10G SerDes PLL driver
2023-01-27 20:59 ` Stephen Boyd
@ 2023-01-27 21:51 ` Sean Anderson
2023-03-03 17:25 ` Sean Anderson
0 siblings, 1 reply; 13+ messages in thread
From: Sean Anderson @ 2023-01-27 21:51 UTC (permalink / raw)
To: Stephen Boyd, Kishon Vijay Abraham I, Vinod Koul, linux-phy
Cc: linux-arm-kernel, Camelia Alexandra Groza, Madalin Bucur,
Bagas Sanjaya, Rob Herring, Ioana Ciornei, linuxppc-dev,
devicetree, Krzysztof Kozlowski, Michael Turquette, linux-clk
On 1/27/23 15:59, Stephen Boyd wrote:
> Quoting Sean Anderson (2022-12-29 16:01:33)
>> This adds support for the PLLs found in Lynx 10G "SerDes" devices found on
>> various NXP QorIQ SoCs. There are two PLLs in each SerDes. This driver has
>> been split from the main PHY driver to allow for better review, even though
>> these PLLs are not present anywhere else besides the SerDes. An auxiliary
>> device is not used as it offers no benefits over a function call (and there
>> is no need to have a separate device).
>>
>> The PLLs are modeled as clocks proper to let us take advantage of the
>> existing clock infrastructure.
>
> What advantage do we gain?
The handling of rate changes, locking, etc is all done by the clock
subsystem. We can use the existing debugfs stuff as well. And everything
is organized by existing API boundaries.
>> I have not given the same treatment to the
>> per-lane clocks because they need to be programmed in-concert with the rest
>> of the lane settings. One tricky thing is that the VCO (PLL) rate exceeds
>> 2^32 (maxing out at around 5GHz). This will be a problem on 32-bit
>> platforms, since clock rates are stored as unsigned longs. To work around
>> this, the pll clock rate is generally treated in units of kHz.
>
> This looks like a disadvantage. Are we reporting the frequency in kHz to
> the clk framework?
It is, and yes.
>>
>> The PLLs are configured rather interestingly. Instead of the usual direct
>> programming of the appropriate divisors, the input and output clock rates
>> are selected directly. Generally, the only restriction is that the input
>> and output must be integer multiples of each other. This suggests some kind
>> of internal look-up table. The datasheets generally list out the supported
>> combinations explicitly, and not all input/output combinations are
>> documented. I'm not sure if this is due to lack of support, or due to an
>> oversight. If this becomes an issue, then some combinations can be
>> blacklisted (or whitelisted). This may also be necessary for other SoCs
>> which have more stringent clock requirements.
>
> I'm wondering if a clk provider should be created at all here. Who is
> the consumer of the clk? The phy driver itself? Does the clk provided
> need to interact with other clks in the system? Or is the clk tree
> wholly self-contained?
It's wholly self-contained, aside from an undocumented mode where you
can output a fixed frequency (for testing). The provider exists so you
can use assigned-clocks to ensure a particular PLL is used for a
particular frequency. This prevents a problem where e.g. you have
reference clocks for 100 Hz and 156.25 Hz, one lane requests 5 GHz and
the PLL with the 156.25 Hz clock gets used. Then, later another lane
requests 5.15625 GHz and the remaining 100 Hz PLL can't provide it. To
prevent this, you can assign the PLLs their rates up front and the lanes
will use the existing rates. Most of the time this should be done by the
RCW, but there are cases where the RCW can't set up the clocks properly.
> Can the phy consumer configure the output frequency directly via
> phy_configure() or when the phy is enabled? I'm thinking the phy driver
> can call clk_set_rate() on the parent 'rfclk' before or after setting
> the bits to control the output rate,
This is what currently happens. See lynx_set_mode in the next patch.
> and use clk_round_rate() to figure
> out what input frequencies are supported for the output frequency
> desired. This would avoid kHz overflowing 32-bits, and the big clk lock
> getting blocked on some other clk in the system changing rates.
Can you describe this in a bit more detail? Are you suggesting to skip
the clock framework?
> BTW, what sort of phy is this? Some networking device?
From the Kconfig in the next commit:
This adds support for the Lynx "SerDes" devices found on various QorIQ
SoCs. There may be up to four SerDes devices on each SoC, and each
device supports up to eight lanes. The SerDes is configured by
default by the RCW, but this module is necessary in order to support
some modes (such as 2.5G SGMII or 1000BASE-KX), or clock setups (as
only as subset of clock configurations are supported by the RCW).
The hardware supports a variety of protocols, including Ethernet,
SATA, PCIe, and more exotic links such as Interlaken and Aurora. This
driver only supports Ethernet, but it will try not to touch lanes
configured for other protocols.
>>
>> diff --git a/drivers/clk/clk-fsl-lynx-10g.c b/drivers/clk/clk-fsl-lynx-10g.c
>> new file mode 100644
>> index 000000000000..61f68b5ae675
>> --- /dev/null
>> +++ b/drivers/clk/clk-fsl-lynx-10g.c
>> @@ -0,0 +1,509 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Copyright (C) 2022 Sean Anderson <sean.anderson@seco.com>
>> + *
>> + * This file contains the implementation for the PLLs found on Lynx 10G phys.
>> + *
>> + * XXX: The VCO rate of the PLLs can exceed ~4GHz, which is the maximum rate
>> + * expressable in an unsigned long. To work around this, rates are specified in
>> + * kHz. This is as if there was a division by 1000 in the PLL.
>> + */
>> +
>> +#include <linux/clk.h>
>
> Is this include used? If not, please remove.
OK
>> +#include <linux/clk-provider.h>
>> +#include <linux/device.h>
>> +#include <linux/bitfield.h>
>> +#include <linux/math64.h>
>> +#include <linux/phy/lynx-10g.h>
>> +#include <linux/regmap.h>
>> +#include <linux/slab.h>
>> +#include <linux/units.h>
>> +#include <dt-bindings/clock/fsl,lynx-10g.h>
>> +
>> +#define PLL_STRIDE 0x20
>> +#define PLLa(a, off) ((a) * PLL_STRIDE + (off))
>> +#define PLLaRSTCTL(a) PLLa(a, 0x00)
>> +#define PLLaCR0(a) PLLa(a, 0x04)
>> +
>> +#define PLLaRSTCTL_RSTREQ BIT(31)
>> +#define PLLaRSTCTL_RST_DONE BIT(30)
>> +#define PLLaRSTCTL_RST_ERR BIT(29)
> [...]
>> +
>> +static int lynx_clk_init(struct clk_hw_onecell_data *hw_data,
>> + struct device *dev, struct regmap *regmap,
>> + unsigned int index)
>> +{
>> + const struct clk_hw *ex_dly_parents;
>> + struct clk_parent_data pll_parents[1] = { };
>> + struct clk_init_data pll_init = {
>> + .ops = &lynx_pll_clk_ops,
>> + .parent_data = pll_parents,
>> + .num_parents = 1,
>> + .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT |
>
> Why is the nocache flag used?
PCIe rate selection can automatically modify the frequency of the
PLL. From the reference manual:
| For PCIe 8 Gbaud, the auto-negotiation also involves a combination of
| switching PLL selects, and/or reconfiguring a PLL. There are two
| scenarios for PLL reconfiguration:
|
| * PCIe starts on any PLL which runs at 5GHz, and the other PLL is off.
| PHY wrapper will switch to the other PLL as part of Gen 3 speed
| switch. In this case, both PLLs must be supplied with valid reference
| clocks.
| * PCIe starts on any PLL which runs at 5GHz, and the other PLL is
| being used for other protocols. PHY wrapper will reconfigure the
| current 5GHz PLL as part of Gen 3 speed switch. PCIe stays on the same
| PLL in this case. This also applies to the scenario where one PCIe
| port runs on all lanes.
As far as I know there's no way to configure or disable this. PCIe isn't
implemented yet, but it would likely need some way to mark PLLs for
exclusive use (not just exclusive rate). I figured it would be better
not to cache the rate so that things like the above would get detected
properly.
--Sean
>> + CLK_OPS_PARENT_ENABLE,
>> + };
>> + struct clk_init_data ex_dly_init = {
>> + .ops = &lynx_ex_dly_clk_ops,
>> + .parent_hws = &ex_dly_parents,
>> + .num_parents = 1,
>> + };
>> + struct lynx_clk *clk;
>> + int ret;
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v9 04/10] clk: Add Lynx 10G SerDes PLL driver
2023-01-27 21:51 ` Sean Anderson
@ 2023-03-03 17:25 ` Sean Anderson
0 siblings, 0 replies; 13+ messages in thread
From: Sean Anderson @ 2023-03-03 17:25 UTC (permalink / raw)
To: Stephen Boyd, Kishon Vijay Abraham I, Vinod Koul, linux-phy
Cc: linux-arm-kernel, Camelia Alexandra Groza, Madalin Bucur,
Bagas Sanjaya, Rob Herring, Ioana Ciornei, linuxppc-dev,
devicetree, Krzysztof Kozlowski, Michael Turquette, linux-clk
Hi Stephen,
On 1/27/23 16:51, Sean Anderson wrote:
> On 1/27/23 15:59, Stephen Boyd wrote:
>> Quoting Sean Anderson (2022-12-29 16:01:33)
>>> This adds support for the PLLs found in Lynx 10G "SerDes" devices found on
>>> various NXP QorIQ SoCs. There are two PLLs in each SerDes. This driver has
>>> been split from the main PHY driver to allow for better review, even though
>>> these PLLs are not present anywhere else besides the SerDes. An auxiliary
>>> device is not used as it offers no benefits over a function call (and there
>>> is no need to have a separate device).
>>>
>>> The PLLs are modeled as clocks proper to let us take advantage of the
>>> existing clock infrastructure.
>>
>> What advantage do we gain?
>
> The handling of rate changes, locking, etc is all done by the clock
> subsystem. We can use the existing debugfs stuff as well. And everything
> is organized by existing API boundaries.
>
>>> I have not given the same treatment to the
>>> per-lane clocks because they need to be programmed in-concert with the rest
>>> of the lane settings. One tricky thing is that the VCO (PLL) rate exceeds
>>> 2^32 (maxing out at around 5GHz). This will be a problem on 32-bit
>>> platforms, since clock rates are stored as unsigned longs. To work around
>>> this, the pll clock rate is generally treated in units of kHz.
>>
>> This looks like a disadvantage. Are we reporting the frequency in kHz to
>> the clk framework?
>
> It is, and yes.
>
>>>
>>> The PLLs are configured rather interestingly. Instead of the usual direct
>>> programming of the appropriate divisors, the input and output clock rates
>>> are selected directly. Generally, the only restriction is that the input
>>> and output must be integer multiples of each other. This suggests some kind
>>> of internal look-up table. The datasheets generally list out the supported
>>> combinations explicitly, and not all input/output combinations are
>>> documented. I'm not sure if this is due to lack of support, or due to an
>>> oversight. If this becomes an issue, then some combinations can be
>>> blacklisted (or whitelisted). This may also be necessary for other SoCs
>>> which have more stringent clock requirements.
>>
>> I'm wondering if a clk provider should be created at all here. Who is
>> the consumer of the clk? The phy driver itself? Does the clk provided
>> need to interact with other clks in the system? Or is the clk tree
>> wholly self-contained?
>
> It's wholly self-contained, aside from an undocumented mode where you
> can output a fixed frequency (for testing). The provider exists so you
> can use assigned-clocks to ensure a particular PLL is used for a
> particular frequency. This prevents a problem where e.g. you have
> reference clocks for 100 Hz and 156.25 Hz, one lane requests 5 GHz and
> the PLL with the 156.25 Hz clock gets used. Then, later another lane
> requests 5.15625 GHz and the remaining 100 Hz PLL can't provide it. To
> prevent this, you can assign the PLLs their rates up front and the lanes
> will use the existing rates. Most of the time this should be done by the
> RCW, but there are cases where the RCW can't set up the clocks properly.
>
>> Can the phy consumer configure the output frequency directly via
>> phy_configure() or when the phy is enabled? I'm thinking the phy driver
>> can call clk_set_rate() on the parent 'rfclk' before or after setting
>> the bits to control the output rate,
>
> This is what currently happens. See lynx_set_mode in the next patch.
>
>> and use clk_round_rate() to figure
>> out what input frequencies are supported for the output frequency
>> desired. This would avoid kHz overflowing 32-bits, and the big clk lock
>> getting blocked on some other clk in the system changing rates.
>
> Can you describe this in a bit more detail? Are you suggesting to skip
> the clock framework?
>
>> BTW, what sort of phy is this? Some networking device?
>
> From the Kconfig in the next commit:
>
> This adds support for the Lynx "SerDes" devices found on various QorIQ
> SoCs. There may be up to four SerDes devices on each SoC, and each
> device supports up to eight lanes. The SerDes is configured by
> default by the RCW, but this module is necessary in order to support
> some modes (such as 2.5G SGMII or 1000BASE-KX), or clock setups (as
> only as subset of clock configurations are supported by the RCW).
> The hardware supports a variety of protocols, including Ethernet,
> SATA, PCIe, and more exotic links such as Interlaken and Aurora. This
> driver only supports Ethernet, but it will try not to touch lanes
> configured for other protocols.
>
>>>
>>> diff --git a/drivers/clk/clk-fsl-lynx-10g.c b/drivers/clk/clk-fsl-lynx-10g.c
>>> new file mode 100644
>>> index 000000000000..61f68b5ae675
>>> --- /dev/null
>>> +++ b/drivers/clk/clk-fsl-lynx-10g.c
>>> @@ -0,0 +1,509 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>> +/*
>>> + * Copyright (C) 2022 Sean Anderson <sean.anderson@seco.com>
>>> + *
>>> + * This file contains the implementation for the PLLs found on Lynx 10G phys.
>>> + *
>>> + * XXX: The VCO rate of the PLLs can exceed ~4GHz, which is the maximum rate
>>> + * expressable in an unsigned long. To work around this, rates are specified in
>>> + * kHz. This is as if there was a division by 1000 in the PLL.
>>> + */
>>> +
>>> +#include <linux/clk.h>
>>
>> Is this include used? If not, please remove.
>
> OK
>
>>> +#include <linux/clk-provider.h>
>>> +#include <linux/device.h>
>>> +#include <linux/bitfield.h>
>>> +#include <linux/math64.h>
>>> +#include <linux/phy/lynx-10g.h>
>>> +#include <linux/regmap.h>
>>> +#include <linux/slab.h>
>>> +#include <linux/units.h>
>>> +#include <dt-bindings/clock/fsl,lynx-10g.h>
>>> +
>>> +#define PLL_STRIDE 0x20
>>> +#define PLLa(a, off) ((a) * PLL_STRIDE + (off))
>>> +#define PLLaRSTCTL(a) PLLa(a, 0x00)
>>> +#define PLLaCR0(a) PLLa(a, 0x04)
>>> +
>>> +#define PLLaRSTCTL_RSTREQ BIT(31)
>>> +#define PLLaRSTCTL_RST_DONE BIT(30)
>>> +#define PLLaRSTCTL_RST_ERR BIT(29)
>> [...]
>>> +
>>> +static int lynx_clk_init(struct clk_hw_onecell_data *hw_data,
>>> + struct device *dev, struct regmap *regmap,
>>> + unsigned int index)
>>> +{
>>> + const struct clk_hw *ex_dly_parents;
>>> + struct clk_parent_data pll_parents[1] = { };
>>> + struct clk_init_data pll_init = {
>>> + .ops = &lynx_pll_clk_ops,
>>> + .parent_data = pll_parents,
>>> + .num_parents = 1,
>>> + .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT |
>>
>> Why is the nocache flag used?
>
> PCIe rate selection can automatically modify the frequency of the
> PLL. From the reference manual:
>
> | For PCIe 8 Gbaud, the auto-negotiation also involves a combination of
> | switching PLL selects, and/or reconfiguring a PLL. There are two
> | scenarios for PLL reconfiguration:
> |
> | * PCIe starts on any PLL which runs at 5GHz, and the other PLL is off.
> | PHY wrapper will switch to the other PLL as part of Gen 3 speed
> | switch. In this case, both PLLs must be supplied with valid reference
> | clocks.
> | * PCIe starts on any PLL which runs at 5GHz, and the other PLL is
> | being used for other protocols. PHY wrapper will reconfigure the
> | current 5GHz PLL as part of Gen 3 speed switch. PCIe stays on the same
> | PLL in this case. This also applies to the scenario where one PCIe
> | port runs on all lanes.
>
> As far as I know there's no way to configure or disable this. PCIe isn't
> implemented yet, but it would likely need some way to mark PLLs for
> exclusive use (not just exclusive rate). I figured it would be better
> not to cache the rate so that things like the above would get detected
> properly.
>
> --Sean
>
>>> + CLK_OPS_PARENT_ENABLE,
>>> + };
>>> + struct clk_init_data ex_dly_init = {
>>> + .ops = &lynx_ex_dly_clk_ops,
>>> + .parent_hws = &ex_dly_parents,
>>> + .num_parents = 1,
>>> + };
>>> + struct lynx_clk *clk;
>>> + int ret;
I am going to try and send out v10 soon. Do you have any comments on my
reply here? At the moment the only change I am planning to make is to
remove the clk.h include.
--Sean
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2023-03-03 17:26 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-12-30 0:01 [PATCH v9 00/10] phy: Add support for Lynx 10G SerDes Sean Anderson
2022-12-30 0:01 ` [PATCH v9 02/10] dt-bindings: phy: Add Lynx 10G phy binding Sean Anderson
2023-01-12 20:37 ` Rob Herring
2022-12-30 0:01 ` [PATCH v9 03/10] dt-bindings: clock: Add ids for Lynx 10g PLLs Sean Anderson
2022-12-30 0:01 ` [PATCH v9 04/10] clk: Add Lynx 10G SerDes PLL driver Sean Anderson
2023-01-27 20:59 ` Stephen Boyd
2023-01-27 21:51 ` Sean Anderson
2023-03-03 17:25 ` Sean Anderson
2023-01-17 16:46 ` [PATCH v9 00/10] phy: Add support for Lynx 10G SerDes Sean Anderson
2023-01-18 16:54 ` Vinod Koul
2023-01-19 16:22 ` Sean Anderson
2023-01-20 8:06 ` Vinod Koul
2023-01-20 16:43 ` Sean Anderson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox