Skip to contentSkip to conversation

serial: Add Zynq serial driver

PATCH Superseded Michal Simek 3 participants 38 messages Aug 16, 2012 – Sep 14, 2012 1 message not in the archive

Subsystems (4)

v2 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

PATCH v2 1/4 serial: Add Zynq serial driver

The driver is used on Xilinx Zynq platform.

---
v2: Use Zynq name instead of Dragonfire and XPSS/XDFUART
Rename driver name
Remove driver description

---
 drivers/serial/Makefile      |    1 +
 drivers/serial/serial_zynq.c |  200 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 201 insertions(+), 0 deletions(-)
 create mode 100644 drivers/serial/serial_zynq.c
drivers/serial/Makefile +1 -0
index 65d0f23..dfc22a4 100644
@@ -56,6 +56,7 @@ COBJS-$(CONFIG_S3C44B0_SERIAL) += serial_s3c44b0.o
 COBJS-$(CONFIG_XILINX_UARTLITE) += serial_xuartlite.o
 COBJS-$(CONFIG_SANDBOX_SERIAL) += sandbox.o
 COBJS-$(CONFIG_SCIF_CONSOLE) += serial_sh.o
+COBJS-$(CONFIG_ZYNQ_SERIAL) += serial_zynq.o
 
 ifndef CONFIG_SPL_BUILD
 COBJS-$(CONFIG_USB_TTY) += usbtty.o
drivers/serial/serial_zynq.c new file +200 -0

200 lines not on this page · raw message

Signature · 1 line
1.7.0.4
#1 lore raw

PATCH v2 1/4 serial: Add Zynq serial driver

Quoted 8 lines · Michal Simek

The driver is used on Xilinx Zynq platform.

---
v2: Use Zynq name instead of Dragonfire and XPSS/XDFUART
Rename driver name
Remove driver description

Quoted 5 lines
---
  drivers/serial/Makefile      |    1 +
  drivers/serial/serial_zynq.c |  200 ++++++++++++++++++++++++++++++++++++++++++
  2 files changed, 201 insertions(+), 0 deletions(-)

create mode 100644 drivers/serial/serial_zynq.c

Joe: you have reviewed the first version of this patch. Can you comment it?

Thanks,
Michal

Signature · 4 lines
Michal Simek, Ing. (M.Eng)
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel 2.6 Microblaze Linux - http://www.monstr.eu/fdt/
Microblaze U-BOOT custodian
#2 lore raw

PATCH v2 2/4 net: Add driver for Zynq Gem IP

In reply to Michal Simek

Device driver for Zynq Gem IP.

CC Joe Hershberger <[email protected]>

---
v2: Remove phylib protection
Rename driver file name xilinx_gem to zynq_gem Rename XEMACPSS to ZYNQ_GEM
Rename gemac_priv to zynq_gem_priv
Rename gem_regs to zynq_gem_regs
Add zynq_ prefix to several functions Remove phy detection
Rename driver name XGem to Gem
Change setup_mac function to reflect u-boot style

---
 drivers/net/Makefile   |    1 +
 drivers/net/zynq_gem.c |  453 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/netdev.h       |    2 +-
 3 files changed, 455 insertions(+), 1 deletions(-)
 create mode 100644 drivers/net/zynq_gem.c
drivers/net/Makefile +1 -0
index 430f90c..b298588 100644
@@ -79,6 +79,7 @@ COBJS-$(CONFIG_XILINX_AXIEMAC) += xilinx_axi_emac.o
 COBJS-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o
 COBJS-$(CONFIG_XILINX_LL_TEMAC) += xilinx_ll_temac.o xilinx_ll_temac_mdio.o \
 		xilinx_ll_temac_fifo.o xilinx_ll_temac_sdma.o
+COBJS-$(CONFIG_ZYNQ_GEM) += zynq_gem.o
 
 COBJS	:= $(sort $(COBJS-y))
 SRCS	:= $(COBJS:.o=.c)
drivers/net/zynq_gem.c new file +453 -0

453 lines not on this page · raw message

include/netdev.h +1 -1
index d1aaf0c..b8d303d 100644
@@ -104,7 +104,7 @@ int xilinx_emaclite_initialize(bd_t *bis, unsigned long base_addr,
 							int txpp, int rxpp);
 int xilinx_ll_temac_eth_init(bd_t *bis, unsigned long base_addr, int flags,
 						unsigned long ctrl_addr);
-
+int zynq_gem_initialize(bd_t *bis, int base_addr);
 /*
  * As long as the Xilinx xps_ll_temac ethernet driver has not its own interface
  * exported by a public hader file, we need a global definition at this point.
Signature · 1 line
1.7.0.4
#3 lore raw

PATCH v2 2/4 net: Add driver for Zynq Gem IP

Quoted 15 lines · Michal Simek

Device driver for Zynq Gem IP.

CC Joe Hershberger <[email protected]>

---
v2: Remove phylib protection
Rename driver file name xilinx_gem to zynq_gem Rename XEMACPSS to ZYNQ_GEM
Rename gemac_priv to zynq_gem_priv Rename gem_regs to zynq_gem_regs
Add zynq_ prefix to several functions Remove phy detection
Rename driver name XGem to Gem
Change setup_mac function to reflect u-boot style

Quoted 6 lines
---
  drivers/net/Makefile   |    1 +
  drivers/net/zynq_gem.c |  453 ++++++++++++++++++++++++++++++++++++++++++++++++
  include/netdev.h       |    2 +-
  3 files changed, 455 insertions(+), 1 deletions(-)

create mode 100644 drivers/net/zynq_gem.c

Joe: I am not sure if you have seen this patch. Can you please review it and comment it.
If is ok, I would like to ask you to add this patch to your net custodian tree or sending me your ACK.

Thanks,
Michal

Signature · 4 lines
Michal Simek, Ing. (M.Eng)
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel 2.6 Microblaze Linux - http://www.monstr.eu/fdt/
Microblaze U-BOOT custodian
#4 lore raw

PATCH v2 2/4 net: Add driver for Zynq Gem IP

In reply to Michal Simek

Dear Michal Simek,

[...]

drivers/net/zynq_gem.c line 124

Quoted 7 lines
drivers/net/zynq_gem.c new file +7 -0
+static inline int mdio_wait(struct eth_device *dev)
+{
+	struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase;
+	u32 timeout = 200;
+
+	/* Wait till MDIO interface is ready to accept a new transaction. */
+	while (timeout && !(readl(&regs->nwsr) & ZYNQ_GEM_NWSR_MDIOIDLE_MASK)) {

I'd say, rework this to

while (--timeout) {
	if (readl() & ... )
		break;
	WATCHDOG_RESET();
}

The WATCHDOG_RESET will give you the udelay and restart the WDT if you use any. Also, I think it's more readable when you omit the complex condition for the while cycle and split it a bit.

Quoted 11 lines
drivers/net/zynq_gem.c new file +11 -0
+		timeout--;
+		udelay(1);
+	}
+
+	if (!timeout) {
+		printf("%s: Timeout\n", __func__);
+		return 1;
+	}
+
+	return 0;
+}

[...]

Quoted 24 lines
drivers/net/zynq_gem.c new file +24 -0
+static int zynq_gem_init(struct eth_device *dev, bd_t * bis)
+{
+	int tmp;
+	int i;
+	struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase;
+	struct zynq_gem_priv *priv = dev->priv;
+	struct phy_device *phydev;
+	u32 supported = SUPPORTED_10baseT_Half |
+			SUPPORTED_10baseT_Full |
+			SUPPORTED_100baseT_Half |
+			SUPPORTED_100baseT_Full |
+			SUPPORTED_1000baseT_Half |
+			SUPPORTED_1000baseT_Full;
+
+	if (priv->initialized)
+		return 0;
+
+	/* Disable all interrupts */
+	writel(0xFFFFFFFF, &regs->idr);
+
+	/* Disable the receiver & transmitter */
+	writel(0, &regs->nwctrl);
+	writel(0, &regs->txsr);
+	writel(0, &regs->rxsr);

drivers/net/zynq_gem.c line 236

Quoted 10 lines
drivers/net/zynq_gem.c new file +10 -0
+	writel(0, &regs->phymntnc);
+
+	/* Clear the Hash registers for the mac address pointed by AddressPtr */
+	writel(0x0, &regs->hashl);
+	/* Write bits [63:32] in TOP */
+	writel(0x0, &regs->hashh);
+
+	/* Clear all counters */
+	for (i = 0; i <= (sizeof(struct zynq_gem_regs) -
+			offsetof(struct zynq_gem_regs, stat)) / 4; i++)

Add a const int variable and use it here so you don't have to break the for () .

Quoted 19 lines
drivers/net/zynq_gem.c new file +19 -0
+		readl(&regs->stat[i]);
+
+	/* Setup RxBD space */
+	memset(&(priv->rx_bd), 0, sizeof(priv->rx_bd));
+	/* Create the RxBD ring */
+	memset(&(priv->rxbuffers), 0, sizeof(priv->rxbuffers));
+
+	for (i = 0; i < RX_BUF; i++) {
+		priv->rx_bd[i].status = 0xF0000000;
+		priv->rx_bd[i].addr = (u32)((char *) &(priv->rxbuffers) +
+							(i * PKTSIZE_ALIGN));
+	}
+	/* WRAP bit to last BD */
+	priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK;
+	/* Write RxBDs to IP */
+	writel((u32) &(priv->rx_bd), &regs->rxqbase);
+
+
+	/* MAC Setup */

drivers/net/zynq_gem.c line 265

Quoted 10 lines
drivers/net/zynq_gem.c new file +10 -0
+	/*
+	 *  Following is the setup for Network Configuration register.
+	 *  Bit 0:  Set for 100 Mbps operation.
+	 *  Bit 1:  Set for Full Duplex mode.
+	 *  Bit 4:  Unset to allow Copy all frames - MAC checking
+	 *  Bit 17: Set for FCS removal.
+	 *  Bits 20-18: Set with value binary 010 to divide pclk by 32
+	 *              (pclk up to 80 MHz)
+	 */
+	writel(0x000A0003, &regs->nwcfg);

Well you know ... magic numbers and defined bits ;-)

Quoted 14 lines
drivers/net/zynq_gem.c new file +14 -0
+	/*
+	 * Following is the setup for DMA Configuration register.
+	 * Bits 4-0: To set AHB fixed burst length for DMA data operations ->
+	 *  Set with binary 00100 to use INCR4 AHB bursts.
+	 * Bits 9-8: Receiver packet buffer memory size ->
+	 *  Set with binary 11 to Use full configured addressable space (8 Kb)
+	 * Bit 10  : Transmitter packet buffer memory size ->
+	 *  Set with binary 1 to Use full configured addressable space (4 Kb)
+	 * Bits 23-16 : DMA receive buffer size in AHB system memory ->
+	 *  Set with binary 00011000 to use 1536 byte(1*max length frame/buffer)
+	 */
+	writel(0x00180704, &regs->dmacr);
+
+	/*

drivers/net/zynq_gem.c line 290

Quoted 10 lines
drivers/net/zynq_gem.c new file +10 -0
+	 * Following is the setup for Network Control register.
+	 * Bit 2:  Set to enable Receive operation.
+	 * Bit 3:  Set to enable Transmitt operation.
+	 * Bit 4:  Set to enable MDIO operation.
+	 */
+	tmp = readl(&regs->nwctrl);
+	/* MDIO, Rx and Tx enable */
+	tmp |= ZYNQ_GEM_NWCTRL_MDEN_MASK | ZYNQ_GEM_NWCTRL_RXEN_MASK |
+	    ZYNQ_GEM_NWCTRL_TXEN_MASK;
+	writel(tmp, &regs->nwctrl);

