ARM: Add support for EP93xx SoCs
Subsystems (3)
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 1/3 ARM: Add support for EP93xx SoCs
Add support for the Cirrus EP93xx platform
--- cpu/arm920t/ep93xx/Makefile | 56 ++++ cpu/arm920t/ep93xx/cpu.c | 51 +++ cpu/arm920t/ep93xx/led.c | 101 ++++++ cpu/arm920t/ep93xx/lowlevel_init.S | 65 ++++ cpu/arm920t/ep93xx/speed.c | 109 ++++++ cpu/arm920t/ep93xx/timer.c | 168 ++++++++++ cpu/arm920t/ep93xx/u-boot.lds | 59 ++++ include/asm-arm/arch-ep93xx/ep93xx.h | 596 ++++++++++++++++++++++++++++++++++ 8 files changed, 1205 insertions(+), 0 deletions(-) create mode 100644 cpu/arm920t/ep93xx/Makefile create mode 100644 cpu/arm920t/ep93xx/cpu.c create mode 100644 cpu/arm920t/ep93xx/led.c create mode 100644 cpu/arm920t/ep93xx/lowlevel_init.S create mode 100644 cpu/arm920t/ep93xx/speed.c create mode 100644 cpu/arm920t/ep93xx/timer.c create mode 100644 cpu/arm920t/ep93xx/u-boot.lds create mode 100644 include/asm-arm/arch-ep93xx/ep93xx.h
cpu/arm920t/ep93xx/Makefile new file +56 -0
@@ -0,0 +1,56 @@ +# +# Cirrus Logic EP93xx CPU-specific Makefile +# +# Copyright (C) 2009 Matthias Kaehlcke <[email protected]> +# +# Copyright (C) 2004, 2005 +# Cory T. Tusar, Videon Central, Inc., <[email protected]> +# +# Copyright (C) 2006 +# Dominic Rath <[email protected]> +# +# Based on an original Makefile, which is +# +# (C) Copyright 2000, 2001, 2002 +# 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., +# 675 Mass Ave, Cambridge, MA 02139, USA. +# +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +COBJS = cpu.o led.o speed.o timer.o +SOBJS = lowlevel_init.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### +
cpu/arm920t/ep93xx/cpu.c new file +51 -0
51 lines not on this page · raw message
cpu/arm920t/ep93xx/led.c new file +101 -0
101 lines not on this page · raw message
cpu/arm920t/ep93xx/lowlevel_init.S new file +65 -0
65 lines not on this page · raw message
cpu/arm920t/ep93xx/speed.c new file +109 -0
109 lines not on this page · raw message
cpu/arm920t/ep93xx/timer.c new file +168 -0
168 lines not on this page · raw message
cpu/arm920t/ep93xx/u-boot.lds new file +59 -0
59 lines not on this page · raw message
include/asm-arm/arch-ep93xx/ep93xx.h new file +596 -0
596 lines not on this page · raw message
Signature · 1 line
1.6.3.1
PATCH 1/3 ARM: Add support for EP93xx SoCs
Dear Matthias Kaehlcke,
Quoted 3 lines · In message <20100119191617.GK16182@darwin> you wrote:
Add support for the Cirrus EP93xx platform
Signed-off-by Matthias Kaehlcke <[email protected]>
...
Quoted 5 lines
include/asm-arm/arch-ep93xx/ep93xx.h new file +2
-0@@ -0,0 +1,596 @@ +/* ----------------------------------------------------------------------------- +* Cirrus Logic EP93xx register definitions.
...
Quoted 1 line
+ */
...
Quoted 3 lines
+/* -----------------------------------------------------------------------------
+ *0x80000000-0x8000FFFF: DMA
+ */
etc.: incorrect multiline comment style. Please fix globally.
And please get rid of the trailing empty line(s).
Best regards,
Wolfgang Denk
Signature · 5 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
There are bugs and then there are bugs. And then there are bugs.
- Karl LehenbauerPATCH 2/3 Add EP93xx ethernet driver
In reply to a message not in the archiveAdded ethernet driver for EP93xx SoCs
--- drivers/net/Makefile | 1 + drivers/net/ep93xx.c | 658 ++++++++++++++++++++++++++++++++++++++++++++++++++ drivers/net/ep93xx.h | 145 +++++++++++ include/common.h | 8 +- include/netdev.h | 1 + 5 files changed, 812 insertions(+), 1 deletions(-) create mode 100644 drivers/net/ep93xx.c create mode 100644 drivers/net/ep93xx.h
drivers/net/Makefile +1 -0
@@ -37,6 +37,7 @@ COBJS-$(CONFIG_DNET) += dnet.o COBJS-$(CONFIG_E1000) += e1000.o COBJS-$(CONFIG_EEPRO100) += eepro100.o COBJS-$(CONFIG_ENC28J60) += enc28j60.o +COBJS-$(CONFIG_EP93XX) += ep93xx.o COBJS-$(CONFIG_FEC_MXC) += fec_mxc.o COBJS-$(CONFIG_FSLDMAFEC) += fsl_mcdmafec.o mcfmii.o COBJS-$(CONFIG_FTMAC100) += ftmac100.o
drivers/net/ep93xx.c new file +658 -0
658 lines not on this page · raw message
drivers/net/ep93xx.h new file +145 -0
145 lines not on this page · raw message
include/common.h +7 -1
@@ -123,6 +123,11 @@ typedef volatile unsigned char vu_char; #define debugX(level,fmt,args...)#endif /* DEBUG */ +#define error(fmt, args...) do { \ + printf("ERROR: " fmt "\nat %s:%d/%s()\n", \ + ##args, __FILE__, __LINE__, __func__); \ +} while (0) +#ifndef BUG #define BUG () do { \ printf("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __FUNCTION__); \
@@ -502,7 +507,8 @@ ulong get_PCI_freq (void);#endif #if defined(CONFIG_S3C24X0 ) || \ defined(CONFIG_LH7A40X ) || \ - defined(CONFIG_S3C6400 ) + defined(CONFIG_S3C6400 ) || \ + defined(CONFIG_EP93XX )ulong get_FCLK (void );ulong get_HCLK (void );ulong get_PCLK (void );
include/netdev.h +1 -0
@@ -49,6 +49,7 @@ int davinci_emac_initialize(void);int dnet_eth_initialize (int id,void *regs,unsigned int phy_addr);int e1000_initialize (bd_t *bis);int eepro100_initialize (bd_t *bis); +int ep93xx_eth_init (bd_t *const bd);int eth_3com_initialize (bd_t * bis);int fec_initialize (bd_t *bis);int fecmxc_initialize (bd_t *bis);
Signature · 1 line
1.6.3.1
PATCH 2/3 Add EP93xx ethernet driver
Hi Matthias,
Quoted 61 lines · Matthias Kaehlcke
Added ethernet driver for EP93xx SoCs
Signed-off-by Matthias Kaehlcke <[email protected]>--- drivers/net/Makefile | 1 + drivers/net/ep93xx.c | 658 ++++++++++++++++++++++++++++++++++++++++++++++++++ drivers/net/ep93xx.h | 145 +++++++++++ include/common.h | 8 +- include/netdev.h | 1 + 5 files changed, 812 insertions(+), 1 deletions(-) create mode 100644 drivers/net/ep93xx.c create mode 100644 drivers/net/ep93xx.hdrivers/net/Makefile +1
-0@@ -37,6 +37,7 @@ COBJS-$(CONFIG_DNET) += dnet.o COBJS-$(CONFIG_E1000) += e1000.o COBJS-$(CONFIG_EEPRO100) += eepro100.o COBJS-$(CONFIG_ENC28J60) += enc28j60.o +COBJS-$(CONFIG_EP93XX) += ep93xx.o COBJS-$(CONFIG_FEC_MXC) += fec_mxc.o COBJS-$(CONFIG_FSLDMAFEC) += fsl_mcdmafec.o mcfmii.o COBJS-$(CONFIG_FTMAC100) += ftmac100.odrivers/net/ep93xx.c new file +29
-0@@ -0,0 +1,658 @@ +/* +* Cirrus Logic EP93xx ethernet MAC / MII driver. +* +* Copyright (C) 2009 Matthias Kaehlcke <[email protected]> +* +* Copyright (C) 2004, 2005 +* Cory T. Tusar, Videon Central, Inc., <[email protected]> +* +* Based on the original eth.[ch] Cirrus Logic EP93xx Rev D. Ethernet Driver, +* which is +* +* (C) Copyright 2002 2003 +* Adam Bezanson, Network Audio Technologies, Inc. +* <[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.,
drivers/net/ep93xx.c line 39
Quoted 10 lines
drivers/net/ep93xx.c new file +10
-0+* 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#include <command.h> +#include <common.h> +#include <asm/arch/ep93xx.h> +#include <asm/io.h> +#include <malloc.h> +#include <miiphy.h> +#include <linux/types.h> +#include "ep93xx.h"
If the EP93XX is an SOC, you should name this driver something with extra namespace, e.g. (ep93xx_mac) or whatever the documentation calls it. The fact that you're including two files with the same name is a bad sign.
drivers/net/ep93xx.c line 48
Quoted 10 lines
drivers/net/ep93xx.c new file +9
-0+ +static int ep93xx_eth_send_packet (struct eth_device *dev, +volatile void *const packet,int const length); +static int ep93xx_eth_rcv_packet (struct eth_device *dev); + +/* ---------------------------------------------------------------------------- +* EP93xx ethernet MAC functionality +*/ +#if defined(CONFIG_DRIVER_EP93XX_MAC )
What's this for?
drivers/net/ep93xx.c line 57
Quoted 10 lines
drivers/net/ep93xx.c new file +9
-0+ +/* ep93xx_miiphy ops forward declarations */ +static int ep93xx_miiphy_read (char *const dev,unsigned char const addr, +unsigned char const reg,unsigned short *const value); +static int ep93xx_miiphy_write (char *const dev,unsigned char const addr, +unsigned char const reg,unsigned short const value); + +/* Reserve memory for the MAC's private data */ +static struct ep93xx_mac ep93xx_mac = {0 };
Each instance of the driver should have its own private structure. In other words, malloc() at runtime.
Quoted 19 lines
drivers/net/ep93xx.c new file +18
-0+ +#if defined(EP93XX_MAC_DEBUG ) +/** +* Dump ep93xx_mac values to the terminal. +*/ +inline void dump_dev (void ) +{ +int i; + +printf ("\ndump_dev()\n" ); +printf (" is_initialized %02X\n" , ep93xx_mac.is_initialized); +printf (" rx_dq.base %08X\n" , ep93xx_mac.rx_dq.base); +printf (" rx_dq.current %08X\n" , ep93xx_mac.rx_dq.current); +printf (" rx_dq.end %08X\n" , ep93xx_mac.rx_dq.end); +printf (" rx_sq.base %08X\n" , ep93xx_mac.rx_sq.base); +printf (" rx_sq.current %08X\n" , ep93xx_mac.rx_sq.current); +printf (" rx_sq.end %08X\n" , ep93xx_mac.rx_sq.end); +
drivers/net/ep93xx.c line 85
Quoted 10 lines
drivers/net/ep93xx.c new file +10
-0+for (i =0 ; i <NUMRXDESC ; i++) +printf (" rx_buffer[%2.d] %08X\n" , i, NetRxPackets[i]); + +printf (" tx_dq.base %08X\n" , ep93xx_mac.tx_dq.base); +printf (" tx_dq.current %08X\n" , ep93xx_mac.tx_dq.current); +printf (" tx_dq.end %08X\n" , ep93xx_mac.tx_dq.end); +printf (" tx_sq.base %08X\n" , ep93xx_mac.tx_sq.base); +printf (" tx_sq.current %08X\n" , ep93xx_mac.tx_sq.current); +printf (" tx_sq.end %08X\n" , ep93xx_mac.tx_sq.end); +}
Pass in eth_device and dereference private data instead of using global. You get the idea...
Quoted 83 lines
drivers/net/ep93xx.c new file +82
-0+ +/** +* Dump all RX status queue entries to the terminal. +*/ +inline void dump_rx_status_queue (void ) +{ +int i; + +printf ("\ndump_rx_status_queue()\n" ); +printf (" descriptor address word1 word2\n" ); +for (i =0 ; i <NUMRXDESC ; i++) { +printf (" [ %08X ] %08X %08X\n" , + (ep93xx_mac.rx_sq.base + i), + (ep93xx_mac.rx_sq.base + i)->word1, + (ep93xx_mac.rx_sq.base + i)->word2); + } +} + +/** +* Dump all RX descriptor queue entries to the terminal. +*/ +inline void dump_rx_descriptor_queue (void ) +{ +int i; + +printf ("\ndump_rx_descriptor_queue()\n" ); +printf (" descriptor address word1 word2\n" ); +for (i =0 ; i <NUMRXDESC ; i++) { +printf (" [ %08X ] %08X %08X\n" , + (ep93xx_mac.rx_dq.base + i), + (ep93xx_mac.rx_dq.base + i)->word1, + (ep93xx_mac.rx_dq.base + i)->word2); + } +} + +/** +* Dump all TX descriptor queue entries to the terminal. +*/ +inline void dump_tx_descriptor_queue (void ) +{ +int i; + +printf ("\ndump_tx_descriptor_queue()\n" ); +printf (" descriptor address word1 word2\n" ); +for (i =0 ; i <NUMTXDESC ; i++) { +printf (" [ %08X ] %08X %08X\n" , + (ep93xx_mac.tx_dq.base + i), + (ep93xx_mac.tx_dq.base + i)->word1, + (ep93xx_mac.tx_dq.base + i)->word2); + } +} + +/** +* Dump all TX status queue entries to the terminal. +*/ +inline void dump_tx_status_queue (void ) +{ +int i; + +printf ("\ndump_tx_status_queue()\n" ); +printf (" descriptor address word1\n" ); +for (i =0 ; i <NUMTXDESC ; i++) { +printf (" [ %08X ] %08X\n" , + (ep93xx_mac.rx_sq.base + i), + (ep93xx_mac.rx_sq.base + i)->word1); + } +} +#else +#define dump_dev (x) +#define dump_rx_descriptor_queue () +#define dump_rx_status_queue () +#define dump_tx_descriptor_queue () +#define dump_tx_status_queue () +#endif /* defined(EP93XX_MAC_DEBUG) */ + +/** +* Reset the EP93xx MAC by twiddling the soft reset bit and spinning until +* it's cleared. +*/ +static void ep93xx_mac_reset (void ) +{ +struct mac_regs *mac = (struct mac_regs *)MAC_BASE ;
drivers/net/ep93xx.c line 177
Quoted 10 lines
drivers/net/ep93xx.c new file +10
-0+uint32_t value; + +debug ("+ep93xx_mac_reset" ); + + value =readl (&mac->selfctl); + value |=SELFCTL_RESET ; +writel (value, &mac->selfctl); + +while (readl (&mac->selfctl) &SELFCTL_RESET ) + ;/* noop */
Most people write this as 'nop', but I won't be too picky...
drivers/net/ep93xx.c line 185
Quoted 9 lines
drivers/net/ep93xx.c new file +8
-0+ +debug ("-ep93xx_mac_reset" ); +} + +/* Eth device open */ +static int ep93xx_eth_open (struct eth_device *dev,bd_t *bd) +{ +struct mac_regs *mac = (struct mac_regs *)MAC_BASE ;
Get this from dev->priv
Quoted 80 lines
drivers/net/ep93xx.c new file +79
-0+uchar enetaddr[6 ]; +int i; + +debug ("+ep93xx_eth_open" ); + +/* Reset the MAC */ +ep93xx_mac_reset (); + +/* Reset the descriptor queues' current and end address values */ + ep93xx_mac.tx_dq.current = ep93xx_mac.tx_dq.base; + ep93xx_mac.tx_dq.end = (ep93xx_mac.tx_dq.base +NUMTXDESC ); + + ep93xx_mac.tx_sq.current = ep93xx_mac.tx_sq.base; + ep93xx_mac.tx_sq.end = (ep93xx_mac.tx_sq.base +NUMTXDESC ); + + ep93xx_mac.rx_dq.current = ep93xx_mac.rx_dq.base; + ep93xx_mac.rx_dq.end = (ep93xx_mac.rx_dq.base +NUMRXDESC ); + + ep93xx_mac.rx_sq.current = ep93xx_mac.rx_sq.base; + ep93xx_mac.rx_sq.end = (ep93xx_mac.rx_sq.base +NUMRXDESC ); + +/* +* Set the transmit descriptor and status queues' base address, +* current address, and length registers. Set the maximum frame +* length and threshold. Enable the transmit descriptor processor. +*/ +writel ((uint32_t )ep93xx_mac.tx_dq.base, &mac->txdq.badd); +writel ((uint32_t )ep93xx_mac.tx_dq.base, &mac->txdq.curadd); +writel (sizeof (struct tx_descriptor ) *NUMTXDESC , &mac->txdq.blen); + +writel ((uint32_t )ep93xx_mac.tx_sq.base, &mac->txstsq.badd); +writel ((uint32_t )ep93xx_mac.tx_sq.base, &mac->txstsq.curadd); +writel (sizeof (struct tx_status ) *NUMTXDESC , &mac->txstsq.blen); + +writel (0x00040000 , &mac->txdthrshld); +writel (0x00040000 , &mac->txststhrshld); + +writel ((TXSTARTMAX <<0 ) | (PKTSIZE_ALIGN <<16 ), &mac->maxfrmlen); +writel (BMCTL_TXEN , &mac->bmctl); + +/* +* Set the receive descriptor and status queues' base address, +* current address, and length registers. Enable the receive +* descriptor processor. +*/ +writel ((uint32_t )ep93xx_mac.rx_dq.base, &mac->rxdq.badd); +writel ((uint32_t )ep93xx_mac.rx_dq.base, &mac->rxdq.curadd); +writel (sizeof (struct rx_descriptor ) *NUMRXDESC , &mac->rxdq.blen); + +writel ((uint32_t )ep93xx_mac.rx_sq.base, &mac->rxstsq.badd); +writel ((uint32_t )ep93xx_mac.rx_sq.base, &mac->rxstsq.curadd); +writel (sizeof (struct rx_status ) *NUMRXDESC , &mac->rxstsq.blen); + +writel (0x00040000 , &mac->rxdthrshld); + +writel (BMCTL_RXEN , &mac->bmctl); + +writel (0x00040000 , &mac->rxststhrshld); + +/* Wait until the receive descriptor processor is active */ +while (!(readl (&mac->bmsts) &BMSTS_RXACT )) + ;/* noop */ + +/* +* Initialize the RX descriptor queue. Clear the TX descriptor queue. +* Clear the RX and TX status queues. Enqueue the RX descriptor and +* status entries to the MAC. +*/ +for (i =0 ; i <NUMRXDESC ; i++) { +/* set buffer address */ + (ep93xx_mac.rx_dq.base + i)->word1 = (uint32_t )NetRxPackets[i]; + +/* set buffer length, clear buffer index and NSOF */ + (ep93xx_mac.rx_dq.base + i)->word2 =PKTSIZE_ALIGN ; + } + +memset (ep93xx_mac.tx_dq.base,0 , + (sizeof (struct tx_descriptor ) *NUMTXDESC )); + memset(ep93xx_mac.rx_sq.base, 0,
drivers/net/ep93xx.c line 274
Quoted 10 lines
drivers/net/ep93xx.c new file +10
-0+ (sizeof(struct rx_status) * NUMRXDESC)); +memset (ep93xx_mac.tx_sq.base,0 , + (sizeof (struct tx_status ) *NUMTXDESC )); + +writel (NUMRXDESC , &mac->rxdqenq); +writel (NUMRXDESC , &mac->rxstsqenq); + +/* Set the primary MAC address */ +writel (AFP_IAPRIMARY , &mac->afp); +eth_getenv_enetaddr ("ethaddr" , enetaddr);
Get this from dev->enetaddr.
Quoted 44 lines
drivers/net/ep93xx.c new file +43
-0+writel (enetaddr[0 ] | (enetaddr[1 ] <<8 ) | + (enetaddr[2 ] <<16 ) | (enetaddr[3 ] <<24 ), + &mac->indad); +writel (enetaddr[4 ] | (enetaddr[5 ] <<8 ), &mac->indad_upper); + +/* Turn on RX and TX */ +writel (RXCTL_IA0 |RXCTL_BA |RXCTL_SRXON | +RXCTL_RCRCA |RXCTL_MA , &mac->rxctl); +writel (TXCTL_STXON , &mac->txctl); + +/* Dump data structures if we're debugging */ +dump_dev (); +dump_rx_descriptor_queue (); +dump_rx_status_queue (); +dump_tx_descriptor_queue (); +dump_tx_status_queue (); + +debug ("-ep93xx_eth_open" ); + +return 1 ; +} + +/** +* Halt EP93xx MAC transmit and receive by clearing the TxCTL and RxCTL +* registers. +*/ +static void ep93xx_eth_close (struct eth_device *dev) +{ +struct mac_regs *mac = (struct mac_regs *)MAC_BASE ; + +debug ("+ep93xx_eth_close" ); + +writel (0x00000000 , &mac->rxctl); +writel (0x00000000 , &mac->txctl); + +debug ("-ep93xx_eth_close" ); +} + +#if defined(CONFIG_MII ) +int ep93xx_miiphy_initialize (bd_t *const bd) +{ +miiphy_register ("ep93xx_eth0" , ep93xx_miiphy_read, ep93xx_miiphy_write); +return 0 ;
drivers/net/ep93xx.c line 327
Quoted 10 lines
drivers/net/ep93xx.c new file +10
-0+} +#endif + +/** +* Initialize the EP93xx MAC. The MAC hardware is reset. Buffers are +* allocated, if necessary, for the TX and RX descriptor and status queues, +* as well as for received packets. The EP93XX MAC hardware is initialized. +* Transmit and receive operations are enabled. +*/ +int ep93xx_eth_init (bd_t *const bd)
Please call this ep93xx_eth_initialize(), as all other drivers do. It doesn't look like you use bd anywhere, so choose parameters that are more relevant. Drivers for memory-mapped devices typically pass in a base address and index (see cs8900.c as an example).
Quoted 5 lines
drivers/net/ep93xx.c new file +4
-0+{ +int ret =-1 ; +struct eth_device *dev; +
drivers/net/ep93xx.c
Quoted 10 lines
drivers/net/ep93xx.c new file +10
-0+debug ("+ep93xx_eth_init" ); + +/* Parameter check */ +BUG_ON (bd ==NULL ); + +/* +* Allocate space for the queues and RX packet buffers if we're not +* already initialized +*/ +if (!ep93xx_mac.is_initialized) {\
As I mentioned earlier, each instance of the driver needs its own private struct. Please malloc() and attach to dev->priv
Quoted 28 lines
drivers/net/ep93xx.c new file +27
-0+ ep93xx_mac.tx_dq.base =calloc (NUMTXDESC , +sizeof (struct tx_descriptor )); +if (ep93xx_mac.tx_dq.base ==NULL ) { +error ("calloc() failed" ); + goto eth_init_failed_0; + } + + ep93xx_mac.tx_sq.base =calloc (NUMTXDESC , +sizeof (struct tx_status )); +if (ep93xx_mac.tx_sq.base ==NULL ) { +error ("calloc() failed" ); + goto eth_init_failed_1; + } + + ep93xx_mac.rx_dq.base =calloc (NUMRXDESC , +sizeof (struct rx_descriptor )); +if (ep93xx_mac.rx_dq.base ==NULL ) { +error ("calloc() failed" ); + goto eth_init_failed_2; + } + + ep93xx_mac.rx_sq.base =calloc (NUMRXDESC , +sizeof (struct rx_status )); +if (ep93xx_mac.rx_sq.base ==NULL ) { +error ("calloc() failed" ); + goto eth_init_failed_3; + }
drivers/net/ep93xx.c line 378
Quoted 10 lines
drivers/net/ep93xx.c new file +10
-0+ + dev =malloc (sizeof *dev); +if (dev ==NULL ) { +error ("malloc() failed" ); + goto eth_init_failed_4; + } + +memset (dev,0 ,sizeof *dev); +sprintf (dev->name,"ep93xx MAC" ); + dev->iobase =0 ;
dev->iobase is a convenient place to put your base address.
drivers/net/ep93xx.c line 390
Quoted 13 lines
drivers/net/ep93xx.c new file +12
-0+ dev->init = ep93xx_eth_open; + dev->halt = ep93xx_eth_close; + dev->send = ep93xx_eth_send_packet; + dev->recv = ep93xx_eth_rcv_packet; + +eth_register (dev); + +/* +* Set is_initialized flag so we don't go through allocation +* portion of init again. +*/ + ep93xx_mac.is_initialized =1 ;
You probably don't need this.
Quoted 26 lines
drivers/net/ep93xx.c new file +25
-0+ } + +/* Done! */ + ret =0 ; + goto eth_init_done; + +eth_init_failed_4: +free (ep93xx_mac.rx_sq.base); +/* Fall through */ + +eth_init_failed_3: +free (ep93xx_mac.rx_dq.base); +/* Fall through */ + +eth_init_failed_2: +free (ep93xx_mac.tx_sq.base); +/* Fall through */ + +eth_init_failed_1: +free (ep93xx_mac.tx_dq.base); +/* Fall through */ + +eth_init_failed_0: +/* Fall through */ +
drivers/net/ep93xx.c line 425
Quoted 10 lines
drivers/net/ep93xx.c new file +10
-0+eth_init_done: +debug ("-ep93xx_eth_init %d" , ret); +return ret; +} + +/** +* Copy a frame of data from the MAC into the protocol layer for further +* processing. +*/ +static int ep93xx_eth_rcv_packet (struct eth_device *dev)
Why not move this up higher to avoid the forward declarations?
Quoted 119 lines
drivers/net/ep93xx.c new file +118
-0+{ +struct mac_regs *mac = (struct mac_regs *)MAC_BASE ; +int len =-1 ; + +debug ("+ep93xx_eth_rcv_packet" ); + +if (RX_STATUS_RFP (ep93xx_mac.rx_sq.current)) { +if (RX_STATUS_RWE (ep93xx_mac.rx_sq.current)) { +/* +* We have a good frame. Extract the frame's length +* from the current rx_status_queue entry, and copy +* the frame's data into NetRxPackets[] of the +* protocol stack. We track the total number of +* bytes in the frame (nbytes_frame) which will be +* used when we pass the data off to the protocol +* layer via NetReceive(). +*/ + len =RX_STATUS_FRAME_LEN (ep93xx_mac.rx_sq.current); + +NetReceive ((uchar *)ep93xx_mac.rx_dq.current->word1, + len); + +debug ("reporting %d bytes...\n" , len); + }else { +/* Do we have an erroneous packet? */ +error ("packet rx error, status %08X %08X" , + ep93xx_mac.rx_sq.current->word1, + ep93xx_mac.rx_sq.current->word2); +dump_rx_descriptor_queue (); +dump_rx_status_queue (); + } + +/* +* Clear the associated status queue entry, and +* increment our current pointers to the next RX +* descriptor and status queue entries (making sure +* we wrap properly). +*/ +memset ((void *)ep93xx_mac.rx_sq.current,0 , +sizeof (struct rx_status )); + + ep93xx_mac.rx_sq.current++; +if (ep93xx_mac.rx_sq.current >= ep93xx_mac.rx_sq.end) + ep93xx_mac.rx_sq.current = ep93xx_mac.rx_sq.base; + + ep93xx_mac.rx_dq.current++; +if (ep93xx_mac.rx_dq.current >= ep93xx_mac.rx_dq.end) + ep93xx_mac.rx_dq.current = ep93xx_mac.rx_dq.base; + +/* +* Finally, return the RX descriptor and status entries +* back to the MAC engine, and loop again, checking for +* more descriptors to process. +*/ +writel (1 , &mac->rxdqenq); +writel (1 , &mac->rxstsqenq); + }else { + len =0 ; + } + +debug ("-ep93xx_eth_rcv_packet %d" , len); +return len; +} + +/** +* Send a block of data via ethernet. +*/ +static int ep93xx_eth_send_packet (struct eth_device *dev, +volatile void *const packet,int const length) +{ +struct mac_regs *mac = (struct mac_regs *)MAC_BASE ; +int ret =-1 ; + +debug ("+ep93xx_eth_send_packet" ); + +/* Parameter check */ +BUG_ON (packet ==NULL ); + +/* +* Initialize the TX descriptor queue with the new packet's info. +* Clear the associated status queue entry. Enqueue the packet +* to the MAC for transmission. +*/ + +/* set buffer address */ + ep93xx_mac.tx_dq.current->word1 = (uint32_t )packet; + +/* set buffer length and EOF bit */ + ep93xx_mac.tx_dq.current->word2 = length |TX_DESC_EOF ; + +/* clear tx status */ + ep93xx_mac.tx_sq.current->word1 =0 ; + +/* enqueue the TX descriptor */ +writel (1 , &mac->txdqenq); + +/* wait for the frame to become processed */ +while (!TX_STATUS_TXFP (ep93xx_mac.tx_sq.current)) + ;/* noop */ + +if (!TX_STATUS_TXWE (ep93xx_mac.tx_sq.current)) { +error ("packet tx error, status %08X" , + ep93xx_mac.tx_sq.current->word1); +dump_tx_descriptor_queue (); +dump_tx_status_queue (); + +/* TODO: Add better error handling? */ + goto eth_send_failed_0; + } + + ret =0 ; +/* Fall through */ + +eth_send_failed_0: +debug ("-ep93xx_eth_send_packet %d" , ret); +return ret; +} +#endif /* defined(CONFIG_DRIVER_EP93XX_MAC) */
drivers/net/ep93xx.c line 553
Quoted 10 lines
drivers/net/ep93xx.c new file +10
-0+ +/* ----------------------------------------------------------------------------- +* EP93xx ethernet MII functionality. +*/ +#if defined(CONFIG_MII ) + +/** +* Maximum MII address we support +*/ +#define MII_ADDRESS_MAX (31)
Parens not needed
Quoted 162 lines
drivers/net/ep93xx.c new file +105
-0+ +/** +* Maximum MII register address we support +*/ +#define MII_REGISTER_MAX (31) + +/** +* Read a 16-bit value from an MII register. +*/ +static int ep93xx_miiphy_read (char *const dev,unsigned char const addr, +unsigned char const reg,unsigned short *const value) +{ +struct mac_regs *mac = (struct mac_regs *)MAC_BASE ; +int ret =-1 ; +uint32_t self_ctl; + +debug ("+ep93xx_miiphy_read" ); + +/* Parameter checks */ +BUG_ON (dev ==NULL ); +BUG_ON (addr >MII_ADDRESS_MAX ); +BUG_ON (reg >MII_REGISTER_MAX ); +BUG_ON (value ==NULL ); + +/* +* Save the current SelfCTL register value. Set MAC to suppress +* preamble bits. Wait for any previous MII command to complete +* before issuing the new command. +*/ + self_ctl =readl (&mac->selfctl); +#if defined(CONFIG_MII_SUPPRESS_PREAMBLE ) +writel (self_ctl & ~(1 <<8 ), &mac->selfctl); +#endif /* defined(CONFIG_MII_SUPPRESS_PREAMBLE) */ + +while (readl (&mac->miists) &MIISTS_BUSY ) + ;/* noop */ + +/* +* Issue the MII 'read' command. Wait for the command to complete. +* Read the MII data value. +*/ +writel (MIICMD_OPCODE_READ | ((uint32_t )addr <<5 ) | (uint32_t )reg, + &mac->miicmd); +while (readl (&mac->miists) &MIISTS_BUSY ) + ;/* noop */ + + *value = (unsigned short )readl (&mac->miidata); + +/* Restore the saved SelfCTL value and return. */ +writel (self_ctl, &mac->selfctl); + + ret =0 ; +/* Fall through */ + +debug ("-ep93xx_miiphy_read" ); +return ret; +} + +/** +* Write a 16-bit value to an MII register. +*/ +static int ep93xx_miiphy_write (char *const dev,unsigned char const addr, +unsigned char const reg,unsigned short const value) +{ +struct mac_regs *mac = (struct mac_regs *)MAC_BASE ; +int ret =-1 ; +uint32_t self_ctl; + +debug ("+ep93xx_miiphy_write" ); + +/* Parameter checks */ +BUG_ON (dev ==NULL ); +BUG_ON (addr >MII_ADDRESS_MAX ); +BUG_ON (reg >MII_REGISTER_MAX ); + +/* +* Save the current SelfCTL register value. Set MAC to suppress +* preamble bits. Wait for any previous MII command to complete +* before issuing the new command. +*/ + self_ctl =readl (&mac->selfctl); +#if defined(CONFIG_MII_SUPPRESS_PREAMBLE ) +writel (self_ctl & ~(1 <<8 ), &mac->selfctl); +#endif /* defined(CONFIG_MII_SUPPRESS_PREAMBLE) */ + +while (readl (&mac->miists) &MIISTS_BUSY ) + ;/* noop */ + +/* Issue the MII 'write' command. Wait for the command to complete. */ +writel ((uint32_t )value, &mac->miidata); +writel (MIICMD_OPCODE_WRITE | ((uint32_t )addr <<5 ) | (uint32_t )reg, + &mac->miicmd); +while (readl (&mac->miists) &MIISTS_BUSY ) + ;/* noop */ + +/* Restore the saved SelfCTL value and return. */ +writel (self_ctl, &mac->selfctl); + + ret =0 ; +/* Fall through */ + +debug ("-ep93xx_miiphy_write" ); +return ret; +} +#endif /* defined(CONFIG_MII) */ drivers/net/ep93xx.h new file +50
-0@@ -0,0 +1,145 @@ +/* +* Copyright (C) 2009 Matthias Kaehlcke <[email protected]> +* +* Copyright (C) 2004, 2005 +* Cory T. Tusar, Videon Central, Inc., <[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 _ETH_H +#define _ETH_H + +#include <net.h> + +/** +* #define this to dump device status and queue info during initialization and +* following errors. +*/ +#undef EP93XX_MAC_DEBUG + +/** +* Number of descriptor and status entries in our RX queues. +* It must be power of 2 ! +*/ +#define NUMRXDESC PKTBUFSRX + +/** +* Number of descriptor and status entries in our TX queues. +*/ +#define NUMTXDESC 1 + +/** +* 944 = (1024 - 64) - 16, Fifo size - Minframesize - 16 (Chip FACT)
drivers/net/ep93xx.h line 60
Quoted 10 lines
drivers/net/ep93xx.h new file +10
-0+*/ +#define TXSTARTMAX 944 + +/** +* Receive descriptor queue entry +*/ +struct rx_descriptor { +uint32_t word1; +uint32_t word2; +} __attribute__((packed));
Why do you need to pack 32-bit integers?
Quoted 90 lines
drivers/net/ep93xx.h new file +85
-0+ +/** +* Receive status queue entry +*/ +struct rx_status { +uint32_t word1; +uint32_t word2; +} __attribute__((packed)); + +#define RX_STATUS_RWE (rx_status) ((rx_status->word1 >> 30) & 0x01) +#define RX_STATUS_RFP (rx_status) ((rx_status->word1 >> 31) & 0x01) +#define RX_STATUS_FRAME_LEN (rx_status) (rx_status->word2 & 0xFFFF) + + +/** +* Transmit descriptor queue entry +*/ +struct tx_descriptor { +uint32_t word1; +uint32_t word2; +} __attribute__((packed)); + +#define TX_DESC_EOF (1 << 31) + +/** +* Transmit status queue entry +*/ +struct tx_status { +uint32_t word1; +} __attribute__((packed)); + +#define TX_STATUS_TXWE (tx_status) (((tx_status)->word1 >> 30) & 0x01) +#define TX_STATUS_TXFP (tx_status) (((tx_status)->word1 >> 31) & 0x01) + +/** +* Transmit descriptor queue +*/ +struct tx_descriptor_queue { +struct tx_descriptor *base; +struct tx_descriptor *current; +struct tx_descriptor *end; +}; + +/** +* Transmit status queue +*/ +struct tx_status_queue { +struct tx_status *base; +volatile struct tx_status *current; +struct tx_status *end; +}; + +/** +* Receive descriptor queue +*/ +struct rx_descriptor_queue { +struct rx_descriptor *base; +struct rx_descriptor *current; +struct rx_descriptor *end; +}; + +/** +* Receive status queue +*/ +struct rx_status_queue { +struct rx_status *base; +volatile struct rx_status *current; +struct rx_status *end; +}; + +/** +* EP93xx MAC private data structure +*/ +struct ep93xx_mac { +int is_initialized; + +struct rx_descriptor_queue rx_dq; +struct rx_status_queue rx_sq; +void *rx_buffer[NUMRXDESC ]; + +struct tx_descriptor_queue tx_dq; +struct tx_status_queue tx_sq; +}; + +#endif include/common.h +0
-0
include/common.h typedef volatile unsigned char vu_char; · line 131
Quoted 9 lines
include/common.h +5
-0@@ -123,6 +123,11 @@ typedef volatile unsigned char vu_char; #define debugX(level,fmt,args...)#endif /* DEBUG */ +#define error(fmt, args...) do { \ + printf("ERROR: " fmt "\nat %s:%d/%s()\n", \ + ##args, __FILE__, __LINE__, __func__); \ +} while (0) +
Is this really needed?
Quoted 5 lines
include/common.h +0
-0#ifndef BUG #define BUG () do { \include/common.h +0
-0printf ("BUG: failure at %s:%d/%s()!\n" , __FILE__, __LINE__, __FUNCTION__); \
include/common.h ulong get_PCI_freq (void); · line 514
Quoted 9 lines
include/common.h +2
-1@@ -502,7 +507,8 @@ ulong get_PCI_freq (void);#endif #if defined(CONFIG_S3C24X0 ) || \ defined(CONFIG_LH7A40X ) || \ - defined(CONFIG_S3C6400 ) + defined(CONFIG_S3C6400 ) || \ + defined(CONFIG_EP93XX )ulong get_FCLK (void );ulong get_HCLK (void );ulong get_PCLK (void );
I don't see these referenced anywhere. How do they apply to this driver?
include/netdev.h int davinci_emac_initialize(void); · line 55
Quoted 13 lines
include/netdev.h +1
-0@@ -49,6 +49,7 @@ int davinci_emac_initialize(void);int dnet_eth_initialize (int id,void *regs,unsigned int phy_addr);int e1000_initialize (bd_t *bis);int eepro100_initialize (bd_t *bis); +int ep93xx_eth_init (bd_t *const bd);int eth_3com_initialize (bd_t * bis);int fec_initialize (bd_t *bis);int fecmxc_initialize (bd_t *bis);
regards,
Ben
PATCH 2/3 Add EP93xx ethernet driver
Hi Ben,
thanks for your review!
El Tue, Jan 19, 2010 at 01:30:21PM -0800 Ben Warren ha dit:
Quoted 68 lines
Quoted 67 lines · Matthias Kaehlcke
Added ethernet driver for EP93xx SoCs
Signed-off-by Matthias Kaehlcke <[email protected]>--- drivers/net/Makefile | 1 + drivers/net/ep93xx.c | 658 ++++++++++++++++++++++++++++++++++++++++++++++++++ drivers/net/ep93xx.h | 145 +++++++++++ include/common.h | 8 +- include/netdev.h | 1 + 5 files changed, 812 insertions(+), 1 deletions(-) create mode 100644 drivers/net/ep93xx.c create mode 100644 drivers/net/ep93xx.hdrivers/net/Makefile +1
-0@@ -37,6 +37,7 @@ COBJS-$(CONFIG_DNET) += dnet.o COBJS-$(CONFIG_E1000) += e1000.o COBJS-$(CONFIG_EEPRO100) += eepro100.o COBJS-$(CONFIG_ENC28J60) += enc28j60.o +COBJS-$(CONFIG_EP93XX) += ep93xx.o COBJS-$(CONFIG_FEC_MXC) += fec_mxc.o COBJS-$(CONFIG_FSLDMAFEC) += fsl_mcdmafec.o mcfmii.o COBJS-$(CONFIG_FTMAC100) += ftmac100.odrivers/net/ep93xx.c new file +36
-0@@ -0,0 +1,658 @@ +/* +* Cirrus Logic EP93xx ethernet MAC / MII driver. +* +* Copyright (C) 2009 Matthias Kaehlcke <[email protected]> +* +* Copyright (C) 2004, 2005 +* Cory T. Tusar, Videon Central, Inc., <[email protected]> +* +* Based on the original eth.[ch] Cirrus Logic EP93xx Rev D. Ethernet Driver, +* which is +* +* (C) Copyright 2002 2003 +* Adam Bezanson, Network Audio Technologies, Inc. +* <[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 <command.h> +#include <common.h> +#include <asm/arch/ep93xx.h> +#include <asm/io.h> +#include <malloc.h>
Quoted 8 lines
drivers/net/ep93xx.c line 39
Quoted 4 lines
drivers/net/ep93xx.c new file +3
-0+#include <miiphy.h> +#include <linux/types.h> +#include "ep93xx.h" If the EP93XX is an SOC, you should name this driver something with extra namespace, e.g. (
ep93xx_mac) or whatever the documentation calls it. The fact that you're including two files with the same name is a bad sign.
ok
Quoted 11 lines
drivers/net/ep93xx.c line 48
Quoted 10 lines
drivers/net/ep93xx.c new file +9
-0+ +static int ep93xx_eth_send_packet (struct eth_device *dev, +volatile void *const packet,int const length); +static int ep93xx_eth_rcv_packet (struct eth_device *dev); + +/* ---------------------------------------------------------------------------- +* EP93xx ethernet MAC functionality +*/ +#if defined(CONFIG_DRIVER_EP93XX_MAC )What's this for?
you're right, this should have been removed
Quoted 4 lines
Quoted 4 lines
drivers/net/ep93xx.c new file +4
-0+ +/* ep93xx_miiphy ops forward declarations */ +static int ep93xx_miiphy_read (char *const dev,unsigned char const addr, +unsigned char const reg,unsigned short *const value);
Quoted 8 lines
drivers/net/ep93xx.c line 57
Quoted 6 lines
drivers/net/ep93xx.c new file +5
-0+static int ep93xx_miiphy_write (char *const dev,unsigned char const addr, +unsigned char const reg,unsigned short const value); + +/* Reserve memory for the MAC's private data */ +static struct ep93xx_mac ep93xx_mac = {0 };Each instance of the driver should have its own private structure. In other words,
malloc()at runtime.
ok
Quoted 23 lines
Quoted 23 lines
drivers/net/ep93xx.c new file +23
-0+ +#if defined(EP93XX_MAC_DEBUG ) +/** +* Dump ep93xx_mac values to the terminal. +*/ +inline void dump_dev (void ) +{ +int i; + +printf ("\ndump_dev()\n" ); +printf (" is_initialized %02X\n" , ep93xx_mac.is_initialized); +printf (" rx_dq.base %08X\n" , ep93xx_mac.rx_dq.base); +printf (" rx_dq.current %08X\n" , ep93xx_mac.rx_dq.current); +printf (" rx_dq.end %08X\n" , ep93xx_mac.rx_dq.end); +printf (" rx_sq.base %08X\n" , ep93xx_mac.rx_sq.base); +printf (" rx_sq.current %08X\n" , ep93xx_mac.rx_sq.current); +printf (" rx_sq.end %08X\n" , ep93xx_mac.rx_sq.end); + +for (i =0 ; i <NUMRXDESC ; i++) +printf (" rx_buffer[%2.d] %08X\n" , i, NetRxPackets[i]); + +printf (" tx_dq.base %08X\n" , ep93xx_mac.tx_dq.base); +printf (" tx_dq.current %08X\n" , ep93xx_mac.tx_dq.current);
Quoted 8 lines
drivers/net/ep93xx.c line 85
Quoted 6 lines
drivers/net/ep93xx.c new file +5
-0+printf (" tx_dq.end %08X\n" , ep93xx_mac.tx_dq.end); +printf (" tx_sq.base %08X\n" , ep93xx_mac.tx_sq.base); +printf (" tx_sq.current %08X\n" , ep93xx_mac.tx_sq.current); +printf (" tx_sq.end %08X\n" , ep93xx_mac.tx_sq.end); +}Pass in
eth_deviceand dereference private data instead of using global. You get the idea...
ok
Quoted 86 lines
Quoted 86 lines
drivers/net/ep93xx.c new file +86
-0+ +/** +* Dump all RX status queue entries to the terminal. +*/ +inline void dump_rx_status_queue (void ) +{ +int i; + +printf ("\ndump_rx_status_queue()\n" ); +printf (" descriptor address word1 word2\n" ); +for (i =0 ; i <NUMRXDESC ; i++) { +printf (" [ %08X ] %08X %08X\n" , + (ep93xx_mac.rx_sq.base + i), + (ep93xx_mac.rx_sq.base + i)->word1, + (ep93xx_mac.rx_sq.base + i)->word2); + } +} + +/** +* Dump all RX descriptor queue entries to the terminal. +*/ +inline void dump_rx_descriptor_queue (void ) +{ +int i; + +printf ("\ndump_rx_descriptor_queue()\n" ); +printf (" descriptor address word1 word2\n" ); +for (i =0 ; i <NUMRXDESC ; i++) { +printf (" [ %08X ] %08X %08X\n" , + (ep93xx_mac.rx_dq.base + i), + (ep93xx_mac.rx_dq.base + i)->word1, + (ep93xx_mac.rx_dq.base + i)->word2); + } +} + +/** +* Dump all TX descriptor queue entries to the terminal. +*/ +inline void dump_tx_descriptor_queue (void ) +{ +int i; + +printf ("\ndump_tx_descriptor_queue()\n" ); +printf (" descriptor address word1 word2\n" ); +for (i =0 ; i <NUMTXDESC ; i++) { +printf (" [ %08X ] %08X %08X\n" , + (ep93xx_mac.tx_dq.base + i), + (ep93xx_mac.tx_dq.base + i)->word1, + (ep93xx_mac.tx_dq.base + i)->word2); + } +} + +/** +* Dump all TX status queue entries to the terminal. +*/ +inline void dump_tx_status_queue (void ) +{ +int i; + +printf ("\ndump_tx_status_queue()\n" ); +printf (" descriptor address word1\n" ); +for (i =0 ; i <NUMTXDESC ; i++) { +printf (" [ %08X ] %08X\n" , + (ep93xx_mac.rx_sq.base + i), + (ep93xx_mac.rx_sq.base + i)->word1); + } +} +#else +#define dump_dev (x) +#define dump_rx_descriptor_queue () +#define dump_rx_status_queue () +#define dump_tx_descriptor_queue () +#define dump_tx_status_queue () +#endif /* defined(EP93XX_MAC_DEBUG) */ + +/** +* Reset the EP93xx MAC by twiddling the soft reset bit and spinning until +* it's cleared. +*/ +static void ep93xx_mac_reset (void ) +{ +struct mac_regs *mac = (struct mac_regs *)MAC_BASE ; +uint32_t value; + +debug ("+ep93xx_mac_reset" ); +
Quoted 8 lines
drivers/net/ep93xx.c line 177
Quoted 7 lines
drivers/net/ep93xx.c new file +6
-0+ value =readl (&mac->selfctl); + value |=SELFCTL_RESET ; +writel (value, &mac->selfctl); + +while (readl (&mac->selfctl) &SELFCTL_RESET ) + ;/* noop */ Most people write this as 'nop', but I won't be too picky...
in the first revision of this patch set it was 'nop' and i was asked to change it to 'noop', and so i did ;)
Quoted 10 lines
drivers/net/ep93xx.c line 185
Quoted 9 lines
drivers/net/ep93xx.c new file +8
-0+ +debug ("-ep93xx_mac_reset" ); +} + +/* Eth device open */ +static int ep93xx_eth_open (struct eth_device *dev,bd_t *bd) +{ +struct mac_regs *mac = (struct mac_regs *)MAC_BASE ;Get this from
dev->priv
ok
Quoted 83 lines
Quoted 83 lines
drivers/net/ep93xx.c new file +83
-0+uchar enetaddr[6 ]; +int i; + +debug ("+ep93xx_eth_open" ); + +/* Reset the MAC */ +ep93xx_mac_reset (); + +/* Reset the descriptor queues' current and end address values */ + ep93xx_mac.tx_dq.current = ep93xx_mac.tx_dq.base; + ep93xx_mac.tx_dq.end = (ep93xx_mac.tx_dq.base +NUMTXDESC ); + + ep93xx_mac.tx_sq.current = ep93xx_mac.tx_sq.base; + ep93xx_mac.tx_sq.end = (ep93xx_mac.tx_sq.base +NUMTXDESC ); + + ep93xx_mac.rx_dq.current = ep93xx_mac.rx_dq.base; + ep93xx_mac.rx_dq.end = (ep93xx_mac.rx_dq.base +NUMRXDESC ); + + ep93xx_mac.rx_sq.current = ep93xx_mac.rx_sq.base; + ep93xx_mac.rx_sq.end = (ep93xx_mac.rx_sq.base +NUMRXDESC ); + +/* +* Set the transmit descriptor and status queues' base address, +* current address, and length registers. Set the maximum frame +* length and threshold. Enable the transmit descriptor processor. +*/ +writel ((uint32_t )ep93xx_mac.tx_dq.base, &mac->txdq.badd); +writel ((uint32_t )ep93xx_mac.tx_dq.base, &mac->txdq.curadd); +writel (sizeof (struct tx_descriptor ) *NUMTXDESC , &mac->txdq.blen); + +writel ((uint32_t )ep93xx_mac.tx_sq.base, &mac->txstsq.badd); +writel ((uint32_t )ep93xx_mac.tx_sq.base, &mac->txstsq.curadd); +writel (sizeof (struct tx_status ) *NUMTXDESC , &mac->txstsq.blen); + +writel (0x00040000 , &mac->txdthrshld); +writel (0x00040000 , &mac->txststhrshld); + +writel ((TXSTARTMAX <<0 ) | (PKTSIZE_ALIGN <<16 ), &mac->maxfrmlen); +writel (BMCTL_TXEN , &mac->bmctl); + +/* +* Set the receive descriptor and status queues' base address, +* current address, and length registers. Enable the receive +* descriptor processor. +*/ +writel ((uint32_t )ep93xx_mac.rx_dq.base, &mac->rxdq.badd); +writel ((uint32_t )ep93xx_mac.rx_dq.base, &mac->rxdq.curadd); +writel (sizeof (struct rx_descriptor ) *NUMRXDESC , &mac->rxdq.blen); + +writel ((uint32_t )ep93xx_mac.rx_sq.base, &mac->rxstsq.badd); +writel ((uint32_t )ep93xx_mac.rx_sq.base, &mac->rxstsq.curadd); +writel (sizeof (struct rx_status ) *NUMRXDESC , &mac->rxstsq.blen); + +writel (0x00040000 , &mac->rxdthrshld); + +writel (BMCTL_RXEN , &mac->bmctl); + +writel (0x00040000 , &mac->rxststhrshld); + +/* Wait until the receive descriptor processor is active */ +while (!(readl (&mac->bmsts) &BMSTS_RXACT )) + ;/* noop */ + +/* +* Initialize the RX descriptor queue. Clear the TX descriptor queue. +* Clear the RX and TX status queues. Enqueue the RX descriptor and +* status entries to the MAC. +*/ +for (i =0 ; i <NUMRXDESC ; i++) { +/* set buffer address */ + (ep93xx_mac.rx_dq.base + i)->word1 = (uint32_t )NetRxPackets[i]; + +/* set buffer length, clear buffer index and NSOF */ + (ep93xx_mac.rx_dq.base + i)->word2 =PKTSIZE_ALIGN ; + } + +memset (ep93xx_mac.tx_dq.base,0 , + (sizeof (struct tx_descriptor ) *NUMTXDESC )); +memset (ep93xx_mac.rx_sq.base,0 , + (sizeof (struct rx_status ) *NUMRXDESC )); +memset (ep93xx_mac.tx_sq.base,0 , + (sizeof (struct tx_status ) *NUMTXDESC )); +
Quoted 8 lines
drivers/net/ep93xx.c line 274
Quoted 7 lines
drivers/net/ep93xx.c new file +6
-0+writel (NUMRXDESC , &mac->rxdqenq); +writel (NUMRXDESC , &mac->rxstsqenq); + +/* Set the primary MAC address */ +writel (AFP_IAPRIMARY , &mac->afp); +eth_getenv_enetaddr ("ethaddr" , enetaddr);Get this from
dev->enetaddr.
ok
Quoted 50 lines
Quoted 50 lines
drivers/net/ep93xx.c new file +50
-0+writel (enetaddr[0 ] | (enetaddr[1 ] <<8 ) | + (enetaddr[2 ] <<16 ) | (enetaddr[3 ] <<24 ), + &mac->indad); +writel (enetaddr[4 ] | (enetaddr[5 ] <<8 ), &mac->indad_upper); + +/* Turn on RX and TX */ +writel (RXCTL_IA0 |RXCTL_BA |RXCTL_SRXON | +RXCTL_RCRCA |RXCTL_MA , &mac->rxctl); +writel (TXCTL_STXON , &mac->txctl); + +/* Dump data structures if we're debugging */ +dump_dev (); +dump_rx_descriptor_queue (); +dump_rx_status_queue (); +dump_tx_descriptor_queue (); +dump_tx_status_queue (); + +debug ("-ep93xx_eth_open" ); + +return 1 ; +} + +/** +* Halt EP93xx MAC transmit and receive by clearing the TxCTL and RxCTL +* registers. +*/ +static void ep93xx_eth_close (struct eth_device *dev) +{ +struct mac_regs *mac = (struct mac_regs *)MAC_BASE ; + +debug ("+ep93xx_eth_close" ); + +writel (0x00000000 , &mac->rxctl); +writel (0x00000000 , &mac->txctl); + +debug ("-ep93xx_eth_close" ); +} + +#if defined(CONFIG_MII ) +int ep93xx_miiphy_initialize (bd_t *const bd) +{ +miiphy_register ("ep93xx_eth0" , ep93xx_miiphy_read, ep93xx_miiphy_write); +return 0 ; +} +#endif + +/** +* Initialize the EP93xx MAC. The MAC hardware is reset. Buffers are +* allocated, if necessary, for the TX and RX descriptor and status queues, +* as well as for received packets. The EP93XX MAC hardware is initialized.
Quoted 8 lines
drivers/net/ep93xx.c line 327
Quoted 4 lines
drivers/net/ep93xx.c new file +3
-0+* Transmit and receive operations are enabled. +*/ +int ep93xx_eth_init (bd_t *const bd)Please call this
ep93xx_eth_initialize(), as all other drivers do. It doesn't look like you use bd anywhere, so choose parameters that are more relevant. Drivers for memory-mapped devices typically pass in a base address and index (seecs8900.cas an example).
ok
Quoted 9 lines
Quoted 9 lines
drivers/net/ep93xx.c new file +9
-0+{ +int ret =-1 ; +struct eth_device *dev; + +debug ("+ep93xx_eth_init" ); + +/* Parameter check */ +BUG_ON (bd ==NULL ); +
Quoted 8 lines
drivers/net/ep93xx.c
Quoted 6 lines
drivers/net/ep93xx.c new file +5
-0+/* +* Allocate space for the queues and RX packet buffers if we're not +* already initialized +*/ +if (!ep93xx_mac.is_initialized) {\As I mentioned earlier, each instance of the driver needs its own private struct. Please
malloc()and attach todev->priv
ok
Quoted 31 lines
Quoted 31 lines
drivers/net/ep93xx.c new file +31
-0+ ep93xx_mac.tx_dq.base =calloc (NUMTXDESC , +sizeof (struct tx_descriptor )); +if (ep93xx_mac.tx_dq.base ==NULL ) { +error ("calloc() failed" ); + goto eth_init_failed_0; + } + + ep93xx_mac.tx_sq.base =calloc (NUMTXDESC , +sizeof (struct tx_status )); +if (ep93xx_mac.tx_sq.base ==NULL ) { +error ("calloc() failed" ); + goto eth_init_failed_1; + } + + ep93xx_mac.rx_dq.base =calloc (NUMRXDESC , +sizeof (struct rx_descriptor )); +if (ep93xx_mac.rx_dq.base ==NULL ) { +error ("calloc() failed" ); + goto eth_init_failed_2; + } + + ep93xx_mac.rx_sq.base =calloc (NUMRXDESC , +sizeof (struct rx_status )); +if (ep93xx_mac.rx_sq.base ==NULL ) { +error ("calloc() failed" ); + goto eth_init_failed_3; + } + + dev =malloc (sizeof *dev); +if (dev ==NULL ) { +error ("malloc() failed" );
Quoted 8 lines
drivers/net/ep93xx.c line 378
Quoted 7 lines
drivers/net/ep93xx.c new file +6
-0+ goto eth_init_failed_4; + } + +memset (dev,0 ,sizeof *dev); +sprintf (dev->name,"ep93xx MAC" ); + dev->iobase =0 ;
dev->iobaseis a convenient place to put your base address.
ok
Quoted 6 lines
Quoted 6 lines
drivers/net/ep93xx.c new file +6
-0+ dev->init = ep93xx_eth_open; + dev->halt = ep93xx_eth_close; + dev->send = ep93xx_eth_send_packet; + dev->recv = ep93xx_eth_rcv_packet; + +eth_register (dev);
Quoted 8 lines
drivers/net/ep93xx.c line 390
Quoted 7 lines
drivers/net/ep93xx.c new file +6
-0+ +/* +* Set is_initialized flag so we don't go through allocation +* portion of init again. +*/ + ep93xx_mac.is_initialized =1 ;You probably don't need this.
ok
Quoted 29 lines
Quoted 29 lines
drivers/net/ep93xx.c new file +29
-0+ } + +/* Done! */ + ret =0 ; + goto eth_init_done; + +eth_init_failed_4: +free (ep93xx_mac.rx_sq.base); +/* Fall through */ + +eth_init_failed_3: +free (ep93xx_mac.rx_dq.base); +/* Fall through */ + +eth_init_failed_2: +free (ep93xx_mac.tx_sq.base); +/* Fall through */ + +eth_init_failed_1: +free (ep93xx_mac.tx_dq.base); +/* Fall through */ + +eth_init_failed_0: +/* Fall through */ + +eth_init_done: +debug ("-ep93xx_eth_init %d" , ret); +return ret; +}
Quoted 8 lines
drivers/net/ep93xx.c line 425
Quoted 7 lines
drivers/net/ep93xx.c new file +6
-0+ +/** +* Copy a frame of data from the MAC into the protocol layer for further +* processing. +*/ +static int ep93xx_eth_rcv_packet (struct eth_device *dev)Why not move this up higher to avoid the forward declarations?
ok
Quoted 122 lines
Quoted 122 lines
drivers/net/ep93xx.c new file +122
-0+{ +struct mac_regs *mac = (struct mac_regs *)MAC_BASE ; +int len =-1 ; + +debug ("+ep93xx_eth_rcv_packet" ); + +if (RX_STATUS_RFP (ep93xx_mac.rx_sq.current)) { +if (RX_STATUS_RWE (ep93xx_mac.rx_sq.current)) { +/* +* We have a good frame. Extract the frame's length +* from the current rx_status_queue entry, and copy +* the frame's data into NetRxPackets[] of the +* protocol stack. We track the total number of +* bytes in the frame (nbytes_frame) which will be +* used when we pass the data off to the protocol +* layer via NetReceive(). +*/ + len =RX_STATUS_FRAME_LEN (ep93xx_mac.rx_sq.current); + +NetReceive ((uchar *)ep93xx_mac.rx_dq.current->word1, + len); + +debug ("reporting %d bytes...\n" , len); + }else { +/* Do we have an erroneous packet? */ +error ("packet rx error, status %08X %08X" , + ep93xx_mac.rx_sq.current->word1, + ep93xx_mac.rx_sq.current->word2); +dump_rx_descriptor_queue (); +dump_rx_status_queue (); + } + +/* +* Clear the associated status queue entry, and +* increment our current pointers to the next RX +* descriptor and status queue entries (making sure +* we wrap properly). +*/ +memset ((void *)ep93xx_mac.rx_sq.current,0 , +sizeof (struct rx_status )); + + ep93xx_mac.rx_sq.current++; +if (ep93xx_mac.rx_sq.current >= ep93xx_mac.rx_sq.end) + ep93xx_mac.rx_sq.current = ep93xx_mac.rx_sq.base; + + ep93xx_mac.rx_dq.current++; +if (ep93xx_mac.rx_dq.current >= ep93xx_mac.rx_dq.end) + ep93xx_mac.rx_dq.current = ep93xx_mac.rx_dq.base; + +/* +* Finally, return the RX descriptor and status entries +* back to the MAC engine, and loop again, checking for +* more descriptors to process. +*/ +writel (1 , &mac->rxdqenq); +writel (1 , &mac->rxstsqenq); + }else { + len =0 ; + } + +debug ("-ep93xx_eth_rcv_packet %d" , len); +return len; +} + +/** +* Send a block of data via ethernet. +*/ +static int ep93xx_eth_send_packet (struct eth_device *dev, +volatile void *const packet,int const length) +{ +struct mac_regs *mac = (struct mac_regs *)MAC_BASE ; +int ret =-1 ; + +debug ("+ep93xx_eth_send_packet" ); + +/* Parameter check */ +BUG_ON (packet ==NULL ); + +/* +* Initialize the TX descriptor queue with the new packet's info. +* Clear the associated status queue entry. Enqueue the packet +* to the MAC for transmission. +*/ + +/* set buffer address */ + ep93xx_mac.tx_dq.current->word1 = (uint32_t )packet; + +/* set buffer length and EOF bit */ + ep93xx_mac.tx_dq.current->word2 = length |TX_DESC_EOF ; + +/* clear tx status */ + ep93xx_mac.tx_sq.current->word1 =0 ; + +/* enqueue the TX descriptor */ +writel (1 , &mac->txdqenq); + +/* wait for the frame to become processed */ +while (!TX_STATUS_TXFP (ep93xx_mac.tx_sq.current)) + ;/* noop */ + +if (!TX_STATUS_TXWE (ep93xx_mac.tx_sq.current)) { +error ("packet tx error, status %08X" , + ep93xx_mac.tx_sq.current->word1); +dump_tx_descriptor_queue (); +dump_tx_status_queue (); + +/* TODO: Add better error handling? */ + goto eth_send_failed_0; + } + + ret =0 ; +/* Fall through */ + +eth_send_failed_0: +debug ("-ep93xx_eth_send_packet %d" , ret); +return ret; +} +#endif /* defined(CONFIG_DRIVER_EP93XX_MAC) */ + +/* ----------------------------------------------------------------------------- +* EP93xx ethernet MII functionality. +*/
Quoted 8 lines
drivers/net/ep93xx.c line 553
Quoted 7 lines
drivers/net/ep93xx.c new file +6
-0+#if defined(CONFIG_MII ) + +/** +* Maximum MII address we support +*/ +#define MII_ADDRESS_MAX (31)Parens not needed
ok
Quoted 165 lines
Quoted 165 lines
drivers/net/ep93xx.c new file +105
-0+ +/** +* Maximum MII register address we support +*/ +#define MII_REGISTER_MAX (31) + +/** +* Read a 16-bit value from an MII register. +*/ +static int ep93xx_miiphy_read (char *const dev,unsigned char const addr, +unsigned char const reg,unsigned short *const value) +{ +struct mac_regs *mac = (struct mac_regs *)MAC_BASE ; +int ret =-1 ; +uint32_t self_ctl; + +debug ("+ep93xx_miiphy_read" ); + +/* Parameter checks */ +BUG_ON (dev ==NULL ); +BUG_ON (addr >MII_ADDRESS_MAX ); +BUG_ON (reg >MII_REGISTER_MAX ); +BUG_ON (value ==NULL ); + +/* +* Save the current SelfCTL register value. Set MAC to suppress +* preamble bits. Wait for any previous MII command to complete +* before issuing the new command. +*/ + self_ctl =readl (&mac->selfctl); +#if defined(CONFIG_MII_SUPPRESS_PREAMBLE ) +writel (self_ctl & ~(1 <<8 ), &mac->selfctl); +#endif /* defined(CONFIG_MII_SUPPRESS_PREAMBLE) */ + +while (readl (&mac->miists) &MIISTS_BUSY ) + ;/* noop */ + +/* +* Issue the MII 'read' command. Wait for the command to complete. +* Read the MII data value. +*/ +writel (MIICMD_OPCODE_READ | ((uint32_t )addr <<5 ) | (uint32_t )reg, + &mac->miicmd); +while (readl (&mac->miists) &MIISTS_BUSY ) + ;/* noop */ + + *value = (unsigned short )readl (&mac->miidata); + +/* Restore the saved SelfCTL value and return. */ +writel (self_ctl, &mac->selfctl); + + ret =0 ; +/* Fall through */ + +debug ("-ep93xx_miiphy_read" ); +return ret; +} + +/** +* Write a 16-bit value to an MII register. +*/ +static int ep93xx_miiphy_write (char *const dev,unsigned char const addr, +unsigned char const reg,unsigned short const value) +{ +struct mac_regs *mac = (struct mac_regs *)MAC_BASE ; +int ret =-1 ; +uint32_t self_ctl; + +debug ("+ep93xx_miiphy_write" ); + +/* Parameter checks */ +BUG_ON (dev ==NULL ); +BUG_ON (addr >MII_ADDRESS_MAX ); +BUG_ON (reg >MII_REGISTER_MAX ); + +/* +* Save the current SelfCTL register value. Set MAC to suppress +* preamble bits. Wait for any previous MII command to complete +* before issuing the new command. +*/ + self_ctl =readl (&mac->selfctl); +#if defined(CONFIG_MII_SUPPRESS_PREAMBLE ) +writel (self_ctl & ~(1 <<8 ), &mac->selfctl); +#endif /* defined(CONFIG_MII_SUPPRESS_PREAMBLE) */ + +while (readl (&mac->miists) &MIISTS_BUSY ) + ;/* noop */ + +/* Issue the MII 'write' command. Wait for the command to complete. */ +writel ((uint32_t )value, &mac->miidata); +writel (MIICMD_OPCODE_WRITE | ((uint32_t )addr <<5 ) | (uint32_t )reg, + &mac->miicmd); +while (readl (&mac->miists) &MIISTS_BUSY ) + ;/* noop */ + +/* Restore the saved SelfCTL value and return. */ +writel (self_ctl, &mac->selfctl); + + ret =0 ; +/* Fall through */ + +debug ("-ep93xx_miiphy_write" ); +return ret; +} +#endif /* defined(CONFIG_MII) */ drivers/net/ep93xx.h new file +54
-0@@ -0,0 +1,145 @@ +/* +* Copyright (C) 2009 Matthias Kaehlcke <[email protected]> +* +* Copyright (C) 2004, 2005 +* Cory T. Tusar, Videon Central, Inc., <[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 _ETH_H +#define _ETH_H + +#include <net.h> + +/** +* #define this to dump device status and queue info during initialization and +* following errors. +*/ +#undef EP93XX_MAC_DEBUG + +/** +* Number of descriptor and status entries in our RX queues. +* It must be power of 2 ! +*/ +#define NUMRXDESC PKTBUFSRX + +/** +* Number of descriptor and status entries in our TX queues. +*/ +#define NUMTXDESC 1 + +/** +* 944 = (1024 - 64) - 16, Fifo size - Minframesize - 16 (Chip FACT) +*/ +#define TXSTARTMAX 944 + +/**
Quoted 8 lines
drivers/net/ep93xx.h line 60
Quoted 7 lines
drivers/net/ep93xx.h new file +6
-0+* Receive descriptor queue entry +*/ +struct rx_descriptor { +uint32_t word1; +uint32_t word2; +} __attribute__((packed));Why do you need to pack 32-bit integers?
you're right, that's superfluous
Quoted 91 lines
Quoted 91 lines
drivers/net/ep93xx.h new file +85
-0+ +/** +* Receive status queue entry +*/ +struct rx_status { +uint32_t word1; +uint32_t word2; +} __attribute__((packed)); + +#define RX_STATUS_RWE (rx_status) ((rx_status->word1 >> 30) & 0x01) +#define RX_STATUS_RFP (rx_status) ((rx_status->word1 >> 31) & 0x01) +#define RX_STATUS_FRAME_LEN (rx_status) (rx_status->word2 & 0xFFFF) + + +/** +* Transmit descriptor queue entry +*/ +struct tx_descriptor { +uint32_t word1; +uint32_t word2; +} __attribute__((packed)); + +#define TX_DESC_EOF (1 << 31) + +/** +* Transmit status queue entry +*/ +struct tx_status { +uint32_t word1; +} __attribute__((packed)); + +#define TX_STATUS_TXWE (tx_status) (((tx_status)->word1 >> 30) & 0x01) +#define TX_STATUS_TXFP (tx_status) (((tx_status)->word1 >> 31) & 0x01) + +/** +* Transmit descriptor queue +*/ +struct tx_descriptor_queue { +struct tx_descriptor *base; +struct tx_descriptor *current; +struct tx_descriptor *end; +}; + +/** +* Transmit status queue +*/ +struct tx_status_queue { +struct tx_status *base; +volatile struct tx_status *current; +struct tx_status *end; +}; + +/** +* Receive descriptor queue +*/ +struct rx_descriptor_queue { +struct rx_descriptor *base; +struct rx_descriptor *current; +struct rx_descriptor *end; +}; + +/** +* Receive status queue +*/ +struct rx_status_queue { +struct rx_status *base; +volatile struct rx_status *current; +struct rx_status *end; +}; + +/** +* EP93xx MAC private data structure +*/ +struct ep93xx_mac { +int is_initialized; + +struct rx_descriptor_queue rx_dq; +struct rx_status_queue rx_sq; +void *rx_buffer[NUMRXDESC ]; + +struct tx_descriptor_queue tx_dq; +struct tx_status_queue tx_sq; +}; + +#endif include/common.h +0
-0@@ -123,6 +123,11 @@ typedef volatile unsigned char vu_char; #define debugX(level,fmt,args...)
Quoted 8 lines
include/common.h typedef volatile unsigned char vu_char;
Quoted 7 lines
include/common.h +4
-0#endif /* DEBUG */ +#define error(fmt, args...) do { \ + printf("ERROR: " fmt "\nat %s:%d/%s()\n", \ + ##args, __FILE__, __LINE__, __func__); \ +} while (0) +Is this really needed?
before i had a private macro defined in the driver, but i was told to use the macros in common.h instead. for the error case no such macro existed, so i created one.
i wondered if it would be interesting to add a set of macros like pr_debug, pr_info, ... in the linux kernel
Quoted 8 lines
Quoted 8 lines
include/common.h +0
-1#ifndef BUG #define BUG () do { \ printf("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __FUNCTION__); \@@ -502,7 +507,8 @@ ulong get_PCI_freq (void);#endif #if defined(CONFIG_S3C24X0) || \ defined(CONFIG_LH7A40X) || \ - defined(CONFIG_S3C6400 )
Quoted 8 lines
include/common.h ulong get_PCI_freq (void); · line 514
Quoted 6 lines
include/common.h +2
-0+defined (CONFIG_S3C6400 ) || \ + defined(CONFIG_EP93XX)ulong get_FCLK (void );ulong get_HCLK (void );ulong get_PCLK (void );I don't see these referenced anywhere. How do they apply to this driver?
oops, amended to the wrong patch
thanks for pointing it out
Quoted 4 lines
Quoted 4 lines
include/netdev.h +0
-0
Quoted 8 lines
include/netdev.h int davinci_emac_initialize(void); · line 55
Quoted 8 lines
include/netdev.h +1
-0@@ -49,6 +49,7 @@ int davinci_emac_initialize(void);int dnet_eth_initialize (int id,void *regs,unsigned int phy_addr);int e1000_initialize (bd_t *bis);int eepro100_initialize (bd_t *bis); +int ep93xx_eth_init (bd_t *const bd);int eth_3com_initialize (bd_t * bis);int fec_initialize (bd_t *bis);int fecmxc_initialize (bd_t *bis);
thanks again for your helpful comments, i'll address them in the next revision of the patch
best regards
Signature · 10 lines
Matthias Kaehlcke
Embedded Linux Developer
Barcelona
The assumption that what currently exists must necessarily
exist is the acid that corrodes all visionary thinking
.''`.
using free software / Debian GNU/Linux | http://debian.org : :' :
`. `'`
gpg --keyserver pgp.mit.edu --recv-keys 47D8E5D4 `-PATCH 3/3 Add support for EDB93xx boards
In reply to a message not in the archiveAdded support for the following EDB93xx boards:
EDB9301
EDB9302
EDB9302A
EDB9307
EDB9307A
EDB93012
EDB9315
EDB9315A
--- MAINTAINERS | 10 ++ MAKEALL | 8 ++ Makefile | 10 ++ board/edb93xx/Makefile | 50 ++++++++ board/edb93xx/config.mk | 33 +++++ board/edb93xx/early_udelay.h | 34 +++++ board/edb93xx/edb93xx.c | 111 +++++++++++++++++ board/edb93xx/flash_cfg.c | 38 ++++++ board/edb93xx/pll_cfg.c | 58 +++++++++ board/edb93xx/pll_cfg.h | 72 +++++++++++ board/edb93xx/sdram_cfg.c | 117 ++++++++++++++++++ board/edb93xx/sdram_cfg.h | 144 ++++++++++++++++++++++ include/configs/edb93xx.h | 273 ++++++++++++++++++++++++++++++++++++++++++ 13 files changed, 958 insertions(+), 0 deletions(-) create mode 100644 board/edb93xx/Makefile create mode 100644 board/edb93xx/config.mk create mode 100644 board/edb93xx/early_udelay.h create mode 100644 board/edb93xx/edb93xx.c create mode 100644 board/edb93xx/flash_cfg.c create mode 100644 board/edb93xx/pll_cfg.c create mode 100644 board/edb93xx/pll_cfg.h create mode 100644 board/edb93xx/sdram_cfg.c create mode 100644 board/edb93xx/sdram_cfg.h create mode 100644 include/configs/edb93xx.h
MAINTAINERS +10 -0
@@ -598,6 +598,16 @@ Gary Jennejohn <[email protected]> smdk2400 ARM920T trab ARM920T +Matthias Kaehlcke <[email protected]> + edb9301 ARM920T (EP9301) + edb9302 ARM920T (EP9302) + edb9302a ARM920T (EP9302) + edb9307 ARM920T (EP9307) + edb9307a ARM920T (EP9307) + edb9312 ARM920T (EP9312) + edb9315 ARM920T (EP9315) + edb9315a ARM920T (EP9315) + Konstantin Kletschke <[email protected]> scb9328 ARM920T
MAKEALL +8 -0
@@ -554,6 +554,14 @@ LIST_ARM9=" \ cp946es \ cp966 \ da830evm \ + edb9301 \ + edb9302 \ + edb9302a \ + edb9307 \ + edb9307a \ + edb9312 \ + edb9315 \ + edb9315a \ imx27lite \ lpd7a400 \ mv88f6281gtw_ge \
Makefile +10 -0
@@ -2404,6 +2404,16 @@ caddy2_config \ vme8349_config: unconfig @$(MKCONFIG) -t $(@:_config=) vme8349 ppc mpc83xx vme8349 esd +edb9301_config \ +edb9302_config \ +edb9302a_config \ +edb9307_config \ +edb9307a_config \ +edb9312_config \ +edb9315_config \ +edb9315a_config: unconfig + @$(MKCONFIG) -t $(@:_config=) edb93xx arm arm920t edb93xx NULL ep93xx + ######################################################################### ## MPC85xx Systems #########################################################################
board/edb93xx/Makefile new file +50 -0
50 lines not on this page · raw message
board/edb93xx/config.mk new file +33 -0
@@ -0,0 +1,33 @@ +LDSCRIPT := $(SRCTREE)/cpu/arm920t/ep93xx/u-boot.lds + +ifdef CONFIG_EDB9301 +TEXT_BASE = 0x05700000 +endif + +ifdef CONFIG_EDB9302 +TEXT_BASE = 0x05700000 +endif + +ifdef CONFIG_EDB9302A +TEXT_BASE = 0xc5700000 +endif + +ifdef CONFIG_EDB9307 +TEXT_BASE = 0x01f00000 +endif + +ifdef CONFIG_EDB9307A +TEXT_BASE = 0xc1f00000 +endif + +ifdef CONFIG_EDB9312 +TEXT_BASE = 0x01f00000 +endif + +ifdef CONFIG_EDB9315 +TEXT_BASE = 0x01f00000 +endif + +ifdef CONFIG_EDB9315A +TEXT_BASE = 0xc1f00000 +endif
board/edb93xx/early_udelay.h new file +34 -0
@@ -0,0 +1,34 @@ +/* +* Copyright (C) 2009 Matthias Kaehlcke <[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> + +/* delay execution before timers are initialized */ +static inline void early_udelay (uint32_t usecs) +{ +/* loop takes 4 cycles at 5.0ns (fastest case, running at 200MHz) */ + registeruint32_t loops = (usecs *1000 ) /20 ; + + __asm__volatile ("1:\n" +"subs %0, %1, #1\n" +"bne 1b" :"=r" (loops):"0" (loops)); +}
board/edb93xx/edb93xx.c new file +111 -0
111 lines not on this page · raw message
board/edb93xx/flash_cfg.c new file +38 -0
@@ -0,0 +1,38 @@ +/* +* Flash setup for Cirrus edb93xx boards +* +* Copyright (C) 2009 Matthias Kaehlcke <[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 <asm/arch/ep93xx.h> +#include <asm/io.h> + +#define SMC_BCR6_VALUE (2 << SMC_BCR_IDCY_SHIFT | 5 << SMC_BCR_WST1_SHIFT | \ + SMC_BCR_BLE | 2 << SMC_BCR_WST2_SHIFT | \ + 1 << SMC_BCR_MW_SHIFT) + +void flash_cfg (void ) +{ +struct smc_regs *smc = (struct smc_regs *)SMC_BASE ; + +writel (SMC_BCR6_VALUE , &smc->bcr6); +}
board/edb93xx/pll_cfg.c new file +58 -0
58 lines not on this page · raw message
board/edb93xx/pll_cfg.h new file +72 -0
72 lines not on this page · raw message
board/edb93xx/sdram_cfg.c new file +117 -0
117 lines not on this page · raw message
board/edb93xx/sdram_cfg.h new file +144 -0
144 lines not on this page · raw message
include/configs/edb93xx.h new file +273 -0
273 lines not on this page · raw message
Signature · 1 line
1.6.3.1
PATCH 3/3 Add support for EDB93xx boards
Dear Matthias Kaehlcke,
Quoted 10 lines · In message <20100119191627.GM16182@darwin> you wrote:
Added support for the following EDB93xx boards:
EDB9301
EDB9302
EDB9302A
EDB9307
EDB9307A
EDB93012
EDB9315
EDB9315A
...
board/edb93xx/edb93xx.c line 49
Quoted 3 lines
board/edb93xx/edb93xx.c new file +3
-0+int board_init (void ) +{ +DECLARE_GLOBAL_DATA_PTR ;
This is bound to fail. DECLARE_GLOBAL_DATA_PTR must be on file level, never at function level! Fix globally!
board/edb93xx/edb93xx.c line 67
Quoted 2 lines
board/edb93xx/edb93xx.c new file +2
-0+/* Machine number, as defined in linux/arch/arm/tools/mach-types */ + gd->bd->bi_arch_number =MACH_TYPE ;
Please use CONFIG_MACH_TYPE instead (fix globally).
...
board/edb93xx/edb93xx.c line 108
Quoted 5 lines
board/edb93xx/edb93xx.c new file +5
-0+/* copy exception vectors */ + src = (unsigned int *)_armboot_start; + +for (i =0 ; i <16 ; i++) + *dst++ = *src++;
Any reason for not using memcpy() ?
include/configs/edb93xx.h line 2
Quoted 8 lines
include/configs/edb93xx.h new file +2
-0@@ -0,0 +1,273 @@ +/* +*/
Please add valid file header.
Best regards,
Wolfgang Denk
Signature · 5 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de Doubt is a pain too lonely to know that faith is his twin brother. - Kahlil Gibran