[PATCH v14 00/15] phy: Add support for Lynx 10G SerDes

Sean Anderson sean.anderson at seco.com
Thu Aug 10 12:58:36 PDT 2023


Hi Vladimir,

On 8/10/23 06:26, Vladimir Oltean wrote:
> Hi Sean,
> 
> On Tue, Jun 13, 2023 at 05:27:54PM +0300, Vladimir Oltean wrote:
>> The way things are supposed to work (*if* this works at all) is that the
>> reset state machine starts with a supported PLL / refclk configuration
>> that permits a certain subset of protocols, and the SERDES protocols can
>> be changed from the reset state, as desired, for the individual lanes.
>> 
>> What is self-inflicted is that the refclks on your board design are not
>> supportable by any reset state machine configuration, and wiring them
>> that way was a conscious decision. Did your company's board designers
>> receive the recommendation to disconnect RESET_REQ from NXP, and has NXP
>> said that the end result will be something that continues to be supportable?
>> I've searched the customer support database and the answer seems to be no.
>> In any case, if you have to disconnect RESET_REQ from the SoC to make
>> the driver in this form useful, then... yeah, no. You're obviously free
>> to do whatever you want with your products, but that's not how mainline
>> Linux works, it needs to be useful beyond you.

As explained previously (and noted by yourself below) 1G and 10G RCWs
have mutally-incompatible clocking requirements. Now that you have
documented an alternate solution, it is possible to boot up with one RCW
and switch to another. But without that it was not possible to have one
board support both RCWs (without e.g. a microcontroller or FPGA to
configure the clock generator before releasing the processor reset). I
do not think that the silicon should assert the reset request line if
the serdes doesn't lock, but it does and it can't really be disabled.

As it happens, our board is set up so that the reference clocks are
configured for 10G by default. During this boot, reset request is never
requested. If we did not have to support software configuration of the
serdes speed (to support 1G SFPs) we would not have to disconnect reset
request.

That said, I have evaluated the various reasons that reset request can
be asserted, and I have determined that for our product they are not
necessary. The only major limitation is the lack of a watchdog, but that
was not a requirement for us. Because of this, using a GPIO for reset is
sufficient and neatly avoids the issue.

We did not see the need to contact NXP support because we internally
came up with a reliable solution. I suspect that they would not have
suggested the solution you present below, but if you think otherwise I
will try them in the future :)

I would appreciate if you are not so derisive in your comments. I do not
like reading your emails because they are very abrasive.

>> If protocol switching works, I will maintain that your board should have
>> wired the refclks to PLLs the other way around (which is supported by
>> the RCW), and then proceed to do protocol switching to reach the desired
>> configuration.
> 
> It was quite a journey to piece everything together.
> 
> There is one thing to be mentioned right from the start, and that is
> that on some SoCs (including the LS1043A and LS1046A), the SerDes data
> path is partially controlled by the RCW, and thus, dynamically performing
> a major SerDes protocol reconfiguration requires a RCW override procedure
> (undocumented in the SerDes reconfiguration steps, but all the info you
> need is summarized below).
> 
> The DCFG block has a set of RCWSR0 - RCWSR15 read-only status registers
> relative to DCFG_CCSR. What we don't document in the SoC RM, but I got
> permission to say here, is that the DCFG block exposes a second set of
> Expert Mode registers in the DCSR address space (base address 2000_0000h).
> The DCFG_DCSR register region spans from offset 2_0000h to 2_05AC into
> the DCSR base address. At the exact same offsets into DCFG_DCSR as
> RCWSR0 - RCWSR15 are into DCFG_CCSR (aka 100h-13ch), one can find the
> shadow RCWCR0 - RCWCR15 (Reset Control Word Control Register) registers
> which are also writable. There is a one-to-one mapping between each
> register (and field) in RCWSR and RCWCR, so I won't detail the
> contents of the RCWCR registers, because we document RCWSR fully.
>
> RCW override means modifying some of the RCWCR registers. In this
> particular case, finalizing the major SerDes reconfiguration requires
> overriding SRDS_PRTCL_S1 in RCWCR5 with the new per-lane settings, to mux
> the correct PCS to the MAC. In the general case, random RCW overrides
> that don't come from the hardware validation team are unsupported by
> NXP, and you should expect the procedure to yield unpredictable results.

