Merge branch 'master' of git://www.denx.de/git/u-boot-microblaze

This commit is contained in:
Tom Rini
2016-04-04 14:34:09 -04:00
27 changed files with 1959 additions and 315 deletions

View File

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

113
drivers/block/sata_ceva.c Normal file
View File

@@ -0,0 +1,113 @@
/*
* (C) Copyright 2015 - 2016 Xilinx, Inc.
* Michal Simek <michal.simek@xilinx.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <netdev.h>
#include <ahci.h>
#include <scsi.h>
#include <asm/arch/hardware.h>
#include <asm/io.h>
/* 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;
}

View File

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

View File

@@ -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;
}

View File

@@ -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) &&

View File

@@ -0,0 +1,144 @@
/*
* Xilinx PCS/PMA Core phy driver
*
* Copyright (C) 2015 - 2016 Xilinx, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <config.h>
#include <common.h>
#include <phy.h>
#include <dm.h>
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;
}

View File

@@ -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;
@@ -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);
@@ -697,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;

View File

@@ -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
@@ -91,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
@@ -137,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 */
@@ -330,10 +336,12 @@ static int zynq_phy_init(struct udevice *dev)
/* Enable only MDIO bus */
writel(ZYNQ_GEM_NWCTRL_MDEN_MASK, &regs->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 +359,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 +434,25 @@ 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;
#ifdef CONFIG_ARM64
writel(readl(&regs->pcscntrl) | ZYNQ_GEM_PCS_CTL_ANEG_ENBL,
&regs->pcscntrl);
#endif
}
switch (priv->phydev->speed) {
case SPEED_1000:
writel(ZYNQ_GEM_NWCFG_INIT | ZYNQ_GEM_NWCFG_SPEED1000,
writel(nwconfig | ZYNQ_GEM_NWCFG_SPEED1000,
&regs->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,
&regs->nwcfg);
clk_rate = ZYNQ_GEM_FREQUENCY_100;
break;
@@ -561,6 +580,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)
{
@@ -611,9 +647,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)
@@ -634,6 +668,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)
@@ -663,6 +698,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));