setbits_le32()

Quoted 28 lines
drivers/net/zynq_gem.c new file +28 -0
+	/* interface - look at tsec */
+	phydev = phy_connect(priv->bus, priv->phyaddr, dev, 0);
+
+	phydev->supported &= supported;
+	phydev->advertising = phydev->supported;
+	priv->phydev = phydev;
+	phy_config(phydev);
+	phy_startup(phydev);
+
+	priv->initialized = 1;
+	return 0;
+}
+
+static int zynq_gem_send(struct eth_device *dev, void *ptr, int len)
+{
+	int status;
+	u32 val;
+	struct zynq_gem_priv *priv = dev->priv;
+	struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase;
+
+	if (!priv->initialized) {
+		puts("Error GMAC not initialized");
+		return -1;
+	}
+
+	/* setup BD */
+	writel((u32)&(priv->tx_bd), &regs->txqbase);
+

drivers/net/zynq_gem.c line 329

Quoted 10 lines
drivers/net/zynq_gem.c new file +10 -0
+	/* Setup Tx BD */
+	memset((void *) &(priv->tx_bd), 0, sizeof(struct emac_bd));
+
+	priv->tx_bd.addr = (u32)ptr;
+	priv->tx_bd.status = len | ZYNQ_GEM_TXBUF_LAST_MASK |
+						ZYNQ_GEM_TXBUF_WRAP_MASK;
+
+	/* Start transmit */
+	val = readl(&regs->nwctrl) | ZYNQ_GEM_NWCTRL_STARTTX_MASK;
+	writel(val, &regs->nwctrl);

setbits_le32()

drivers/net/zynq_gem.c line 334

Quoted 4 lines
drivers/net/zynq_gem.c new file +4 -0
+	/* Read the stat register to know if the packet has been transmitted */
+	status = readl(&regs->txsr);
+	if (status & (ZYNQ_GEM_TXSR_HRESPNOK_MASK | ZYNQ_GEM_TXSR_URUN_MASK |
+						ZYNQ_GEM_TXSR_BUFEXH_MASK)) {

Add const int mask for the above.

Quoted 16 lines
drivers/net/zynq_gem.c new file +10 -0
+		printf("Something has gone wrong here!? Status is 0x%x.\n",
+		       status);
+	}
+
+	/* Clear Tx status register before leaving . */
+	writel(status, &regs->txsr);
+	return 0;
+}
+
+/* Do not check frame_recd flag in rx_status register 0x20 - just poll BD

*/ +static int zynq_gem_recv(struct eth_device *dev)

drivers/net/zynq_gem.c new file +5 -0
+{
+	int frame_len;
+	struct zynq_gem_priv *priv = dev->priv;
+
+	if (!(priv->rx_bd[priv->rxbd_current].addr & ZYNQ_GEM_RXBUF_NEW_MASK))

drivers/net/zynq_gem.c line 360

Quoted 10 lines
drivers/net/zynq_gem.c new file +10 -0
+		return 0;
+
+	if (!(priv->rx_bd[priv->rxbd_current].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;
+	}
+
+	frame_len = priv->rx_bd[priv->rxbd_current].status &
+							ZYNQ_GEM_RXBUF_LEN_MASK;

Just introduce some variable for priv->rx_bd[priv->rxbd_current] so you don't have such long lines

Quoted 22 lines
drivers/net/zynq_gem.c new file +22 -0
+	if (frame_len) {
+		NetReceive((u8 *) (priv->rx_bd[priv->rxbd_current].addr &
+					ZYNQ_GEM_RXBUF_ADD_MASK), frame_len);
+
+		if (priv->rx_bd[priv->rxbd_current].status &
+							ZYNQ_GEM_RXBUF_SOF_MASK)
+			priv->rx_first_buf = priv->rxbd_current;
+		else {
+			priv->rx_bd[priv->rxbd_current].addr &=
+						~ZYNQ_GEM_RXBUF_NEW_MASK;
+			priv->rx_bd[priv->rxbd_current].status = 0xF0000000;
+		}
+
+		if (priv->rx_bd[priv->rxbd_current].status &
+						ZYNQ_GEM_RXBUF_EOF_MASK) {
+			priv->rx_bd[priv->rx_first_buf].addr &=
+						~ZYNQ_GEM_RXBUF_NEW_MASK;
+			priv->rx_bd[priv->rx_first_buf].status = 0xF0000000;
+		}
+
+		if ((++priv->rxbd_current) >= RX_BUF)
+			priv->rxbd_current = 0;

drivers/net/zynq_gem.c line 392

Quoted 10 lines
drivers/net/zynq_gem.c new file +10 -0
+
+		return frame_len;
+	}
+
+	return 0;
+}
+
+static void zynq_gem_halt(struct eth_device *dev)
+{
+	return;

Does this need to be implemented at all ?

Quoted 75 lines
drivers/net/zynq_gem.c new file +61 -0
+}
+
+static int zynq_gem_miiphyread(const char *devname, uchar addr,
+							uchar reg, ushort *val)
+{
+	struct eth_device *dev = eth_get_dev();
+	int ret;
+
+	ret = phyread(dev, addr, reg, val);
+	debug("%s 0x%x, 0x%x, 0x%x\n", __func__, addr, reg, *val);
+	return ret;
+}
+
+static int zynq_gem_miiphy_write(const char *devname, uchar addr,
+							uchar reg, ushort val)
+{
+	struct eth_device *dev = eth_get_dev();
+
+	debug("%s 0x%x, 0x%x, 0x%x\n", __func__, addr, reg, val);
+	return phywrite(dev, addr, reg, val);
+}
+
+int zynq_gem_initialize(bd_t *bis, int base_addr)
+{
+	struct eth_device *dev;
+	struct zynq_gem_priv *priv;
+
+	dev = calloc(1, sizeof(*dev));
+	if (dev == NULL)
+		return -1;
+
+	dev->priv = calloc(1, sizeof(struct zynq_gem_priv));
+	if (dev->priv == NULL) {
+		free(dev);
+		return -1;
+	}
+	priv = dev->priv;
+
+#ifdef CONFIG_PHY_ADDR
+	priv->phyaddr = CONFIG_PHY_ADDR;
+#else
+	priv->phyaddr = -1;
+#endif
+
+	sprintf(dev->name, "Gem.%x", base_addr);
+
+	dev->iobase = base_addr;
+
+	dev->init = zynq_gem_init;
+	dev->halt = zynq_gem_halt;
+	dev->send = zynq_gem_send;
+	dev->recv = zynq_gem_recv;
+	dev->write_hwaddr = zynq_gem_setup_mac;
+
+	eth_register(dev);
+
+	miiphy_register(dev->name, zynq_gem_miiphyread, zynq_gem_miiphy_write);
+	priv->bus = miiphy_get_dev_by_name(dev->name);
+
+	return 1;
+}
include/netdev.h +1 -1
index d1aaf0c..b8d303d 100644
@@ -104,7 +104,7 @@ int xilinx_emaclite_initialize(bd_t *bis, unsigned long
 base_addr, int txpp, int rxpp);
 int xilinx_ll_temac_eth_init(bd_t *bis, unsigned long base_addr, int
 flags, unsigned long ctrl_addr);
-
+int zynq_gem_initialize(bd_t *bis, int base_addr);
 /*
  * As long as the Xilinx xps_ll_temac ethernet driver has not its own

interface * exported by a public hader file, we need a global definition at this point.

#5 lore raw

PATCH v2 2/4 net: Add driver for Zynq Gem IP

Quoted 20 lines · Marek Vasut

Dear Michal Simek,

[...]

drivers/net/zynq_gem.c line 124

Quoted 7 lines
drivers/net/zynq_gem.c new file +7 -0
+static inline int mdio_wait(struct eth_device *dev)
+{
+	struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase;
+	u32 timeout = 200;
+
+	/* Wait till MDIO interface is ready to accept a new transaction. */
+	while (timeout && !(readl(&regs->nwsr) & ZYNQ_GEM_NWSR_MDIOIDLE_MASK)) {

I'd say, rework this to

while (--timeout) {
	if (readl() & ... )
		break;
	WATCHDOG_RESET();
}
Quoted 3 lines

The WATCHDOG_RESET will give you the udelay and restart the WDT if you use any. Also, I think it's more readable when you omit the complex condition for the while cycle and split it a bit.

make sense

Quoted 43 lines
Quoted 12 lines
drivers/net/zynq_gem.c new file +11 -0
+		timeout--;
+		udelay(1);
+	}
+
+	if (!timeout) {
+		printf("%s: Timeout\n", __func__);
+		return 1;
+	}
+
+	return 0;
+}

[...]

Quoted 28 lines
drivers/net/zynq_gem.c new file +28 -0
+static int zynq_gem_init(struct eth_device *dev, bd_t * bis)
+{
+	int tmp;
+	int i;
+	struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase;
+	struct zynq_gem_priv *priv = dev->priv;
+	struct phy_device *phydev;
+	u32 supported = SUPPORTED_10baseT_Half |
+			SUPPORTED_10baseT_Full |
+			SUPPORTED_100baseT_Half |
+			SUPPORTED_100baseT_Full |
+			SUPPORTED_1000baseT_Half |
+			SUPPORTED_1000baseT_Full;
+
+	if (priv->initialized)
+		return 0;
+
+	/* Disable all interrupts */
+	writel(0xFFFFFFFF, &regs->idr);
+
+	/* Disable the receiver & transmitter */
+	writel(0, &regs->nwctrl);
+	writel(0, &regs->txsr);
+	writel(0, &regs->rxsr);
+	writel(0, &regs->phymntnc);
+
+	/* Clear the Hash registers for the mac address pointed by AddressPtr */
+	writel(0x0, &regs->hashl);
Quoted 8 lines

drivers/net/zynq_gem.c line 236

Quoted 6 lines
drivers/net/zynq_gem.c new file +6 -0
+	/* Write bits [63:32] in TOP */
+	writel(0x0, &regs->hashh);
+
+	/* Clear all counters */
+	for (i = 0; i <= (sizeof(struct zynq_gem_regs) -
+			offsetof(struct zynq_gem_regs, stat)) / 4; i++)

Add a const int variable and use it here so you don't have to break the for () .

if you like.

Quoted 24 lines
Quoted 24 lines
drivers/net/zynq_gem.c new file +23 -0
+		readl(&regs->stat[i]);
+
+	/* Setup RxBD space */
+	memset(&(priv->rx_bd), 0, sizeof(priv->rx_bd));
+	/* Create the RxBD ring */
+	memset(&(priv->rxbuffers), 0, sizeof(priv->rxbuffers));
+
+	for (i = 0; i < RX_BUF; i++) {
+		priv->rx_bd[i].status = 0xF0000000;
+		priv->rx_bd[i].addr = (u32)((char *) &(priv->rxbuffers) +
+							(i * PKTSIZE_ALIGN));
+	}
+	/* WRAP bit to last BD */
+	priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK;
+	/* Write RxBDs to IP */
+	writel((u32) &(priv->rx_bd), &regs->rxqbase);
+
+
+	/* MAC Setup */
+	/*
+	 *  Following is the setup for Network Configuration register.
+	 *  Bit 0:  Set for 100 Mbps operation.
+	 *  Bit 1:  Set for Full Duplex mode.
Quoted 8 lines

drivers/net/zynq_gem.c line 265

Quoted 6 lines
drivers/net/zynq_gem.c new file +6 -0
+	 *  Bit 4:  Unset to allow Copy all frames - MAC checking
+	 *  Bit 17: Set for FCS removal.
+	 *  Bits 20-18: Set with value binary 010 to divide pclk by 32
+	 *              (pclk up to 80 MHz)
+	 */
+	writel(0x000A0003, &regs->nwcfg);

Well you know ... magic numbers and defined bits ;-)

