From ed6fad3e25e945e7042a53e129adde6a27476c90 Mon Sep 17 00:00:00 2001 From: Siva Durga Prasad Paladugu Date: Fri, 5 Feb 2016 13:22:10 +0530 Subject: phy: Add phy driver support for xilinx PCS/PMA core Add phy driver support for xilinx PCS/PMA core Signed-off-by: Siva Durga Prasad Paladugu Signed-off-by: Kedareswara rao Appana Signed-off-by: Michal Simek --- drivers/net/phy/Makefile | 1 + drivers/net/phy/phy.c | 3 + drivers/net/phy/xilinx_phy.c | 144 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 148 insertions(+) create mode 100644 drivers/net/phy/xilinx_phy.c (limited to 'drivers') diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index 9e4d4927e67..1e299b97b96 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile @@ -25,4 +25,5 @@ obj-$(CONFIG_PHY_REALTEK) += realtek.o obj-$(CONFIG_PHY_SMSC) += smsc.o obj-$(CONFIG_PHY_TERANETICS) += teranetics.o obj-$(CONFIG_PHY_TI) += ti.o +obj-$(CONFIG_PHY_XILINX) += xilinx_phy.o obj-$(CONFIG_PHY_VITESSE) += vitesse.o diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 17866a244b3..23c82bb36e9 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -503,6 +503,9 @@ int phy_init(void) #ifdef CONFIG_PHY_VITESSE phy_vitesse_init(); #endif +#ifdef CONFIG_PHY_XILINX + phy_xilinx_init(); +#endif return 0; } diff --git a/drivers/net/phy/xilinx_phy.c b/drivers/net/phy/xilinx_phy.c new file mode 100644 index 00000000000..f3eaf2e97ce --- /dev/null +++ b/drivers/net/phy/xilinx_phy.c @@ -0,0 +1,144 @@ +/* + * Xilinx PCS/PMA Core phy driver + * + * Copyright (C) 2015 - 2016 Xilinx, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#define MII_PHY_STATUS_SPD_MASK 0x0C00 +#define MII_PHY_STATUS_FULLDUPLEX 0x1000 +#define MII_PHY_STATUS_1000 0x0800 +#define MII_PHY_STATUS_100 0x0400 +#define XPCSPMA_PHY_CTRL_ISOLATE_DISABLE 0xFBFF + +/* Mask used for ID comparisons */ +#define XILINX_PHY_ID_MASK 0xfffffff0 + +/* Known PHY IDs */ +#define XILINX_PHY_ID 0x01740c00 + +/* struct phy_device dev_flags definitions */ +#define XAE_PHY_TYPE_MII 0 +#define XAE_PHY_TYPE_GMII 1 +#define XAE_PHY_TYPE_RGMII_1_3 2 +#define XAE_PHY_TYPE_RGMII_2_0 3 +#define XAE_PHY_TYPE_SGMII 4 +#define XAE_PHY_TYPE_1000BASE_X 5 + +static int xilinxphy_startup(struct phy_device *phydev) +{ + int err; + int status = 0; + + debug("%s\n", __func__); + /* Update the link, but return if there + * was an error + */ + err = genphy_update_link(phydev); + if (err) + return err; + + if (AUTONEG_ENABLE == phydev->autoneg) { + status = phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA); + status = status & MII_PHY_STATUS_SPD_MASK; + + if (status & MII_PHY_STATUS_FULLDUPLEX) + phydev->duplex = DUPLEX_FULL; + else + phydev->duplex = DUPLEX_HALF; + + switch (status) { + case MII_PHY_STATUS_1000: + phydev->speed = SPEED_1000; + break; + + case MII_PHY_STATUS_100: + phydev->speed = SPEED_100; + break; + + default: + phydev->speed = SPEED_10; + break; + } + } else { + int bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR); + + if (bmcr < 0) + return bmcr; + + if (bmcr & BMCR_FULLDPLX) + phydev->duplex = DUPLEX_FULL; + else + phydev->duplex = DUPLEX_HALF; + + if (bmcr & BMCR_SPEED1000) + phydev->speed = SPEED_1000; + else if (bmcr & BMCR_SPEED100) + phydev->speed = SPEED_100; + else + phydev->speed = SPEED_10; + } + + /* + * For 1000BASE-X Phy Mode the speed/duplex will always be + * 1000Mbps/fullduplex + */ + if (phydev->flags == XAE_PHY_TYPE_1000BASE_X) { + phydev->duplex = DUPLEX_FULL; + phydev->speed = SPEED_1000; + } + + return 0; +} + +static int xilinxphy_of_init(struct phy_device *phydev) +{ + struct udevice *dev = (struct udevice *)&phydev->dev; + u32 phytype; + + debug("%s\n", __func__); + phytype = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "phy-type", -1); + if (phytype == XAE_PHY_TYPE_1000BASE_X) + phydev->flags |= XAE_PHY_TYPE_1000BASE_X; + + return 0; +} + +static int xilinxphy_config(struct phy_device *phydev) +{ + int temp; + + debug("%s\n", __func__); + xilinxphy_of_init(phydev); + temp = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR); + temp &= XPCSPMA_PHY_CTRL_ISOLATE_DISABLE; + phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, temp); + + return 0; +} + +static struct phy_driver xilinxphy_driver = { + .uid = XILINX_PHY_ID, + .mask = XILINX_PHY_ID_MASK, + .name = "Xilinx PCS/PMA PHY", + .features = PHY_GBIT_FEATURES, + .config = &xilinxphy_config, + .startup = &xilinxphy_startup, + .shutdown = &genphy_shutdown, +}; + +int phy_xilinx_init(void) +{ + debug("%s\n", __func__); + phy_register(&xilinxphy_driver); + + return 0; +} -- cgit v1.2.3 From a06c341faadf35c58675ff5af8f6c164d07d4f20 Mon Sep 17 00:00:00 2001 From: Siva Durga Prasad Paladugu Date: Fri, 5 Feb 2016 13:22:11 +0530 Subject: net: zynq_gem: Add support for SGMII interface Add support of SGMII interface for zynq GEM. Read xlnx,emio property from DT. Signed-off-by: Siva Durga Prasad Paladugu Signed-off-by: Michal Simek --- drivers/net/zynq_gem.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c index b3821c31a91..4049e1cb94e 100644 --- a/drivers/net/zynq_gem.c +++ b/drivers/net/zynq_gem.c @@ -57,6 +57,8 @@ DECLARE_GLOBAL_DATA_PTR; #define ZYNQ_GEM_NWCFG_SPEED1000 0x000000400 /* 1Gbps operation */ #define ZYNQ_GEM_NWCFG_FDEN 0x000000002 /* Full Duplex mode */ #define ZYNQ_GEM_NWCFG_FSREM 0x000020000 /* FCS removal */ +#define ZYNQ_GEM_NWCFG_SGMII_ENBL 0x080000000 /* SGMII Enable */ +#define ZYNQ_GEM_NWCFG_PCS_SEL 0x000000800 /* PCS select */ #ifdef CONFIG_ARM64 #define ZYNQ_GEM_NWCFG_MDCCLKDIV 0x000100000 /* Div pclk by 64, max 160MHz */ #else @@ -330,10 +332,12 @@ static int zynq_phy_init(struct udevice *dev) /* Enable only MDIO bus */ writel(ZYNQ_GEM_NWCTRL_MDEN_MASK, ®s->nwctrl); - ret = phy_detection(dev); - if (ret) { - printf("GEM PHY init failed\n"); - return ret; + if (priv->interface != PHY_INTERFACE_MODE_SGMII) { + ret = phy_detection(dev); + if (ret) { + printf("GEM PHY init failed\n"); + return ret; + } } priv->phydev = phy_connect(priv->bus, priv->phyaddr, dev, @@ -351,7 +355,7 @@ static int zynq_phy_init(struct udevice *dev) static int zynq_gem_init(struct udevice *dev) { - u32 i; + u32 i, nwconfig; unsigned long clk_rate = 0; struct zynq_gem_priv *priv = dev_get_priv(dev); struct zynq_gem_regs *regs = priv->iobase; @@ -426,14 +430,20 @@ static int zynq_gem_init(struct udevice *dev) return -1; } + nwconfig = ZYNQ_GEM_NWCFG_INIT; + + if (priv->interface == PHY_INTERFACE_MODE_SGMII) + nwconfig |= ZYNQ_GEM_NWCFG_SGMII_ENBL | + ZYNQ_GEM_NWCFG_PCS_SEL; + switch (priv->phydev->speed) { case SPEED_1000: - writel(ZYNQ_GEM_NWCFG_INIT | ZYNQ_GEM_NWCFG_SPEED1000, + writel(nwconfig | ZYNQ_GEM_NWCFG_SPEED1000, ®s->nwcfg); clk_rate = ZYNQ_GEM_FREQUENCY_1000; break; case SPEED_100: - writel(ZYNQ_GEM_NWCFG_INIT | ZYNQ_GEM_NWCFG_SPEED100, + writel(nwconfig | ZYNQ_GEM_NWCFG_SPEED100, ®s->nwcfg); clk_rate = ZYNQ_GEM_FREQUENCY_100; break; @@ -663,6 +673,8 @@ static int zynq_gem_ofdata_to_platdata(struct udevice *dev) } priv->interface = pdata->phy_interface; + priv->emio = fdtdec_get_bool(gd->fdt_blob, dev->of_offset, "xlnx,emio"); + printf("ZYNQ GEM: %lx, phyaddr %d, interface %s\n", (ulong)priv->iobase, priv->phyaddr, phy_string_for_interface(priv->interface)); -- cgit v1.2.3 From 9c0da76220b4010b756c76d6fbbcf66d6b3d8dfd Mon Sep 17 00:00:00 2001 From: Siva Durga Prasad Paladugu Date: Sun, 21 Feb 2016 15:46:14 +0530 Subject: net: xilinx_axi: Use interface type instead of zero Pass appropriate interface type to phy_connect instead of zero. Signed-off-by: Siva Durga Prasad Paladugu Acked-by: Joe Hershberger Signed-off-by: Michal Simek --- drivers/net/xilinx_axi_emac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c index 81274ee13bc..46b8d2d07ee 100644 --- a/drivers/net/xilinx_axi_emac.c +++ b/drivers/net/xilinx_axi_emac.c @@ -251,7 +251,7 @@ static int axiemac_phy_init(struct udevice *dev) } /* Interface - look at tsec */ - phydev = phy_connect(priv->bus, priv->phyaddr, dev, 0); + phydev = phy_connect(priv->bus, priv->phyaddr, dev, priv->interface); phydev->supported &= supported; phydev->advertising = phydev->supported; -- cgit v1.2.3 From 8964f241790181b08eae02b2da56fbadb0375930 Mon Sep 17 00:00:00 2001 From: Siva Durga Prasad Paladugu Date: Sun, 21 Feb 2016 15:46:15 +0530 Subject: net: xilinx_axi: Clear Isolate bit if found during phy setup In SGMII cases the isolate bit might set after DMA and ethernet resets and hence check and clear during setup_phy if it was set. Signed-off-by: Siva Durga Prasad Paladugu Acked-by: Joe Hershberger Signed-off-by: Michal Simek --- drivers/net/xilinx_axi_emac.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c index 46b8d2d07ee..3d69bed3093 100644 --- a/drivers/net/xilinx_axi_emac.c +++ b/drivers/net/xilinx_axi_emac.c @@ -264,11 +264,29 @@ static int axiemac_phy_init(struct udevice *dev) /* Setting axi emac and phy to proper setting */ static int setup_phy(struct udevice *dev) { - u32 speed, emmc_reg; + u16 temp; + u32 speed, emmc_reg, ret; struct axidma_priv *priv = dev_get_priv(dev); struct axi_regs *regs = priv->iobase; struct phy_device *phydev = priv->phydev; + if (priv->interface == PHY_INTERFACE_MODE_SGMII) { + /* + * In SGMII cases the isolate bit might set + * after DMA and ethernet resets and hence + * check and clear if set. + */ + ret = phyread(priv, priv->phyaddr, MII_BMCR, &temp); + if (ret) + return 0; + if (temp & BMCR_ISOLATE) { + temp &= ~BMCR_ISOLATE; + ret = phywrite(priv, priv->phyaddr, MII_BMCR, temp); + if (ret) + return 0; + } + } + if (phy_startup(phydev)) { printf("axiemac: could not initialize PHY %s\n", phydev->dev->name); -- cgit v1.2.3 From a509a1d40264516821d0ba2d1d6a6ab2e1a2acbd Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Tue, 26 Jan 2016 11:57:03 -0600 Subject: net: gem: Allow to set the MAC from an EEPROM Provide board specific option how to read MAC address from ROM. Do it in generic way to be reusable by differnet boards. If this is not enough board specific functions can be created. Signed-off-by: Joe Hershberger # driver part Signed-off-by: Michal Simek Signed-off-by: Michal Simek --- arch/arm/mach-zynq/include/mach/sys_proto.h | 2 ++ board/xilinx/zynq/board.c | 13 +++++++++++++ drivers/net/zynq_gem.c | 18 ++++++++++++++++++ 3 files changed, 33 insertions(+) (limited to 'drivers') diff --git a/arch/arm/mach-zynq/include/mach/sys_proto.h b/arch/arm/mach-zynq/include/mach/sys_proto.h index 882beabe132..44c9b50fe5b 100644 --- a/arch/arm/mach-zynq/include/mach/sys_proto.h +++ b/arch/arm/mach-zynq/include/mach/sys_proto.h @@ -19,6 +19,8 @@ extern int zynq_slcr_get_mio_pin_status(const char *periph); extern void zynq_ddrc_init(void); extern unsigned int zynq_get_silicon_version(void); +int zynq_board_read_rom_ethaddr(unsigned char *ethaddr); + /* Driver extern functions */ extern void ps7_init(void); diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c index 2f17e977a4b..4c20450b635 100644 --- a/board/xilinx/zynq/board.c +++ b/board/xilinx/zynq/board.c @@ -98,6 +98,19 @@ int checkboard(void) } #endif +int zynq_board_read_rom_ethaddr(unsigned char *ethaddr) +{ +#if defined(CONFIG_ZYNQ_GEM_EEPROM_ADDR) && \ + defined(CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET) + if (eeprom_read(CONFIG_ZYNQ_GEM_EEPROM_ADDR, + CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET, + ethaddr, 6)) + printf("I2C EEPROM MAC address read failed\n"); +#endif + + return 0; +} + int dram_init(void) { int node; diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c index 4049e1cb94e..103ed6169c0 100644 --- a/drivers/net/zynq_gem.c +++ b/drivers/net/zynq_gem.c @@ -571,6 +571,23 @@ static void zynq_gem_halt(struct udevice *dev) ZYNQ_GEM_NWCTRL_TXEN_MASK, 0); } +__weak int zynq_board_read_rom_ethaddr(unsigned char *ethaddr) +{ + return -ENOSYS; +} + +static int zynq_gem_read_rom_mac(struct udevice *dev) +{ + int retval; + struct eth_pdata *pdata = dev_get_platdata(dev); + + retval = zynq_board_read_rom_ethaddr(pdata->enetaddr); + if (retval == -ENOSYS) + retval = 0; + + return retval; +} + static int zynq_gem_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg) { @@ -644,6 +661,7 @@ static const struct eth_ops zynq_gem_ops = { .free_pkt = zynq_gem_free_pkt, .stop = zynq_gem_halt, .write_hwaddr = zynq_gem_setup_mac, + .read_rom_hwaddr = zynq_gem_read_rom_mac, }; static int zynq_gem_ofdata_to_platdata(struct udevice *dev) -- cgit v1.2.3 From ceb04e1a5d9fb956190d9f5bcc32da0f9291d416 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 8 Feb 2016 13:54:05 +0100 Subject: net: axi_emac: Report phy-node error message permanently Do not use debug() when printing error message. Use printf instead. Signed-off-by: Michal Simek --- drivers/net/xilinx_axi_emac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c index 3d69bed3093..5de06ef01e8 100644 --- a/drivers/net/xilinx_axi_emac.c +++ b/drivers/net/xilinx_axi_emac.c @@ -715,7 +715,7 @@ static int axi_emac_ofdata_to_platdata(struct udevice *dev) if (phy_mode) pdata->phy_interface = phy_get_interface_by_name(phy_mode); if (pdata->phy_interface == -1) { - debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode); + printf("%s: Invalid PHY interface '%s'\n", __func__, phy_mode); return -EINVAL; } priv->interface = pdata->phy_interface; -- cgit v1.2.3 From 679b994a2b56c65d53f94ab85baa68c252abdda4 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 30 Sep 2015 17:26:55 +0200 Subject: block: Add support for Ceva sata Initial Ceva Sata init code. Signed-off-by: Michal Simek Reviewed-by: Tom Rini --- board/xilinx/zynqmp/zynqmp.c | 4 ++ drivers/block/Makefile | 1 + drivers/block/sata_ceva.c | 113 ++++++++++++++++++++++++++++++++++++++++ include/configs/xilinx_zynqmp.h | 2 +- 4 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 drivers/block/sata_ceva.c (limited to 'drivers') diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c index 0f44b04c1ef..087578cb6b9 100644 --- a/board/xilinx/zynqmp/zynqmp.c +++ b/board/xilinx/zynqmp/zynqmp.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -185,6 +186,9 @@ void reset_cpu(ulong addr) #ifdef CONFIG_SCSI_AHCI_PLAT void scsi_init(void) { +#if defined(CONFIG_SATA_CEVA) + init_sata(0); +#endif ahci_init((void __iomem *)ZYNQMP_SATA_BASEADDR); scsi_scan(1); } diff --git a/drivers/block/Makefile b/drivers/block/Makefile index b4cbb093441..a43492f2082 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_LIBATA) += libata.o obj-$(CONFIG_MVSATA_IDE) += mvsata_ide.o obj-$(CONFIG_MX51_PATA) += mxc_ata.o obj-$(CONFIG_PATA_BFIN) += pata_bfin.o +obj-$(CONFIG_SATA_CEVA) += sata_ceva.o obj-$(CONFIG_SATA_DWC) += sata_dwc.o obj-$(CONFIG_SATA_MV) += sata_mv.o obj-$(CONFIG_SATA_SIL3114) += sata_sil3114.o diff --git a/drivers/block/sata_ceva.c b/drivers/block/sata_ceva.c new file mode 100644 index 00000000000..dcc3b90b17f --- /dev/null +++ b/drivers/block/sata_ceva.c @@ -0,0 +1,113 @@ +/* + * (C) Copyright 2015 - 2016 Xilinx, Inc. + * Michal Simek + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include +#include +#include +#include +#include + +#include + +/* Vendor Specific Register Offsets */ +#define AHCI_VEND_PCFG 0xA4 +#define AHCI_VEND_PPCFG 0xA8 +#define AHCI_VEND_PP2C 0xAC +#define AHCI_VEND_PP3C 0xB0 +#define AHCI_VEND_PP4C 0xB4 +#define AHCI_VEND_PP5C 0xB8 +#define AHCI_VEND_PAXIC 0xC0 +#define AHCI_VEND_PTC 0xC8 + +/* Vendor Specific Register bit definitions */ +#define PAXIC_ADBW_BW64 0x1 +#define PAXIC_MAWIDD (1 << 8) +#define PAXIC_MARIDD (1 << 16) +#define PAXIC_OTL (0x4 << 20) + +#define PCFG_TPSS_VAL (0x32 << 16) +#define PCFG_TPRS_VAL (0x2 << 12) +#define PCFG_PAD_VAL 0x2 + +#define PPCFG_TTA 0x1FFFE +#define PPCFG_PSSO_EN (1 << 28) +#define PPCFG_PSS_EN (1 << 29) +#define PPCFG_ESDF_EN (1 << 31) + +#define PP2C_CIBGMN 0x0F +#define PP2C_CIBGMX (0x25 << 8) +#define PP2C_CIBGN (0x18 << 16) +#define PP2C_CINMP (0x29 << 24) + +#define PP3C_CWBGMN 0x04 +#define PP3C_CWBGMX (0x0B << 8) +#define PP3C_CWBGN (0x08 << 16) +#define PP3C_CWNMP (0x0F << 24) + +#define PP4C_BMX 0x0a +#define PP4C_BNM (0x08 << 8) +#define PP4C_SFD (0x4a << 16) +#define PP4C_PTST (0x06 << 24) + +#define PP5C_RIT 0x60216 +#define PP5C_RCT (0x7f0 << 20) + +#define PTC_RX_WM_VAL 0x40 +#define PTC_RSVD (1 << 27) + +#define PORT0_BASE 0x100 +#define PORT1_BASE 0x180 + +/* Port Control Register Bit Definitions */ +#define PORT_SCTL_SPD_GEN3 (0x3 << 4) +#define PORT_SCTL_SPD_GEN2 (0x2 << 4) +#define PORT_SCTL_SPD_GEN1 (0x1 << 4) +#define PORT_SCTL_IPM (0x3 << 8) + +#define PORT_BASE 0x100 +#define PORT_OFFSET 0x80 +#define NR_PORTS 2 +#define DRV_NAME "ahci-ceva" +#define CEVA_FLAG_BROKEN_GEN2 1 + +int init_sata(int dev) +{ + ulong tmp; + ulong mmio = ZYNQMP_SATA_BASEADDR; + int i; + + /* + * AXI Data bus width to 64 + * Set Mem Addr Read, Write ID for data transfers + * Transfer limit to 72 DWord + */ + tmp = PAXIC_ADBW_BW64 | PAXIC_MAWIDD | PAXIC_MARIDD | PAXIC_OTL; + writel(tmp, mmio + AHCI_VEND_PAXIC); + + /* Set AHCI Enable */ + tmp = readl(mmio + HOST_CTL); + tmp |= HOST_AHCI_EN; + writel(tmp, mmio + HOST_CTL); + + for (i = 0; i < NR_PORTS; i++) { + /* TPSS TPRS scalars, CISE and Port Addr */ + tmp = PCFG_TPSS_VAL | PCFG_TPRS_VAL | (PCFG_PAD_VAL + i); + writel(tmp, mmio + AHCI_VEND_PCFG); + + /* Port Phy Cfg register enables */ + tmp = PPCFG_TTA | PPCFG_PSS_EN | PPCFG_ESDF_EN; + writel(tmp, mmio + AHCI_VEND_PPCFG); + + /* Rx Watermark setting */ + tmp = PTC_RX_WM_VAL | PTC_RSVD; + writel(tmp, mmio + AHCI_VEND_PTC); + + /* Default to Gen 2 Speed and Gen 1 if Gen2 is broken */ + tmp = PORT_SCTL_SPD_GEN3 | PORT_SCTL_IPM; + writel(tmp, mmio + PORT_SCR_CTL + PORT_BASE + PORT_OFFSET * i); + } + return 0; +} diff --git a/include/configs/xilinx_zynqmp.h b/include/configs/xilinx_zynqmp.h index 4062e01824e..8c760967f6d 100644 --- a/include/configs/xilinx_zynqmp.h +++ b/include/configs/xilinx_zynqmp.h @@ -226,7 +226,7 @@ #define CONFIG_LIBATA #define CONFIG_SCSI_AHCI #define CONFIG_SCSI_AHCI_PLAT -#define CONFIG_SYS_SCSI_MAX_SCSI_ID 1 +#define CONFIG_SYS_SCSI_MAX_SCSI_ID 2 #define CONFIG_SYS_SCSI_MAX_LUN 1 #define CONFIG_SYS_SCSI_MAX_DEVICE (CONFIG_SYS_SCSI_MAX_SCSI_ID * \ CONFIG_SYS_SCSI_MAX_LUN) -- cgit v1.2.3 From e76d2dcaeb9fe3d0d6f5105de518178b45423842 Mon Sep 17 00:00:00 2001 From: Siva Durga Prasad Paladugu Date: Wed, 30 Mar 2016 12:29:49 +0530 Subject: net: zynq_gem: Return error incase of invalid phy address Return error from probe in case of invalid phy address. This fixes the issue of uboot crash if phy is not detected. Signed-off-by: Siva Durga Prasad Paladugu Signed-off-by: Michal Simek --- drivers/net/zynq_gem.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c index 103ed6169c0..52a8f276001 100644 --- a/drivers/net/zynq_gem.c +++ b/drivers/net/zynq_gem.c @@ -638,9 +638,7 @@ static int zynq_gem_probe(struct udevice *dev) if (ret) return ret; - zynq_phy_init(dev); - - return 0; + return zynq_phy_init(dev); } static int zynq_gem_remove(struct udevice *dev) -- cgit v1.2.3 From 85b949f40b0688b58af0c02e4e3b38596b4376fb Mon Sep 17 00:00:00 2001 From: Siva Durga Prasad Paladugu Date: Fri, 25 Mar 2016 12:53:43 +0530 Subject: net: phy: Add SGMII support for TI phy Add support of SGMII to TI phy dp838367 Enable the SGMII and PCS settings in phy control, CFG2 and BIST registers Signed-off-by: Siva Durga Prasad Paladugu Signed-off-by: Michal Simek --- drivers/net/phy/ti.c | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/phy/ti.c b/drivers/net/phy/ti.c index c3912d52f32..937426bc856 100644 --- a/drivers/net/phy/ti.c +++ b/drivers/net/phy/ti.c @@ -12,6 +12,8 @@ #define MII_DP83867_PHYCTRL 0x10 #define MII_DP83867_MICR 0x12 +#define MII_DP83867_CFG2 0x14 +#define MII_DP83867_BISCR 0x16 #define DP83867_CTRL 0x1f /* Extended Registers */ @@ -43,10 +45,22 @@ #define DP83867_PHYCR_FIFO_DEPTH_SHIFT 14 #define DP83867_MDI_CROSSOVER 5 #define DP83867_MDI_CROSSOVER_AUTO 2 +#define DP83867_MDI_CROSSOVER_MDIX 2 +#define DP83867_PHYCTRL_SGMIIEN 0x0800 +#define DP83867_PHYCTRL_RXFIFO_SHIFT 12 +#define DP83867_PHYCTRL_TXFIFO_SHIFT 14 /* RGMIIDCTL bits */ #define DP83867_RGMII_TX_CLK_DELAY_SHIFT 4 +/* CFG2 bits */ +#define MII_DP83867_CFG2_SPEEDOPT_10EN 0x0040 +#define MII_DP83867_CFG2_SGMII_AUTONEGEN 0x0080 +#define MII_DP83867_CFG2_SPEEDOPT_ENH 0x0100 +#define MII_DP83867_CFG2_SPEEDOPT_CNT 0x0800 +#define MII_DP83867_CFG2_SPEEDOPT_INTLOW 0x2000 +#define MII_DP83867_CFG2_MASK 0x003F + #define MII_MMD_CTRL 0x0d /* MMD Access Control Register */ #define MII_MMD_DATA 0x0e /* MMD Access Data Register */ @@ -141,7 +155,7 @@ static inline bool phy_interface_is_rgmii(struct phy_device *phydev) static int dp83867_config(struct phy_device *phydev) { - unsigned int val, delay; + unsigned int val, delay, cfg2; int ret; /* Restart the PHY. */ @@ -155,6 +169,29 @@ static int dp83867_config(struct phy_device *phydev) (FIFO_DEPTH << DP83867_PHYCR_FIFO_DEPTH_SHIFT)); if (ret) return ret; + } else { + phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, + (BMCR_ANENABLE | BMCR_FULLDPLX | BMCR_SPEED1000)); + + cfg2 = phy_read(phydev, phydev->addr, MII_DP83867_CFG2); + cfg2 &= MII_DP83867_CFG2_MASK; + cfg2 |= (MII_DP83867_CFG2_SPEEDOPT_10EN | + MII_DP83867_CFG2_SGMII_AUTONEGEN | + MII_DP83867_CFG2_SPEEDOPT_ENH | + MII_DP83867_CFG2_SPEEDOPT_CNT | + MII_DP83867_CFG2_SPEEDOPT_INTLOW); + phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_CFG2, cfg2); + + phy_write_mmd_indirect(phydev, DP83867_RGMIICTL, + DP83867_DEVADDR, phydev->addr, 0x0); + + phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_PHYCTRL, + DP83867_PHYCTRL_SGMIIEN | + (DP83867_MDI_CROSSOVER_MDIX << + DP83867_MDI_CROSSOVER) | + (FIFO_DEPTH << DP83867_PHYCTRL_RXFIFO_SHIFT) | + (FIFO_DEPTH << DP83867_PHYCTRL_TXFIFO_SHIFT)); + phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_BISCR, 0x0); } if ((phydev->interface >= PHY_INTERFACE_MODE_RGMII_ID) && -- cgit v1.2.3 From 845ee5f623861ec274466f85b967d744c5b811e0 Mon Sep 17 00:00:00 2001 From: Siva Durga Prasad Paladugu Date: Fri, 25 Mar 2016 12:53:44 +0530 Subject: net: zynq_gem: Add SGMII support for zynqMP PCS auto negotaiation bit should be enabled along with SGMII autonegotation enabled in phy. Signed-off-by: Siva Durga Prasad Paladugu Signed-off-by: Michal Simek --- drivers/net/zynq_gem.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c index 52a8f276001..aec8077f10b 100644 --- a/drivers/net/zynq_gem.c +++ b/drivers/net/zynq_gem.c @@ -93,6 +93,8 @@ DECLARE_GLOBAL_DATA_PTR; #define ZYNQ_GEM_TSR_DONE 0x00000020 /* Tx done mask */ +#define ZYNQ_GEM_PCS_CTL_ANEG_ENBL 0x1000 + /* Use MII register 1 (MII status register) to detect PHY */ #define PHY_DETECT_REG 1 @@ -139,7 +141,9 @@ struct zynq_gem_regs { u32 reserved6[18]; #define STAT_SIZE 44 u32 stat[STAT_SIZE]; /* 0x100 - Octects transmitted Low reg */ - u32 reserved7[164]; + u32 reserved9[20]; + u32 pcscntrl; + u32 reserved7[143]; u32 transmit_q1_ptr; /* 0x440 - Transmit priority queue 1 */ u32 reserved8[15]; u32 receive_q1_ptr; /* 0x480 - Receive priority queue 1 */ @@ -432,9 +436,14 @@ static int zynq_gem_init(struct udevice *dev) nwconfig = ZYNQ_GEM_NWCFG_INIT; - if (priv->interface == PHY_INTERFACE_MODE_SGMII) + if (priv->interface == PHY_INTERFACE_MODE_SGMII) { nwconfig |= ZYNQ_GEM_NWCFG_SGMII_ENBL | ZYNQ_GEM_NWCFG_PCS_SEL; +#ifdef CONFIG_ARM64 + writel(readl(®s->pcscntrl) | ZYNQ_GEM_PCS_CTL_ANEG_ENBL, + ®s->pcscntrl); +#endif + } switch (priv->phydev->speed) { case SPEED_1000: -- cgit v1.2.3