Good to see these finally documented (in some form or other). Perhaps
these could also be used to enable e.g. a UART in the hard-coded RCW
without requiring e.g. JTAG...

> I don't know how much of the above steps is applicable to the other 10G Lynx
> SoCs (LS1088, LS2088 etc). Not all SoCs may require RCW override, and
> the RCW override procedure may not be the same. That is TBD, and we'd
> appreciate if support for other SoCs than the LS1046 to be added no
> earlier than when we have a validated SerDes reconfiguration procedure.
> 
> I believe this is enough information to permit the creation of a Linux
> driver on the DCFG_DCSR registers which permits RCW override at runtime.
> It seems this will be necessary at least on LS1046.
> 
> We should discuss who and when picks up your patches, removes the
> unsupported, untested and unnecessary code and adds the RCW override
> procedure.

Well, while I don't agree with your characterization (since this code
was indeed tested by me and was indeed necessary), I am glad to see that
you think there is a path forward.

> It can be you, it can also be someone from NXP. If it will be
> you, please let me know, because there are concrete implementation
> choices I want to leave comments on.

I can look into doing this. It will be in my free time, so it will
likely be a bit before I can update this series.

> There is also the previous observation from Ioana that you should not
> delete PHY interrupts without finding out why they don't work.

Well, if you have a better solution, please let me know. The interrupt
does not work in real hardware.

I was hampered in my efforts to determine the cause because the interrupt
passes through an FPGA to which I lack the HDL. So far, I have not seen
any argument against polling except that we do not understand the
problem yet. However, I have not seen any other analysis of the problem
either.

> Only what was thoroughly tested and is based on a hardware validated
> procedure should be submitted. This means only a 1G <-> 10G transition
> on LS1046 for now.
> 
> Nonetheless, below is a functional example of how NXP would recommend
> you to achieve the desired PLL mapping for any RCW-based SerDes protocol.
> My testing platform was the LS1046A-QDS with PLL1 at 100 MHz and PLL2 at
> 156.25 MHz. I believe that this should eliminate the need for a clk
> driver for the PLLs, and should make your Ethernet lanes usable much
> earlier than Linux. That being said, our position at NXP is that you
> don't need a clk driver for the PLLs, and I would like to see the clk
> portion removed from future patch revisions.

I have not had any issues with clocking. This is actually one of the
areas where the reference manual is sufficient to create a working
driver. Adding flexibility here is very useful, because we can solve
hardware problems in software. This can reduce e.g. board respins, and
allow for more interesting clocking solutions (such as allowing clock
generators which must be configured before use).