:-) Or. let me create macros.

Quoted 13 lines

drivers/net/zynq_gem.c line 278

Quoted 13 lines
drivers/net/zynq_gem.c new file +12 -0
+	/*
+	 * Following is the setup for DMA Configuration register.
+	 * Bits 4-0: To set AHB fixed burst length for DMA data operations ->
+	 *  Set with binary 00100 to use INCR4 AHB bursts.
+	 * Bits 9-8: Receiver packet buffer memory size ->
+	 *  Set with binary 11 to Use full configured addressable space (8 Kb)
+	 * Bit 10  : Transmitter packet buffer memory size ->
+	 *  Set with binary 1 to Use full configured addressable space (4 Kb)
+	 * Bits 23-16 : DMA receive buffer size in AHB system memory ->
+	 *  Set with binary 00011000 to use 1536 byte(1*max length frame/buffer)
+	 */
+	writel(0x00180704, &regs->dmacr);

the same here.

Quoted 6 lines
Quoted 6 lines
drivers/net/zynq_gem.c new file +6 -0
+
+	/*
+	 * Following is the setup for Network Control register.
+	 * Bit 2:  Set to enable Receive operation.
+	 * Bit 3:  Set to enable Transmitt operation.
+	 * Bit 4:  Set to enable MDIO operation.
Quoted 8 lines

drivers/net/zynq_gem.c line 290

Quoted 6 lines
drivers/net/zynq_gem.c new file +6 -0
+	 */
+	tmp = readl(&regs->nwctrl);
+	/* MDIO, Rx and Tx enable */
+	tmp |= ZYNQ_GEM_NWCTRL_MDEN_MASK | ZYNQ_GEM_NWCTRL_RXEN_MASK |
+	    ZYNQ_GEM_NWCTRL_TXEN_MASK;
+	writel(tmp, &regs->nwctrl);

setbits_le32()

ok.

Quoted 33 lines
Quoted 33 lines
drivers/net/zynq_gem.c new file +32 -0
+	/* interface - look at tsec */
+	phydev = phy_connect(priv->bus, priv->phyaddr, dev, 0);
+
+	phydev->supported &= supported;
+	phydev->advertising = phydev->supported;
+	priv->phydev = phydev;
+	phy_config(phydev);
+	phy_startup(phydev);
+
+	priv->initialized = 1;
+	return 0;
+}
+
+static int zynq_gem_send(struct eth_device *dev, void *ptr, int len)
+{
+	int status;
+	u32 val;
+	struct zynq_gem_priv *priv = dev->priv;
+	struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase;
+
+	if (!priv->initialized) {
+		puts("Error GMAC not initialized");
+		return -1;
+	}
+
+	/* setup BD */
+	writel((u32)&(priv->tx_bd), &regs->txqbase);
+
+	/* Setup Tx BD */
+	memset((void *) &(priv->tx_bd), 0, sizeof(struct emac_bd));
+
+	priv->tx_bd.addr = (u32)ptr;
Quoted 8 lines

drivers/net/zynq_gem.c line 329

Quoted 6 lines
drivers/net/zynq_gem.c new file +6 -0
+	priv->tx_bd.status = len | ZYNQ_GEM_TXBUF_LAST_MASK |
+						ZYNQ_GEM_TXBUF_WRAP_MASK;
+
+	/* Start transmit */
+	val = readl(&regs->nwctrl) | ZYNQ_GEM_NWCTRL_STARTTX_MASK;
+	writel(val, &regs->nwctrl);

setbits_le32()

ok

Quoted 7 lines

drivers/net/zynq_gem.c line 334

Quoted 5 lines
drivers/net/zynq_gem.c new file +4 -0
+	/* Read the stat register to know if the packet has been transmitted */
+	status = readl(&regs->txsr);
+	if (status & (ZYNQ_GEM_TXSR_HRESPNOK_MASK | ZYNQ_GEM_TXSR_URUN_MASK |
+						ZYNQ_GEM_TXSR_BUFEXH_MASK)) {

Add const int mask for the above.

or macro should be fine.

Quoted 22 lines
Quoted 22 lines
drivers/net/zynq_gem.c new file +10 -0
+		printf("Something has gone wrong here!? Status is 0x%x.\n",
+		       status);
+	}
+
+	/* Clear Tx status register before leaving . */
+	writel(status, &regs->txsr);
+	return 0;
+}
+
+/* Do not check frame_recd flag in rx_status register 0x20 - just poll BD

*/ +static int zynq_gem_recv(struct eth_device *dev)

drivers/net/zynq_gem.c new file +10 -0
+{
+	int frame_len;
+	struct zynq_gem_priv *priv = dev->priv;
+
+	if (!(priv->rx_bd[priv->rxbd_current].addr & ZYNQ_GEM_RXBUF_NEW_MASK))
+		return 0;
+
+	if (!(priv->rx_bd[priv->rxbd_current].status &
+			(ZYNQ_GEM_RXBUF_SOF_MASK | ZYNQ_GEM_RXBUF_EOF_MASK))) {
+		printf("GEM: SOF or EOF not set for last buffer received!\n");
Quoted 8 lines

drivers/net/zynq_gem.c line 360

Quoted 5 lines
drivers/net/zynq_gem.c new file +5 -0
+		return 0;
+	}
+
+	frame_len = priv->rx_bd[priv->rxbd_current].status &
+							ZYNQ_GEM_RXBUF_LEN_MASK;

Just introduce some variable for priv->rx_bd[priv->rxbd_current] so you don't have such long lines

no problem.

Quoted 27 lines
Quoted 27 lines
drivers/net/zynq_gem.c new file +26 -0
+	if (frame_len) {
+		NetReceive((u8 *) (priv->rx_bd[priv->rxbd_current].addr &
+					ZYNQ_GEM_RXBUF_ADD_MASK), frame_len);
+
+		if (priv->rx_bd[priv->rxbd_current].status &
+							ZYNQ_GEM_RXBUF_SOF_MASK)
+			priv->rx_first_buf = priv->rxbd_current;
+		else {
+			priv->rx_bd[priv->rxbd_current].addr &=
+						~ZYNQ_GEM_RXBUF_NEW_MASK;
+			priv->rx_bd[priv->rxbd_current].status = 0xF0000000;
+		}
+
+		if (priv->rx_bd[priv->rxbd_current].status &
+						ZYNQ_GEM_RXBUF_EOF_MASK) {
+			priv->rx_bd[priv->rx_first_buf].addr &=
+						~ZYNQ_GEM_RXBUF_NEW_MASK;
+			priv->rx_bd[priv->rx_first_buf].status = 0xF0000000;
+		}
+
+		if ((++priv->rxbd_current) >= RX_BUF)
+			priv->rxbd_current = 0;
+
+		return frame_len;
+	}
+
Quoted 8 lines

drivers/net/zynq_gem.c line 392

Quoted 6 lines
drivers/net/zynq_gem.c new file +6 -0
+	return 0;
+}
+
+static void zynq_gem_halt(struct eth_device *dev)
+{
+	return;

Does this need to be implemented at all ?

probably not.
Let me do that changes and I will send updated version.

Thanks,
Michal

Signature · 4 lines
Michal Simek, Ing. (M.Eng)
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel 2.6 Microblaze Linux - http://www.monstr.eu/fdt/
Microblaze U-BOOT custodian
#6 lore raw

PATCH v2 2/4 net: Add driver for Zynq Gem IP

Dear Michal Simek,

[...]

Quoted 4 lines
Quoted 2 lines

Add const int mask for the above.

or macro should be fine.

const int is better due to type checking .

[...]

Thanks!

Best regards,
Marek Vasut

#7 lore raw

PATCH v2 2/4 net: Add driver for Zynq Gem IP

In reply to Marek Vasut

Hi Marek,

Quoted 13 lines · Marek Vasut

Dear Michal Simek,

drivers/net/zynq_gem.c line 290

Quoted 11 lines
drivers/net/zynq_gem.c new file +11 -0
+     /*
+      * Following is the setup for Network Control register.
+      * Bit 2:  Set to enable Receive operation.
+      * Bit 3:  Set to enable Transmitt operation.
+      * Bit 4:  Set to enable MDIO operation.
+      */
+     tmp = readl(&regs->nwctrl);
+     /* MDIO, Rx and Tx enable */
+     tmp |= ZYNQ_GEM_NWCTRL_MDEN_MASK | ZYNQ_GEM_NWCTRL_RXEN_MASK |
+         ZYNQ_GEM_NWCTRL_TXEN_MASK;
+     writel(tmp, &regs->nwctrl);
Quoted 1 line

setbits_le32()

This is not equivalent. Using setbits_le32() will not provide a dmb() on the operations the way that readl(), writel() does. I believe this will cause problems when the dcache is enabled, right?

-Joe

#8 lore raw

PATCH v2 2/4 net: Add driver for Zynq Gem IP

Dear Joe Hershberger,

Quoted 17 lines

Hi Marek,

Quoted 14 lines · Marek Vasut

Dear Michal Simek,

Quoted 11 lines
drivers/net/zynq_gem.c new file +11 -0
+     /*
+      * Following is the setup for Network Control register.
+      * Bit 2:  Set to enable Receive operation.
+      * Bit 3:  Set to enable Transmitt operation.
+      * Bit 4:  Set to enable MDIO operation.
+      */
+     tmp = readl(&regs->nwctrl);
+     /* MDIO, Rx and Tx enable */
+     tmp |= ZYNQ_GEM_NWCTRL_MDEN_MASK | ZYNQ_GEM_NWCTRL_RXEN_MASK |
+         ZYNQ_GEM_NWCTRL_TXEN_MASK;
+     writel(tmp, &regs->nwctrl);
Quoted 5 lines
Quoted 1 line

setbits_le32()

This is not equivalent. Using setbits_le32() will not provide a dmb() on the operations the way that readl(), writel() does. I believe this will cause problems when the dcache is enabled, right?

Not when dcache is enabled, the register space isn't cached. But the compiler can run some wild optimizations across that. So where's the problem, do we add dmb() to clrsetbits() calls ?

Quoted 1 line

-Joe

Best regards,
Marek Vasut

A message that is not in the archive (sent off-list or not yet received): CANr=Z=aejhXoGabpcderroSeQSWJM+cbXS7yg6NVeHKJLqQhRQ@mail.gmail.com

#10 lore raw

PATCH v2 2/4 net: Add driver for Zynq Gem IP

Dear Joe Hershberger,

Quoted 26 lines · Marek Vasut
Quoted 25 lines

Dear Joe Hershberger,

Quoted 22 lines

Hi Marek,

Quoted 14 lines · Marek Vasut

Dear Michal Simek,

drivers/net/zynq_gem.c line 290

Quoted 11 lines
drivers/net/zynq_gem.c new file +11 -0
+     /*
+      * Following is the setup for Network Control register.
+      * Bit 2:  Set to enable Receive operation.
+      * Bit 3:  Set to enable Transmitt operation.
+      * Bit 4:  Set to enable MDIO operation.
+      */
+     tmp = readl(&regs->nwctrl);
+     /* MDIO, Rx and Tx enable */
+     tmp |= ZYNQ_GEM_NWCTRL_MDEN_MASK | ZYNQ_GEM_NWCTRL_RXEN_MASK |
+         ZYNQ_GEM_NWCTRL_TXEN_MASK;
+     writel(tmp, &regs->nwctrl);
Quoted 1 line

setbits_le32()

This is not equivalent. Using setbits_le32() will not provide a dmb() on the operations the way that readl(), writel() does. I believe this will cause problems when the dcache is enabled, right?

Quoted 5 lines
Quoted 3 lines

Not when dcache is enabled, the register space isn't cached. But the compiler can run some wild optimizations across that. So where's the problem, do we add dmb() to clrsetbits() calls ?

I'm not grokking this paragraph.

The only thing that is ever cached is DRAM. It's the only cacheable area configured in the MMU tables. The rest is uncached.

And the dmb() doesn't have anything to do with caches, it has to do with compiler reordering the register accesses, which might screw things up.

But wait, I shouldn't reply to emails when I've been awake for 20+ hours. Look at the macro again. Let's see an example:

clrbits_le32 expands to clrbits(le32, ...) clrbits(le32, ...) expands to out_le32(..., in_le32(...) & ~...)

out_le32() expands to out_arch() which expands to __raw_writel() in_le32() expands to in_arch() which expands to __raw_readl()

__raw_writel() expands to __arch_putl()
__raw_readl() expands to __arch_getl()

arch_putl() is *(volatile unsigned long *), therefore compiler reordering doesn't happen accross this (because of the volatile). So is arch_getl() .

Bottom line, no need for explicit dmb() in clrsetbits_le32() and friends. But whew, you got me scared there ;-)

