
-----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