> This patch is on top of https://cas5-0-urlprotect.trendmicro.com:443/wis/clicktime/v1/query?url=https%3a%2f%2fgithub.com%2fnxp%2dqoriq%2frcw%2ftree%2flf%2d6.1.22%2d2.0.0&umid=9173333f-cda0-48a2-a652-ccb5b892d77e&auth=d807158c60b7d2502abde8a2fc01f40662980862-d3ec43c9e78658dbb409cef29887d136eca21c6a
> 
> From 9f90d6805883f23a898f9d66826f89b7ba73afe3 Mon Sep 17 00:00:00 2001
> From: Vladimir Oltean <vladimir.oltean at nxp.com>
> Date: Thu, 25 May 2023 11:23:41 +0300
> Subject: [PATCH] LS1046A: implement a PBI-based SerDes protocol switching
>  mechanism
> 
> The LS1046A reset state machine is a bit limited in the SRDS_PRTCL_S1
> protocol combinations that it offers. For example, it offers protocol
> 0x3333 (4x SGMII) only with PLL mapping 2222, and that is good as long
> as dynamic protocol switching between 1G (SGMII) and 10G (XFI) isn't
> desired at runtime.
> 
> If that is taken into account as an additional constraint, then we need
> PLL2 (yes, specifically 2) to have a refclk of 156.25 MHz, and that is
> in conflict with the PLL mapping of the aforementioned 0x3333, because
> 1G (SGMII) can only work with a PLL refclk of 100 or 125 MHz, so that's
> what has to be fed into PLL 2.
> 
> Dynamic frequency switching of PLLs is hard and out of question.
> 
> It is desirable to be able to use PLL2 for the 156.25 MHz refclk
> frequency (for the 10G link modes), and PLL1 for the 100 MHz refclk
> frequency (for the 1G link modes). It turns out, this is possible, even
> if not 100% natively through the reset state machine built-in options.
> 
> The strategy is to pick a pair of SerDes refclk frequencies in the RCW
> that is correct for the given board (thus allowing the SerDes PLLs to
> lock, and the SoC to boot) as a first step. The SerDes protocol can be
> absolutely anything as long as the PLL frequencies are right, because as
> a second step, we'll be fixing up the SerDes lane registers for the
> desired final protocol, to appear as if we had that protocol natively.
> 
> Signed-off-by: Vladimir Oltean <vladimir.oltean at nxp.com>
> ---
>  .../rcw_1600.rcw                              |  99 +++++++++++++++++
>  ls1046ardb/serdes_1133_to_3333.rcw            |  73 +++++++++++++
>  serdes_10g.rcw                                | 102 ++++++++++++++++++
>  3 files changed, 274 insertions(+)
>  create mode 100644 ls1046aqds/RR_FFSNPPPH_1133_5559_to_3333_5559/rcw_1600.rcw
>  create mode 100644 ls1046ardb/serdes_1133_to_3333.rcw
>  create mode 100644 serdes_10g.rcw
> 
> diff --git a/ls1046aqds/RR_FFSNPPPH_1133_5559_to_3333_5559/rcw_1600.rcw b/ls1046aqds/RR_FFSNPPPH_1133_5559_to_3333_5559/rcw_1600.rcw
> new file mode 100644
> index 000000000000..2bbc0163392d
> --- /dev/null
> +++ b/ls1046aqds/RR_FFSNPPPH_1133_5559_to_3333_5559/rcw_1600.rcw
> @@ -0,0 +1,99 @@
> +/*
> + * LS1046AQDS RCW for SerDes Protocol 0x3333_5559 derived from 0x1133_5559
> + *
> + * 42G configuration -- 2 RGMII + 4 SGMII (reconfigurable to XFI) + 3 PCIe + SATA
> + *
> + * Frequencies:
> + *
> + * Sys Clock: 100 MHz
> + * DDR_Refclock: 100 MHz
> + *
> + * Core		-- 1600 MHz (Mul 16)
> + * Platform	-- 600 MHz (Mul 6)
> + * DDR		-- 2100 MT/s (Mul 21)
> + * FMan		-- 700 MHz (CGA2 /2)
> + * XFI		-- 156.25 MHz (10.3125G)
> + * SGMII	-- 100 MHz (5G)
> + * PCIE		-- 100 MHz (5G)
> + * eSDHC	-- 1400 MHz (CGA2 /1)
> + *
> + * Hardware Accelerator Block Cluster Group A Mux Clock:
> + *   FMan        - HWA_CGA_M1_CLK_SEL = 6 - Async mode, CGA PLL 2 /2 is clock
> + *   eSDHC, QSPI - HWA_CGA_M2_CLK_SEL = 1 - Async mode, CGA PLL 2 /1 is clock
> + *
> + * Serdes Lanes vs Slot information
> + *  Serdes1 Lane 0 (D) - Starts as XFI9, switches to SGMII9
> + *  Serdes1 Lane 1 (C) - Starts as XFI10, switches to SGMII10
> + *  Serdes1 Lane 2 (B) - SGMII5, Slot 1
> + *  Serdes1 Lane 3 (A) - SGMII6, Slot 1
> + *
> + *  Serdes2 Lane 0 (A) - PCIe1 Gen2 x1, Slot 3
> + *  Serdes2 Lane 1 (B) - PCIe2 Gen2 x1, Slot 4
> + *  Serdes2 Lane 2 (C) - PCIe3 Gen2 x1, Slot 5
> + *  Serdes2 Lane 3 (D) - SATA
> + *
> + * PLL mapping: starts as 2211_2221, ends as 1111_2221
> + *
> + * Serdes 1:
> + *  PLL mapping: 1111
> + *  SRDS_PLL_REF_CLK_SEL_S1 : 0b'01
> + *    SerDes 1, PLL1[160] : 0 - 100MHz for SGMII and PCIe
> + *    SerDes 1, PLL2[161] : 1 - 156.25MHz for XFI
> + *  SRDS_PLL_PD_S1 : 0b'0
> + *    SerDes 1, PLL1 : 0 - not powered down
> + *    SerDes 1, PLL2 : 0 - not powered down
> + *  SRDS_DIV_PEX_S1 :
> + *    Only used for PEX, not used.
> + *
> + * Serdes 2:
> + *  PLL mapping: 2221
> + *  SRDS_PLL_REF_CLK_SEL_S2 : 0b'00
> + *    SerDes 2, PLL1[162] : 0 - 100MHz for SATA
> + *    SerDes 2, PLL2[163] : 0 - 100MHz for PCIe
> + *  SRDS_PLL_PD_S2 : 0b'00
> + *    SerDes 2, PLL1 : 0 - not powered down
> + *    SerDes 2, PLL2 : 0 - not powered down
> + *  SRDS_DIV_PEX_S2 : 0b'01
> + *    00 - train up to max rate of 8G
> + *    01 - train up to max rate of 5G
> + *    10 - train up to max rate of 2.5G
> + *
> + * DDR clock:
> + * DDR_REFCLK_SEL : 1 - DDRCLK pin provides the reference clock to the DDR PLL
> + *
> + */
> +
> +#include <../ls1046ardb/ls1046a.rcwi>
> +
> +SYS_PLL_RAT=6
> +MEM_PLL_RAT=21
> +CGA_PLL1_RAT=16
> +CGA_PLL2_RAT=14
> +SRDS_PRTCL_S1=4403
> +SRDS_PRTCL_S2=21849