Quoted 4 lines

You are saying that when the dcache is enabled, that the register space is not cached? Why would it not be? It doesn't know those addresses from any other memory, right?

Quoted 8 lines

clrsetbits() does not call dmb(). Perhaps it should. It's never been clear to me why writeX/readX used dmb, but out_XY/in_XY/clrsetbits_XY do not. Are they not both for accessing registers?

Perhaps test all of these drivers with write-back cache enabled and make sure they work.

-Joe

Best regards,
Marek Vasut

#11 lore raw

PATCH v3 4/4 xilinx: Add new Zynq board

In reply to Michal Simek

Add support for Xilinx Zynq board.

---
v2: Forget to also add config file

v3: Change name for serial driver
Remove lowlevel_init from board folder
Remove XPSS part from timer baseaddr
Change name for Zynq gem driver
Clean coding style
Remove mac + ip addresses from config file
Remove additional PHYs

---
 board/xilinx/zynq/Makefile |   54 +++++++++++++++++++++
 board/xilinx/zynq/board.c  |   64 +++++++++++++++++++++++++
 boards.cfg                 |    1 +
 include/configs/zynq.h     |  110 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 229 insertions(+), 0 deletions(-)
 create mode 100644 board/xilinx/zynq/Makefile
 create mode 100644 board/xilinx/zynq/board.c
 create mode 100644 include/configs/zynq.h
board/xilinx/zynq/Makefile new file +54 -0
new file mode 100644
index 0000000..ef4faa1
@@ -0,0 +1,54 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+ifneq ($(OBJTREE),$(SRCTREE))
+$(shell mkdir -p $(obj)../common)
+endif
+
+LIB	= $(obj)lib$(BOARD).o
+
+COBJS-y	:= board.o
+
+COBJS	:= $(sort $(COBJS-y))
+
+SRCS	:= $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+
+$(LIB):	$(obj).depend $(OBJS)
+	$(call cmd_link_o_target, $(OBJS))
+
+clean:
+	rm -f $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak $(obj).depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
board/xilinx/zynq/board.c new file +64 -0

64 lines not on this page · raw message

boards.cfg +1 -0
index fdb84ad..aeca912 100644
@@ -261,6 +261,7 @@ seaboard                     arm         armv7       seaboard            nvidia
 ventana                      arm         armv7       ventana             nvidia         tegra2
 whistler                     arm         armv7       whistler            nvidia         tegra2
 u8500_href                   arm         armv7       u8500               st-ericsson    u8500
+zynq                         arm         armv7       zynq                xilinx         zynq
 actux1_4_16                  arm         ixp         actux1              -              -           actux1:FLASH2X2
 actux1_4_32                  arm         ixp         actux1              -              -           actux1:FLASH2X2,RAM_32MB
 actux1_8_16                  arm         ixp         actux1              -              -           actux1:FLASH1X8
include/configs/zynq.h new file +110 -0

110 lines not on this page · raw message

Signature · 1 line
1.7.0.4
#12 lore raw

PATCH v3 4/4 xilinx: Add new Zynq board

Quoted 20 lines · Michal Simek

Add support for Xilinx Zynq board.

---
v2: Forget to also add config file

v3: Change name for serial driver
Remove lowlevel_init from board folder
Remove XPSS part from timer baseaddr
Change name for Zynq gem driver
Clean coding style
Remove mac + ip addresses from config file
Remove additional PHYs

---
  board/xilinx/zynq/Makefile |   54 +++++++++++++++++++++
  board/xilinx/zynq/board.c  |   64 +++++++++++++++++++++++++
  boards.cfg                 |    1 +
  include/configs/zynq.h     |  110 ++++++++++++++++++++++++++++++++++++++++++++
  4 files changed, 229 insertions(+), 0 deletions(-)
Quoted 4 lines

create mode 100644 board/xilinx/zynq/Makefile
create mode 100644 board/xilinx/zynq/board.c
create mode 100644 include/configs/zynq.h

The same for this one.
Marek and Joe: Can you please review this?

Thanks,
Michal

Signature · 4 lines
Michal Simek, Ing. (M.Eng)
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel 2.6 Microblaze Linux - http://www.monstr.eu/fdt/
Microblaze U-BOOT custodian
#13 lore raw

PATCH v3 4/4 xilinx: Add new Zynq board

In reply to Michal Simek

Dear Michal Simek,

[...]

board/xilinx/zynq/board.c line 30

Quoted 3 lines
board/xilinx/zynq/board.c new file +3 -0
+int board_init(void)
+{
+	icache_enable();

Uh oh ... isn't this on by default when CONFIG_ICACHE_OFF isn't present?

board/xilinx/zynq/board.c line 37

Quoted 6 lines
board/xilinx/zynq/board.c new file +6 -0
+	return 0;
+}
+
+int board_late_init(void)
+{
+	return 0;

You don't need this.

board/xilinx/zynq/board.c line 46

Quoted 9 lines
board/xilinx/zynq/board.c new file +9 -0
+}
+
+#ifdef CONFIG_CMD_NET
+int board_eth_init(bd_t *bis)
+{
+	int ret = 0;
+
+#if defined(CONFIG_ZYNQ_GEM) && defined(CONFIG_ZYNQ_GEM_BASEADDR0)
+	ret |= zynq_gem_initialize(bis, CONFIG_ZYNQ_GEM_BASEADDR0);

ret |= ? ;-)

Quoted 7 lines
board/xilinx/zynq/board.c new file +7 -0
+#endif
+
+	return ret;
+}
+#endif
+
+int dram_init(void)

board/xilinx/zynq/board.c line 64

Quoted 10 lines
board/xilinx/zynq/board.c new file +10 -0
+{
+	gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
+	return 0;
+}
+
+void reset_cpu(ulong addr)
+{
+	while (1)
+		;
+}

This is definitelly CPU specific.
[...]

#14 lore raw

PATCH v3 4/4 xilinx: Add new Zynq board

Quoted 9 lines · Marek Vasut

Dear Michal Simek,

[...]

board/xilinx/zynq/board.c line 30

Quoted 3 lines
board/xilinx/zynq/board.c new file +3 -0
+int board_init(void)
+{
+	icache_enable();

Uh oh ... isn't this on by default when CONFIG_ICACHE_OFF isn't present?

Will check this one.

Quoted 9 lines

board/xilinx/zynq/board.c line 37

Quoted 7 lines
board/xilinx/zynq/board.c new file +6 -0
+	return 0;
+}
+
+int board_late_init(void)
+{
+	return 0;

You don't need this.

Will check it too.

Quoted 12 lines

board/xilinx/zynq/board.c line 46

Quoted 10 lines
board/xilinx/zynq/board.c new file +9 -0
+}
+
+#ifdef CONFIG_CMD_NET
+int board_eth_init(bd_t *bis)
+{
+	int ret = 0;
+
+#if defined(CONFIG_ZYNQ_GEM) && defined(CONFIG_ZYNQ_GEM_BASEADDR0)
+	ret |= zynq_gem_initialize(bis, CONFIG_ZYNQ_GEM_BASEADDR0);

ret |= ? ;-)

The reason is that I will wire axi_ethernet and ethernet lite drivers here too. If this is the problem I can fix it but the next patch will return it to this style.

Quoted 13 lines
Quoted 13 lines
board/xilinx/zynq/board.c new file +12 -0
+#endif
+
+	return ret;
+}
+#endif
+
+int dram_init(void)
+{
+	gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
+	return 0;
+}
+
Quoted 9 lines

board/xilinx/zynq/board.c line 64

Quoted 5 lines
board/xilinx/zynq/board.c new file +5 -0
+void reset_cpu(ulong addr)
+{
+	while (1)
+		;
+}

This is definitelly CPU specific.
[...]

Right, Moving to different folder make sense.

Thanks,
Michal

Signature · 4 lines
Michal Simek, Ing. (M.Eng)
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel 2.6 Microblaze Linux - http://www.monstr.eu/fdt/
Microblaze U-BOOT custodian
#15 lore raw

PATCH v3 4/4 xilinx: Add new Zynq board

Dear Michal Simek,

Quoted 36 lines · Marek Vasut
Quoted 9 lines

Dear Michal Simek,

[...]

board/xilinx/zynq/board.c line 30

