[U-Boot] [PATCH v2] net: phy: add TSE PCS support to dwmac-socfpga

Joe Hershberger joe.hershberger at ni.com
Mon Oct 22 20:39:04 UTC 2018


On Wed, Oct 17, 2018 at 4:46 AM Ooi, Joyce <joyce.ooi at intel.com> wrote:
>
> This adds support for TSE PCS (Triple Speed Ethernet Physical Coding
> Sublayer) that uses SGMII adapter when the phy-mode in device tree is
> set to sgmii.
>
> Signed-off-by: Ooi, Joyce <joyce.ooi at intel.com>
> ---
>  arch/arm/mach-socfpga/include/mach/misc.h |   1 +
>  arch/arm/mach-socfpga/misc.c              |   5 +
>  arch/arm/mach-socfpga/misc_s10.c          |   6 +
>  drivers/net/Makefile                      |   3 +-
>  drivers/net/designware.c                  |   5 +
>  drivers/net/designware.h                  |   1 +
>  drivers/net/dwmac_socfpga.c               | 121 ++++++++++++++++++
>  drivers/net/phy/altr_tse_pcs.c            | 197 ++++++++++++++++++++++++++++++
>  drivers/net/phy/altr_tse_pcs.h            |  59 +++++++++
>  9 files changed, 397 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/net/phy/altr_tse_pcs.c
>  create mode 100644 drivers/net/phy/altr_tse_pcs.h
> ---
> v2: add a __weak function to make it compatible for all socfpga platforms
>
> diff --git a/arch/arm/mach-socfpga/include/mach/misc.h b/arch/arm/mach-socfpga/include/mach/misc.h
> index 2660992..d1de5cf 100644
> --- a/arch/arm/mach-socfpga/include/mach/misc.h
> +++ b/arch/arm/mach-socfpga/include/mach/misc.h
> @@ -39,6 +39,7 @@ void socfpga_init_security_policies(void);
>  void socfpga_sdram_remap_zero(void);
>  #endif
>
> +int socfpga_test_fpga_ready(void);
>  void do_bridge_reset(int enable);
>
>  #endif /* _MISC_H_ */
> diff --git a/arch/arm/mach-socfpga/misc.c b/arch/arm/mach-socfpga/misc.c
> index 350aad1..3a2a1a4 100644
> --- a/arch/arm/mach-socfpga/misc.c
> +++ b/arch/arm/mach-socfpga/misc.c
> @@ -227,6 +227,11 @@ int socfpga_eth_reset_common(void (*resetfn)(const u8 of_reset_id,
>
>         return 0;
>  }
> +
> +__weak int socfpga_test_fpga_ready(void)
> +{
> +       return 0;
> +}

Nak.

This approach is frowned-upon, especially in driver model.

A better approach is to make most of the driver functions public (when
needed) and have a board-specific (s10?) implementation of the driver
that has its own compatible string and does whatever extra it needs to
do in init, then calls the shared init. All other functions are simply
registered in the board-specific driver.

>  #endif
>
>  #ifndef CONFIG_SPL_BUILD
> diff --git a/arch/arm/mach-socfpga/misc_s10.c b/arch/arm/mach-socfpga/misc_s10.c
> index e611d2c..3a8646f 100644
> --- a/arch/arm/mach-socfpga/misc_s10.c
> +++ b/arch/arm/mach-socfpga/misc_s10.c
> @@ -11,6 +11,7 @@
>  #include <miiphy.h>
>  #include <netdev.h>
>  #include <asm/io.h>
> +#include <asm/arch/mailbox_s10.h>
>  #include <asm/arch/reset_manager.h>
>  #include <asm/arch/system_manager.h>
>  #include <asm/arch/misc.h>
> @@ -91,6 +92,11 @@ static int socfpga_set_phymode(void)
>
>         return 0;
>  }
> +
> +int socfpga_test_fpga_ready(void)
> +{
> +       return mbox_get_fpga_config_status(MBOX_CONFIG_STATUS);
> +}
>  #else
>  static int socfpga_set_phymode(void)
>  {
> diff --git a/drivers/net/Makefile b/drivers/net/Makefile
> index 48a2878..c2333b5 100644
> --- a/drivers/net/Makefile
> +++ b/drivers/net/Makefile
> @@ -14,7 +14,7 @@ obj-$(CONFIG_CALXEDA_XGMAC) += calxedaxgmac.o
>  obj-$(CONFIG_CS8900) += cs8900.o
>  obj-$(CONFIG_TULIP) += dc2114x.o
>  obj-$(CONFIG_ETH_DESIGNWARE) += designware.o
> -obj-$(CONFIG_ETH_DESIGNWARE_SOCFPGA) += dwmac_socfpga.o
> +obj-$(CONFIG_ETH_DESIGNWARE_SOCFPGA) += dwmac-socfpga.o
>  obj-$(CONFIG_DRIVER_DM9000) += dm9000x.o
>  obj-$(CONFIG_DNET) += dnet.o
>  obj-$(CONFIG_E1000) += e1000.o
> @@ -73,3 +73,4 @@ obj-$(CONFIG_PIC32_ETH) += pic32_mdio.o pic32_eth.o
>  obj-$(CONFIG_DWC_ETH_QOS) += dwc_eth_qos.o
>  obj-$(CONFIG_FSL_PFE) += pfe_eth/
>  obj-$(CONFIG_SNI_AVE) += sni_ave.o
> +dwmac-socfpga-objs := phy/altr_tse_pcs.o dwmac_socfpga.o
> diff --git a/drivers/net/designware.c b/drivers/net/designware.c
> index 19db0a8..666cf41 100644
> --- a/drivers/net/designware.c
> +++ b/drivers/net/designware.c
> @@ -235,6 +235,8 @@ static int dw_adjust_link(struct dw_eth_dev *priv, struct eth_mac_regs *mac_p,
>                           struct phy_device *phydev)
>  {
>         u32 conf = readl(&mac_p->conf) | FRAMEBURSTENABLE | DISABLERXOWN;
> +       struct udevice *dev = priv->phydev->dev;
> +       struct dw_eth_pdata *dw_pdata = dev_get_platdata(dev);
>
>         if (!phydev->link) {
>                 printf("%s: No link.\n", phydev->dev->name);
> @@ -254,6 +256,9 @@ static int dw_adjust_link(struct dw_eth_dev *priv, struct eth_mac_regs *mac_p,
>
>         writel(conf, &mac_p->conf);
>
> +       if (dw_pdata->pcs_adjust_link)
> +               dw_pdata->pcs_adjust_link(dev, phydev);
> +
>         printf("Speed: %d, %s duplex%s\n", phydev->speed,
>                (phydev->duplex) ? "full" : "half",
>                (phydev->port == PORT_FIBRE) ? ", fiber mode" : "");
> diff --git a/drivers/net/designware.h b/drivers/net/designware.h
> index dea12b7..3a5a93f 100644
> --- a/drivers/net/designware.h
> +++ b/drivers/net/designware.h
> @@ -255,6 +255,7 @@ extern const struct eth_ops designware_eth_ops;
>  struct dw_eth_pdata {
>         struct eth_pdata eth_pdata;
>         u32 reset_delays[3];
> +       void (*pcs_adjust_link)(struct udevice *dev, struct phy_device *phydev);
>  };
>
>  int designware_eth_init(struct dw_eth_dev *priv, u8 *enetaddr);
> diff --git a/drivers/net/dwmac_socfpga.c b/drivers/net/dwmac_socfpga.c
> index 08fc967..70e95f8 100644
> --- a/drivers/net/dwmac_socfpga.c
> +++ b/drivers/net/dwmac_socfpga.c
> @@ -9,12 +9,16 @@
>  #include <asm/io.h>
>  #include <dm.h>
>  #include <clk.h>
> +#include <fdt_support.h>
>  #include <phy.h>
>  #include <regmap.h>
>  #include <reset.h>
>  #include <syscon.h>
>  #include "designware.h"
> +#include "phy/altr_tse_pcs.h"
>
> +#include <asm/arch/misc.h>
> +#include <asm/arch/reset_manager.h>
>  #include <asm/arch/system_manager.h>
>
>  enum dwmac_type {
> @@ -27,8 +31,122 @@ struct dwmac_socfpga_platdata {
>         struct dw_eth_pdata     dw_eth_pdata;
>         enum dwmac_type         type;
>         void                    *phy_intf;
> +       struct tse_pcs          pcs;
>  };
>
> +static void socfpga_tse_pcs_adjust_link(struct udevice *dev,
> +                                       struct phy_device *phydev)
> +{
> +       struct dwmac_socfpga_platdata *pdata = dev_get_platdata(dev);
> +       phys_addr_t tse_pcs_base = pdata->pcs.tse_pcs_base;
> +       phys_addr_t sgmii_adapter_base = pdata->pcs.sgmii_adapter_base;
> +
> +       if ((tse_pcs_base) && (sgmii_adapter_base))
> +               writew(SGMII_ADAPTER_DISABLE,
> +                      sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG);
> +
> +       if ((tse_pcs_base) && (sgmii_adapter_base))
> +               tse_pcs_fix_mac_speed(&pdata->pcs, phydev, phydev->speed);
> +}
> +
> +static int socfpga_dw_tse_pcs_init(struct udevice *dev)
> +{
> +       struct dwmac_socfpga_platdata *pdata = dev_get_platdata(dev);
> +       struct dw_eth_pdata *dw_pdata = &pdata->dw_eth_pdata;
> +       struct eth_pdata *eth_pdata = &pdata->dw_eth_pdata.eth_pdata;
> +       phys_addr_t tse_pcs_base = pdata->pcs.tse_pcs_base;
> +       phys_addr_t sgmii_adapter_base = pdata->pcs.sgmii_adapter_base;
> +       const fdt32_t *reg;
> +       int ret = 0;
> +       int parent, index, na, ns, offset, len;
> +
> +       offset = fdtdec_lookup_phandle(gd->fdt_blob, dev_of_offset(dev),
> +                                      "altr,gmii-to-sgmii-converter");
> +       if (offset > 0) {
> +               /* check FPGA status */
> +               ret = socfpga_test_fpga_ready();
> +               if (ret) {
> +                       debug("%s: FPGA status returns %d\n", __func__, ret);

Something like "%s: FPGA not ready (%d)\n" seems more appropriate.

> +                       return -EPERM;
> +               }
> +
> +               /* enable HPS bridge */
> +               do_bridge_reset(1);
> +
> +               parent = fdt_parent_offset(gd->fdt_blob, offset);
> +               if (parent < 0) {
> +                       debug("s10-hps-bridge DT not found\n");
> +                       return -ENODEV;
> +               }
> +
> +               na = fdt_address_cells(gd->fdt_blob, parent);
> +               if (na < 1) {
> +                       debug("bad #address-cells\n");
> +                       return -EINVAL;
> +               }
> +
> +               ns = fdt_size_cells(gd->fdt_blob, parent);
> +               if (ns < 1) {
> +                       debug("bad #size-cells\n");
> +                       return -EINVAL;
> +               }
> +
> +               index = fdt_stringlist_search(gd->fdt_blob, offset, "reg-names",
> +                                             "eth_tse_control_port");
> +               if (index < 0) {
> +                       debug("fail to find eth_tse_control_port: %s\n",
> +                             fdt_strerror(index));
> +                       return -ENOENT;
> +               }
> +
> +               reg = fdt_getprop(gd->fdt_blob, offset, "reg", &len);
> +               if (!reg || (len <= (index * sizeof(fdt32_t) * (na + ns))))
> +                       return -EINVAL;
> +
> +               reg += index * (na + ns);
> +               tse_pcs_base = fdt_translate_address((void *)gd->fdt_blob,
> +                                                    offset, reg);
> +               if (tse_pcs_base == FDT_ADDR_T_NONE) {
> +                       debug("tse pcs address not found\n");
> +                       return -EINVAL;
> +               }
> +
> +               index = fdt_stringlist_search(gd->fdt_blob, offset, "reg-names",
> +                                             "gmii_to_sgmii_adapter_avalon_slave");
> +               if (index < 0) {
> +                       debug("fail to find gmii_to_sgmii_adapter_avalon_slave: %s\n",
> +                             fdt_strerror(index));
> +                       return -EINVAL;
> +               }
> +
> +               reg = fdt_getprop(gd->fdt_blob, offset, "reg", &len);
> +               if (!reg || (len <= (index * sizeof(fdt32_t) * (na + ns))))
> +                       return -EINVAL;
> +
> +               reg += index * (na + ns);
> +               sgmii_adapter_base = fdt_translate_address((void *)gd->fdt_blob,
> +                                                          offset, reg);
> +               if (sgmii_adapter_base == FDT_ADDR_T_NONE) {
> +                       debug("gmii-to-sgmii adapter address not found\n");
> +                       return -EINVAL;
> +               }
> +
> +               if (eth_pdata->phy_interface == PHY_INTERFACE_MODE_SGMII) {
> +                       if (tse_pcs_init(tse_pcs_base, &pdata->pcs) != 0) {
> +                               debug("Unable to intiialize TSE PCS\n");
> +                               return -EINVAL;
> +                       }
> +               }
> +               /* Clear sgmii_adapter_base first */
> +               writel(0, sgmii_adapter_base);
> +
> +               pdata->pcs.tse_pcs_base = tse_pcs_base;
> +               pdata->pcs.sgmii_adapter_base = sgmii_adapter_base;
> +               dw_pdata->pcs_adjust_link = socfpga_tse_pcs_adjust_link;
> +       }
> +       return ret;
> +}
> +
>  static int dwmac_socfpga_ofdata_to_platdata(struct udevice *dev)
>  {
>         struct dwmac_socfpga_platdata *pdata = dev_get_platdata(dev);
> @@ -94,6 +212,7 @@ static int dwmac_socfpga_probe(struct udevice *dev)
>                 switch (edata->phy_interface) {
>                 case PHY_INTERFACE_MODE_MII:
>                 case PHY_INTERFACE_MODE_GMII:
> +               case PHY_INTERFACE_MODE_SGMII:
>                         modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII;
>                         break;
>                 case PHY_INTERFACE_MODE_RMII:
> @@ -122,6 +241,8 @@ static int dwmac_socfpga_probe(struct udevice *dev)
>                 reset_release_bulk(&reset_bulk);
>         }
>
> +       socfpga_dw_tse_pcs_init(dev);
> +
>         return designware_eth_probe(dev);
>  }
>
> diff --git a/drivers/net/phy/altr_tse_pcs.c b/drivers/net/phy/altr_tse_pcs.c
> new file mode 100644
> index 0000000..459695c
> --- /dev/null
> +++ b/drivers/net/phy/altr_tse_pcs.c
> @@ -0,0 +1,197 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2018 Intel Corporation <www.intel.com>
> + */
> +
> +#include <asm/io.h>
> +#include <common.h>
> +#include <command.h>
> +#include <malloc.h>
> +#include <net.h>
> +#include <linux/compat.h>
> +#include <phy.h>
> +#include <timer.h>
> +#include <linux/ethtool.h>
> +
> +#include <asm/omap_common.h>
> +#include <asm/omap_musb.h>
> +
> +#include "altr_tse_pcs.h"
> +
> +static int tse_pcs_reset(phys_addr_t base, struct tse_pcs *pcs)
> +{
> +       int counter = 0;
> +       u16 val;
> +
> +       val = readw(base + TSE_PCS_CONTROL_REG);
> +       val |= TSE_PCS_SW_RST_MASK;
> +
> +       writew(val, base + TSE_PCS_CONTROL_REG);
> +
> +       while (counter < TSE_PCS_SW_RESET_TIMEOUT) {
> +               val = readw(base + TSE_PCS_CONTROL_REG);
> +               val &= TSE_PCS_SW_RST_MASK;
> +               if (val == 0)
> +                       break;
> +               counter++;
> +               udelay(1);
> +       }

Please use wait_for_bit_le16() from include/wait_bit.h.

> +
> +       if (counter >= TSE_PCS_SW_RESET_TIMEOUT) {
> +               debug("%s: PCS could not get out of sw reset\n", __func__);
> +               return -ETIMEDOUT;
> +       }
> +
> +       return 0;
> +}
> +
> +int tse_pcs_init(phys_addr_t base, struct tse_pcs *pcs)
> +{
> +       int ret = 0;
> +
> +       writew(TSE_PCS_USE_SGMII_ENA, base + TSE_PCS_IF_MODE_REG);
> +       writew(TSE_PCS_SGMII_LINK_TIMER_0, base + TSE_PCS_LINK_TIMER_0_REG);
> +       writew(TSE_PCS_SGMII_LINK_TIMER_1, base + TSE_PCS_LINK_TIMER_1_REG);
> +
> +       ret = tse_pcs_reset(base, pcs);
> +       if (ret == 0)
> +               writew(SGMII_ADAPTER_ENABLE,
> +                      pcs->sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG);
> +
> +       return ret;
> +}
> +
> +static void pcs_link_timer_callback(struct tse_pcs *pcs)
> +{
> +       u16 val = 0;
> +       phys_addr_t tse_pcs_base = pcs->tse_pcs_base;
> +       phys_addr_t sgmii_adapter_base = pcs->sgmii_adapter_base;
> +
> +       val = readw(tse_pcs_base + TSE_PCS_STATUS_REG);
> +       val &= TSE_PCS_STATUS_LINK_MASK;
> +
> +       if (val != 0) {
> +               printf("Adapter: Link is established\n");
> +               writew(SGMII_ADAPTER_ENABLE,
> +                      sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG);
> +       } else {
> +               printf("Adapter: Link fail to establish\n");
> +       }
> +}
> +
> +static void auto_nego_timer_callback(struct tse_pcs *pcs)
> +{
> +       u16 val = 0;
> +       u16 speed = 0;
> +       u16 duplex = 0;
> +       phys_addr_t tse_pcs_base = pcs->tse_pcs_base;
> +       phys_addr_t sgmii_adapter_base = pcs->sgmii_adapter_base;
> +
> +       val = readw(tse_pcs_base + TSE_PCS_STATUS_REG);
> +       val &= TSE_PCS_STATUS_AN_COMPLETED_MASK;
> +
> +       if (val != 0) {
> +               printf("Adapter: Auto Negotiation is completed\n");
> +               val = readw(tse_pcs_base + TSE_PCS_PARTNER_ABILITY_REG);
> +               speed = val & TSE_PCS_PARTNER_SPEED_MASK;
> +               duplex = val & TSE_PCS_PARTNER_DUPLEX_MASK;
> +
> +               if (speed == TSE_PCS_PARTNER_SPEED_10 &&
> +                   duplex == TSE_PCS_PARTNER_DUPLEX_FULL)
> +                       printf("Adapter: Link Partner is Up - 10/Full\n");
> +               else if (speed == TSE_PCS_PARTNER_SPEED_100 &&
> +                        duplex == TSE_PCS_PARTNER_DUPLEX_FULL)
> +                       printf("Adapter: Link Partner is Up - 100/Full\n");
> +               else if (speed == TSE_PCS_PARTNER_SPEED_1000 &&
> +                        duplex == TSE_PCS_PARTNER_DUPLEX_FULL)
> +                       printf("Adapter: Link Partner is Up - 1000/Full\n");
> +               else if (speed == TSE_PCS_PARTNER_SPEED_10 &&
> +                        duplex == TSE_PCS_PARTNER_DUPLEX_HALF)
> +                       printf("Adapter does not support Half Duplex\n");
> +               else if (speed == TSE_PCS_PARTNER_SPEED_100 &&
> +                        duplex == TSE_PCS_PARTNER_DUPLEX_HALF)
> +                       printf("Adapter does not support Half Duplex\n");
> +               else if (speed == TSE_PCS_PARTNER_SPEED_1000 &&
> +                        duplex == TSE_PCS_PARTNER_DUPLEX_HALF)
> +                       printf("Adapter does not support Half Duplex\n");

Please consolidate this to simply one test of:

                if (duplex == TSE_PCS_PARTNER_DUPLEX_HALF) {
                        printf("Adapter does not support Half Duplex\n");
                        return;
                }

instead of 3 tests with the same output, and move it to the top.

> +               else
> +                       printf("Adapter: Invalid Partner Speed and Duplex\n");

Similarly, move this just after the half duplex check, and use not (!
- the operator) of the test immediately below.

Then the rest of this is simplified. No need to check the blow again
and no need to test for full duplex on each print.

> +
> +               if (duplex == TSE_PCS_PARTNER_DUPLEX_FULL &&
> +                   (speed == TSE_PCS_PARTNER_SPEED_10 ||
> +                    speed == TSE_PCS_PARTNER_SPEED_100 ||
> +                    speed == TSE_PCS_PARTNER_SPEED_1000))
> +                       writew(SGMII_ADAPTER_ENABLE,
> +                              sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG);
> +       } else {
> +               printf("Auto-negotioation failed\n");
> +       }
> +}
> +
> +void tse_pcs_fix_mac_speed(struct tse_pcs *pcs, struct phy_device *phy_dev,
> +                          unsigned int speed)
> +{
> +       phys_addr_t tse_pcs_base = pcs->tse_pcs_base;
> +       phys_addr_t sgmii_adapter_base = pcs->sgmii_adapter_base;
> +       u32 val, start;
> +
> +       writew(SGMII_ADAPTER_ENABLE,
> +              sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG);
> +       pcs->autoneg = phy_dev->autoneg;
> +
> +       if (pcs->autoneg == AUTONEG_ENABLE) {
> +               val = readw(tse_pcs_base + TSE_PCS_CONTROL_REG);
> +               val |= TSE_PCS_CONTROL_AN_EN_MASK;
> +               writew(val, tse_pcs_base + TSE_PCS_CONTROL_REG);
> +
> +               val = readw(tse_pcs_base + TSE_PCS_IF_MODE_REG);
> +               val |= TSE_PCS_USE_SGMII_AN_MASK;
> +               writew(val, tse_pcs_base + TSE_PCS_IF_MODE_REG);
> +
> +               val = readw(tse_pcs_base + TSE_PCS_CONTROL_REG);
> +               val |= TSE_PCS_CONTROL_RESTART_AN_MASK;
> +
> +               tse_pcs_reset(tse_pcs_base, pcs);
> +
> +       } else if (pcs->autoneg == AUTONEG_DISABLE) {
> +               val = readw(tse_pcs_base + TSE_PCS_CONTROL_REG);
> +               val &= ~TSE_PCS_CONTROL_AN_EN_MASK;
> +               writew(val, tse_pcs_base + TSE_PCS_CONTROL_REG);
> +
> +               val = readw(tse_pcs_base + TSE_PCS_IF_MODE_REG);
> +               val &= ~TSE_PCS_USE_SGMII_AN_MASK;
> +               writew(val, tse_pcs_base + TSE_PCS_IF_MODE_REG);
> +
> +               val = readw(tse_pcs_base + TSE_PCS_IF_MODE_REG);
> +               val &= ~TSE_PCS_SGMII_SPEED_MASK;
> +
> +               switch (speed) {
> +               case 1000:
> +                       val |= TSE_PCS_SGMII_SPEED_1000;
> +                       break;
> +               case 100:
> +                       val |= TSE_PCS_SGMII_SPEED_100;
> +                       break;
> +               case 10:
> +                       val |= TSE_PCS_SGMII_SPEED_10;
> +                       break;
> +               default:
> +                       return;
> +               }
> +               writew(val, tse_pcs_base + TSE_PCS_IF_MODE_REG);
> +
> +               tse_pcs_reset(tse_pcs_base, pcs);
> +       }
> +
> +       start = get_timer(0);
> +       while (1) {
> +               if (get_timer(start) >= AUTONEGO_LINK_TIMER) {
> +                       if (pcs->autoneg == AUTONEG_ENABLE)
> +                               auto_nego_timer_callback(pcs);
> +                       else if (pcs->autoneg == AUTONEG_DISABLE)
> +                               pcs_link_timer_callback(pcs);
> +                       return;
> +               }
> +               udelay(100);
> +       }
> +}
> diff --git a/drivers/net/phy/altr_tse_pcs.h b/drivers/net/phy/altr_tse_pcs.h
> new file mode 100644
> index 0000000..e0c0c34
> --- /dev/null
> +++ b/drivers/net/phy/altr_tse_pcs.h
> @@ -0,0 +1,59 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2018 Intel Corporation <www.intel.com>
> + */
> +
> +#ifndef __TSE_PCS_H__
> +#define __TSE_PCS_H__
> +
> +#define TSE_PCS_CONTROL_AN_EN_MASK                     BIT(12)
> +#define TSE_PCS_CONTROL_REG                            0x00
> +#define TSE_PCS_CONTROL_RESTART_AN_MASK                        BIT(9)
> +#define TSE_PCS_IF_MODE_REG                            0x28
> +#define TSE_PCS_LINK_TIMER_0_REG                       0x24
> +#define TSE_PCS_LINK_TIMER_1_REG                       0x26
> +#define TSE_PCS_SIZE                                   0x40
> +#define TSE_PCS_STATUS_AN_COMPLETED_MASK               BIT(5)
> +#define TSE_PCS_STATUS_LINK_MASK                       0x0004
> +#define TSE_PCS_STATUS_REG                             0x02
> +#define TSE_PCS_SGMII_SPEED_1000                       BIT(3)
> +#define TSE_PCS_SGMII_SPEED_100                                BIT(2)
> +#define TSE_PCS_SGMII_SPEED_10                         0x0
> +#define TSE_PCS_SW_RST_MASK                            0x8000

Please use BIT() and GEN_MASK() consistently here.

> +#define TSE_PCS_PARTNER_ABILITY_REG                    0x0A
> +#define TSE_PCS_PARTNER_DUPLEX_FULL                    0x1000
> +#define TSE_PCS_PARTNER_DUPLEX_HALF                    0x0000
> +#define TSE_PCS_PARTNER_DUPLEX_MASK                    0x1000
> +#define TSE_PCS_PARTNER_SPEED_MASK                     GENMASK(11, 10)
> +#define TSE_PCS_PARTNER_SPEED_1000                     BIT(11)
> +#define TSE_PCS_PARTNER_SPEED_100                      BIT(10)
> +#define TSE_PCS_PARTNER_SPEED_10                       0x0000
> +#define TSE_PCS_PARTNER_SPEED_1000                     BIT(11)
> +#define TSE_PCS_PARTNER_SPEED_100                      BIT(10)
> +#define TSE_PCS_PARTNER_SPEED_10                       0x0000

These 3 are defined twice here. Please delete them.

> +#define TSE_PCS_SGMII_SPEED_MASK                       GENMASK(3, 2)

Please move this up after TSE_PCS_SGMII_SPEED_10.

> +#define TSE_PCS_SGMII_LINK_TIMER_0                     0x0D40
> +#define TSE_PCS_SGMII_LINK_TIMER_1                     0x0003
> +#define TSE_PCS_SW_RESET_TIMEOUT                       100
> +#define TSE_PCS_USE_SGMII_AN_MASK                      BIT(1)
> +#define TSE_PCS_USE_SGMII_ENA                          BIT(0)
> +
> +#define SGMII_ADAPTER_CTRL_REG                         0x00
> +#define SGMII_ADAPTER_DISABLE                          0x0001
> +#define SGMII_ADAPTER_ENABLE                           0x0000
> +
> +#define AUTONEGO_LINK_TIMER                            20
> +
> +struct tse_pcs {
> +       struct device *dev;
> +       phys_addr_t tse_pcs_base;
> +       phys_addr_t sgmii_adapter_base;
> +       struct timer_list aneg_link_timer;
> +       int autoneg;
> +};
> +
> +int tse_pcs_init(phys_addr_t base, struct tse_pcs *pcs);
> +void tse_pcs_fix_mac_speed(struct tse_pcs *pcs, struct phy_device *phy_dev,
> +                          unsigned int speed);
> +
> +#endif /* __TSE_PCS_H__ */
> --
> 1.9.1
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> https://lists.denx.de/listinfo/u-boot


More information about the U-Boot mailing list