I know it is not typical for NXP RCWs, but your rcw tool supports using
hex/binary prefixes. Thus, you could rewrite the above lines as

SRDS_PRTCL_S1=0x1133
SRDS_PRTCL_S2=0x5559

IMO this is much easier to read, since it matches the documentation.

> +SRDS_PLL_REF_CLK_SEL_S1=1
> +SRDS_PLL_REF_CLK_SEL_S2=0
> +SRDS_DIV_PEX_S1=1
> +SRDS_DIV_PEX_S2=1
> +DDR_FDBK_MULT=2
> +DDR_REFCLK_SEL=1
> +PBI_SRC=14

As another example, here you can do e.g.

PBI_SRC=0b1110

which better matches the documentation.

> +IFC_MODE=37
> +HWA_CGA_M1_CLK_SEL=6
> +DRAM_LAT=1
> +UART_BASE=7
> +IRQ_OUT=1
> +LVDD_VSEL=1
> +TVDD_VSEL=0
> +DVDD_VSEL=2
> +EVDD_VSEL=2
> +IIC2_EXT=1
> +SYSCLK_FREQ=600
> +HWA_CGA_M2_CLK_SEL=1
> +
> +#include <../ls1046ardb/cci_barrier_disable.rcw>
> +#include <../ls1046ardb/usb_phy_freq.rcw>
> +#include <../ls1046ardb/uboot_address.rcw>
> +#include <../ls1046ardb/serdes_sata.rcw>
> +#include <../ls1046ardb/a009531.rcw>
> +#include <../ls1046ardb/serdes_1133_to_3333.rcw>
> diff --git a/ls1046ardb/serdes_1133_to_3333.rcw b/ls1046ardb/serdes_1133_to_3333.rcw
> new file mode 100644
> index 000000000000..ffd548a73675
> --- /dev/null
> +++ b/ls1046ardb/serdes_1133_to_3333.rcw
> @@ -0,0 +1,73 @@
> +/*
> + * Change protocols on SerDes1 from 1133 to 3333, and their PLL mappings from
> + * 2211 to 1111. This is useful because, although the reset state machine has a
> + * native 0x3333 SerDes protocol option, the PLL mapping of that is 2222.
> + * This non-native option frees up PLL 2, and it can be provisioned e.g. with a
> + * 156.25 MHz for any lanes that might want to switch to XFI at runtime.
> + */
> +
> +#define SRDS_BASE		0xea0000 /* SerDes 1 relative to CCSR_BASE */
> +#include <../serdes_10g.rcw>
> +
> +/* For writing outside the CCSR space (in DCSR), an indirect access method is
> + * used. The SCFG_ALTCBAR register (field ALTCFG) holds the upper 24 bits of
> + * the 48-bit address, and the awrite PBL instruction gets the lower 24 bits of
> + * the address that is relative to that. Here we work with 32-bit addresses,
> + * so we only care about the upper 8 bits.
> + */
> +#define SCFG_ALTCBAR		0x570158
> +#define ALTCFG(x)		(((x) << 8) & 0xffffff00)
> +#define DCFG_DCSR_RCWCR5	0x20140110
> +#define RCWCR5_SRDS_PRTCL_S1(x)	(((x) << 16) & 0xffff0000)
> +#define RCWCR5_SRDS_PRTCL_S2(x)	((x) & 0xffff)
> +#define upper_8_bits(x)		(((x) & 0xff000000) >> 24)
> +#define lower_24_bits(x)	((x) & 0xffffff)
> +
> +#define GCR0_SGMII_FROM_PLL1	RPLL_LES(1) | RRAT_SEL(2) | \
> +				TPLL_LES(1) | TRAT_SEL(2) | \
> +				FIRST_LANE(1) | PROTS(1)
> +
> +.pbi
> +
> +write LNmGCR0(2), RRST_B(0) | TRST_B(0)
> +write LNmGCR0(3), RRST_B(0) | TRST_B(0)
> +
> +wait 50
> +
> +write LNmGCR0(2), GCR0_SGMII_FROM_PLL1
> +write LNmGCR0(3), GCR0_SGMII_FROM_PLL1
> +
> +write LNmGCR1(2), REIDL_TH(1) | REIDL_EX_SEL(3) | REIDL_ET_MSB(1) | \
> +		  ISLEW_RCTL(1) | OSLEW_RCTL(1)
> +write LNmGCR1(3), REIDL_TH(1) | REIDL_EX_SEL(3) | REIDL_ET_MSB(1) | \
> +		  ISLEW_RCTL(1) | OSLEW_RCTL(1)
> +
> +write LNmRECR0(2), GK2OVD_EN(1) | GK2OVD(15) | GK3OVD_EN(1) | GK3OVD(15)
> +write LNmRECR0(3), GK2OVD_EN(1) | GK2OVD(15) | GK3OVD_EN(1) | GK3OVD(15)
> +
> +write LNmTECR0(2), ADPT_EQ(48) | AMP_RED(6)
> +write LNmTECR0(3), ADPT_EQ(48) | AMP_RED(6)
> +
> +/* LS1046A requires RCW override to reconfigure the mux between
> + * the PCS and the MAC.
> + */
> +write SCFG_ALTCBAR, ALTCFG(upper_8_bits(DCFG_DCSR_RCWCR5))
> +flush
> +awrite lower_24_bits(DCFG_DCSR_RCWCR5), RCWCR5_SRDS_PRTCL_S1(0x3333) | \
> +					RCWCR5_SRDS_PRTCL_S2(0x5559)
> +
> +/* PCCRB: 0x21000000 -> 0x00000000 */
> +write PCCRB, XFIA_CFG(0) | XFIB_CFG(0)
> +
> +/* PCCR8: 0x11000000 -> 0x11110000 */
> +write PCCR8, SGMIIA_CFG(1) | SGMIIB_CFG(1) | SGMIIC_CFG(1) | SGMIID_CFG(1)
> +
> +write SGMIIaCR1(2), SGMII_MDEV_PORT(0) | SGPCS_EN(1)
> +write SGMIIaCR1(3), SGMII_MDEV_PORT(0) | SGPCS_EN(1)
> +
> +wait 120
> +
> +write LNmGCR0(2), GCR0_SGMII_FROM_PLL1 | RRST_B(1) | TRST_B(1)
> +write LNmGCR0(3), GCR0_SGMII_FROM_PLL1 | RRST_B(1) | TRST_B(1)
> +
> +.end
> diff --git a/serdes_10g.rcw b/serdes_10g.rcw
> new file mode 100644
> index 000000000000..714d53fde8af
> --- /dev/null
> +++ b/serdes_10g.rcw
> @@ -0,0 +1,102 @@
> +/*
> + * Registers for the Lynx 10G SerDes block.
> + *
> + * Must be included by an SoC-specific header that defines the
> + * SRDS_BASE value.
> + */
> +
> +#define PLLnRSTCTL(n)		(SRDS_BASE + (0x20 * (n)))
> +#define PLLnCR0(n)		(SRDS_BASE + (0x20 * (n)) + 0x0004)
> +#define  POFF(x)		(((x) << 31) & 0x80000000)
> +#define  REFCLK_SEL(x)		(((x) << 28) & 0x70000000)
> +#define  REFCLK_EN(x)		(((x) << 27) & 0x08000000)
> +#define  FRATE_SEL(x)		(((x) << 16) & 0x000f0000)
> +#define  DLYDIV_SEL(x)		((x) & 0x00000003)
> +#define PCCR8			(SRDS_BASE + 0x0220)
> +#define  SGMIIA_KX(x)		(((x) << 31) & 0x80000000)
> +#define  SGMIIA_CFG(x)		(((x) << 28) & 0x70000000)
> +#define  SGMIIB_KX(x)		(((x) << 27) & 0x08000000)
> +#define  SGMIIB_CFG(x)		(((x) << 24) & 0x07000000)
> +#define  SGMIIC_KX(x)		(((x) << 23) & 0x00800000)
> +#define  SGMIIC_CFG(x)		(((x) << 20) & 0x00700000)
> +#define  SGMIID_KX(x)		(((x) << 19) & 0x00080000)
> +#define  SGMIID_CFG(x)		(((x) << 16) & 0x00070000)
> +#define  SGMIIE_KX(x)		(((x) << 15) & 0x00008000)
> +#define  SGMIIE_CFG(x)		(((x) << 12) & 0x00007000)
> +#define  SGMIIF_KX(x)		(((x) << 11) & 0x00000800)
> +#define  SGMIIF_CFG(x)		(((x) << 8) & 0x00000700)
> +#define  SGMIIG_KX(x)		(((x) << 7) & 0x00000080)
> +#define  SGMIIG_CFG(x)		(((x) << 4) & 0x00000070)
> +#define  SGMIIH_KX(x)		(((x) << 3) & 0x00000008)
> +#define  SGMIIH_CFG(x)		((x) & 0x00000007)
> +#define PCCRB			(SRDS_BASE + 0x022c)
> +#define  XFIA_CFG(x)		(((x) << 28) & 0x70000000)
> +#define  XFIB_CFG(x)		(((x) << 24) & 0x07000000)
> +#define  XFIC_CFG(x)		(((x) << 20) & 0x00700000)
> +#define  XFID_CFG(x)		(((x) << 16) & 0x00070000)
> +#define  XFIE_CFG(x)		(((x) << 12) & 0x00007000)
> +#define  XFIF_CFG(x)		(((x) << 8) & 0x00000700)
> +#define  XFIG_CFG(x)		(((x) << 4) & 0x00000070)
> +#define  XFIH_CFG(x)		((x) & 0x00000007)
> +#define LNmGCR0(m)		(SRDS_BASE + (0x40 * (m)) + 0x0800)
> +#define  RPLL_LES(x)		(((x) << 31) & 0x80000000)
> +#define  RRAT_SEL(x)		(((x) << 28) & 0x30000000)
> +#define  TPLL_LES(x)		(((x) << 27) & 0x08000000)
> +#define  TRAT_SEL(x)		(((x) << 24) & 0x03000000)
> +#define  RRST_B(x)		(((x) << 22) & 0x00400000)
> +#define  TRST_B(x)		(((x) << 21) & 0x00200000)
> +#define  RX_PD(x)		(((x) << 20) & 0x00100000)
> +#define  TX_PD(x)		(((x) << 19) & 0x00080000)
> +#define  IF20BIT_EN(x)		(((x) << 18) & 0x00040000)
> +#define  FIRST_LANE(x)		(((x) << 16) & 0x00010000)
> +#define  GCR0_RSV		0x1000
> +#define  PROTS(x)		(((x) << 7) & 0x00000f80)
> +#define LNmGCR1(m)		(SRDS_BASE + (0x40 * (m)) + 0x0804)
> +#define  RDAT_INV(x)		(((x) << 31) & 0x80000000)
> +#define  TDAT_INV(x)		(((x) << 30) & 0x40000000)
> +#define  OPAD_CTL(x)		(((x) << 26) & 0x04000000)
> +#define  REIDL_TH(x)		(((x) << 20) & 0x00700000)
> +#define  REIDL_EX_SEL(x)	(((x) << 18) & 0x000C0000)
> +#define  REIDL_ET_SEL(x)	(((x) << 16) & 0x00030000)
> +#define  REIDL_EX_MSB(x)	(((x) << 15) & 0x00008000)
> +#define  REIDL_ET_MSB(x)	(((x) << 14) & 0x00004000)
> +#define  REQ_CTL_SNP(x)		(((x) << 13) & 0x00002000)
> +#define  REQ_CDR_SNP(x)		(((x) << 12) & 0x00001000)
> +#define  TRSTDIR(x)		(((x) << 7) & 0x00000080)
> +#define  REQ_BIN_SNP(x)		(((x) << 6) & 0x00000040)
> +#define  ISLEW_RCTL(x)		(((x) << 4) & 0x00000030)
> +#define  GCR1_RSV		0x8
> +#define  OSLEW_RCTL(x)		((x) & 0x3)
> +#define LNmRECR0(m)		(SRDS_BASE + (0x40 * (m)) + 0x0810)
> +#define  RXEQ_BST(x)		(((x) << 28) & 0x10000000)
> +#define  GK2OVD(x)		(((x) << 24) & 0x0f000000)
> +#define  GK3OVD(x)		(((x) << 16) & 0x000f0000)
> +#define  GK2OVD_EN(x)		(((x) << 15) & 0x00008000)
> +#define  GK3OVD_EN(x)		(((x) << 14) & 0x00004000)
> +#define  OSETOVD_EN(x)		(((x) << 13) & 0x00002000)
> +#define  BASE_WAND(x)		(((x) << 10) & 0x00000c00)
> +#define  OSETOVD(x)		((x) & 0x0000007F)
> +#define LNmTECR0(m)		(SRDS_BASE + (0x40 * (m)) + 0x0818)
> +#define  TEQ_TYPE(x)		(((x) << 28) & 0x30000000)
> +#define  SGN_PREQ(x)		(((x) << 26) & 0x04000000)
> +#define  RATIO_PREQ(x)		(((x) << 22) & 0x03C00000)
> +#define  SGN_POST1Q(x)		(((x) << 21) & 0x00200000)
> +#define  RATIO_PST1Q(x)		(((x) << 16) & 0x001F0000)
> +#define  ADPT_EQ(x)		(((x) << 8) & 0x00003F00)
> +#define  AMP_RED(x)		((x) & 0x0000003f)
> +#define LNmTTLCR0(m)		(SRDS_BASE + (0x40 * (m)) + 0x0820)
> +#define LNmTCSR0(m)		(SRDS_BASE + (0x40 * (m)) + 0x0830)
> +#define LNmTCSR1(m)		(SRDS_BASE + (0x40 * (m)) + 0x0834)
> +#define LNmTCSR2(m)		(SRDS_BASE + (0x40 * (m)) + 0x0838)
> +#define LNmTCSR3(m)		(SRDS_BASE + (0x40 * (m)) + 0x083c)
> +#define SGMIIaCR0(a)		(SRDS_BASE + (0x10 * (a)) + 0x1800)
> +#define  RST_SGM(x)		(((x) << 31) & 0x80000000)
> +#define  PD_SGM(x)		(((x) << 30) & 0x40000000)
> +#define SGMIIaCR1(a)		(SRDS_BASE + (0x10 * (a)) + 0x1804)
> +#define  SGMII_MDEV_PORT(x)	(((x) << 27) & 0xf8000000)
> +#define  SGPCS_EN(x)		(((x) << 11) & 0x00000800)
> +#define XFIaCR0(a)		(SRDS_BASE + (0x10 * (a)) + 0x1980)
> +#define  RST_XFI(x)		(((x) << 31) & 0x80000000)
> +#define  PD_XFI(x)		(((x) << 30) & 0x40000000)
> +#define XFIaCR1(a)		(SRDS_BASE + (0x10 * (a)) + 0x1984)
> +#define  XFI_MDEV_PORT(x)	(((x) << 27) & 0xf8000000)
> --
> 2.34.1
> 
>> > This driver would also be a good place to add the KR link training with
>> > NXP tried to upstream a few years ago.
>> 
>> Well, speaking as someone who is now also tasked with the copper backplane
>> support, believe me that I know that, and this is why I'm so desperate
>> with the logic you're trying to push forward. It's clear that we should
>> try to collaborate rather than try to push individualistic non-tested
>> non-solutions.
> 
> Speaking of this, I will send an RFC in the upcoming days which proposes
> a model for the copper backplane PHY support on LX2160A and its already
> existing Lynx 28G SerDes driver.
> 
> I will concern myself with porting that support on Lynx 10G only once
> the model I propose turns out to be acceptable for both the network PHY
> as well as the generic PHY maintainers.

Well, as far as I know this driver is only a few changes from being
acceptable to these maintainers as well :)

--Sean



More information about the linux-arm-kernel mailing list