Quoted 3 lines
board/xilinx/zynq/board.c new file +3 -0
+int board_init(void)
+{
+	icache_enable();

Uh oh ... isn't this on by default when CONFIG_ICACHE_OFF isn't present?

Will check this one.

Quoted 8 lines

board/xilinx/zynq/board.c line 37

Quoted 6 lines
board/xilinx/zynq/board.c new file +6 -0
+	return 0;
+}
+
+int board_late_init(void)
+{
+	return 0;

You don't need this.

Will check it too.

Quoted 11 lines

board/xilinx/zynq/board.c line 46

Quoted 9 lines
board/xilinx/zynq/board.c new file +9 -0
+}
+
+#ifdef CONFIG_CMD_NET
+int board_eth_init(bd_t *bis)
+{
+	int ret = 0;
+
+#if defined(CONFIG_ZYNQ_GEM) && defined(CONFIG_ZYNQ_GEM_BASEADDR0)
+	ret |= zynq_gem_initialize(bis, CONFIG_ZYNQ_GEM_BASEADDR0);

ret |= ? ;-)

Quoted 3 lines

The reason is that I will wire axi_ethernet and ethernet lite drivers here too. If this is the problem I can fix it but the next patch will return it to this style.

Logical OR on signed type is wrong. Besides, if one fails, you don't want to init the others.

Quoted 21 lines
Quoted 12 lines
Quoted 12 lines
board/xilinx/zynq/board.c new file +12 -0
+#endif
+
+	return ret;
+}
+#endif
+
+int dram_init(void)
+{
+	gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
+	return 0;
+}
+
Quoted 8 lines

board/xilinx/zynq/board.c line 64

Quoted 5 lines
board/xilinx/zynq/board.c new file +5 -0
+void reset_cpu(ulong addr)
+{
+	while (1)
+		;
+}

This is definitelly CPU specific.
[...]

Quoted 1 line

Right, Moving to different folder make sense.

Directory, no wind blows here :p

Quoted 2 lines

Thanks,
Michal

Best regards,
Marek Vasut

#16 lore raw

PATCH v3 4/4 xilinx: Add new Zynq board

In reply to Marek Vasut
Quoted 9 lines · Marek Vasut

Dear Michal Simek,

[...]

board/xilinx/zynq/board.c line 30

Quoted 3 lines
board/xilinx/zynq/board.c new file +3 -0
+int board_init(void)
+{
+	icache_enable();

Uh oh ... isn't this on by default when CONFIG_ICACHE_OFF isn't present?

That option is valid just for blackfin.

In arm1176 and s3c44b0v is this done in arch_cpu_init() but it is not there for armv7

I have seen that several armv7 boards enable it. For example vexpress, highbank, u8500, etc.

Quoted 9 lines

board/xilinx/zynq/board.c line 37

Quoted 7 lines
board/xilinx/zynq/board.c new file +6 -0
+	return 0;
+}
+
+int board_late_init(void)
+{
+	return 0;

You don't need this.

correct.

Michal

Signature · 4 lines
Michal Simek, Ing. (M.Eng)
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel 2.6 Microblaze Linux - http://www.monstr.eu/fdt/
Microblaze U-BOOT custodian
#17 lore raw

PATCH v3 4/4 xilinx: Add new Zynq board

In reply to Michal Simek

Hi Michal,

Quoted 84 lines · Michal Simek

Add support for Xilinx Zynq board.

---
v2: Forget to also add config file

v3: Change name for serial driver
Remove lowlevel_init from board folder
Remove XPSS part from timer baseaddr
Change name for Zynq gem driver
Clean coding style
Remove mac + ip addresses from config file
Remove additional PHYs

---
 board/xilinx/zynq/Makefile |   54 +++++++++++++++++++++
 board/xilinx/zynq/board.c  |   64 +++++++++++++++++++++++++
 boards.cfg                 |    1 +
 include/configs/zynq.h     |  110 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 229 insertions(+), 0 deletions(-)
 create mode 100644 board/xilinx/zynq/Makefile
 create mode 100644 board/xilinx/zynq/board.c
 create mode 100644 include/configs/zynq.h
board/xilinx/zynq/board.c new file +54 -0
new file mode 100644
index 0000000..4cb36f6
@@ -0,0 +1,64 @@
+/*
+ * (C) Copyright 2012 Michal Simek <[email protected]>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <netdev.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_init(void)
+{
+       icache_enable();
+
+       return 0;
+}
+
+int board_late_init(void)
+{
+       return 0;
+}
+
+#ifdef CONFIG_CMD_NET
+int board_eth_init(bd_t *bis)
+{
+       int ret = 0;
+
+#if defined(CONFIG_ZYNQ_GEM) && defined(CONFIG_ZYNQ_GEM_BASEADDR0)
+       ret |= zynq_gem_initialize(bis, CONFIG_ZYNQ_GEM_BASEADDR0);
+#endif
+
+       return ret;
+}
+#endif
+
+int dram_init(void)
+{

board/xilinx/zynq/board.c line 64

Quoted 10 lines
board/xilinx/zynq/board.c new file +10 -0
+       gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
+
+       return 0;
+}
+
+void reset_cpu(ulong addr)
+{
+       while (1)
+               ;
+}

Why not explicitly reset, like Xilinx tree?

void reset_cpu(ulong addr)

{
        /* unlock SLCR */
        writel(XPSS_SLCR_UNLOCK_KEY, XPSS_SYS_CTRL_BASEADDR | XPSS_SLCR_UNLOCK);
        /* Tickle soft reset bit */
        writel(1, XPSS_SYS_CTRL_BASEADDR | XPSS_SLCR_PSS_RST_CTRL);

        while (1)
                ;
}
Quoted 119 lines
include/configs/zynq.h new file +110 -1
new file mode 100644
index 0000000..8fb4f1b
@@ -0,0 +1,110 @@
+/*
+ * (C) Copyright 2012 Michal Simek <[email protected]>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __CONFIG_ZYNQ_H
+#define __CONFIG_ZYNQ_H
+
+#define CONFIG_ARMV7 /* This is an ARM V7 CPU core */
+#define CONFIG_ZYNQ
+
+/* CPU clock */
+#define CONFIG_CPU_FREQ_HZ     800000000
+#define CONFIG_SYS_HZ          1000
+
+/* Ram */
+#define CONFIG_NR_DRAM_BANKS           1
+#define CONFIG_SYS_SDRAM_BASE          0
+#define CONFIG_SYS_SDRAM_SIZE          0x40000000
+#define CONFIG_SYS_MEMTEST_START       CONFIG_SYS_SDRAM_BASE
+#define CONFIG_SYS_MEMTEST_END         (CONFIG_SYS_SDRAM_BASE + 0x1000)
+
+/* The following table includes the supported baudrates */
+#define CONFIG_SYS_BAUDRATE_TABLE  \
+       {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400}
+
+#define CONFIG_BAUDRATE                115200
+
+/* XPSS Serial driver */
+#define CONFIG_ZYNQ_SERIAL
+#define CONFIG_ZYNQ_SERIAL_BASEADDR0   0xE0001000
+#define CONFIG_ZYNQ_SERIAL_BAUDRATE0   CONFIG_BAUDRATE
+#define CONFIG_ZYNQ_SERIAL_CLOCK0      50000000
+
+/* SCU timer address is hardcoded */
+#define CONFIG_SCUTIMER_BASEADDR       0xF8F00600
+
+/* Ethernet driver */
+#define CONFIG_NET_MULTI
+#define CONFIG_ZYNQ_GEM
+#define CONFIG_ZYNQ_GEM_BASEADDR0      0xE000B000
+
+#define CONFIG_BOOTP_SERVERIP
+#define CONFIG_BOOTP_BOOTPATH
+#define CONFIG_BOOTP_GATEWAY
+#define CONFIG_BOOTP_HOSTNAME
+#define CONFIG_BOOTP_MAY_FAIL
+
+/* MII and Phylib */
+#define CONFIG_MII
+#define CONFIG_SYS_FAULT_ECHO_LINK_DOWN
+#define CONFIG_PHYLIB
+#define CONFIG_PHY_MARVELL
+
+/* Environment */
+#define CONFIG_ENV_IS_NOWHERE
+#define CONFIG_ENV_SIZE 0x10000
+
+#define CONFIG_SYS_NO_FLASH
+
+#define CONFIG_SYS_MALLOC_LEN          0x400000
+#define CONFIG_SYS_INIT_RAM_ADDR       CONFIG_SYS_SDRAM_BASE
+#define CONFIG_SYS_INIT_RAM_SIZE       CONFIG_SYS_MALLOC_LEN
+#define CONFIG_SYS_INIT_SP_ADDR                (CONFIG_SYS_INIT_RAM_ADDR + \
+                                               CONFIG_SYS_INIT_RAM_SIZE - \
+                                               GENERATED_GBL_DATA_SIZE)
+
+#define CONFIG_SYS_PROMPT      "U-Boot> "
+#define CONFIG_SYS_CBSIZE      256 /* Console I/O Buffer Size */
+#define CONFIG_SYS_PBSIZE      (CONFIG_SYS_CBSIZE + \
+                                       sizeof(CONFIG_SYS_PROMPT) + 16)
+
+#define CONFIG_SYS_LOAD_ADDR   0
+#define CONFIG_SYS_MAXARGS     15 /* max number of command args */
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_AUTO_COMPLETE
+#define CONFIG_CMDLINE_EDITING
+
+#define CONFIG_SYS_HUSH_PARSER
+#define CONFIG_SYS_PROMPT_HUSH_PS2     "> "
+
+/* OF */
+#define CONFIG_FIT
+#define CONFIG_OF_LIBFDT
+
+/* Commands */
+#include <config_cmd_default.h>
+
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_MII
+
+#endif /* __CONFIG_ZYNQ_H */
--

1.7.0.4

#18 lore raw

PATCH v3 4/4 xilinx: Add new Zynq board

Quoted 101 lines · Joe Hershberger

Hi Michal,

Quoted 84 lines · Michal Simek

Add support for Xilinx Zynq board.

---
v2: Forget to also add config file

v3: Change name for serial driver
Remove lowlevel_init from board folder
Remove XPSS part from timer baseaddr
Change name for Zynq gem driver
Clean coding style
Remove mac + ip addresses from config file
Remove additional PHYs

---
  board/xilinx/zynq/Makefile |   54 +++++++++++++++++++++
  board/xilinx/zynq/board.c  |   64 +++++++++++++++++++++++++
  boards.cfg                 |    1 +
  include/configs/zynq.h     |  110 ++++++++++++++++++++++++++++++++++++++++++++
  4 files changed, 229 insertions(+), 0 deletions(-)

create mode 100644 board/xilinx/zynq/Makefile
create mode 100644 board/xilinx/zynq/board.c
create mode 100644 include/configs/zynq.h

board/xilinx/zynq/board.c new file +54 -0
new file mode 100644
index 0000000..4cb36f6
@@ -0,0 +1,64 @@
+/*
+ * (C) Copyright 2012 Michal Simek <[email protected]>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <netdev.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_init(void)
+{
+       icache_enable();
+
+       return 0;
+}
+
+int board_late_init(void)
+{
+       return 0;
+}
+
+#ifdef CONFIG_CMD_NET
+int board_eth_init(bd_t *bis)
+{
+       int ret = 0;
+
+#if defined(CONFIG_ZYNQ_GEM) && defined(CONFIG_ZYNQ_GEM_BASEADDR0)
+       ret |= zynq_gem_initialize(bis, CONFIG_ZYNQ_GEM_BASEADDR0);
+#endif
+
+       return ret;
+}
+#endif
+
+int dram_init(void)
+{

board/xilinx/zynq/board.c line 64

Quoted 10 lines
board/xilinx/zynq/board.c new file +10 -0
+       gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
+
+       return 0;
+}
+
+void reset_cpu(ulong addr)
+{
+       while (1)
+               ;
+}

Why not explicitly reset, like Xilinx tree?

void reset_cpu(ulong addr)

Quoted 10 lines
{
         /* unlock SLCR */
         writel(XPSS_SLCR_UNLOCK_KEY, XPSS_SYS_CTRL_BASEADDR | XPSS_SLCR_UNLOCK);
         /* Tickle soft reset bit */
         writel(1, XPSS_SYS_CTRL_BASEADDR | XPSS_SLCR_PSS_RST_CTRL);

         while (1)
                 ;
}

