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@xxxxxxx> > 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@xxxxxxx> > --- > .../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