diff options
author | Tom Rini <trini@konsulko.com> | 2015-12-18 07:28:24 -0500 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2015-12-18 07:28:24 -0500 |
commit | 4832e17787acb29734d895751bc7a594908aecc6 (patch) | |
tree | 74d28b656a3b31fd4053279535c13f1a808fb035 /drivers | |
parent | 123b70177931a5aed92beca76bb622b2f4005be8 (diff) | |
parent | b5e9b9a9a1bb231e35e206f8f3e2becee1dd06ab (diff) |
Merge branch 'master' of git://www.denx.de/git/u-boot-microblaze
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/Kconfig | 3 | ||||
-rw-r--r-- | drivers/net/zynq_gem.c | 61 | ||||
-rw-r--r-- | drivers/spi/zynq_qspi.c | 9 |
3 files changed, 46 insertions, 27 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 6905cc02e39..ae5e78dd344 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -103,8 +103,9 @@ config PCH_GBE config ZYNQ_GEM depends on DM_ETH && (ARCH_ZYNQ || ARCH_ZYNQMP) + select PHYLIB bool "Xilinx Ethernet GEM" help - This MAC is presetn in Xilinx Zynq and ZynqMP SoCs. + This MAC is present in Xilinx Zynq and ZynqMP SoCs. endif # NETDEVICES diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c index 0a41281e901..7059c8432a3 100644 --- a/drivers/net/zynq_gem.c +++ b/drivers/net/zynq_gem.c @@ -27,10 +27,6 @@ DECLARE_GLOBAL_DATA_PTR; -#if !defined(CONFIG_PHYLIB) -# error XILINX_GEM_ETHERNET requires PHYLIB -#endif - /* Bit/mask specification */ #define ZYNQ_GEM_PHYMNTNC_OP_MASK 0x40020000 /* operation mask bits */ #define ZYNQ_GEM_PHYMNTNC_OP_R_MASK 0x20000000 /* read operation */ @@ -532,44 +528,55 @@ static int zynq_gem_send(struct udevice *dev, void *ptr, int len) static int zynq_gem_recv(struct udevice *dev, int flags, uchar **packetp) { int frame_len; + u32 addr; struct zynq_gem_priv *priv = dev_get_priv(dev); struct emac_bd *current_bd = &priv->rx_bd[priv->rxbd_current]; - struct emac_bd *first_bd; if (!(current_bd->addr & ZYNQ_GEM_RXBUF_NEW_MASK)) - return 0; + return -1; if (!(current_bd->status & (ZYNQ_GEM_RXBUF_SOF_MASK | ZYNQ_GEM_RXBUF_EOF_MASK))) { printf("GEM: SOF or EOF not set for last buffer received!\n"); - return 0; + return -1; } frame_len = current_bd->status & ZYNQ_GEM_RXBUF_LEN_MASK; - if (frame_len) { - u32 addr = current_bd->addr & ZYNQ_GEM_RXBUF_ADD_MASK; - addr &= ~(ARCH_DMA_MINALIGN - 1); + if (!frame_len) { + printf("%s: Zero size packet?\n", __func__); + return -1; + } - net_process_received_packet((u8 *)(ulong)addr, frame_len); + addr = current_bd->addr & ZYNQ_GEM_RXBUF_ADD_MASK; + addr &= ~(ARCH_DMA_MINALIGN - 1); + *packetp = (uchar *)(uintptr_t)addr; - if (current_bd->status & ZYNQ_GEM_RXBUF_SOF_MASK) - priv->rx_first_buf = priv->rxbd_current; - else { - current_bd->addr &= ~ZYNQ_GEM_RXBUF_NEW_MASK; - current_bd->status = 0xF0000000; /* FIXME */ - } + return frame_len; +} - if (current_bd->status & ZYNQ_GEM_RXBUF_EOF_MASK) { - first_bd = &priv->rx_bd[priv->rx_first_buf]; - first_bd->addr &= ~ZYNQ_GEM_RXBUF_NEW_MASK; - first_bd->status = 0xF0000000; - } +static int zynq_gem_free_pkt(struct udevice *dev, uchar *packet, int length) +{ + struct zynq_gem_priv *priv = dev_get_priv(dev); + struct emac_bd *current_bd = &priv->rx_bd[priv->rxbd_current]; + struct emac_bd *first_bd; - if ((++priv->rxbd_current) >= RX_BUF) - priv->rxbd_current = 0; + if (current_bd->status & ZYNQ_GEM_RXBUF_SOF_MASK) { + priv->rx_first_buf = priv->rxbd_current; + } else { + current_bd->addr &= ~ZYNQ_GEM_RXBUF_NEW_MASK; + current_bd->status = 0xF0000000; /* FIXME */ } - return frame_len; + if (current_bd->status & ZYNQ_GEM_RXBUF_EOF_MASK) { + first_bd = &priv->rx_bd[priv->rx_first_buf]; + first_bd->addr &= ~ZYNQ_GEM_RXBUF_NEW_MASK; + first_bd->status = 0xF0000000; + } + + if ((++priv->rxbd_current) >= RX_BUF) + priv->rxbd_current = 0; + + return 0; } static void zynq_gem_halt(struct udevice *dev) @@ -651,6 +658,7 @@ static const struct eth_ops zynq_gem_ops = { .start = zynq_gem_init, .send = zynq_gem_send, .recv = zynq_gem_recv, + .free_pkt = zynq_gem_free_pkt, .stop = zynq_gem_halt, .write_hwaddr = zynq_gem_setup_mac, }; @@ -666,11 +674,12 @@ static int zynq_gem_ofdata_to_platdata(struct udevice *dev) priv->iobase = (struct zynq_gem_regs *)pdata->iobase; /* Hardcode for now */ priv->emio = 0; + priv->phyaddr = -1; offset = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset, "phy-handle"); if (offset > 0) - priv->phyaddr = fdtdec_get_int(gd->fdt_blob, offset, "reg", 0); + priv->phyaddr = fdtdec_get_int(gd->fdt_blob, offset, "reg", -1); phy_mode = fdt_getprop(gd->fdt_blob, dev->of_offset, "phy-mode", NULL); if (phy_mode) diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c index 5825c6d8f1f..b98663c23b2 100644 --- a/drivers/spi/zynq_qspi.c +++ b/drivers/spi/zynq_qspi.c @@ -30,6 +30,7 @@ DECLARE_GLOBAL_DATA_PTR; #define ZYNQ_QSPI_IXR_TXOW_MASK BIT(2) /* TX_FIFO_not_full */ #define ZYNQ_QSPI_IXR_ALL_MASK GENMASK(6, 0) /* All IXR bits */ #define ZYNQ_QSPI_ENR_SPI_EN_MASK BIT(0) /* SPI Enable */ +#define ZYNQ_QSPI_LQSPICFG_LQMODE_MASK BIT(31) /* Linear QSPI Mode */ /* zynq qspi Transmit Data Register */ #define ZYNQ_QSPI_TXD_00_00_OFFSET 0x1C /* Transmit 4-byte inst */ @@ -68,6 +69,9 @@ struct zynq_qspi_regs { u32 txd1r; /* 0x80 */ u32 txd2r; /* 0x84 */ u32 txd3r; /* 0x88 */ + u32 reserved1[5]; + u32 lqspicfg; /* 0xA0 */ + u32 lqspists; /* 0xA4 */ }; /* zynq qspi platform data */ @@ -143,6 +147,11 @@ static void zynq_qspi_init_hw(struct zynq_qspi_priv *priv) ZYNQ_QSPI_CR_MSTREN_MASK; writel(confr, ®s->cr); + /* Disable the LQSPI feature */ + confr = readl(®s->lqspicfg); + confr &= ~ZYNQ_QSPI_LQSPICFG_LQMODE_MASK; + writel(confr, ®s->lqspicfg); + /* Enable SPI */ writel(ZYNQ_QSPI_ENR_SPI_EN_MASK, ®s->enr); } |