I haven't started to merge all these features and want to merge minimum platform and then start to clean drivers and features.
Maybe for slcr make sense to create driver and not just unlock it and use it for code.

Thanks,
Michal

Signature · 4 lines
Michal Simek, Ing. (M.Eng)
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel 2.6 Microblaze Linux - http://www.monstr.eu/fdt/
Microblaze U-BOOT custodian
#19 lore raw

PATCH v2 3/4 arm: Support new Xilinx Zynq platform

In reply to Michal Simek

Add timer driver.

---
v2: Move lowlevel_init.S from board to cpu folder
Remove XPSS prefix
Rename XSCUTIMER -> SCUTIMER

Keep timer in zynq folder till ARM custodian comments it.

---
 arch/arm/cpu/armv7/zynq/Makefile        |   52 +++++++++++
 arch/arm/cpu/armv7/zynq/lowlevel_init.S |   27 ++++++
 arch/arm/cpu/armv7/zynq/timer.c         |  151 +++++++++++++++++++++++++++++++
 3 files changed, 230 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/zynq/Makefile
 create mode 100644 arch/arm/cpu/armv7/zynq/lowlevel_init.S
 create mode 100644 arch/arm/cpu/armv7/zynq/timer.c
arch/arm/cpu/armv7/zynq/Makefile new file +52 -0
new file mode 100644
index 0000000..1d2d7e1
@@ -0,0 +1,52 @@
+#
+# (C) Copyright 2000-2003
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# (C) Copyright 2008
+# Guennadi Liakhovetki, DENX Software Engineering, <[email protected]>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(SOC).o
+
+SOBJS-y	:= lowlevel_init.o
+COBJS-y	:= timer.o
+
+SOBJS	:= $(SOBJS-y)
+COBJS	:= $(COBJS-y)
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+
+all:	$(obj).depend $(LIB)
+
+$(LIB): $(OBJS)
+	$(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
arch/arm/cpu/armv7/zynq/lowlevel_init.S new file +27 -0
new file mode 100644
index 0000000..642eb18
@@ -0,0 +1,27 @@
+/*
+ * (C) Copyright 2012 Michal Simek <[email protected]>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <config.h>
+#include <linux/linkage.h>
+
+ENTRY(lowlevel_init)
+        mov     pc, lr
+ENDPROC(lowlevel_init)
arch/arm/cpu/armv7/zynq/timer.c new file +151 -0

151 lines not on this page · raw message

Signature · 1 line
1.7.0.4
#20 lore raw

PATCH v2 3/4 arm: Support new Xilinx Zynq platform

Quoted 10 lines · Michal Simek

Add timer driver.

---
v2: Move lowlevel_init.S from board to cpu folder
Remove XPSS prefix
Rename XSCUTIMER -> SCUTIMER

Keep timer in zynq folder till ARM custodian comments it.

Quoted 8 lines
---
  arch/arm/cpu/armv7/zynq/Makefile        |   52 +++++++++++
  arch/arm/cpu/armv7/zynq/lowlevel_init.S |   27 ++++++
  arch/arm/cpu/armv7/zynq/timer.c         |  151 +++++++++++++++++++++++++++++++
  3 files changed, 230 insertions(+), 0 deletions(-)

create mode 100644 arch/arm/cpu/armv7/zynq/Makefile create mode 100644 arch/arm/cpu/armv7/zynq/lowlevel_init.S create mode 100644 arch/arm/cpu/armv7/zynq/timer.c

We haven't got any reaction for Albert.
Marek and Joe: Can you review this? And give me your ACK or NACK.

Thanks,
Michal

Signature · 4 lines
Michal Simek, Ing. (M.Eng)
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel 2.6 Microblaze Linux - http://www.monstr.eu/fdt/
Microblaze U-BOOT custodian
#21 lore raw

PATCH v2 3/4 arm: Support new Xilinx Zynq platform

Dear Michal Simek,

Quoted 23 lines · Michal Simek
Quoted 13 lines

Add timer driver.

---
v2: Move lowlevel_init.S from board to cpu folder

Remove XPSS prefix
Rename XSCUTIMER -> SCUTIMER

Keep timer in zynq folder till ARM custodian comments it.
---

Quoted 8 lines
  arch/arm/cpu/armv7/zynq/Makefile        |   52 +++++++++++
  arch/arm/cpu/armv7/zynq/lowlevel_init.S |   27 ++++++
  arch/arm/cpu/armv7/zynq/timer.c         |  151

+++++++++++++++++++++++++++++++ 3 files changed, 230 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/cpu/armv7/zynq/Makefile
create mode 100644 arch/arm/cpu/armv7/zynq/lowlevel_init.S create mode 100644 arch/arm/cpu/armv7/zynq/timer.c

Quoted 2 lines

We haven't got any reaction for Albert.
Marek and Joe: Can you review this? And give me your ACK or NACK.

Oh I'll gladly torture you :-)

btw I might need a bit of a review for a ublaze stuff eventually and maybe some xilinx uart too, there's a large stdio patchset I have queued. Would you review please?

Quoted 2 lines

Thanks,
Michal

Best regards,
Marek Vasut

#22 lore raw

PATCH v2 3/4 arm: Support new Xilinx Zynq platform

Quoted 25 lines · Marek Vasut

Dear Michal Simek,

Quoted 23 lines · Michal Simek
Quoted 21 lines

Add timer driver.

---
v2: Move lowlevel_init.S from board to cpu folder

Remove XPSS prefix
Rename XSCUTIMER -> SCUTIMER

Keep timer in zynq folder till ARM custodian comments it.
---

   arch/arm/cpu/armv7/zynq/Makefile        |   52 +++++++++++
   arch/arm/cpu/armv7/zynq/lowlevel_init.S |   27 ++++++
   arch/arm/cpu/armv7/zynq/timer.c         |  151

+++++++++++++++++++++++++++++++ 3 files changed, 230 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/cpu/armv7/zynq/Makefile create mode 100644 arch/arm/cpu/armv7/zynq/lowlevel_init.S create mode 100644 arch/arm/cpu/armv7/zynq/timer.c

Quoted 4 lines
Quoted 2 lines

We haven't got any reaction for Albert.
Marek and Joe: Can you review this? And give me your ACK or NACK.

Oh I'll gladly torture you :-)

Go ahead. :-)

Quoted 4 lines

btw I might need a bit of a review for a ublaze stuff eventually and maybe some xilinx uart too, there's a large stdio patchset I have queued. Would you review please?

Feel free to contact me if you need any help with any xilinx stuff. Microblaze/xilinx ppc or current arm code.
I am keen to change current code to u-boot new standard and also with dts support.

Thanks,
Michal

Signature · 4 lines
Michal Simek, Ing. (M.Eng)
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel 2.6 Microblaze Linux - http://www.monstr.eu/fdt/
Microblaze U-BOOT custodian
#23 lore raw

PATCH v2 3/4 arm: Support new Xilinx Zynq platform

In reply to Michal Simek

Dear Michal Simek,

[...]

arch/arm/cpu/armv7/zynq/lowlevel_init.S line 27

Quoted 6 lines
arch/arm/cpu/armv7/zynq/lowlevel_init.S new file +6 -0
+#include <config.h>
+#include <linux/linkage.h>
+
+ENTRY(lowlevel_init)
+        mov     pc, lr
+ENDPROC(lowlevel_init)

inline void lowlevel_init(void) {} works as well and you don't need the assembly file.

Quoted 80 lines
(quoted diff) +0 -0

b/arch/arm/cpu/armv7/zynq/timer.c new file mode 100644 index 0000000..0252220

arch/arm/cpu/armv7/zynq/timer.c new file +74 -0
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2012 Michal Simek <[email protected]>
+ * Copyright (C) 2011-2012 Xilinx, Inc. All rights reserved.
+ *
+ * (C) Copyright 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <[email protected]>
+ *
+ * (C) Copyright 2004
+ * Philippe Robin, ARM Ltd. <[email protected]>
+ *
+ * (C) Copyright 2002-2004
+ * Gary Jennejohn, DENX Software Engineering, <[email protected]>
+ *
+ * (C) Copyright 2003
+ * Texas Instruments <www.ti.com>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <[email protected]>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <[email protected]>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <div64.h>
+#include <asm/io.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct scu_timer {
+	u32 load; /* Timer Load Register */
+	u32 counter; /* Timer Counter Register */
+	u32 control; /* Timer Control Register */
+};
+
+static struct scu_timer *timer_base = CONFIG_SCUTIMER_BASEADDR;
+
+#define SCUTIMER_CONTROL_PRESCALER_MASK	0x0000FF00 /* Prescaler */
+#define SCUTIMER_CONTROL_PRESCALER_SHIFT	8
+#define SCUTIMER_CONTROL_AUTO_RELOAD_MASK	0x00000002 /* Auto-reload */
+#define SCUTIMER_CONTROL_ENABLE_MASK		0x00000001 /* Timer enable */
+
+#define TIMER_LOAD_VAL 0xFFFFFFFF
+#define TIMER_PRESCALE 255
+#define TIMER_TICK_HZ  (CONFIG_CPU_FREQ_HZ / 2 / TIMER_PRESCALE)
+
+int timer_init(void)
+{
+	u32 val;
+
+	/* Load the timer counter register */
+	writel(0xFFFFFFFF, &timer_base->counter);
+
+	/* Start the A9Timer device */

arch/arm/cpu/armv7/zynq/timer.c line 84

Quoted 10 lines
arch/arm/cpu/armv7/zynq/timer.c new file +10 -0
+	val = readl(&timer_base->control);
+	/* Enable Auto reload mode */
+	val |= SCUTIMER_CONTROL_AUTO_RELOAD_MASK;
+	/* Clear prescaler control bits */
+	val &= ~SCUTIMER_CONTROL_PRESCALER_MASK;
+	/* Set prescaler value */
+	val |= (TIMER_PRESCALE << SCUTIMER_CONTROL_PRESCALER_SHIFT);
+	/* Enable the decrementer */
+	val |= SCUTIMER_CONTROL_ENABLE_MASK;
+	writel(val, &timer_base->control);

clrsetbits_le32()

Quoted 66 lines
arch/arm/cpu/armv7/zynq/timer.c new file +10 -0
+	/* Reset time */
+	gd->lastinc = readl(&timer_base->counter) /
+					(TIMER_TICK_HZ / CONFIG_SYS_HZ);
+	gd->tbl = 0;
+
+	return 0;
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long

long). + * On ARM it just returns the timer value.
+ */

