On 12/26/18 8:47 AM, Ooi, Joyce wrote: > Adding Marek. > >> -----Original Message----- >> From: U-Boot [mailto:u-boot-boun...@lists.denx.de] On Behalf Of Ooi, Joyce >> Sent: Tuesday, November 27, 2018 5:40 PM >> To: Joe Hershberger <joe.hershber...@ni.com> >> Cc: Ong, Hean Loong <hean.loong....@intel.com>; Priyanka Jain >> <priyanka.j...@nxp.com>; See, Chin Liang <chin.liang....@intel.com>; u- >> b...@lists.denx.de >> Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- >> socfpga >> >> Hi Joe, >> >> Any comments/feedback on this v3 patch?
I thought we already had TSE support in drivers/net/altera_tse.c , is this related ? >> Thanks. >> >> Regards, >> Joyce Ooi >> >>> -----Original Message----- >>> From: Ooi, Joyce >>> Sent: Friday, November 9, 2018 6:16 PM >>> To: Joe Hershberger <joe.hershber...@ni.com> >>> Cc: Grygorii Strashko <grygorii.stras...@ti.com>; Neil Armstrong >>> <narmstr...@baylibre.com>; Mario Six <mario....@gdsys.cc>; Florian >>> Fainelli <f.faine...@gmail.com>; Priyanka Jain >>> <priyanka.j...@nxp.com>; Ooi, Joyce <joyce....@intel.com>; See, Chin >>> Liang <chin.liang....@intel.com>; Ong, Hean Loong >>> <hean.loong....@intel.com>; u-boot@lists.denx.de >>> Subject: [PATCH v3] net: phy: add TSE PCS support to dwmac-socfpga >>> >>> 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....@intel.com> >>> --- >>> arch/arm/mach-socfpga/include/mach/misc.h | 3 + >>> 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 | 122 +++++++++++++++++++ >>> drivers/net/phy/altr_tse_pcs.c | 184 >> +++++++++++++++++++++++++++++ >>> drivers/net/phy/altr_tse_pcs.h | 56 +++++++++ >>> 8 files changed, 379 insertions(+), 1 deletions(-) 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 >>> v3: remove __weak function and use board-specific implementation >>> instead >>> >>> diff --git a/arch/arm/mach-socfpga/include/mach/misc.h >>> b/arch/arm/mach- socfpga/include/mach/misc.h index 4fc9570..751705e >>> 100644 >>> --- a/arch/arm/mach-socfpga/include/mach/misc.h >>> +++ b/arch/arm/mach-socfpga/include/mach/misc.h >>> @@ -30,6 +30,9 @@ void socfpga_init_security_policies(void); >>> void socfpga_sdram_remap_zero(void); >>> #endif >>> >>> +#ifdef CONFIG_TARGET_SOCFPGA_STRATIX10 int >>> +socfpga_test_fpga_ready(void); #endif >>> void do_bridge_reset(int enable); >>> >>> #endif /* _MISC_H_ */ >>> diff --git a/arch/arm/mach-socfpga/misc_s10.c b/arch/arm/mach- >>> socfpga/misc_s10.c index e599362..3cd9c30 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..7d13f3c 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,123 @@ 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) { >>> +#ifdef CONFIG_TARGET_SOCFPGA_STRATIX10 >>> + /* check FPGA status */ >>> + ret = socfpga_test_fpga_ready(); >>> + if (ret) { >>> + debug("%s: FPGA not ready (%d)\n", __func__, ret); >>> + return -EPERM; >>> + } >>> +#endif >>> + /* enable HPS bridge */ >>> + do_bridge_reset(1); Why is generic ethernet driver touching FPGA bridges ? >>> + 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"); devfdt_get_addr_name() ? >>> + 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 +213,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 +242,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..4423538 >>> --- /dev/null >>> +++ b/drivers/net/phy/altr_tse_pcs.c >>> @@ -0,0 +1,184 @@ >>> +// 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 <wait_bit.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 ret; >>> + u16 val; >>> + phys_addr_t reg = base + TSE_PCS_CONTROL_REG; >>> + >>> + val = readw(reg); >>> + val |= TSE_PCS_SW_RST_MASK; setbits_le16() , fix globally. [...] -- Best regards, Marek Vasut _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot