[U-Boot] [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.ooi@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); + + 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 +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; + + writew(val, reg); + + ret = wait_for_bit_le16(®, TSE_PCS_SW_RST_MASK, false, + TSE_PCS_SW_RESET_TIMEOUT, false); + + if (ret) { + 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 (duplex == TSE_PCS_PARTNER_DUPLEX_FULL) { + if (speed == TSE_PCS_PARTNER_SPEED_10) + printf("Adapter: Link Partner is Up - 10/Full\n"); + else if (speed == TSE_PCS_PARTNER_SPEED_100) + printf("Adapter: Link Partner is Up - 100/Full\n"); + else if (speed == TSE_PCS_PARTNER_SPEED_1000) + printf("Adapter: Link Partner is Up - 1000/Full\n"); + } else if (duplex == TSE_PCS_PARTNER_DUPLEX_HALF) + printf("Adapter does not support Half Duplex\n"); + else + printf("Adapter: Invalid Partner Speed and Duplex\n"); + + 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..0e8d4f4 --- /dev/null +++ b/drivers/net/phy/altr_tse_pcs.h @@ -0,0 +1,56 @@ +// 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 BIT(2) +#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_SGMII_SPEED_MASK GENMASK(3, 2) +#define TSE_PCS_SW_RST_MASK BIT(15) +#define TSE_PCS_PARTNER_ABILITY_REG 0x0A +#define TSE_PCS_PARTNER_DUPLEX_FULL BIT(12) +#define TSE_PCS_PARTNER_DUPLEX_HALF 0x0000 +#define TSE_PCS_PARTNER_DUPLEX_MASK BIT(12) +#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_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__ */

Hi Joe,
Any comments/feedback on this v3 patch?
Thanks.
Regards, Joyce Ooi
-----Original Message----- From: Ooi, Joyce Sent: Friday, November 9, 2018 6:16 PM To: Joe Hershberger joe.hershberger@ni.com Cc: Grygorii Strashko grygorii.strashko@ti.com; Neil Armstrong narmstrong@baylibre.com; Mario Six mario.six@gdsys.cc; Florian Fainelli f.fainelli@gmail.com; Priyanka Jain priyanka.jain@nxp.com; Ooi, Joyce joyce.ooi@intel.com; See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@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.ooi@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);
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 +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;
- writew(val, reg);
- ret = wait_for_bit_le16(®, TSE_PCS_SW_RST_MASK, false,
TSE_PCS_SW_RESET_TIMEOUT, false);
- if (ret) {
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 (duplex == TSE_PCS_PARTNER_DUPLEX_FULL) {
if (speed == TSE_PCS_PARTNER_SPEED_10)
printf("Adapter: Link Partner is Up - 10/Full\n");
else if (speed == TSE_PCS_PARTNER_SPEED_100)
printf("Adapter: Link Partner is Up -
100/Full\n");
else if (speed == TSE_PCS_PARTNER_SPEED_1000)
printf("Adapter: Link Partner is Up -
1000/Full\n");
} else if (duplex == TSE_PCS_PARTNER_DUPLEX_HALF)
printf("Adapter does not support Half Duplex\n");
else
printf("Adapter: Invalid Partner Speed and Duplex\n");
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..0e8d4f4 --- /dev/null +++ b/drivers/net/phy/altr_tse_pcs.h @@ -0,0 +1,56 @@ +// 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 BIT(2) +#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_SGMII_SPEED_MASK GENMASK(3, 2) +#define TSE_PCS_SW_RST_MASK BIT(15) +#define TSE_PCS_PARTNER_ABILITY_REG 0x0A +#define TSE_PCS_PARTNER_DUPLEX_FULL BIT(12) +#define TSE_PCS_PARTNER_DUPLEX_HALF 0x0000 +#define TSE_PCS_PARTNER_DUPLEX_MASK BIT(12) +#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_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.7.1

Adding Marek.
-----Original Message----- From: U-Boot [mailto:u-boot-bounces@lists.denx.de] On Behalf Of Ooi, Joyce Sent: Tuesday, November 27, 2018 5:40 PM To: Joe Hershberger joe.hershberger@ni.com Cc: Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; See, Chin Liang chin.liang.see@intel.com; u- boot@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?
Thanks.
Regards, Joyce Ooi
-----Original Message----- From: Ooi, Joyce Sent: Friday, November 9, 2018 6:16 PM To: Joe Hershberger joe.hershberger@ni.com Cc: Grygorii Strashko grygorii.strashko@ti.com; Neil Armstrong narmstrong@baylibre.com; Mario Six mario.six@gdsys.cc; Florian Fainelli f.fainelli@gmail.com; Priyanka Jain priyanka.jain@nxp.com; Ooi, Joyce joyce.ooi@intel.com; See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@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.ooi@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);
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 +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;
- writew(val, reg);
- ret = wait_for_bit_le16(®, TSE_PCS_SW_RST_MASK, false,
TSE_PCS_SW_RESET_TIMEOUT, false);
- if (ret) {
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 (duplex == TSE_PCS_PARTNER_DUPLEX_FULL) {
if (speed == TSE_PCS_PARTNER_SPEED_10)
printf("Adapter: Link Partner is Up - 10/Full\n");
else if (speed == TSE_PCS_PARTNER_SPEED_100)
printf("Adapter: Link Partner is Up -
100/Full\n");
else if (speed == TSE_PCS_PARTNER_SPEED_1000)
printf("Adapter: Link Partner is Up -
1000/Full\n");
} else if (duplex == TSE_PCS_PARTNER_DUPLEX_HALF)
printf("Adapter does not support Half Duplex\n");
else
printf("Adapter: Invalid Partner Speed and Duplex\n");
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..0e8d4f4 --- /dev/null +++ b/drivers/net/phy/altr_tse_pcs.h @@ -0,0 +1,56 @@ +// 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 BIT(2) +#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_SGMII_SPEED_MASK GENMASK(3,
+#define TSE_PCS_SW_RST_MASK BIT(15) +#define TSE_PCS_PARTNER_ABILITY_REG 0x0A +#define TSE_PCS_PARTNER_DUPLEX_FULL BIT(12) +#define TSE_PCS_PARTNER_DUPLEX_HALF 0x0000 +#define TSE_PCS_PARTNER_DUPLEX_MASK BIT(12) +#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_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.7.1
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot

On 12/26/18 8:47 AM, Ooi, Joyce wrote:
Adding Marek.
-----Original Message----- From: U-Boot [mailto:u-boot-bounces@lists.denx.de] On Behalf Of Ooi, Joyce Sent: Tuesday, November 27, 2018 5:40 PM To: Joe Hershberger joe.hershberger@ni.com Cc: Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; See, Chin Liang chin.liang.see@intel.com; u- boot@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.hershberger@ni.com Cc: Grygorii Strashko grygorii.strashko@ti.com; Neil Armstrong narmstrong@baylibre.com; Mario Six mario.six@gdsys.cc; Florian Fainelli f.fainelli@gmail.com; Priyanka Jain priyanka.jain@nxp.com; Ooi, Joyce joyce.ooi@intel.com; See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@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.ooi@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.
[...]

-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Thursday, December 27, 2018 2:55 AM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 12/26/18 8:47 AM, Ooi, Joyce wrote:
Adding Marek.
-----Original Message----- From: U-Boot [mailto:u-boot-bounces@lists.denx.de] On Behalf Of Ooi, Joyce Sent: Tuesday, November 27, 2018 5:40 PM To: Joe Hershberger joe.hershberger@ni.com Cc: Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; See, Chin Liang chin.liang.see@intel.com; u- boot@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 ?
drivers/net/altera_tse.c is a different IP, which contains of MAC driver from Intel FPGA and PCS driver from Intel FPGA using MDIO PMA.
This net/phy/altr_tse_pcs.c is the Physical Coding Sublayer for DWMAC SGMII IP. The DWMAC SGMII IP contains of MAC driver from DWMAC (Synopsis) and PCS driver from Intel FPGA controlling Marvell PHY.
Thanks.
Regards, Joyce Ooi
-----Original Message----- From: Ooi, Joyce Sent: Friday, November 9, 2018 6:16 PM To: Joe Hershberger joe.hershberger@ni.com Cc: Grygorii Strashko grygorii.strashko@ti.com; Neil Armstrong narmstrong@baylibre.com; Mario Six mario.six@gdsys.cc; Florian Fainelli f.fainelli@gmail.com; Priyanka Jain priyanka.jain@nxp.com; Ooi, Joyce joyce.ooi@intel.com; See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@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.ooi@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

On 12/27/18 7:16 AM, Ooi, Joyce wrote:
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Thursday, December 27, 2018 2:55 AM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 12/26/18 8:47 AM, Ooi, Joyce wrote:
Adding Marek.
-----Original Message----- From: U-Boot [mailto:u-boot-bounces@lists.denx.de] On Behalf Of Ooi, Joyce Sent: Tuesday, November 27, 2018 5:40 PM To: Joe Hershberger joe.hershberger@ni.com Cc: Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; See, Chin Liang chin.liang.see@intel.com; u- boot@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 ?
drivers/net/altera_tse.c is a different IP, which contains of MAC driver from Intel FPGA and PCS driver from Intel FPGA using MDIO PMA.
This net/phy/altr_tse_pcs.c is the Physical Coding Sublayer for DWMAC SGMII IP. The DWMAC SGMII IP contains of MAC driver from DWMAC (Synopsis) and PCS driver from Intel FPGA controlling Marvell PHY.
Does this patch need to be split into two (three) patches then ?
[...]

-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Thursday, December 27, 2018 4:21 PM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 12/27/18 7:16 AM, Ooi, Joyce wrote:
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Thursday, December 27, 2018 2:55 AM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 12/26/18 8:47 AM, Ooi, Joyce wrote:
Adding Marek.
-----Original Message----- From: U-Boot [mailto:u-boot-bounces@lists.denx.de] On Behalf Of Ooi, Joyce Sent: Tuesday, November 27, 2018 5:40 PM To: Joe Hershberger joe.hershberger@ni.com Cc: Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; See, Chin Liang chin.liang.see@intel.com; u- boot@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 ?
drivers/net/altera_tse.c is a different IP, which contains of MAC driver from Intel FPGA and PCS driver from Intel FPGA using MDIO PMA.
This net/phy/altr_tse_pcs.c is the Physical Coding Sublayer for DWMAC SGMII
IP.
The DWMAC SGMII IP contains of MAC driver from DWMAC (Synopsis) and PCS driver from Intel FPGA controlling Marvell PHY.
Does this patch need to be split into two (three) patches then ?
This patch adds TSE PCS support to existing dwmac-socfpga.c and designware.c, which adds a new file net/phy/altr_tse_pcs.c, while dwmac-socfpga.c and designware.c call its functions. Hence, I didn't split this implementation into several patches because I didn't want net/phy/altr_tse_pcs.c to appear like a dead code.
If it's confusing, I could rename altr_tse_pcs.c to altr_dwmac_pcs.c, since it is under DWMAC SGMII.
[...]
-- Best regards, Marek Vasut

On 12/28/18 7:57 AM, Ooi, Joyce wrote:
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Thursday, December 27, 2018 4:21 PM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 12/27/18 7:16 AM, Ooi, Joyce wrote:
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Thursday, December 27, 2018 2:55 AM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 12/26/18 8:47 AM, Ooi, Joyce wrote:
Adding Marek.
-----Original Message----- From: U-Boot [mailto:u-boot-bounces@lists.denx.de] On Behalf Of Ooi, Joyce Sent: Tuesday, November 27, 2018 5:40 PM To: Joe Hershberger joe.hershberger@ni.com Cc: Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; See, Chin Liang chin.liang.see@intel.com; u- boot@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 ?
drivers/net/altera_tse.c is a different IP, which contains of MAC driver from Intel FPGA and PCS driver from Intel FPGA using MDIO PMA.
This net/phy/altr_tse_pcs.c is the Physical Coding Sublayer for DWMAC SGMII
IP.
The DWMAC SGMII IP contains of MAC driver from DWMAC (Synopsis) and PCS driver from Intel FPGA controlling Marvell PHY.
Does this patch need to be split into two (three) patches then ?
This patch adds TSE PCS support to existing dwmac-socfpga.c and designware.c, which adds a new file net/phy/altr_tse_pcs.c, while dwmac-socfpga.c and designware.c call its functions. Hence, I didn't split this implementation into several patches because I didn't want net/phy/altr_tse_pcs.c to appear like a dead code.
If it's confusing, I could rename altr_tse_pcs.c to altr_dwmac_pcs.c, since it is under DWMAC SGMII.
Is it a separate block which could be used by both Altera TSE and DWMAC or not ?

-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Friday, December 28, 2018 6:06 PM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 12/28/18 7:57 AM, Ooi, Joyce wrote:
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Thursday, December 27, 2018 4:21 PM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 12/27/18 7:16 AM, Ooi, Joyce wrote:
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Thursday, December 27, 2018 2:55 AM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 12/26/18 8:47 AM, Ooi, Joyce wrote:
Adding Marek.
> -----Original Message----- > From: U-Boot [mailto:u-boot-bounces@lists.denx.de] On Behalf Of > Ooi, Joyce > Sent: Tuesday, November 27, 2018 5:40 PM > To: Joe Hershberger joe.hershberger@ni.com > Cc: Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain > priyanka.jain@nxp.com; See, Chin Liang > chin.liang.see@intel.com; > u- boot@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 ?
drivers/net/altera_tse.c is a different IP, which contains of MAC driver from Intel FPGA and PCS driver from Intel FPGA using MDIO PMA.
This net/phy/altr_tse_pcs.c is the Physical Coding Sublayer for DWMAC SGMII
IP.
The DWMAC SGMII IP contains of MAC driver from DWMAC (Synopsis) and PCS driver from Intel FPGA controlling Marvell PHY.
Does this patch need to be split into two (three) patches then ?
This patch adds TSE PCS support to existing dwmac-socfpga.c and designware.c, which adds a new file net/phy/altr_tse_pcs.c, while dwmac-socfpga.c and designware.c call its functions. Hence, I didn't split this implementation into several patches because I didn't want
net/phy/altr_tse_pcs.c to appear like a dead code.
If it's confusing, I could rename altr_tse_pcs.c to altr_dwmac_pcs.c, since it is under DWMAC SGMII.
Is it a separate block which could be used by both Altera TSE and DWMAC or not ?
Yes, both Altera TSE and DWMAC can use it. Now that you mention it, I guess I'll remain with altr_tse_pcs.c in case Altera TSE needs to enable SGMII in the future.
-- Best regards, Marek Vasut

On 12/28/18 2:38 PM, Ooi, Joyce wrote:
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Friday, December 28, 2018 6:06 PM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 12/28/18 7:57 AM, Ooi, Joyce wrote:
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Thursday, December 27, 2018 4:21 PM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 12/27/18 7:16 AM, Ooi, Joyce wrote:
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Thursday, December 27, 2018 2:55 AM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 12/26/18 8:47 AM, Ooi, Joyce wrote: > Adding Marek. > >> -----Original Message----- >> From: U-Boot [mailto:u-boot-bounces@lists.denx.de] On Behalf Of >> Ooi, Joyce >> Sent: Tuesday, November 27, 2018 5:40 PM >> To: Joe Hershberger joe.hershberger@ni.com >> Cc: Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain >> priyanka.jain@nxp.com; See, Chin Liang >> chin.liang.see@intel.com; >> u- boot@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 ?
drivers/net/altera_tse.c is a different IP, which contains of MAC driver from Intel FPGA and PCS driver from Intel FPGA using MDIO PMA.
This net/phy/altr_tse_pcs.c is the Physical Coding Sublayer for DWMAC SGMII
IP.
The DWMAC SGMII IP contains of MAC driver from DWMAC (Synopsis) and PCS driver from Intel FPGA controlling Marvell PHY.
Does this patch need to be split into two (three) patches then ?
This patch adds TSE PCS support to existing dwmac-socfpga.c and designware.c, which adds a new file net/phy/altr_tse_pcs.c, while dwmac-socfpga.c and designware.c call its functions. Hence, I didn't split this implementation into several patches because I didn't want
net/phy/altr_tse_pcs.c to appear like a dead code.
If it's confusing, I could rename altr_tse_pcs.c to altr_dwmac_pcs.c, since it is under DWMAC SGMII.
Is it a separate block which could be used by both Altera TSE and DWMAC or not ?
Yes, both Altera TSE and DWMAC can use it. Now that you mention it, I guess I'll remain with altr_tse_pcs.c in case Altera TSE needs to enable SGMII in the future.
Right, and it should be split accordingly.

-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Thursday, December 27, 2018 2:55 AM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 12/26/18 8:47 AM, Ooi, Joyce wrote:
Adding Marek.
-----Original Message----- From: U-Boot [mailto:u-boot-bounces@lists.denx.de] On Behalf Of Ooi, Joyce Sent: Tuesday, November 27, 2018 5:40 PM To: Joe Hershberger joe.hershberger@ni.com Cc: Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; See, Chin Liang chin.liang.see@intel.com; u- boot@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.hershberger@ni.com Cc: Grygorii Strashko grygorii.strashko@ti.com; Neil Armstrong narmstrong@baylibre.com; Mario Six mario.six@gdsys.cc; Florian Fainelli f.fainelli@gmail.com; Priyanka Jain priyanka.jain@nxp.com; Ooi, Joyce joyce.ooi@intel.com; See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@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.ooi@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 ?
This is because the TSE PCS IP is in FPGA whereas DWMAC is in hard processor. So, in order for DWMAC SGMII to access to TSE PCS, the FPGA bridge needs to be enabled.
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

On 12/28/18 8:28 AM, Ooi, Joyce wrote:
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Thursday, December 27, 2018 2:55 AM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 12/26/18 8:47 AM, Ooi, Joyce wrote:
Adding Marek.
-----Original Message----- From: U-Boot [mailto:u-boot-bounces@lists.denx.de] On Behalf Of Ooi, Joyce Sent: Tuesday, November 27, 2018 5:40 PM To: Joe Hershberger joe.hershberger@ni.com Cc: Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; See, Chin Liang chin.liang.see@intel.com; u- boot@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.hershberger@ni.com Cc: Grygorii Strashko grygorii.strashko@ti.com; Neil Armstrong narmstrong@baylibre.com; Mario Six mario.six@gdsys.cc; Florian Fainelli f.fainelli@gmail.com; Priyanka Jain priyanka.jain@nxp.com; Ooi, Joyce joyce.ooi@intel.com; See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@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.ooi@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 ?
This is because the TSE PCS IP is in FPGA whereas DWMAC is in hard processor. So, in order for DWMAC SGMII to access to TSE PCS, the FPGA bridge needs to be enabled.
This is the wrong place to enable them, that should be handled by the FPGA manager driver. If you model this correctly in the DT, then this hack shouldn't be needed here.
btw. if I use nios2 softcore with this block, and altera TSE ethernet, I suspect I won't need the bridge enable at all ?
[...]

-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Friday, December 28, 2018 6:08 PM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 12/28/18 8:28 AM, Ooi, Joyce wrote:
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Thursday, December 27, 2018 2:55 AM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 12/26/18 8:47 AM, Ooi, Joyce wrote:
Adding Marek.
-----Original Message----- From: U-Boot [mailto:u-boot-bounces@lists.denx.de] On Behalf Of Ooi, Joyce Sent: Tuesday, November 27, 2018 5:40 PM To: Joe Hershberger joe.hershberger@ni.com Cc: Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; See, Chin Liang chin.liang.see@intel.com; u- boot@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.hershberger@ni.com Cc: Grygorii Strashko grygorii.strashko@ti.com; Neil Armstrong narmstrong@baylibre.com; Mario Six mario.six@gdsys.cc; Florian Fainelli f.fainelli@gmail.com; Priyanka Jain priyanka.jain@nxp.com; Ooi, Joyce joyce.ooi@intel.com; See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@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.ooi@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 ?
This is because the TSE PCS IP is in FPGA whereas DWMAC is in hard processor. So, in order for DWMAC SGMII to access to TSE PCS, the FPGA bridge needs to be enabled.
This is the wrong place to enable them, that should be handled by the FPGA manager driver. If you model this correctly in the DT, then this hack shouldn't be needed here.
In that case, would it be better if I move it to the u-boot init sequence? I'll do a checking if FPGA is in usermode - if yes, then I'll enable the bridge. Then, no FPGA codes will need to appear in dwmac driver.
btw. if I use nios2 softcore with this block, and altera TSE ethernet, I suspect I won't need the bridge enable at all ?
Yes, you are right. So, if the bridge enable is done during the u-boot init sequence based on board specific, bridge will not be enabled when nios2 is used with TSE PCS.
[...]
Best regards, Marek Vasut

On 1/4/19 10:26 AM, Ooi, Joyce wrote:
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Friday, December 28, 2018 6:08 PM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 12/28/18 8:28 AM, Ooi, Joyce wrote:
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Thursday, December 27, 2018 2:55 AM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 12/26/18 8:47 AM, Ooi, Joyce wrote:
Adding Marek.
-----Original Message----- From: U-Boot [mailto:u-boot-bounces@lists.denx.de] On Behalf Of Ooi, Joyce Sent: Tuesday, November 27, 2018 5:40 PM To: Joe Hershberger joe.hershberger@ni.com Cc: Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; See, Chin Liang chin.liang.see@intel.com; u- boot@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.hershberger@ni.com > Cc: Grygorii Strashko grygorii.strashko@ti.com; Neil Armstrong > narmstrong@baylibre.com; Mario Six mario.six@gdsys.cc; Florian > Fainelli f.fainelli@gmail.com; Priyanka Jain > priyanka.jain@nxp.com; Ooi, Joyce joyce.ooi@intel.com; See, > Chin Liang chin.liang.see@intel.com; Ong, Hean Loong > hean.loong.ong@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.ooi@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 ?
This is because the TSE PCS IP is in FPGA whereas DWMAC is in hard processor. So, in order for DWMAC SGMII to access to TSE PCS, the FPGA bridge needs to be enabled.
This is the wrong place to enable them, that should be handled by the FPGA manager driver. If you model this correctly in the DT, then this hack shouldn't be needed here.
In that case, would it be better if I move it to the u-boot init sequence? I'll do a checking if FPGA is in usermode - if yes, then I'll enable the bridge. Then, no FPGA codes will need to appear in dwmac driver.
This stuff should be entirely in drivers/fpga/* , if the FPGA gets loaded (thus, enters usermode) AND a driver gets bound to anything in the FPGA bridge area, then the bridge needs to be enabled.
btw. if I use nios2 softcore with this block, and altera TSE ethernet, I suspect I won't need the bridge enable at all ?
Yes, you are right. So, if the bridge enable is done during the u-boot init sequence based on board specific, bridge will not be enabled when nios2 is used with TSE PCS.
This doesn't fit into the driver model though. And you cannot tell which bridge you need to enable. However, the FPGA driver does/should know that.

-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Friday, January 4, 2019 10:56 PM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 1/4/19 10:26 AM, Ooi, Joyce wrote:
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Friday, December 28, 2018 6:08 PM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 12/28/18 8:28 AM, Ooi, Joyce wrote:
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Thursday, December 27, 2018 2:55 AM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 12/26/18 8:47 AM, Ooi, Joyce wrote:
Adding Marek.
> -----Original Message----- > From: U-Boot [mailto:u-boot-bounces@lists.denx.de] On Behalf Of > Ooi, Joyce > Sent: Tuesday, November 27, 2018 5:40 PM > To: Joe Hershberger joe.hershberger@ni.com > Cc: Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain > priyanka.jain@nxp.com; See, Chin Liang > chin.liang.see@intel.com; > u- boot@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.hershberger@ni.com >> Cc: Grygorii Strashko grygorii.strashko@ti.com; Neil Armstrong >> narmstrong@baylibre.com; Mario Six mario.six@gdsys.cc; >> Florian Fainelli f.fainelli@gmail.com; Priyanka Jain >> priyanka.jain@nxp.com; Ooi, Joyce joyce.ooi@intel.com; See, >> Chin Liang chin.liang.see@intel.com; Ong, Hean Loong >> hean.loong.ong@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.ooi@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 ?
This is because the TSE PCS IP is in FPGA whereas DWMAC is in hard
processor.
So, in order for DWMAC SGMII to access to TSE PCS, the FPGA bridge needs to be enabled.
This is the wrong place to enable them, that should be handled by the FPGA manager driver. If you model this correctly in the DT, then this hack shouldn't be needed here.
In that case, would it be better if I move it to the u-boot init sequence? I'll do a checking if FPGA is in usermode - if yes, then I'll enable the bridge. Then, no FPGA codes will need to appear in dwmac
driver.
This stuff should be entirely in drivers/fpga/* , if the FPGA gets loaded (thus, enters usermode) AND a driver gets bound to anything in the FPGA bridge area, then the bridge needs to be enabled.
The drivers/fpga/* does not seem to use the driver model. They're like individual APIs that get called by others. So, I'm not sure how this can be done in FPGA driver.
btw. if I use nios2 softcore with this block, and altera TSE ethernet, I suspect I won't need the bridge enable at all ?
Yes, you are right. So, if the bridge enable is done during the u-boot init sequence based on board specific, bridge will not be enabled when nios2 is
used with TSE PCS.
This doesn't fit into the driver model though. And you cannot tell which bridge you need to enable. However, the FPGA driver does/should know that.
-- Best regards, Marek Vasut

On 1/25/19 3:35 PM, Ooi, Joyce wrote:
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Friday, January 4, 2019 10:56 PM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 1/4/19 10:26 AM, Ooi, Joyce wrote:
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Friday, December 28, 2018 6:08 PM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 12/28/18 8:28 AM, Ooi, Joyce wrote:
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Thursday, December 27, 2018 2:55 AM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 12/26/18 8:47 AM, Ooi, Joyce wrote: > Adding Marek. > >> -----Original Message----- >> From: U-Boot [mailto:u-boot-bounces@lists.denx.de] On Behalf Of >> Ooi, Joyce >> Sent: Tuesday, November 27, 2018 5:40 PM >> To: Joe Hershberger joe.hershberger@ni.com >> Cc: Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain >> priyanka.jain@nxp.com; See, Chin Liang >> chin.liang.see@intel.com; >> u- boot@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.hershberger@ni.com >>> Cc: Grygorii Strashko grygorii.strashko@ti.com; Neil Armstrong >>> narmstrong@baylibre.com; Mario Six mario.six@gdsys.cc; >>> Florian Fainelli f.fainelli@gmail.com; Priyanka Jain >>> priyanka.jain@nxp.com; Ooi, Joyce joyce.ooi@intel.com; See, >>> Chin Liang chin.liang.see@intel.com; Ong, Hean Loong >>> hean.loong.ong@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.ooi@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 ?
This is because the TSE PCS IP is in FPGA whereas DWMAC is in hard
processor.
So, in order for DWMAC SGMII to access to TSE PCS, the FPGA bridge needs to be enabled.
This is the wrong place to enable them, that should be handled by the FPGA manager driver. If you model this correctly in the DT, then this hack shouldn't be needed here.
In that case, would it be better if I move it to the u-boot init sequence? I'll do a checking if FPGA is in usermode - if yes, then I'll enable the bridge. Then, no FPGA codes will need to appear in dwmac
driver.
This stuff should be entirely in drivers/fpga/* , if the FPGA gets loaded (thus, enters usermode) AND a driver gets bound to anything in the FPGA bridge area, then the bridge needs to be enabled.
The drivers/fpga/* does not seem to use the driver model. They're like individual APIs that get called by others. So, I'm not sure how this can be done in FPGA driver.
CCing Chee, he's been working on the altera FPGA code recently, I hope he can give you some hints. We might need a new API for this, possibly add DM support to FPGA framework (should be easy) and then let the FPGA framework handle the bridges and stuff. Really, this shouldn't be in the network code.

-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Saturday, January 26, 2019 4:34 PM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de; Tan, Ley Foon ley.foon.tan@intel.com; Chee, Tien Fong tien.fong.chee@intel.com Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 1/25/19 3:35 PM, Ooi, Joyce wrote:
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Friday, January 4, 2019 10:56 PM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 1/4/19 10:26 AM, Ooi, Joyce wrote:
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Friday, December 28, 2018 6:08 PM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 12/28/18 8:28 AM, Ooi, Joyce wrote:
> -----Original Message----- > From: Marek Vasut [mailto:marex@denx.de] > Sent: Thursday, December 27, 2018 2:55 AM > To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger > joe.hershberger@ni.com > Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong > hean.loong.ong@intel.com; Priyanka Jain > priyanka.jain@nxp.com; > u- boot@lists.denx.de > Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to > dwmac- socfpga > > On 12/26/18 8:47 AM, Ooi, Joyce wrote: >> Adding Marek. >> >>> -----Original Message----- >>> From: U-Boot [mailto:u-boot-bounces@lists.denx.de] On Behalf Of >>> Ooi, Joyce >>> Sent: Tuesday, November 27, 2018 5:40 PM >>> To: Joe Hershberger joe.hershberger@ni.com >>> Cc: Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain >>> priyanka.jain@nxp.com; See, Chin Liang >>> chin.liang.see@intel.com; >>> u- boot@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.hershberger@ni.com >>>> Cc: Grygorii Strashko grygorii.strashko@ti.com; Neil >>>> Armstrong narmstrong@baylibre.com; Mario Six >>>> mario.six@gdsys.cc; Florian Fainelli f.fainelli@gmail.com; >>>> Priyanka Jain priyanka.jain@nxp.com; Ooi, Joyce >>>> joyce.ooi@intel.com; See, Chin Liang >>>> chin.liang.see@intel.com; Ong, Hean Loong >>>> hean.loong.ong@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.ooi@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 ? This is because the TSE PCS IP is in FPGA whereas DWMAC is in hard
processor.
So, in order for DWMAC SGMII to access to TSE PCS, the FPGA bridge needs to be enabled.
This is the wrong place to enable them, that should be handled by the FPGA manager driver. If you model this correctly in the DT, then this hack shouldn't be needed here.
In that case, would it be better if I move it to the u-boot init sequence? I'll do a checking if FPGA is in usermode - if yes, then I'll enable the bridge. Then, no FPGA codes will need to appear in dwmac
driver.
This stuff should be entirely in drivers/fpga/* , if the FPGA gets loaded (thus, enters usermode) AND a driver gets bound to anything in the FPGA bridge area, then the bridge needs to be enabled.
The drivers/fpga/* does not seem to use the driver model. They're like individual APIs that get called by others. So, I'm not sure how this can be done
in FPGA driver.
CCing Chee, he's been working on the altera FPGA code recently, I hope he can give you some hints. We might need a new API for this, possibly add DM support to FPGA framework (should be easy) and then let the FPGA framework handle the bridges and stuff. Really, this shouldn't be in the network code.
Since this isn't related to FPGA drivers, I think it's better to have a separate driver for the bridge. I can create a bridge driver, perhaps a new drivers/bridge/*. It'll consist of a uclass driver, which has new APIs to enable bridge, disable bridge, and check for bridge status. The bridge enablement will be based on device tree setting and utilizes reset manager APIs. I'll also create a bridge-socfpga driver that implements the bridge enablement.
With this, the appropriate bridge will be enabled when the bridge driver is loaded.
What do you think?
-- Best regards, Marek Vasut

On 2/1/19 4:45 AM, Ooi, Joyce wrote:
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Saturday, January 26, 2019 4:34 PM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de; Tan, Ley Foon ley.foon.tan@intel.com; Chee, Tien Fong tien.fong.chee@intel.com Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 1/25/19 3:35 PM, Ooi, Joyce wrote:
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Friday, January 4, 2019 10:56 PM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 1/4/19 10:26 AM, Ooi, Joyce wrote:
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Friday, December 28, 2018 6:08 PM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 12/28/18 8:28 AM, Ooi, Joyce wrote: >> -----Original Message----- >> From: Marek Vasut [mailto:marex@denx.de] >> Sent: Thursday, December 27, 2018 2:55 AM >> To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger >> joe.hershberger@ni.com >> Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong >> hean.loong.ong@intel.com; Priyanka Jain >> priyanka.jain@nxp.com; >> u- boot@lists.denx.de >> Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to >> dwmac- socfpga >> >> On 12/26/18 8:47 AM, Ooi, Joyce wrote: >>> Adding Marek. >>> >>>> -----Original Message----- >>>> From: U-Boot [mailto:u-boot-bounces@lists.denx.de] On Behalf Of >>>> Ooi, Joyce >>>> Sent: Tuesday, November 27, 2018 5:40 PM >>>> To: Joe Hershberger joe.hershberger@ni.com >>>> Cc: Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain >>>> priyanka.jain@nxp.com; See, Chin Liang >>>> chin.liang.see@intel.com; >>>> u- boot@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.hershberger@ni.com >>>>> Cc: Grygorii Strashko grygorii.strashko@ti.com; Neil >>>>> Armstrong narmstrong@baylibre.com; Mario Six >>>>> mario.six@gdsys.cc; Florian Fainelli f.fainelli@gmail.com; >>>>> Priyanka Jain priyanka.jain@nxp.com; Ooi, Joyce >>>>> joyce.ooi@intel.com; See, Chin Liang >>>>> chin.liang.see@intel.com; Ong, Hean Loong >>>>> hean.loong.ong@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.ooi@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 ? > This is because the TSE PCS IP is in FPGA whereas DWMAC is in hard
processor.
> So, in order for DWMAC SGMII to access to TSE PCS, the FPGA bridge > needs to be enabled.
This is the wrong place to enable them, that should be handled by the FPGA manager driver. If you model this correctly in the DT, then this hack shouldn't be needed here.
In that case, would it be better if I move it to the u-boot init sequence? I'll do a checking if FPGA is in usermode - if yes, then I'll enable the bridge. Then, no FPGA codes will need to appear in dwmac
driver.
This stuff should be entirely in drivers/fpga/* , if the FPGA gets loaded (thus, enters usermode) AND a driver gets bound to anything in the FPGA bridge area, then the bridge needs to be enabled.
The drivers/fpga/* does not seem to use the driver model. They're like individual APIs that get called by others. So, I'm not sure how this can be done
in FPGA driver.
CCing Chee, he's been working on the altera FPGA code recently, I hope he can give you some hints. We might need a new API for this, possibly add DM support to FPGA framework (should be easy) and then let the FPGA framework handle the bridges and stuff. Really, this shouldn't be in the network code.
Since this isn't related to FPGA drivers, I think it's better to have a separate driver for the bridge. I can create a bridge driver, perhaps a new drivers/bridge/*. It'll consist of a uclass driver, which has new APIs to enable bridge, disable bridge, and check for bridge status. The bridge enablement will be based on device tree setting and utilizes reset manager APIs. I'll also create a bridge-socfpga driver that implements the bridge enablement.
With this, the appropriate bridge will be enabled when the bridge driver is loaded.
What do you think?
Can we model this so the framework looks similar to Linux FPGA manager ?

-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Friday, February 1, 2019 4:21 PM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de; Tan, Ley Foon ley.foon.tan@intel.com; Chee, Tien Fong tien.fong.chee@intel.com Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 2/1/19 4:45 AM, Ooi, Joyce wrote:
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Saturday, January 26, 2019 4:34 PM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de; Tan, Ley Foon ley.foon.tan@intel.com; Chee, Tien Fong tien.fong.chee@intel.com Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 1/25/19 3:35 PM, Ooi, Joyce wrote:
-----Original Message----- From: Marek Vasut [mailto:marex@denx.de] Sent: Friday, January 4, 2019 10:56 PM To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger joe.hershberger@ni.com Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain priyanka.jain@nxp.com; u- boot@lists.denx.de Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to dwmac- socfpga
On 1/4/19 10:26 AM, Ooi, Joyce wrote:
> -----Original Message----- > From: Marek Vasut [mailto:marex@denx.de] > Sent: Friday, December 28, 2018 6:08 PM > To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger > joe.hershberger@ni.com > Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong > hean.loong.ong@intel.com; Priyanka Jain > priyanka.jain@nxp.com; > u- boot@lists.denx.de > Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support to > dwmac- socfpga > > On 12/28/18 8:28 AM, Ooi, Joyce wrote: >>> -----Original Message----- >>> From: Marek Vasut [mailto:marex@denx.de] >>> Sent: Thursday, December 27, 2018 2:55 AM >>> To: Ooi, Joyce joyce.ooi@intel.com; Joe Hershberger >>> joe.hershberger@ni.com >>> Cc: See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong >>> hean.loong.ong@intel.com; Priyanka Jain >>> priyanka.jain@nxp.com; >>> u- boot@lists.denx.de >>> Subject: Re: [U-Boot] [PATCH v3] net: phy: add TSE PCS support >>> to >>> dwmac- socfpga >>> >>> On 12/26/18 8:47 AM, Ooi, Joyce wrote: >>>> Adding Marek. >>>> >>>>> -----Original Message----- >>>>> From: U-Boot [mailto:u-boot-bounces@lists.denx.de] On Behalf >>>>> Of Ooi, Joyce >>>>> Sent: Tuesday, November 27, 2018 5:40 PM >>>>> To: Joe Hershberger joe.hershberger@ni.com >>>>> Cc: Ong, Hean Loong hean.loong.ong@intel.com; Priyanka Jain >>>>> priyanka.jain@nxp.com; See, Chin Liang >>>>> chin.liang.see@intel.com; >>>>> u- boot@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.hershberger@ni.com >>>>>> Cc: Grygorii Strashko grygorii.strashko@ti.com; Neil >>>>>> Armstrong narmstrong@baylibre.com; Mario Six >>>>>> mario.six@gdsys.cc; Florian Fainelli >>>>>> f.fainelli@gmail.com; Priyanka Jain >>>>>> priyanka.jain@nxp.com; Ooi, Joyce joyce.ooi@intel.com; >>>>>> See, Chin Liang chin.liang.see@intel.com; Ong, Hean Loong >>>>>> hean.loong.ong@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.ooi@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 ? >> This is because the TSE PCS IP is in FPGA whereas DWMAC is in >> hard
processor.
>> So, in order for DWMAC SGMII to access to TSE PCS, the FPGA >> bridge needs to be enabled. > > This is the wrong place to enable them, that should be handled by > the FPGA manager driver. If you model this correctly in the DT, > then this hack shouldn't be needed here. In that case, would it be better if I move it to the u-boot init sequence? I'll do a checking if FPGA is in usermode - if yes, then I'll enable the bridge. Then, no FPGA codes will need to appear in dwmac
driver.
This stuff should be entirely in drivers/fpga/* , if the FPGA gets loaded (thus, enters usermode) AND a driver gets bound to anything in the FPGA bridge area, then the bridge needs to be enabled.
The drivers/fpga/* does not seem to use the driver model. They're like individual APIs that get called by others. So, I'm not sure how this can be done
in FPGA driver.
CCing Chee, he's been working on the altera FPGA code recently, I hope he can give you some hints. We might need a new API for this, possibly add DM support to FPGA framework (should be easy) and then let the FPGA framework handle the bridges and stuff. Really, this shouldn't be
in the network code.
Since this isn't related to FPGA drivers, I think it's better to have a separate driver for the bridge. I can create a bridge driver, perhaps a new drivers/bridge/*. It'll consist of a uclass driver, which has new APIs to enable bridge, disable bridge, and check for bridge status. The bridge enablement will be based on device tree setting and utilizes reset manager APIs. I'll also create a bridge-socfpga driver
that implements the bridge enablement.
With this, the appropriate bridge will be enabled when the bridge driver is
loaded.
What do you think?
Can we model this so the framework looks similar to Linux FPGA manager ?
Do you mean this FPGA bridge driver in Linux: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/driv... https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/driv...
I can port over or model the FPGA bridge driver similar to the one in Linux kernel.
-- Best regards, Marek Vasut

On 2/14/19 8:50 AM, Ooi, Joyce wrote: [...]
CCing Chee, he's been working on the altera FPGA code recently, I hope he can give you some hints. We might need a new API for this, possibly add DM support to FPGA framework (should be easy) and then let the FPGA framework handle the bridges and stuff. Really, this shouldn't be
in the network code.
Since this isn't related to FPGA drivers, I think it's better to have a separate driver for the bridge. I can create a bridge driver, perhaps a new drivers/bridge/*. It'll consist of a uclass driver, which has new APIs to enable bridge, disable bridge, and check for bridge status. The bridge enablement will be based on device tree setting and utilizes reset manager APIs. I'll also create a bridge-socfpga driver
that implements the bridge enablement.
With this, the appropriate bridge will be enabled when the bridge driver is
loaded.
What do you think?
Can we model this so the framework looks similar to Linux FPGA manager ?
Do you mean this FPGA bridge driver in Linux: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/driv... https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/driv...
I can port over or model the FPGA bridge driver similar to the one in Linux kernel.
Yes please.
participants (2)
-
Marek Vasut
-
Ooi, Joyce