arch/arm/cpu/armv7/zynq/timer.c new file +39 -0
+ulong get_timer_masked(void)
+{
+	ulong now;
+
+	now = readl(&timer_base->counter) / (TIMER_TICK_HZ / CONFIG_SYS_HZ);
+
+	if (gd->lastinc >= now) {
+		/* Normal mode */
+		gd->tbl += gd->lastinc - now;
+	} else {
+		/* We have an overflow ... */
+		gd->tbl += gd->lastinc + TIMER_LOAD_VAL - now;
+	}
+	gd->lastinc = now;
+
+	return gd->tbl;
+}
+
+void __udelay(unsigned long usec)
+{
+	unsigned long long tmp;
+	ulong tmo;
+
+	tmo = usec / (1000000 / CONFIG_SYS_HZ);
+	tmp = get_ticks() + tmo; /* Get current timestamp */
+
+	while (get_ticks() < tmp) { /* Loop till event */
+		 /* NOP */;
+	}
+}
+
+/* Timer without interrupts */
+ulong get_timer(ulong base)
+{
+	return get_timer_masked() - base;
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long

long). + * On ARM it just returns the timer value.
+ */

arch/arm/cpu/armv7/zynq/timer.c new file +13 -0
+unsigned long long get_ticks(void)
+{
+	return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+	return CONFIG_SYS_HZ;
+}
#24 lore raw

PATCH v2 3/4 arm: Support new Xilinx Zynq platform

Quoted 4 lines · Marek Vasut

Dear Michal Simek,

[...]

Quoted 9 lines

arch/arm/cpu/armv7/zynq/lowlevel_init.S line 27

Quoted 6 lines
arch/arm/cpu/armv7/zynq/lowlevel_init.S new file +6 -0
+#include <config.h>
+#include <linux/linkage.h>
+
+ENTRY(lowlevel_init)
+        mov     pc, lr
+ENDPROC(lowlevel_init)

inline void lowlevel_init(void) {} works as well and you don't need the assembly file.

:-) yes. The reason why I have done it in this way that we have some asm code which will go to this area. That's why I have kept it in asm instead of C.

Michal

Signature · 4 lines
Michal Simek, Ing. (M.Eng)
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel 2.6 Microblaze Linux - http://www.monstr.eu/fdt/
Microblaze U-BOOT custodian
#25 lore raw

PATCH v2 3/4 arm: Support new Xilinx Zynq platform

Dear Michal Simek,

Quoted 14 lines · Marek Vasut
Quoted 4 lines

Dear Michal Simek,

[...]

Quoted 9 lines

arch/arm/cpu/armv7/zynq/lowlevel_init.S line 27

Quoted 6 lines
arch/arm/cpu/armv7/zynq/lowlevel_init.S new file +6 -0
+#include <config.h>
+#include <linux/linkage.h>
+
+ENTRY(lowlevel_init)
+        mov     pc, lr
+ENDPROC(lowlevel_init)

inline void lowlevel_init(void) {} works as well and you don't need the assembly file.

Quoted 5 lines

:
:-) yes. The reason why I have done it in this way that we have some asm :code

which will go to this area. That's why I have kept it in asm instead of C.

What code? Will the code go into lowlevel_init() ?

Best regards,
Marek Vasut

#26 lore raw

PATCH v2 3/4 arm: Support new Xilinx Zynq platform

Quoted 16 lines · Marek Vasut

Dear Michal Simek,

Quoted 14 lines · Marek Vasut
Quoted 13 lines

Dear Michal Simek,

[...]

arch/arm/cpu/armv7/zynq/lowlevel_init.S line 27

Quoted 6 lines
arch/arm/cpu/armv7/zynq/lowlevel_init.S new file +6 -0
+#include <config.h>
+#include <linux/linkage.h>
+
+ENTRY(lowlevel_init)
+        mov     pc, lr
+ENDPROC(lowlevel_init)

inline void lowlevel_init(void) {} works as well and you don't need the assembly file.

Quoted 7 lines
Quoted 5 lines

:
:-) yes. The reason why I have done it in this way that we have some asm :code

which will go to this area. That's why I have kept it in asm instead of C.

What code? Will the code go into lowlevel_init() ?

For example SLCR locking if is not locked from the first stage bootloader. Also if necessary OCM and DDR remap, FPGA reset can be also there based on configuration.

Thanks,
Michal

Signature · 4 lines
Michal Simek, Ing. (M.Eng)
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel 2.6 Microblaze Linux - http://www.monstr.eu/fdt/
Microblaze U-BOOT custodian
#27 lore raw

PATCH v2 3/4 arm: Support new Xilinx Zynq platform

Dear Michal Simek,

Quoted 21 lines · Marek Vasut
Quoted 20 lines

Dear Michal Simek,

Quoted 18 lines · Marek Vasut
Quoted 4 lines

Dear Michal Simek,

[...]

Quoted 10 lines

arch/arm/cpu/armv7/zynq/lowlevel_init.S line 27

Quoted 6 lines
arch/arm/cpu/armv7/zynq/lowlevel_init.S new file +6 -0
+#include <config.h>
+#include <linux/linkage.h>
+
+ENTRY(lowlevel_init)
+        mov     pc, lr
+ENDPROC(lowlevel_init)

inline void lowlevel_init(void) {} works as well and you don't need the assembly file.

:-) yes. The reason why I have done it in this way that we have some asm :code

Quoted 8 lines
Quoted 4 lines
Quoted 2 lines

which will go to this area. That's why I have kept it in asm instead of C.

What code? Will the code go into lowlevel_init() ?

For example SLCR locking if is not locked from the first stage bootloader. Also if necessary OCM and DDR remap, FPGA reset can be also there based on configuration.

Can it not be in C code ?

Quoted 2 lines

Thanks,
Michal

Best regards,
Marek Vasut

#28 lore raw

PATCH v2 3/4 arm: Support new Xilinx Zynq platform

Quoted 26 lines · Marek Vasut

Dear Michal Simek,

Quoted 24 lines · Marek Vasut
Quoted 23 lines

Dear Michal Simek,

Quoted 20 lines · Marek Vasut
Quoted 4 lines

Dear Michal Simek,

[...]

Quoted 10 lines

arch/arm/cpu/armv7/zynq/lowlevel_init.S line 27

Quoted 6 lines
arch/arm/cpu/armv7/zynq/lowlevel_init.S new file +6 -0
+#include <config.h>
+#include <linux/linkage.h>
+
+ENTRY(lowlevel_init)
+        mov     pc, lr
+ENDPROC(lowlevel_init)

inline void lowlevel_init(void) {} works as well and you don't need the assembly file.

:-) yes. The reason why I have done it in this way that we have some asm :code

which will go to this area. That's why I have kept it in asm instead of C.

Quoted 7 lines
Quoted 5 lines
Quoted 1 line

What code? Will the code go into lowlevel_init() ?

For example SLCR locking if is not locked from the first stage bootloader. Also if necessary OCM and DDR remap, FPGA reset can be also there based on configuration.

Can it not be in C code ?

Probably can be in C code. I have no problem to move it to C.

Cheers,
Michal

Signature · 4 lines
Michal Simek, Ing. (M.Eng)
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel 2.6 Microblaze Linux - http://www.monstr.eu/fdt/
Microblaze U-BOOT custodian
#29 lore raw

PATCH v2 3/4 arm: Support new Xilinx Zynq platform

Dear Michal Simek,

Quoted 29 lines · Marek Vasut
Quoted 28 lines

Dear Michal Simek,

Quoted 26 lines · Marek Vasut
Quoted 24 lines

Dear Michal Simek,

Quoted 15 lines · Marek Vasut
Quoted 4 lines

Dear Michal Simek,

[...]

Quoted 10 lines

Review

Quoted 6 lines
(quoted diff) +6 -0
+#include <config.h>
+#include <linux/linkage.h>
+
+ENTRY(lowlevel_init)
+        mov     pc, lr
+ENDPROC(lowlevel_init)

inline void lowlevel_init(void) {} works as well and you don't need the assembly file.

Quoted 5 lines

:-) yes. The reason why I have done it in this way that we have some :asm code

which will go to this area. That's why I have kept it in asm instead of C.

What code? Will the code go into lowlevel_init() ?

Quoted 7 lines
Quoted 5 lines
Quoted 3 lines

For example SLCR locking if is not locked from the first stage bootloader. Also if necessary OCM and DDR remap, FPGA reset can be also there based on configuration.

Can it not be in C code ?

Probably can be in C code. I have no problem to move it to C.

Please do, cut the assembly to minimum.

Quoted 2 lines

Cheers,
Michal

Best regards,
Marek Vasut

#30 lore raw

PATCH v2 1/4 serial: Add Zynq serial driver

In reply to Michal Simek

Dear Michal Simek,

Quoted 8 lines

The driver is used on Xilinx Zynq platform.

---
v2: Use Zynq name instead of Dragonfire and XPSS/XDFUART
Rename driver name
Remove driver description

Quoted 6 lines
---
 drivers/serial/Makefile      |    1 +
 drivers/serial/serial_zynq.c |  200
++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 201
insertions(+), 0 deletions(-)
 create mode 100644 drivers/serial/serial_zynq.c

[...]

It looks ok, but can you make it support CONFIG_SERIAL_MULTI right away please?

Best regards,
Marek Vasut

#31 lore raw

PATCH v2 1/4 serial: Add Zynq serial driver

Quoted 16 lines · Marek Vasut

Dear Michal Simek,

Quoted 8 lines

The driver is used on Xilinx Zynq platform.

---
v2: Use Zynq name instead of Dragonfire and XPSS/XDFUART
Rename driver name
Remove driver description

Quoted 6 lines
---
  drivers/serial/Makefile      |    1 +
  drivers/serial/serial_zynq.c |  200

++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 201 insertions(+), 0 deletions(-)
create mode 100644 drivers/serial/serial_zynq.c

Quoted 3 lines

[...]

It looks ok, but can you make it support CONFIG_SERIAL_MULTI right away please?

Yes, it will add serial_multi in the next patch.
Can you give me your ACK or reviewed-by line? :-)

Maybe you have seen it. I have asked for pulling serial multi for uartlite.

Thanks,
Michal

Signature · 4 lines
Michal Simek, Ing. (M.Eng)
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel 2.6 Microblaze Linux - http://www.monstr.eu/fdt/
Microblaze U-BOOT custodian
#32 lore raw

PATCH v2 1/4 serial: Add Zynq serial driver

Dear Michal Simek,

Quoted 23 lines · Marek Vasut
Quoted 22 lines

Dear Michal Simek,

Quoted 19 lines

The driver is used on Xilinx Zynq platform.

---
v2: Use Zynq name instead of Dragonfire and XPSS/XDFUART

Rename driver name
Remove driver description

---

  drivers/serial/Makefile      |    1 +
  drivers/serial/serial_zynq.c |  200

++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 201 insertions(+), 0 deletions(-)

create mode 100644 drivers/serial/serial_zynq.c

Quoted 7 lines
Quoted 4 lines

[...]

It looks ok, but can you make it support CONFIG_SERIAL_MULTI right away please?

Yes, it will add serial_multi in the next patch.
Can you give me your ACK or reviewed-by line? :-)

Just squash them into one patch please.

Quoted 1 line

