summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2015-12-18 07:28:24 -0500
committerTom Rini <trini@konsulko.com>2015-12-18 07:28:24 -0500
commit4832e17787acb29734d895751bc7a594908aecc6 (patch)
tree74d28b656a3b31fd4053279535c13f1a808fb035 /drivers
parent123b70177931a5aed92beca76bb622b2f4005be8 (diff)
parentb5e9b9a9a1bb231e35e206f8f3e2becee1dd06ab (diff)
Merge branch 'master' of git://www.denx.de/git/u-boot-microblaze
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/Kconfig3
-rw-r--r--drivers/net/zynq_gem.c61
-rw-r--r--drivers/spi/zynq_qspi.c9
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, &regs->cr);
+ /* Disable the LQSPI feature */
+ confr = readl(&regs->lqspicfg);
+ confr &= ~ZYNQ_QSPI_LQSPICFG_LQMODE_MASK;
+ writel(confr, &regs->lqspicfg);
+
/* Enable SPI */
writel(ZYNQ_QSPI_ENR_SPI_EN_MASK, &regs->enr);
}