Maybe you have seen it. I have asked for pulling serial multi for uartlite.

Pulling ?

Quoted 2 lines

Thanks,
Michal

Best regards,
Marek Vasut

#33 lore raw

PATCH v2 1/4 serial: Add Zynq serial driver

Quoted 27 lines · Marek Vasut

Dear Michal Simek,

Quoted 25 lines · Marek Vasut
Quoted 24 lines

Dear Michal Simek,

Quoted 19 lines

The driver is used on Xilinx Zynq platform.

---
v2: Use Zynq name instead of Dragonfire and XPSS/XDFUART

Rename driver name
Remove driver description

---

   drivers/serial/Makefile      |    1 +
   drivers/serial/serial_zynq.c |  200

++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 201 insertions(+), 0 deletions(-)

create mode 100644 drivers/serial/serial_zynq.c

[...]

Quoted 7 lines
Quoted 5 lines
Quoted 2 lines

It looks ok, but can you make it support CONFIG_SERIAL_MULTI right away please?

Yes, it will add serial_multi in the next patch.
Can you give me your ACK or reviewed-by line? :-)

Just squash them into one patch please.

Done.

Michal

Signature · 4 lines
Michal Simek, Ing. (M.Eng)
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel 2.6 Microblaze Linux - http://www.monstr.eu/fdt/
Microblaze U-BOOT custodian
#34 lore raw

PATCH v2 1/4 serial: Add Zynq serial driver

Dear Michal Simek,

Quoted 31 lines · Marek Vasut
Quoted 30 lines

Dear Michal Simek,

Quoted 28 lines · Marek Vasut
Quoted 26 lines

Dear Michal Simek,

Quoted 12 lines

The driver is used on Xilinx Zynq platform.

---
v2: Use Zynq name instead of Dragonfire and XPSS/XDFUART

Rename driver name
Remove driver description

---

Quoted 7 lines
   drivers/serial/Makefile      |    1 +
   drivers/serial/serial_zynq.c |  200

++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 201 insertions(+), 0 deletions(-)

create mode 100644 drivers/serial/serial_zynq.c

[...]

It looks ok, but can you make it support CONFIG_SERIAL_MULTI right away please?

Quoted 6 lines
Quoted 4 lines
Quoted 2 lines

Yes, it will add serial_multi in the next patch.
Can you give me your ACK or reviewed-by line? :-)

Just squash them into one patch please.

Done.

Thanks ... my idea is to switch to serial_multi completely, then rework stdio, unify serial on top of it and clean up the whole subsystem. Thanks for helping!

Quoted 1 line

Michal

Best regards,
Marek Vasut

#35 lore raw

PATCH v2 1/4 serial: Add Zynq serial driver

Hi Marek,

Quoted 36 lines · Marek Vasut

Dear Michal Simek,

Quoted 34 lines · Marek Vasut
Quoted 33 lines

Dear Michal Simek,

Quoted 30 lines · Marek Vasut
Quoted 20 lines

Dear Michal Simek,

Quoted 18 lines

The driver is used on Xilinx Zynq platform.

---
v2: Use Zynq name instead of Dragonfire and XPSS/XDFUART

Rename driver name
Remove driver description

---

   drivers/serial/Makefile      |    1 +
   drivers/serial/serial_zynq.c |  200

++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 201 insertions(+), 0 deletions(-)

Quoted 6 lines
Quoted 1 line

create mode 100644 drivers/serial/serial_zynq.c

[...]

It looks ok, but can you make it support CONFIG_SERIAL_MULTI right away please?

Yes, it will add serial_multi in the next patch.
Can you give me your ACK or reviewed-by line? :-)

Quoted 6 lines
Quoted 3 lines
Quoted 1 line

Just squash them into one patch please.

Done.

Thanks ... my idea is to switch to serial_multi completely, then rework stdio, unify serial on top of it and clean up the whole subsystem. Thanks for helping!

I have a patch that I'll send soon that moves the "nulldev" driver to the serial driver (if CONFIG_SERIAL_MULTI is defined) so that it is possible to avoid serial init. I had the problem that the serial port on my Zynq product lives in the fabric instead of using the hard-core ones. This means that the FPGA neds to be configured first, but since I'm using u-boot for that too, I need it to start as null and switch to the fabric serial after the FPGA is configured. Anyway, just more support for supporting CONFIG_SERIAL_MULTI.

-Joe

#36 lore raw

PATCH v2 1/4 serial: Add Zynq serial driver

Dear Joe Hershberger,

Quoted 43 lines

Hi Marek,

Quoted 40 lines · Marek Vasut

Dear Michal Simek,

Quoted 37 lines · Marek Vasut
Quoted 27 lines

Dear Michal Simek,

Quoted 25 lines · Marek Vasut
Quoted 24 lines

Dear Michal Simek,

Quoted 19 lines

The driver is used on Xilinx Zynq platform.

---
v2: Use Zynq name instead of Dragonfire and XPSS/XDFUART

Rename driver name
Remove driver description

---

   drivers/serial/Makefile      |    1 +
   drivers/serial/serial_zynq.c |  200

++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 201 insertions(+), 0 deletions(-)

create mode 100644 drivers/serial/serial_zynq.c

[...]

Quoted 7 lines
Quoted 5 lines
Quoted 2 lines

It looks ok, but can you make it support CONFIG_SERIAL_MULTI right away please?

Yes, it will add serial_multi in the next patch.
Can you give me your ACK or reviewed-by line? :-)

Just squash them into one patch please.

Done.

Quoted 7 lines
Quoted 3 lines

Thanks ... my idea is to switch to serial_multi completely, then rework stdio, unify serial on top of it and clean up the whole subsystem. Thanks for helping!

I have a patch that I'll send soon that moves the "nulldev" driver to the serial driver (if CONFIG_SERIAL_MULTI is defined) so that it is possible to avoid serial init.

Thanks, this will break my massive patchset though. Can you check
git://git.denx.de/u-boot-marex.git / stdio branch ? I did something to nulldev there. Probably ignore the top 7 patches, they're bogus and need further work. It's all still work in progress to some point.

Quoted 3 lines

I had the problem that the serial port
on my Zynq product lives in the fabric instead of using the hard-core ones.

I see ... why don't you implement nulldev_serial instead and leave nulldev stdio as is?

Quoted 6 lines

This means that the FPGA neds to be configured first, but since I'm using u-boot for that too, I need it to start as null and switch to the fabric serial after the FPGA is configured. Anyway, just more support for supporting CONFIG_SERIAL_MULTI.

-Joe

Best regards,
Marek Vasut

#37 lore raw

PATCH v2 1/4 serial: Add Zynq serial driver

Hi Marek,

Quoted 49 lines · Marek Vasut

Dear Joe Hershberger,

Quoted 47 lines

Hi Marek,

Quoted 43 lines · Marek Vasut

Dear Michal Simek,

Quoted 31 lines · Marek Vasut
Quoted 30 lines

Dear Michal Simek,

Quoted 28 lines · Marek Vasut
Quoted 26 lines

Dear Michal Simek,

Quoted 12 lines

The driver is used on Xilinx Zynq platform.

---
v2: Use Zynq name instead of Dragonfire and XPSS/XDFUART

Rename driver name
Remove driver description

---

Quoted 7 lines
   drivers/serial/Makefile      |    1 +
   drivers/serial/serial_zynq.c |  200

++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 201 insertions(+), 0 deletions(-)

create mode 100644 drivers/serial/serial_zynq.c

[...]

It looks ok, but can you make it support CONFIG_SERIAL_MULTI right away please?

Quoted 6 lines
Quoted 4 lines
Quoted 2 lines

Yes, it will add serial_multi in the next patch.
Can you give me your ACK or reviewed-by line? :-)

Just squash them into one patch please.

Done.

Thanks ... my idea is to switch to serial_multi completely, then rework stdio, unify serial on top of it and clean up the whole subsystem. Thanks for helping!

Quoted 8 lines
Quoted 3 lines

I have a patch that I'll send soon that moves the "nulldev" driver to the serial driver (if CONFIG_SERIAL_MULTI is defined) so that it is possible to avoid serial init.

Thanks, this will break my massive patchset though. Can you check
git://git.denx.de/u-boot-marex.git / stdio branch ? I did something to nulldev there. Probably ignore the top 7 patches, they're bogus and need further work. It's all still work in progress to some point.

Too bad I can't just browse this at gitweb.

Quoted 6 lines
Quoted 3 lines

I had the problem that the serial port
on my Zynq product lives in the fabric instead of using the hard-core ones.

I see ... why don't you implement nulldev_serial instead and leave nulldev stdio as is?

Mostly because there is little point in supporting both at the same time.

-Joe

#38 lore raw

PATCH v2 1/4 serial: Add Zynq serial driver

Dear Joe Hershberger,

Quoted 56 lines

Hi Marek,

Quoted 53 lines · Marek Vasut

Dear Joe Hershberger,

Quoted 50 lines

Hi Marek,

Quoted 36 lines · Marek Vasut

Dear Michal Simek,

Quoted 34 lines · Marek Vasut
Quoted 33 lines

Dear Michal Simek,

Quoted 30 lines · Marek Vasut
Quoted 20 lines

Dear Michal Simek,

Quoted 18 lines

The driver is used on Xilinx Zynq platform.

---
v2: Use Zynq name instead of Dragonfire and XPSS/XDFUART

Rename driver name
Remove driver description

---

   drivers/serial/Makefile      |    1 +
   drivers/serial/serial_zynq.c |  200

++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 201 insertions(+), 0 deletions(-)

Quoted 6 lines
Quoted 1 line

create mode 100644 drivers/serial/serial_zynq.c

[...]

It looks ok, but can you make it support CONFIG_SERIAL_MULTI right away please?

Yes, it will add serial_multi in the next patch.
Can you give me your ACK or reviewed-by line? :-)

Quoted 7 lines
Quoted 3 lines
Quoted 1 line

Just squash them into one patch please.

Done.

Thanks ... my idea is to switch to serial_multi completely, then rework stdio, unify serial on top of it and clean up the whole subsystem. Thanks for helping!

I have a patch that I'll send soon that moves the "nulldev" driver to the serial driver (if CONFIG_SERIAL_MULTI is defined) so that it is possible to avoid serial init.

Quoted 6 lines
Quoted 4 lines

Thanks, this will break my massive patchset though. Can you check
git://git.denx.de/u-boot-marex.git / stdio branch ? I did something to nulldev there. Probably ignore the top 7 patches, they're bogus and need further work. It's all still work in progress to some point.

Too bad I can't just browse this at gitweb.

Intended ... just

git remote add marex git://...
git fetch marex
git checkout -t -b stdio marex/stdio

And enjoy the horror show :-)

Quoted 8 lines
Quoted 6 lines
Quoted 3 lines

I had the problem that the serial port
on my Zynq product lives in the fabric instead of using the hard-core ones.

I see ... why don't you implement nulldev_serial instead and leave nulldev stdio as is?

Mostly because there is little point in supporting both at the same time.

Can you enlighten me ? stdio != serial, the purpose is different really.

If someone wants to setenv stdout serial and have serial null, be my guest. But then there really should be a direct, explicit stdio nulldev too.

Quoted 1 line

-Joe

Best regards,
Marek Vasut