From 4c52783b3d024e153c4972b97332e314bc3bdc46 Mon Sep 17 00:00:00 2001 From: roy zang Date: Thu, 2 Nov 2006 18:49:51 +0800 Subject: General code modification for mpc7448hpc2 board support. 1. Add 7447A and 7448 processor support. 2. Add the following flags. CFG_CONFIG_BUS_CLK : If the 74xx bus frequency can be configured dynamically (such as by switch on board), this flag should be set. CFG_EXCEPTION_AFTER_RELOCATE: If an exception occurs after the u-boot relocates to RAM, this flag should be set. CFG_SERIAL_HANG_IN_EXCEPTION: If the print out function will cause the system hang in exception, this flag should be set. There is a design issue for tsi108/109 pci configure read. When pci scan the slots, if there is no pci card, the tsi108/9 will cause a machine check exception for mpc7448 processor. Signed-off-by: Alexandre Bounine Signed-off-by: Roy Zang --- drivers/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/Makefile b/drivers/Makefile index 5a369df..6a3ea5d 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -35,8 +35,8 @@ COBJS = 3c589.o 5701rls.o ali512x.o atmel_usart.o \ lan91c96.o \ natsemi.o ne2000.o netarm_eth.o netconsole.o \ ns16550.o ns8382x.o ns87308.o ns7520_eth.o omap1510_i2c.o \ - omap24xx_i2c.o pci.o pci_auto.o pci_indirect.o \ - pcnet.o plb2800_eth.o \ + omap24xx_i2c.o pci.o pci_auto.o pci_indirect.o tsi108_pci.o\ + tsi108_i2c.o pcnet.o plb2800_eth.o \ ps2ser.o ps2mult.o pc_keyb.o \ rtl8019.o rtl8139.o rtl8169.o \ s3c4510b_eth.o s3c4510b_uart.o \ @@ -45,7 +45,7 @@ COBJS = 3c589.o 5701rls.o ali512x.o atmel_usart.o \ serial_pl010.o serial_pl011.o serial_xuartlite.o \ sl811_usb.o sm501.o smc91111.o smiLynxEM.o \ status_led.o sym53c8xx.o ahci.o \ - ti_pci1410a.o tigon3.o tsec.o \ + ti_pci1410a.o tigon3.o tsec.o tsi108_eth.o\ usbdcore.o usbdcore_ep0.o usbdcore_omap1510.o usbtty.o \ videomodes.o w83c553f.o \ ks8695eth.o \ -- cgit v1.1 From d1927cee977126e547ceeba23e4f978f377cfb8f Mon Sep 17 00:00:00 2001 From: roy zang Date: Thu, 2 Nov 2006 19:08:55 +0800 Subject: Tundra tsi108 on chip Ethernet controller support. The following is a brief description of the Ethernet controller: The Tsi108/9 Ethernet Controller connects Switch Fabric to two independent Gigabit Ethernet ports,E0 and E1. It uses a single Management interface to manage the two physical connection devices (PHYs). Each Ethernet port has its own statistics monitor that tracks and reports key interface statistics. Each port supports a 256-entry hash table for address filtering. In addition, each port is bridged to the Switch Fabric through a 2-Kbyte transmit FIFO and a 4-Kbyte Receive FIFO. Each Ethernet port also has a pair of internal Ethernet DMA channels to support the transmit and receive data flows. The Ethernet DMA channels use descriptors set up in memory, the memory map of the device, and access via the Switch Fabric. The Ethernet Controller?s DMA arbiter handles arbitration for the Switch Fabric. The Controller also has a register businterface for register accesses and status monitor control. The PMD (Physical Media Device) interface operates in MII, GMII, or TBI modes. The MII mode is used for connecting with 10 or 100 Mbit/s PMDs. The GMII and TBI modes are used to connect with Gigabit PMDs. Internal data flows to and from the Ethernet Controller through the Switch Fabric. Each Ethernet port uses its transmit and receive DMA channels to manage data flows through buffer descriptors that are predefined by the system (the descriptors can exist anywhere in the system memory map). These descriptors are data structures that point to buffers filled with data ready to transmit over Ethernet, or they point to empty buffers ready to receive data from Ethernet. Signed-off-by: Alexandre Bounine Signed-off-by: Roy Zang --- drivers/tsi108_eth.c | 1043 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1043 insertions(+) create mode 100644 drivers/tsi108_eth.c (limited to 'drivers') diff --git a/drivers/tsi108_eth.c b/drivers/tsi108_eth.c new file mode 100644 index 0000000..d95a047 --- /dev/null +++ b/drivers/tsi108_eth.c @@ -0,0 +1,1043 @@ +/*********************************************************************** + * + * Copyright (c) 2005 Freescale Semiconductor, Inc. + * + * 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 + * + * Description: + * Ethernet interface for Tundra TSI108 bridge chip + * + ***********************************************************************/ + +#include + +#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) \ + && defined(CONFIG_TSI108_ETH) + +#if !defined(CONFIG_TSI108_ETH_NUM_PORTS) || (CONFIG_TSI108_ETH_NUM_PORTS > 2) +#error "CONFIG_TSI108_ETH_NUM_PORTS must be defined as 1 or 2" +#endif + +#include +#include +#include +#include + +#ifdef DEBUG +#define TSI108_ETH_DEBUG 7 +#else +#define TSI108_ETH_DEBUG 0 +#endif + +#if TSI108_ETH_DEBUG > 0 +#define debug_lev(lev, fmt, args...) if (lev <= TSI108_ETH_DEBUG) printf("%s %d: " fmt, __FUNCTION__, __LINE__, ##args) +#else +#define debug_lev(lev, fmt, args...) do{}while(0) +#endif + +#define RX_PRINT_ERRORS +#define TX_PRINT_ERRORS + +#define ETH_BASE (CFG_TSI108_CSR_BASE + 0x6000) + +#define ETH_PORT_OFFSET 0x400 + +#define __REG32(base, offset) (*((volatile u32 *)((char *)(base) + (offset)))) + +#define reg_MAC_CONFIG_1(base) __REG32(base, 0x00000000) +#define MAC_CONFIG_1_TX_ENABLE (0x00000001) +#define MAC_CONFIG_1_SYNC_TX_ENABLE (0x00000002) +#define MAC_CONFIG_1_RX_ENABLE (0x00000004) +#define MAC_CONFIG_1_SYNC_RX_ENABLE (0x00000008) +#define MAC_CONFIG_1_TX_FLOW_CONTROL (0x00000010) +#define MAC_CONFIG_1_RX_FLOW_CONTROL (0x00000020) +#define MAC_CONFIG_1_LOOP_BACK (0x00000100) +#define MAC_CONFIG_1_RESET_TX_FUNCTION (0x00010000) +#define MAC_CONFIG_1_RESET_RX_FUNCTION (0x00020000) +#define MAC_CONFIG_1_RESET_TX_MAC (0x00040000) +#define MAC_CONFIG_1_RESET_RX_MAC (0x00080000) +#define MAC_CONFIG_1_SIM_RESET (0x40000000) +#define MAC_CONFIG_1_SOFT_RESET (0x80000000) + +#define reg_MAC_CONFIG_2(base) __REG32(base, 0x00000004) +#define MAC_CONFIG_2_FULL_DUPLEX (0x00000001) +#define MAC_CONFIG_2_CRC_ENABLE (0x00000002) +#define MAC_CONFIG_2_PAD_CRC (0x00000004) +#define MAC_CONFIG_2_LENGTH_CHECK (0x00000010) +#define MAC_CONFIG_2_HUGE_FRAME (0x00000020) +#define MAC_CONFIG_2_INTERFACE_MODE(val) (((val) & 0x3) << 8) +#define MAC_CONFIG_2_PREAMBLE_LENGTH(val) (((val) & 0xf) << 12) +#define INTERFACE_MODE_NIBBLE 1 /* 10/100 Mb/s MII) */ +#define INTERFACE_MODE_BYTE 2 /* 1000 Mb/s GMII/TBI */ + +#define reg_MAXIMUM_FRAME_LENGTH(base) __REG32(base, 0x00000010) + +#define reg_MII_MGMT_CONFIG(base) __REG32(base, 0x00000020) +#define MII_MGMT_CONFIG_MGMT_CLOCK_SELECT(val) ((val) & 0x7) +#define MII_MGMT_CONFIG_NO_PREAMBLE (0x00000010) +#define MII_MGMT_CONFIG_SCAN_INCREMENT (0x00000020) +#define MII_MGMT_CONFIG_RESET_MGMT (0x80000000) + +#define reg_MII_MGMT_COMMAND(base) __REG32(base, 0x00000024) +#define MII_MGMT_COMMAND_READ_CYCLE (0x00000001) +#define MII_MGMT_COMMAND_SCAN_CYCLE (0x00000002) + +#define reg_MII_MGMT_ADDRESS(base) __REG32(base, 0x00000028) +#define reg_MII_MGMT_CONTROL(base) __REG32(base, 0x0000002c) +#define reg_MII_MGMT_STATUS(base) __REG32(base, 0x00000030) + +#define reg_MII_MGMT_INDICATORS(base) __REG32(base, 0x00000034) +#define MII_MGMT_INDICATORS_BUSY (0x00000001) +#define MII_MGMT_INDICATORS_SCAN (0x00000002) +#define MII_MGMT_INDICATORS_NOT_VALID (0x00000004) + +#define reg_INTERFACE_STATUS(base) __REG32(base, 0x0000003c) +#define INTERFACE_STATUS_LINK_FAIL (0x00000008) +#define INTERFACE_STATUS_EXCESS_DEFER (0x00000200) + +#define reg_STATION_ADDRESS_1(base) __REG32(base, 0x00000040) +#define reg_STATION_ADDRESS_2(base) __REG32(base, 0x00000044) + +#define reg_PORT_CONTROL(base) __REG32(base, 0x00000200) +#define PORT_CONTROL_PRI (0x00000001) +#define PORT_CONTROL_BPT (0x00010000) +#define PORT_CONTROL_SPD (0x00040000) +#define PORT_CONTROL_RBC (0x00080000) +#define PORT_CONTROL_PRB (0x00200000) +#define PORT_CONTROL_DIS (0x00400000) +#define PORT_CONTROL_TBI (0x00800000) +#define PORT_CONTROL_STE (0x10000000) +#define PORT_CONTROL_ZOR (0x20000000) +#define PORT_CONTROL_CLR (0x40000000) +#define PORT_CONTROL_SRT (0x80000000) + +#define reg_TX_CONFIG(base) __REG32(base, 0x00000220) +#define TX_CONFIG_START_Q (0x00000003) +#define TX_CONFIG_EHP (0x00400000) +#define TX_CONFIG_CHP (0x00800000) +#define TX_CONFIG_RST (0x80000000) + +#define reg_TX_CONTROL(base) __REG32(base, 0x00000224) +#define TX_CONTROL_GO (0x00008000) +#define TX_CONTROL_MP (0x01000000) +#define TX_CONTROL_EAI (0x20000000) +#define TX_CONTROL_ABT (0x40000000) +#define TX_CONTROL_EII (0x80000000) + +#define reg_TX_STATUS(base) __REG32(base, 0x00000228) +#define TX_STATUS_QUEUE_USABLE (0x0000000f) +#define TX_STATUS_CURR_Q (0x00000300) +#define TX_STATUS_ACT (0x00008000) +#define TX_STATUS_QUEUE_IDLE (0x000f0000) +#define TX_STATUS_EOQ_PENDING (0x0f000000) + +#define reg_TX_EXTENDED_STATUS(base) __REG32(base, 0x0000022c) +#define TX_EXTENDED_STATUS_END_OF_QUEUE_CONDITION (0x0000000f) +#define TX_EXTENDED_STATUS_END_OF_FRAME_CONDITION (0x00000f00) +#define TX_EXTENDED_STATUS_DESCRIPTOR_INTERRUPT_CONDITION (0x000f0000) +#define TX_EXTENDED_STATUS_ERROR_FLAG (0x0f000000) + +#define reg_TX_THRESHOLDS(base) __REG32(base, 0x00000230) + +#define reg_TX_DIAGNOSTIC_ADDR(base) __REG32(base, 0x00000270) +#define TX_DIAGNOSTIC_ADDR_INDEX (0x0000007f) +#define TX_DIAGNOSTIC_ADDR_DFR (0x40000000) +#define TX_DIAGNOSTIC_ADDR_AI (0x80000000) + +#define reg_TX_DIAGNOSTIC_DATA(base) __REG32(base, 0x00000274) + +#define reg_TX_ERROR_STATUS(base) __REG32(base, 0x00000278) +#define TX_ERROR_STATUS (0x00000278) +#define TX_ERROR_STATUS_QUEUE_0_ERROR_RESPONSE (0x0000000f) +#define TX_ERROR_STATUS_TEA_ON_QUEUE_0 (0x00000010) +#define TX_ERROR_STATUS_RER_ON_QUEUE_0 (0x00000020) +#define TX_ERROR_STATUS_TER_ON_QUEUE_0 (0x00000040) +#define TX_ERROR_STATUS_DER_ON_QUEUE_0 (0x00000080) +#define TX_ERROR_STATUS_QUEUE_1_ERROR_RESPONSE (0x00000f00) +#define TX_ERROR_STATUS_TEA_ON_QUEUE_1 (0x00001000) +#define TX_ERROR_STATUS_RER_ON_QUEUE_1 (0x00002000) +#define TX_ERROR_STATUS_TER_ON_QUEUE_1 (0x00004000) +#define TX_ERROR_STATUS_DER_ON_QUEUE_1 (0x00008000) +#define TX_ERROR_STATUS_QUEUE_2_ERROR_RESPONSE (0x000f0000) +#define TX_ERROR_STATUS_TEA_ON_QUEUE_2 (0x00100000) +#define TX_ERROR_STATUS_RER_ON_QUEUE_2 (0x00200000) +#define TX_ERROR_STATUS_TER_ON_QUEUE_2 (0x00400000) +#define TX_ERROR_STATUS_DER_ON_QUEUE_2 (0x00800000) +#define TX_ERROR_STATUS_QUEUE_3_ERROR_RESPONSE (0x0f000000) +#define TX_ERROR_STATUS_TEA_ON_QUEUE_3 (0x10000000) +#define TX_ERROR_STATUS_RER_ON_QUEUE_3 (0x20000000) +#define TX_ERROR_STATUS_TER_ON_QUEUE_3 (0x40000000) +#define TX_ERROR_STATUS_DER_ON_QUEUE_3 (0x80000000) + +#define reg_TX_QUEUE_0_CONFIG(base) __REG32(base, 0x00000280) +#define TX_QUEUE_0_CONFIG_OCN_PORT (0x0000003f) +#define TX_QUEUE_0_CONFIG_BSWP (0x00000400) +#define TX_QUEUE_0_CONFIG_WSWP (0x00000800) +#define TX_QUEUE_0_CONFIG_AM (0x00004000) +#define TX_QUEUE_0_CONFIG_GVI (0x00008000) +#define TX_QUEUE_0_CONFIG_EEI (0x00010000) +#define TX_QUEUE_0_CONFIG_ELI (0x00020000) +#define TX_QUEUE_0_CONFIG_ENI (0x00040000) +#define TX_QUEUE_0_CONFIG_ESI (0x00080000) +#define TX_QUEUE_0_CONFIG_EDI (0x00100000) + +#define reg_TX_QUEUE_0_BUF_CONFIG(base) __REG32(base, 0x00000284) +#define TX_QUEUE_0_BUF_CONFIG_OCN_PORT (0x0000003f) +#define TX_QUEUE_0_BUF_CONFIG_BURST (0x00000300) +#define TX_QUEUE_0_BUF_CONFIG_BSWP (0x00000400) +#define TX_QUEUE_0_BUF_CONFIG_WSWP (0x00000800) + +#define OCN_PORT_HLP 0 /* HLP Interface */ +#define OCN_PORT_PCI_X 1 /* PCI-X Interface */ +#define OCN_PORT_PROCESSOR_MASTER 2 /* Processor Interface (master) */ +#define OCN_PORT_PROCESSOR_SLAVE 3 /* Processor Interface (slave) */ +#define OCN_PORT_MEMORY 4 /* Memory Controller */ +#define OCN_PORT_DMA 5 /* DMA Controller */ +#define OCN_PORT_ETHERNET 6 /* Ethernet Controller */ +#define OCN_PORT_PRINT 7 /* Print Engine Interface */ + +#define reg_TX_QUEUE_0_PTR_LOW(base) __REG32(base, 0x00000288) + +#define reg_TX_QUEUE_0_PTR_HIGH(base) __REG32(base, 0x0000028c) +#define TX_QUEUE_0_PTR_HIGH_VALID (0x80000000) + +#define reg_RX_CONFIG(base) __REG32(base, 0x00000320) +#define RX_CONFIG_DEF_Q (0x00000003) +#define RX_CONFIG_EMF (0x00000100) +#define RX_CONFIG_EUF (0x00000200) +#define RX_CONFIG_BFE (0x00000400) +#define RX_CONFIG_MFE (0x00000800) +#define RX_CONFIG_UFE (0x00001000) +#define RX_CONFIG_SE (0x00002000) +#define RX_CONFIG_ABF (0x00200000) +#define RX_CONFIG_APE (0x00400000) +#define RX_CONFIG_CHP (0x00800000) +#define RX_CONFIG_RST (0x80000000) + +#define reg_RX_CONTROL(base) __REG32(base, 0x00000324) +#define GE_E0_RX_CONTROL_QUEUE_ENABLES (0x0000000f) +#define GE_E0_RX_CONTROL_GO (0x00008000) +#define GE_E0_RX_CONTROL_EAI (0x20000000) +#define GE_E0_RX_CONTROL_ABT (0x40000000) +#define GE_E0_RX_CONTROL_EII (0x80000000) + +#define reg_RX_EXTENDED_STATUS(base) __REG32(base, 0x0000032c) +#define RX_EXTENDED_STATUS (0x0000032c) +#define RX_EXTENDED_STATUS_EOQ (0x0000000f) +#define RX_EXTENDED_STATUS_EOQ_0 (0x00000001) +#define RX_EXTENDED_STATUS_EOF (0x00000f00) +#define RX_EXTENDED_STATUS_DESCRIPTOR_INTERRUPT_CONDITION (0x000f0000) +#define RX_EXTENDED_STATUS_ERROR_FLAG (0x0f000000) + +#define reg_RX_THRESHOLDS(base) __REG32(base, 0x00000330) + +#define reg_RX_DIAGNOSTIC_ADDR(base) __REG32(base, 0x00000370) +#define RX_DIAGNOSTIC_ADDR_INDEX (0x0000007f) +#define RX_DIAGNOSTIC_ADDR_DFR (0x40000000) +#define RX_DIAGNOSTIC_ADDR_AI (0x80000000) + +#define reg_RX_DIAGNOSTIC_DATA(base) __REG32(base, 0x00000374) + +#define reg_RX_QUEUE_0_CONFIG(base) __REG32(base, 0x00000380) +#define RX_QUEUE_0_CONFIG_OCN_PORT (0x0000003f) +#define RX_QUEUE_0_CONFIG_BSWP (0x00000400) +#define RX_QUEUE_0_CONFIG_WSWP (0x00000800) +#define RX_QUEUE_0_CONFIG_AM (0x00004000) +#define RX_QUEUE_0_CONFIG_EEI (0x00010000) +#define RX_QUEUE_0_CONFIG_ELI (0x00020000) +#define RX_QUEUE_0_CONFIG_ENI (0x00040000) +#define RX_QUEUE_0_CONFIG_ESI (0x00080000) +#define RX_QUEUE_0_CONFIG_EDI (0x00100000) + +#define reg_RX_QUEUE_0_BUF_CONFIG(base) __REG32(base, 0x00000384) +#define RX_QUEUE_0_BUF_CONFIG_OCN_PORT (0x0000003f) +#define RX_QUEUE_0_BUF_CONFIG_BURST (0x00000300) +#define RX_QUEUE_0_BUF_CONFIG_BSWP (0x00000400) +#define RX_QUEUE_0_BUF_CONFIG_WSWP (0x00000800) + +#define reg_RX_QUEUE_0_PTR_LOW(base) __REG32(base, 0x00000388) + +#define reg_RX_QUEUE_0_PTR_HIGH(base) __REG32(base, 0x0000038c) +#define RX_QUEUE_0_PTR_HIGH_VALID (0x80000000) + +/* + * PHY register definitions + */ +/* the first 15 PHY registers are standard. */ +#define PHY_CTRL_REG 0 /* Control Register */ +#define PHY_STATUS_REG 1 /* Status Regiser */ +#define PHY_ID1_REG 2 /* Phy Id Reg (word 1) */ +#define PHY_ID2_REG 3 /* Phy Id Reg (word 2) */ +#define PHY_AN_ADV_REG 4 /* Autoneg Advertisement */ +#define PHY_LP_ABILITY_REG 5 /* Link Partner Ability (Base Page) */ +#define PHY_AUTONEG_EXP_REG 6 /* Autoneg Expansion Reg */ +#define PHY_NEXT_PAGE_TX_REG 7 /* Next Page TX */ +#define PHY_LP_NEXT_PAGE_REG 8 /* Link Partner Next Page */ +#define PHY_1000T_CTRL_REG 9 /* 1000Base-T Control Reg */ +#define PHY_1000T_STATUS_REG 10 /* 1000Base-T Status Reg */ +#define PHY_EXT_STATUS_REG 11 /* Extended Status Reg */ + +/* + * PHY Register bit masks. + */ +#define PHY_CTRL_RESET (1 << 15) +#define PHY_CTRL_LOOPBACK (1 << 14) +#define PHY_CTRL_SPEED0 (1 << 13) +#define PHY_CTRL_AN_EN (1 << 12) +#define PHY_CTRL_PWR_DN (1 << 11) +#define PHY_CTRL_ISOLATE (1 << 10) +#define PHY_CTRL_RESTART_AN (1 << 9) +#define PHY_CTRL_FULL_DUPLEX (1 << 8) +#define PHY_CTRL_CT_EN (1 << 7) +#define PHY_CTRL_SPEED1 (1 << 6) + +#define PHY_STAT_100BASE_T4 (1 << 15) +#define PHY_STAT_100BASE_X_FD (1 << 14) +#define PHY_STAT_100BASE_X_HD (1 << 13) +#define PHY_STAT_10BASE_T_FD (1 << 12) +#define PHY_STAT_10BASE_T_HD (1 << 11) +#define PHY_STAT_100BASE_T2_FD (1 << 10) +#define PHY_STAT_100BASE_T2_HD (1 << 9) +#define PHY_STAT_EXT_STAT (1 << 8) +#define PHY_STAT_RESERVED (1 << 7) +#define PHY_STAT_MFPS (1 << 6) /* Management Frames Preamble Suppression */ +#define PHY_STAT_AN_COMPLETE (1 << 5) +#define PHY_STAT_REM_FAULT (1 << 4) +#define PHY_STAT_AN_CAP (1 << 3) +#define PHY_STAT_LINK_UP (1 << 2) +#define PHY_STAT_JABBER (1 << 1) +#define PHY_STAT_EXT_CAP (1 << 0) + +#define TBI_CONTROL_2 0x11 +#define TBI_CONTROL_2_ENABLE_COMMA_DETECT 0x0001 +#define TBI_CONTROL_2_ENABLE_WRAP 0x0002 +#define TBI_CONTROL_2_G_MII_MODE 0x0010 +#define TBI_CONTROL_2_RECEIVE_CLOCK_SELECT 0x0020 +#define TBI_CONTROL_2_AUTO_NEGOTIATION_SENSE 0x0100 +#define TBI_CONTROL_2_DISABLE_TRANSMIT_RUNNING_DISPARITY 0x1000 +#define TBI_CONTROL_2_DISABLE_RECEIVE_RUNNING_DISPARITY 0x2000 +#define TBI_CONTROL_2_SHORTCUT_LINK_TIMER 0x4000 +#define TBI_CONTROL_2_SOFT_RESET 0x8000 + +/* marvel specific */ +#define MV1111_EXT_CTRL1_REG 16 /* PHY Specific Control Reg */ +#define MV1111_SPEC_STAT_REG 17 /* PHY Specific Status Reg */ +#define MV1111_EXT_CTRL2_REG 20 /* Extended PHY Specific Control Reg */ + +/* + * MARVELL 88E1111 PHY register bit masks + */ +/* PHY Specific Status Register (MV1111_EXT_CTRL1_REG) */ + +#define SPEC_STAT_SPEED_MASK (3 << 14) +#define SPEC_STAT_FULL_DUP (1 << 13) +#define SPEC_STAT_PAGE_RCVD (1 << 12) +#define SPEC_STAT_RESOLVED (1 << 11) /* Speed and Duplex Resolved */ +#define SPEC_STAT_LINK_UP (1 << 10) +#define SPEC_STAT_CABLE_LEN_MASK (7 << 7) /* Cable Length (100/1000 modes only) */ +#define SPEC_STAT_MDIX (1 << 6) +#define SPEC_STAT_POLARITY (1 << 1) +#define SPEC_STAT_JABBER (1 << 0) + +#define SPEED_1000 (2 << 14) +#define SPEED_100 (1 << 14) +#define SPEED_10 (0 << 14) + +#define TBI_ADDR 0x1E /* Ten Bit Interface address */ + +/* negotiated link parameters */ +#define LINK_SPEED_UNKNOWN 0 +#define LINK_SPEED_10 1 +#define LINK_SPEED_100 2 +#define LINK_SPEED_1000 3 + +#define LINK_DUPLEX_UNKNOWN 0 +#define LINK_DUPLEX_HALF 1 +#define LINK_DUPLEX_FULL 2 + +static unsigned int phy_address[] = { 8, 9 }; + +#define vuint32 volatile u32 + +/* TX/RX buffer descriptors. MUST be cache line aligned in memory. (32 byte) + * This structure is accessed by the ethernet DMA engine which means it + * MUST be in LITTLE ENDIAN format */ +struct dma_descriptor { + vuint32 start_addr0; /* buffer address, least significant bytes. */ + vuint32 start_addr1; /* buffer address, most significant bytes. */ + vuint32 next_descr_addr0;/* next descriptor address, least significant bytes. Must be 64-bit aligned. */ + vuint32 next_descr_addr1;/* next descriptor address, most significant bytes. */ + vuint32 vlan_byte_count;/* VLAN tag(top 2 bytes) and byte countt (bottom 2 bytes). */ + vuint32 config_status; /* Configuration/Status. */ + vuint32 reserved1; /* reserved to make the descriptor cache line aligned. */ + vuint32 reserved2; /* reserved to make the descriptor cache line aligned. */ +}; + +/* last next descriptor address flag */ +#define DMA_DESCR_LAST (1 << 31) + +/* TX DMA descriptor config status bits */ +#define DMA_DESCR_TX_EOF (1 << 0) /* end of frame */ +#define DMA_DESCR_TX_SOF (1 << 1) /* start of frame */ +#define DMA_DESCR_TX_PFVLAN (1 << 2) +#define DMA_DESCR_TX_HUGE (1 << 3) +#define DMA_DESCR_TX_PAD (1 << 4) +#define DMA_DESCR_TX_CRC (1 << 5) +#define DMA_DESCR_TX_DESCR_INT (1 << 14) +#define DMA_DESCR_TX_RETRY_COUNT 0x000F0000 +#define DMA_DESCR_TX_ONE_COLLISION (1 << 20) +#define DMA_DESCR_TX_LATE_COLLISION (1 << 24) +#define DMA_DESCR_TX_UNDERRUN (1 << 25) +#define DMA_DESCR_TX_RETRY_LIMIT (1 << 26) +#define DMA_DESCR_TX_OK (1 << 30) +#define DMA_DESCR_TX_OWNER (1 << 31) + +/* RX DMA descriptor status bits */ +#define DMA_DESCR_RX_EOF (1 << 0) +#define DMA_DESCR_RX_SOF (1 << 1) +#define DMA_DESCR_RX_VTF (1 << 2) +#define DMA_DESCR_RX_FRAME_IS_TYPE (1 << 3) +#define DMA_DESCR_RX_SHORT_FRAME (1 << 4) +#define DMA_DESCR_RX_HASH_MATCH (1 << 7) +#define DMA_DESCR_RX_BAD_FRAME (1 << 8) +#define DMA_DESCR_RX_OVERRUN (1 << 9) +#define DMA_DESCR_RX_MAX_FRAME_LEN (1 << 11) +#define DMA_DESCR_RX_CRC_ERROR (1 << 12) +#define DMA_DESCR_RX_DESCR_INT (1 << 13) +#define DMA_DESCR_RX_OWNER (1 << 15) + +#define RX_BUFFER_SIZE PKTSIZE +#define NUM_RX_DESC PKTBUFSRX + +static struct dma_descriptor tx_descriptor __attribute__ ((aligned(32))); + +static struct dma_descriptor rx_descr_array[NUM_RX_DESC] + __attribute__ ((aligned(32))); + +static struct dma_descriptor *rx_descr_current; + +static int tsi108_eth_probe(struct eth_device *dev, bd_t * bis); +static int tsi108_eth_send(struct eth_device *dev, + volatile void *packet, int length); +static int tsi108_eth_recv(struct eth_device *dev); +static void tsi108_eth_halt(struct eth_device *dev); +static unsigned int read_phy(unsigned int base, + unsigned int phy_addr, unsigned int phy_reg); +static void write_phy(unsigned int base, + unsigned int phy_addr, + unsigned int phy_reg, unsigned int phy_data); + +#if TSI108_ETH_DEBUG > 100 +/* + * print phy debug infomation + */ +static void dump_phy_regs(unsigned int phy_addr) +{ + int i; + + printf("PHY %d registers\n", phy_addr); + for (i = 0; i <= 30; i++) { + printf("%2d 0x%04x\n", i, read_phy(ETH_BASE, phy_addr, i)); + } + printf("\n"); + +} +#else +#define dump_phy_regs(base) do{}while(0) +#endif + +#if TSI108_ETH_DEBUG > 100 +/* + * print debug infomation + */ +static void tx_diag_regs(unsigned int base) +{ + int i; + unsigned long dummy; + + printf("TX diagnostics registers\n"); + reg_TX_DIAGNOSTIC_ADDR(base) = 0x00 | TX_DIAGNOSTIC_ADDR_AI; + udelay(1000); + dummy = reg_TX_DIAGNOSTIC_DATA(base); + for (i = 0x00; i <= 0x05; i++) { + udelay(1000); + printf("0x%02x 0x%08x\n", i, reg_TX_DIAGNOSTIC_DATA(base)); + } + reg_TX_DIAGNOSTIC_ADDR(base) = 0x40 | TX_DIAGNOSTIC_ADDR_AI; + udelay(1000); + dummy = reg_TX_DIAGNOSTIC_DATA(base); + for (i = 0x40; i <= 0x47; i++) { + udelay(1000); + printf("0x%02x 0x%08x\n", i, reg_TX_DIAGNOSTIC_DATA(base)); + } + printf("\n"); + +} +#else +#define tx_diag_regs(base) do{}while(0) +#endif + +#if TSI108_ETH_DEBUG > 100 +/* + * print debug infomation + */ +static void rx_diag_regs(unsigned int base) +{ + int i; + unsigned long dummy; + + printf("RX diagnostics registers\n"); + reg_RX_DIAGNOSTIC_ADDR(base) = 0x00 | RX_DIAGNOSTIC_ADDR_AI; + udelay(1000); + dummy = reg_RX_DIAGNOSTIC_DATA(base); + for (i = 0x00; i <= 0x05; i++) { + udelay(1000); + printf("0x%02x 0x%08x\n", i, reg_RX_DIAGNOSTIC_DATA(base)); + } + reg_RX_DIAGNOSTIC_ADDR(base) = 0x40 | RX_DIAGNOSTIC_ADDR_AI; + udelay(1000); + dummy = reg_RX_DIAGNOSTIC_DATA(base); + for (i = 0x08; i <= 0x0a; i++) { + udelay(1000); + printf("0x%02x 0x%08x\n", i, reg_RX_DIAGNOSTIC_DATA(base)); + } + printf("\n"); + +} +#else +#define rx_diag_regs(base) do{}while(0) +#endif + +#if TSI108_ETH_DEBUG > 100 +/* + * print debug infomation + */ +static void debug_mii_regs(unsigned int base) +{ + printf("MII_MGMT_CONFIG 0x%08x\n", reg_MII_MGMT_CONFIG(base)); + printf("MII_MGMT_COMMAND 0x%08x\n", reg_MII_MGMT_COMMAND(base)); + printf("MII_MGMT_ADDRESS 0x%08x\n", reg_MII_MGMT_ADDRESS(base)); + printf("MII_MGMT_CONTROL 0x%08x\n", reg_MII_MGMT_CONTROL(base)); + printf("MII_MGMT_STATUS 0x%08x\n", reg_MII_MGMT_STATUS(base)); + printf("MII_MGMT_INDICATORS 0x%08x\n", reg_MII_MGMT_INDICATORS(base)); + printf("\n"); + +} +#else +#define debug_mii_regs(base) do{}while(0) +#endif + +/* + * Wait until the phy bus is non-busy + */ +static void phy_wait(unsigned int base, unsigned int condition) +{ + int timeout; + + timeout = 0; + while (reg_MII_MGMT_INDICATORS(base) & condition) { + udelay(10); + if (++timeout > 10000) { + printf("ERROR: timeout waiting for phy bus (%d)\n", + condition); + break; + } + } +} + +/* + * read phy register + */ +static unsigned int read_phy(unsigned int base, + unsigned int phy_addr, unsigned int phy_reg) +{ + unsigned int value; + + phy_wait(base, MII_MGMT_INDICATORS_BUSY); + + reg_MII_MGMT_ADDRESS(base) = (phy_addr << 8) | phy_reg; + + /* Ensure that the Read Cycle bit is cleared prior to next read cycle */ + reg_MII_MGMT_COMMAND(base) = 0; + + /* start the read */ + reg_MII_MGMT_COMMAND(base) = MII_MGMT_COMMAND_READ_CYCLE; + + /* wait for the read to complete */ + phy_wait(base, + MII_MGMT_INDICATORS_NOT_VALID | MII_MGMT_INDICATORS_BUSY); + + value = reg_MII_MGMT_STATUS(base); + + reg_MII_MGMT_COMMAND(base) = 0; + + return value; +} + +/* + * write phy register + */ +static void write_phy(unsigned int base, + unsigned int phy_addr, + unsigned int phy_reg, unsigned int phy_data) +{ + phy_wait(base, MII_MGMT_INDICATORS_BUSY); + + reg_MII_MGMT_ADDRESS(base) = (phy_addr << 8) | phy_reg; + + /* Ensure that the Read Cycle bit is cleared prior to next cycle */ + reg_MII_MGMT_COMMAND(base) = 0; + + /* start the write */ + reg_MII_MGMT_CONTROL(base) = phy_data; +} + +/* + * configure the marvell 88e1111 phy + */ +static int marvell_88e_phy_config(struct eth_device *dev, int *speed, + int *duplex) +{ + unsigned long base; + unsigned long phy_addr; + unsigned int phy_status; + unsigned int phy_spec_status; + int timeout; + int phy_speed; + int phy_duplex; + unsigned int value; + + phy_speed = LINK_SPEED_UNKNOWN; + phy_duplex = LINK_DUPLEX_UNKNOWN; + + base = dev->iobase; + phy_addr = (unsigned long)dev->priv; + + /* Take the PHY out of reset. */ + write_phy(ETH_BASE, phy_addr, PHY_CTRL_REG, PHY_CTRL_RESET); + + /* Wait for the reset process to complete. */ + udelay(10); + timeout = 0; + while ((phy_status = + read_phy(ETH_BASE, phy_addr, PHY_CTRL_REG)) & PHY_CTRL_RESET) { + udelay(10); + if (++timeout > 10000) { + printf("ERROR: timeout waiting for phy reset\n"); + break; + } + } + + /* TBI Configuration. */ + write_phy(base, TBI_ADDR, TBI_CONTROL_2, TBI_CONTROL_2_G_MII_MODE | + TBI_CONTROL_2_RECEIVE_CLOCK_SELECT); + /* Wait for the link to be established. */ + timeout = 0; + do { + udelay(20000); + phy_status = read_phy(ETH_BASE, phy_addr, PHY_STATUS_REG); + if (++timeout > 100) { + debug_lev(1, "ERROR: unable to establish link!!!\n"); + break; + } + } while ((phy_status & PHY_STAT_LINK_UP) == 0); + + if ((phy_status & PHY_STAT_LINK_UP) == 0) { + return 0; + } + + value = 0; + phy_spec_status = read_phy(ETH_BASE, phy_addr, MV1111_SPEC_STAT_REG); + if (phy_spec_status & SPEC_STAT_RESOLVED) { + switch (phy_spec_status & SPEC_STAT_SPEED_MASK) { + case SPEED_1000: + phy_speed = LINK_SPEED_1000; + value |= PHY_CTRL_SPEED1; + break; + case SPEED_100: + phy_speed = LINK_SPEED_100; + value |= PHY_CTRL_SPEED0; + break; + case SPEED_10: + phy_speed = LINK_SPEED_10; + break; + } + if (phy_spec_status & SPEC_STAT_FULL_DUP) { + phy_duplex = LINK_DUPLEX_FULL; + value |= PHY_CTRL_FULL_DUPLEX; + } else { + phy_duplex = LINK_DUPLEX_HALF; + } + } + /* set TBI speed */ + write_phy(base, TBI_ADDR, PHY_CTRL_REG, value); + write_phy(base, TBI_ADDR, PHY_AN_ADV_REG, 0x0060); + +#if TSI108_ETH_DEBUG > 0 + printf("%s link is up", dev->name); + phy_spec_status = read_phy(ETH_BASE, phy_addr, MV1111_SPEC_STAT_REG); + if (phy_spec_status & SPEC_STAT_RESOLVED) { + switch (phy_speed) { + case LINK_SPEED_1000: + printf(", 1000 Mbps"); + break; + case LINK_SPEED_100: + printf(", 100 Mbps"); + break; + case LINK_SPEED_10: + printf(", 10 Mbps"); + break; + } + if (phy_duplex == LINK_DUPLEX_FULL) { + printf(", Full duplex"); + } else { + printf(", Half duplex"); + } + } + printf("\n"); +#endif + + dump_phy_regs(TBI_ADDR); + if (speed) { + *speed = phy_speed; + } + if (duplex) { + *duplex = phy_duplex; + } + + return 1; +} + +/* + * External interface + * + * register the tsi108 ethernet controllers with the multi-ethernet system + */ +int tsi108_eth_initialize(bd_t * bis) +{ + struct eth_device *dev; + int index; + + for (index = 0; index < CONFIG_TSI108_ETH_NUM_PORTS; index++) { + dev = (struct eth_device *)malloc(sizeof(struct eth_device)); + + sprintf(dev->name, "TSI108_eth%d", index); + + dev->iobase = ETH_BASE + (index * ETH_PORT_OFFSET); + dev->priv = (void *)(phy_address[index]); + dev->init = tsi108_eth_probe; + dev->halt = tsi108_eth_halt; + dev->send = tsi108_eth_send; + dev->recv = tsi108_eth_recv; + + eth_register(dev); + } + return index; +} + +/* + * probe for and initialize a single ethernet interface + */ +static int tsi108_eth_probe(struct eth_device *dev, bd_t * bis) +{ + unsigned long base; + unsigned long value; + int index; + struct dma_descriptor *tx_descr; + struct dma_descriptor *rx_descr; + int speed; + int duplex; + + base = dev->iobase; + + reg_PORT_CONTROL(base) = PORT_CONTROL_STE | PORT_CONTROL_BPT; + + /* Bring DMA/FIFO out of reset. */ + reg_TX_CONFIG(base) = 0x00000000; + reg_RX_CONFIG(base) = 0x00000000; + + reg_TX_THRESHOLDS(base) = (192 << 16) | 192; + reg_RX_THRESHOLDS(base) = (192 << 16) | 112; + + /* Bring MAC out of reset. */ + reg_MAC_CONFIG_1(base) = 0x00000000; + + /* DMA MAC configuration. */ + reg_MAC_CONFIG_1(base) = + MAC_CONFIG_1_RX_ENABLE | MAC_CONFIG_1_TX_ENABLE; + + reg_MII_MGMT_CONFIG(base) = MII_MGMT_CONFIG_NO_PREAMBLE; + reg_MAXIMUM_FRAME_LENGTH(base) = RX_BUFFER_SIZE; + + /* Note: Early tsi108 manual did not have correct byte order + * for the station address.*/ + reg_STATION_ADDRESS_1(base) = (dev->enetaddr[5] << 24) | + (dev->enetaddr[4] << 16) | + (dev->enetaddr[3] << 8) | (dev->enetaddr[2] << 0); + + reg_STATION_ADDRESS_2(base) = (dev->enetaddr[1] << 24) | + (dev->enetaddr[0] << 16); + + if (marvell_88e_phy_config(dev, &speed, &duplex) == 0) { + return 0; + } + + value = + MAC_CONFIG_2_PREAMBLE_LENGTH(7) | MAC_CONFIG_2_PAD_CRC | + MAC_CONFIG_2_CRC_ENABLE; + if (speed == LINK_SPEED_1000) { + value |= MAC_CONFIG_2_INTERFACE_MODE(INTERFACE_MODE_BYTE); + } else { + value |= MAC_CONFIG_2_INTERFACE_MODE(INTERFACE_MODE_NIBBLE); + reg_PORT_CONTROL(base) |= PORT_CONTROL_SPD; + } + if (duplex == LINK_DUPLEX_FULL) { + value |= MAC_CONFIG_2_FULL_DUPLEX; + reg_PORT_CONTROL(base) &= ~PORT_CONTROL_BPT; + } else { + reg_PORT_CONTROL(base) |= PORT_CONTROL_BPT; + } + reg_MAC_CONFIG_2(base) = value; + + reg_RX_CONFIG(base) = RX_CONFIG_SE; + reg_RX_QUEUE_0_CONFIG(base) = OCN_PORT_MEMORY; + reg_RX_QUEUE_0_BUF_CONFIG(base) = OCN_PORT_MEMORY; + + /* initialize the RX DMA descriptors */ + rx_descr = &rx_descr_array[0]; + rx_descr_current = rx_descr; + for (index = 0; index < NUM_RX_DESC; index++) { + /* make sure the receive buffers are not in cache */ + invalidate_dcache_range((unsigned long)NetRxPackets[index], + (unsigned long)NetRxPackets[index] + + RX_BUFFER_SIZE); + rx_descr->start_addr0 = + cpu_to_le32((vuint32) NetRxPackets[index]); + rx_descr->start_addr1 = 0; + rx_descr->next_descr_addr0 = + cpu_to_le32((vuint32) (rx_descr + 1)); + rx_descr->next_descr_addr1 = 0; + rx_descr->vlan_byte_count = 0; + rx_descr->config_status = cpu_to_le32((RX_BUFFER_SIZE << 16) | + DMA_DESCR_RX_OWNER); + rx_descr++; + } + rx_descr--; + rx_descr->next_descr_addr0 = 0; + rx_descr->next_descr_addr1 = cpu_to_le32(DMA_DESCR_LAST); + /* Push the descriptors to RAM so the ethernet DMA can see them */ + invalidate_dcache_range((unsigned long)rx_descr_array, + (unsigned long)rx_descr_array + + sizeof(rx_descr_array)); + + /* enable RX queue */ + reg_RX_CONTROL(base) = TX_CONTROL_GO | 0x01; + reg_RX_QUEUE_0_PTR_LOW(base) = (u32) rx_descr_current; + /* enable receive DMA */ + reg_RX_QUEUE_0_PTR_HIGH(base) = RX_QUEUE_0_PTR_HIGH_VALID; + + reg_TX_QUEUE_0_CONFIG(base) = OCN_PORT_MEMORY; + reg_TX_QUEUE_0_BUF_CONFIG(base) = OCN_PORT_MEMORY; + + /* initialize the TX DMA descriptor */ + tx_descr = &tx_descriptor; + + tx_descr->start_addr0 = 0; + tx_descr->start_addr1 = 0; + tx_descr->next_descr_addr0 = 0; + tx_descr->next_descr_addr1 = cpu_to_le32(DMA_DESCR_LAST); + tx_descr->vlan_byte_count = 0; + tx_descr->config_status = cpu_to_le32(DMA_DESCR_TX_OK | + DMA_DESCR_TX_SOF | + DMA_DESCR_TX_EOF); + /* enable TX queue */ + reg_TX_CONTROL(base) = TX_CONTROL_GO | 0x01; + + return 1; +} + +/* + * send a packet + */ +static int tsi108_eth_send(struct eth_device *dev, + volatile void *packet, int length) +{ + unsigned long base; + int timeout; + struct dma_descriptor *tx_descr; + unsigned long status; + + base = dev->iobase; + tx_descr = &tx_descriptor; + + /* Wait until the last packet has been transmitted. */ + timeout = 0; + do { + /* make sure we see the changes made by the DMA engine */ + invalidate_dcache_range((unsigned long)tx_descr, + (unsigned long)tx_descr + + sizeof(struct dma_descriptor)); + + if (timeout != 0) { + udelay(15); + } + if (++timeout > 10000) { + tx_diag_regs(base); + debug_lev(1, + "ERROR: timeout waiting for last transmit packet to be sent\n"); + return 0; + } + } while (tx_descr->config_status & cpu_to_le32(DMA_DESCR_TX_OWNER)); + + status = le32_to_cpu(tx_descr->config_status); + if ((status & DMA_DESCR_TX_OK) == 0) { +#ifdef TX_PRINT_ERRORS + printf("TX packet error: 0x%08x\n %s%s%s%s\n", status, + status & DMA_DESCR_TX_OK ? "tx error, " : "", + status & DMA_DESCR_TX_RETRY_LIMIT ? + "retry limit reached, " : "", + status & DMA_DESCR_TX_UNDERRUN ? "underrun, " : "", + status & DMA_DESCR_TX_LATE_COLLISION ? "late collision, " + : ""); +#endif + } + + debug_lev(9, "sending packet %d\n", length); + tx_descr->start_addr0 = cpu_to_le32((vuint32) packet); + tx_descr->start_addr1 = 0; + tx_descr->next_descr_addr0 = 0; + tx_descr->next_descr_addr1 = cpu_to_le32(DMA_DESCR_LAST); + tx_descr->vlan_byte_count = cpu_to_le32(length); + tx_descr->config_status = cpu_to_le32(DMA_DESCR_TX_OWNER | + DMA_DESCR_TX_CRC | + DMA_DESCR_TX_PAD | + DMA_DESCR_TX_SOF | + DMA_DESCR_TX_EOF); + + invalidate_dcache_range((unsigned long)tx_descr, + (unsigned long)tx_descr + + sizeof(struct dma_descriptor)); + + invalidate_dcache_range((unsigned long)packet, + (unsigned long)packet + length); + + reg_TX_QUEUE_0_PTR_LOW(base) = (u32) tx_descr; + reg_TX_QUEUE_0_PTR_HIGH(base) = TX_QUEUE_0_PTR_HIGH_VALID; + + return length; +} + +/* + * Check for received packets and send them up the protocal stack + */ +static int tsi108_eth_recv(struct eth_device *dev) +{ + struct dma_descriptor *rx_descr; + unsigned long base; + int length = 0; + unsigned long status; + volatile uchar *buffer; + + base = dev->iobase; + + /* make sure we see the changes made by the DMA engine */ + invalidate_dcache_range((unsigned long)rx_descr_array, + (unsigned long)rx_descr_array + + sizeof(rx_descr_array)); + + /* process all of the received packets */ + rx_descr = rx_descr_current; + while ((rx_descr->config_status & cpu_to_le32(DMA_DESCR_RX_OWNER)) == 0) { + /* check for error */ + status = le32_to_cpu(rx_descr->config_status); + if (status & DMA_DESCR_RX_BAD_FRAME) { +#ifdef RX_PRINT_ERRORS + printf("RX packet error: 0x%08x\n %s%s%s%s%s%s\n", + status, + status & DMA_DESCR_RX_FRAME_IS_TYPE ? "too big, " + : "", + status & DMA_DESCR_RX_SHORT_FRAME ? "too short, " + : "", + status & DMA_DESCR_RX_BAD_FRAME ? "bad frame, " : + "", + status & DMA_DESCR_RX_OVERRUN ? "overrun, " : "", + status & DMA_DESCR_RX_MAX_FRAME_LEN ? + "max length, " : "", + status & DMA_DESCR_RX_CRC_ERROR ? "CRC error, " : + ""); +#endif + } else { + length = + le32_to_cpu(rx_descr->vlan_byte_count) & 0xFFFF; + + /*** process packet ***/ + buffer = + (volatile uchar + *)(le32_to_cpu(rx_descr->start_addr0)); + NetReceive(buffer, length); + + invalidate_dcache_range((unsigned long)buffer, + (unsigned long)buffer + + RX_BUFFER_SIZE); + } + /* Give this buffer back to the DMA engine */ + rx_descr->vlan_byte_count = 0; + rx_descr->config_status = cpu_to_le32((RX_BUFFER_SIZE << 16) | + DMA_DESCR_RX_OWNER); + /* move descriptor pointer forward */ + rx_descr = + (struct dma_descriptor + *)(le32_to_cpu(rx_descr->next_descr_addr0)); + if (rx_descr == 0) { + rx_descr = &rx_descr_array[0]; + } + } + /* remember where we are for next time */ + rx_descr_current = rx_descr; + + /* If the DMA engine has reached the end of the queue + * start over at the begining */ + if (reg_RX_EXTENDED_STATUS(base) & RX_EXTENDED_STATUS_EOQ_0) { + + reg_RX_EXTENDED_STATUS(base) = RX_EXTENDED_STATUS_EOQ_0; + reg_RX_QUEUE_0_PTR_LOW(base) = (u32) & rx_descr_array[0]; + reg_RX_QUEUE_0_PTR_HIGH(base) = RX_QUEUE_0_PTR_HIGH_VALID; + } + + return length; +} + +/* + * disable an ethernet interface + */ +static void tsi108_eth_halt(struct eth_device *dev) +{ + unsigned long base; + + base = dev->iobase; + + /* Put DMA/FIFO into reset state. */ + reg_TX_CONFIG(base) = TX_CONFIG_RST; + reg_RX_CONFIG(base) = RX_CONFIG_RST; + + /* Put MAC into reset state. */ + reg_MAC_CONFIG_1(base) = MAC_CONFIG_1_SOFT_RESET; +} + +#endif -- cgit v1.1 From 9226e7d6f09b9a1ac074cd918c81225a4689bba8 Mon Sep 17 00:00:00 2001 From: roy zang Date: Thu, 2 Nov 2006 19:11:06 +0800 Subject: Tsi108 on chip pci controller support. If there is no pci card, the tsi108/109 pci configure read will cause a machine check exception to the processor. PCI error should also be cleared after the read. Signed-off-by: Alexandre Bounine Signed-off-by: Roy Zang --- drivers/tsi108_pci.c | 178 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 drivers/tsi108_pci.c (limited to 'drivers') diff --git a/drivers/tsi108_pci.c b/drivers/tsi108_pci.c new file mode 100644 index 0000000..f374ede --- /dev/null +++ b/drivers/tsi108_pci.c @@ -0,0 +1,178 @@ +/* + * (C) Copyright 2004 Tundra Semiconductor Corp. + * Alex Bounine + * + * 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 + */ + +/* + * PCI initialisation for the Tsi108 EMU board. + */ + +#include + +#ifdef CONFIG_TSI108_PCI + +#include +#include +#include +#include + +struct pci_controller local_hose; + +void tsi108_clear_pci_error(void) +{ + u32 err_stat, err_addr, pci_stat; + + /* + * Quietly clear errors signalled as result of PCI/X configuration read + * requests. + */ + /* Read PB Error Log Registers */ + err_stat = *(volatile u32 *)(CFG_TSI108_CSR_BASE + + TSI108_PB_REG_OFFSET + PB_ERRCS); + err_addr = *(volatile u32 *)(CFG_TSI108_CSR_BASE + + TSI108_PB_REG_OFFSET + PB_AERR); + if (err_stat & PB_ERRCS_ES) { + /* Clear PCI/X bus errors if applicable */ + if ((err_addr & 0xFF000000) == CFG_PCI_CFG_BASE) { + /* Clear error flag */ + *(u32 *) (CFG_TSI108_CSR_BASE + + TSI108_PB_REG_OFFSET + PB_ERRCS) = + PB_ERRCS_ES; + + /* Clear read error reported in PB_ISR */ + *(u32 *) (CFG_TSI108_CSR_BASE + + TSI108_PB_REG_OFFSET + PB_ISR) = + PB_ISR_PBS_RD_ERR; + + /* Clear errors reported by PCI CSR (Normally Master Abort) */ + pci_stat = *(volatile u32 *)(CFG_TSI108_CSR_BASE + + TSI108_PCI_REG_OFFSET + + PCI_CSR); + *(volatile u32 *)(CFG_TSI108_CSR_BASE + + TSI108_PCI_REG_OFFSET + PCI_CSR) = + pci_stat; + + *(volatile u32 *)(CFG_TSI108_CSR_BASE + + TSI108_PCI_REG_OFFSET + + PCI_IRP_STAT) = PCI_IRP_STAT_P_CSR; + } + } + + return; +} + +unsigned int __get_pci_config_dword(u32 addr) +{ + unsigned int retval; + + __asm__ __volatile__(" lwbrx %0,0,%1\n" + "1: eieio\n" + "2:\n" + ".section .fixup,\"ax\"\n" + "3: li %0,-1\n" + " b 2b\n" + ".section __ex_table,\"a\"\n" + " .align 2\n" + " .long 1b,3b\n" + ".text":"=r"(retval):"r"(addr)); + + return (retval); +} + +static int tsi108_read_config_dword(struct pci_controller *hose, + pci_dev_t dev, int offset, u32 * value) +{ + dev &= (CFG_PCI_CFG_SIZE - 1); + dev |= (CFG_PCI_CFG_BASE | (offset & 0xfc)); + *value = __get_pci_config_dword(dev); + if (0xFFFFFFFF == *value) + tsi108_clear_pci_error(); + return 0; +} + +static int tsi108_write_config_dword(struct pci_controller *hose, + pci_dev_t dev, int offset, u32 value) +{ + dev &= (CFG_PCI_CFG_SIZE - 1); + dev |= (CFG_PCI_CFG_BASE | (offset & 0xfc)); + + out_le32((volatile unsigned *)dev, value); + + return 0; +} + +void pci_init_board(void) +{ + struct pci_controller *hose = (struct pci_controller *)&local_hose; + + hose->first_busno = 0; + hose->last_busno = 0xff; + + pci_set_region(hose->regions + 0, + CFG_PCI_MEMORY_BUS, + CFG_PCI_MEMORY_PHYS, + CFG_PCI_MEMORY_SIZE, PCI_REGION_MEM | PCI_REGION_MEMORY); + + /* PCI memory space */ + pci_set_region(hose->regions + 1, + CFG_PCI_MEM_BUS, + CFG_PCI_MEM_PHYS, CFG_PCI_MEM_SIZE, PCI_REGION_MEM); + + /* PCI I/O space */ + pci_set_region(hose->regions + 2, + CFG_PCI_IO_BUS, + CFG_PCI_IO_PHYS, CFG_PCI_IO_SIZE, PCI_REGION_IO); + + hose->region_count = 3; + + pci_set_ops(hose, + pci_hose_read_config_byte_via_dword, + pci_hose_read_config_word_via_dword, + tsi108_read_config_dword, + pci_hose_write_config_byte_via_dword, + pci_hose_write_config_word_via_dword, + tsi108_write_config_dword); + + pci_register_hose(hose); + + hose->last_busno = pci_hose_scan(hose); + + debug("Done PCI initialization\n"); + return; +} + +#ifdef CONFIG_OF_FLAT_TREE +void +ft_pci_setup(void *blob, bd_t *bd) +{ + u32 *p; + int len; + + p = (u32 *)ft_get_prop(blob, "/" OF_TSI "/pci@1000/bus-range", &len); + if (p != NULL) { + p[0] = local_hose.first_busno; + p[1] = local_hose.last_busno; + } + +} +#endif + +#endif /* CONFIG_TSI108_PCI */ -- cgit v1.1 From b825f158e449e1e9cf74c08e572955e122394c96 Mon Sep 17 00:00:00 2001 From: roy zang Date: Thu, 2 Nov 2006 19:12:31 +0800 Subject: Tsi108 on chip i2c support. The i2c Interface provides a master-only, serial interface that can be used for initializing Tsi108/Tsi109 registers from an EEPROM after a device reset. Signed-off-by: Alexandre Bounine Signed-off-by: Roy Zang --- drivers/tsi108_i2c.c | 300 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 300 insertions(+) create mode 100644 drivers/tsi108_i2c.c (limited to 'drivers') diff --git a/drivers/tsi108_i2c.c b/drivers/tsi108_i2c.c new file mode 100644 index 0000000..08e5e3b --- /dev/null +++ b/drivers/tsi108_i2c.c @@ -0,0 +1,300 @@ +/* + * (C) Copyright 2004 Tundra Semiconductor Corp. + * Author: Alex Bounine + * + * 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 + +#ifdef CONFIG_TSI108_I2C + +#include +#include + +#if (CONFIG_COMMANDS & CFG_CMD_I2C) + +#define I2C_DELAY 100000 +#undef DEBUG_I2C + +#ifdef DEBUG_I2C +#define DPRINT(x) printf(x) +#else +#define DPRINT(x) +#endif + +/* All functions assume that Tsi108 I2C block is the only master on the bus */ +/* I2C read helper function */ + +static int i2c_read_byte( + uint i2c_chan, /* I2C channel number: 0 - main, 1 - SDC SPD */ + uchar chip_addr,/* I2C device address on the bus */ + uint byte_addr, /* Byte address within I2C device */ + uchar * buffer /* pointer to data buffer */ + ) +{ + u32 temp; + u32 to_count = I2C_DELAY; + u32 op_status = TSI108_I2C_TIMEOUT_ERR; + u32 chan_offset = TSI108_I2C_OFFSET; + + DPRINT(("I2C read_byte() %d 0x%02x 0x%02x\n", + i2c_chan, chip_addr, byte_addr)); + + if (0 != i2c_chan) { + chan_offset = TSI108_I2C_SDRAM_OFFSET; + } + + /* Check if I2C operation is in progress */ + temp = *(u32 *) (CFG_TSI108_CSR_BASE + chan_offset + I2C_CNTRL2); + + if (0 == (temp & (I2C_CNTRL2_RD_STATUS | I2C_CNTRL2_WR_STATUS | + I2C_CNTRL2_START)) + ) { + /* Set device address and operation (read = 0) */ + temp = (byte_addr << 16) | ((chip_addr & 0x07) << 8) | + ((chip_addr >> 3) & 0x0F); + *(u32 *) (CFG_TSI108_CSR_BASE + chan_offset + I2C_CNTRL1) = + temp; + + /* Issue the read command + * (at this moment all other parameters are 0 + * (size = 1 byte, lane = 0) + */ + + *(u32 *) (CFG_TSI108_CSR_BASE + chan_offset + I2C_CNTRL2) = + (I2C_CNTRL2_START); + + /* Wait until operation completed */ + do { + /* Read I2C operation status */ + temp = + *(u32 *) (CFG_TSI108_CSR_BASE + chan_offset + + I2C_CNTRL2); + + if (0 == + (temp & (I2C_CNTRL2_RD_STATUS | I2C_CNTRL2_START))) + { + if (0 == + (temp & + (I2C_CNTRL2_I2C_CFGERR | + I2C_CNTRL2_I2C_TO_ERR)) + ) { + op_status = TSI108_I2C_SUCCESS; + + temp = *(u32 *) (CFG_TSI108_CSR_BASE + + chan_offset + + I2C_RD_DATA); + + *buffer = (u8) (temp & 0xFF); + } else { + /* report HW error */ + op_status = TSI108_I2C_IF_ERROR; + + DPRINT(("I2C HW error reported: 0x%02x\n", temp)); + } + + break; + } + } while (to_count--); + } else { + op_status = TSI108_I2C_IF_BUSY; + + DPRINT(("I2C Transaction start failed: 0x%02x\n", temp)); + } + + DPRINT(("I2C read_byte() status: 0x%02x\n", op_status)); + return op_status; +} + +/* + * I2C Read interface as defined in "include/i2c.h" : + * chip_addr: I2C chip address, range 0..127 + * (to read from SPD channel EEPROM use (0xD0 ... 0xD7) + * NOTE: The bit 7 in the chip_addr serves as a channel select. + * This hack is for enabling "isdram" command on Tsi108 boards + * without changes to common code. Used for I2C reads only. + * byte_addr: Memory or register address within the chip + * alen: Number of bytes to use for addr (typically 1, 2 for larger + * memories, 0 for register type devices with only one + * register) + * buffer: Pointer to destination buffer for data to be read + * len: How many bytes to read + * + * Returns: 0 on success, not 0 on failure + */ + +int i2c_read(uchar chip_addr, uint byte_addr, int alen, uchar * buffer, int len) +{ + u32 op_status = TSI108_I2C_PARAM_ERR; + u32 i2c_if = 0; + + /* Hack to support second (SPD) I2C controller (SPD EEPROM read only).*/ + if (0xD0 == (chip_addr & ~0x07)) { + i2c_if = 1; + chip_addr &= 0x7F; + } + /* Check for valid I2C address */ + if (chip_addr <= 0x7F && (byte_addr + len) <= (0x01 << (alen * 8))) { + while (len--) { + op_status = + i2c_read_byte(i2c_if, chip_addr, byte_addr++, + buffer++); + + if (TSI108_I2C_SUCCESS != op_status) { + DPRINT(("I2C read_byte() failed: 0x%02x (%d left)\n", op_status, len)); + + break; + } + } + } + + DPRINT(("I2C read() status: 0x%02x\n", op_status)); + return op_status; +} + +/* I2C write helper function */ + +static int i2c_write_byte(uchar chip_addr,/* I2C device address on the bus */ + uint byte_addr, /* Byte address within I2C device */ + uchar * buffer /* pointer to data buffer */ + ) +{ + u32 temp; + u32 to_count = I2C_DELAY; + u32 op_status = TSI108_I2C_TIMEOUT_ERR; + + /* Check if I2C operation is in progress */ + temp = *(u32 *) (CFG_TSI108_CSR_BASE + TSI108_I2C_OFFSET + I2C_CNTRL2); + + if (0 == + (temp & + (I2C_CNTRL2_RD_STATUS | I2C_CNTRL2_WR_STATUS | I2C_CNTRL2_START))) + { + /* Place data into the I2C Tx Register */ + *(u32 *) (CFG_TSI108_CSR_BASE + TSI108_I2C_OFFSET + + I2C_TX_DATA) = (u32) * buffer; + + /* Set device address and operation */ + temp = + I2C_CNTRL1_I2CWRITE | (byte_addr << 16) | + ((chip_addr & 0x07) << 8) | ((chip_addr >> 3) & 0x0F); + *(u32 *) (CFG_TSI108_CSR_BASE + TSI108_I2C_OFFSET + + I2C_CNTRL1) = temp; + + /* Issue the write command (at this moment all other parameters + * are 0 (size = 1 byte, lane = 0) + */ + + *(u32 *) (CFG_TSI108_CSR_BASE + TSI108_I2C_OFFSET + + I2C_CNTRL2) = (I2C_CNTRL2_START); + + op_status = TSI108_I2C_TIMEOUT_ERR; + + /* Wait until operation completed */ + do { + // Read I2C operation status + temp = + *(u32 *) (CFG_TSI108_CSR_BASE + TSI108_I2C_OFFSET + + I2C_CNTRL2); + + if (0 == + (temp & (I2C_CNTRL2_WR_STATUS | I2C_CNTRL2_START))) + { + if (0 == + (temp & + (I2C_CNTRL2_I2C_CFGERR | + I2C_CNTRL2_I2C_TO_ERR))) { + op_status = TSI108_I2C_SUCCESS; + } else { + /* report detected HW error */ + op_status = TSI108_I2C_IF_ERROR; + + DPRINT(("I2C HW error reported: 0x%02x\n", temp)); + } + + break; + } + + } while (to_count--); + } else { + op_status = TSI108_I2C_IF_BUSY; + + DPRINT(("I2C Transaction start failed: 0x%02x\n", temp)); + } + + return op_status; +} + +/* + * I2C Write interface as defined in "include/i2c.h" : + * chip_addr: I2C chip address, range 0..127 + * byte_addr: Memory or register address within the chip + * alen: Number of bytes to use for addr (typically 1, 2 for larger + * memories, 0 for register type devices with only one + * register) + * buffer: Pointer to data to be written + * len: How many bytes to write + * + * Returns: 0 on success, not 0 on failure + */ + +int i2c_write(uchar chip_addr, uint byte_addr, int alen, uchar * buffer, + int len) +{ + u32 op_status = TSI108_I2C_PARAM_ERR; + + /* Check for valid I2C address */ + if (chip_addr <= 0x7F && (byte_addr + len) <= (0x01 << (alen * 8))) { + while (len--) { + op_status = + i2c_write_byte(chip_addr, byte_addr++, buffer++); + + if (TSI108_I2C_SUCCESS != op_status) { + DPRINT(("I2C write_byte() failed: 0x%02x (%d left)\n", op_status, len)); + + break; + } + } + } + + return op_status; +} + +/* + * I2C interface function as defined in "include/i2c.h". + * Probe the given I2C chip address by reading single byte from offset 0. + * Returns 0 if a chip responded, not 0 on failure. + */ + +int i2c_probe(uchar chip) +{ + u32 tmp; + + /* + * Try to read the first location of the chip. + * The Tsi108 HW doesn't support sending just the chip address + * and checkong for an back. + */ + return i2c_read(chip, 0, 1, (char *)&tmp, 1); +} + +#endif /* (CONFIG_COMMANDS & CFG_CMD_I2C) */ +#endif /* CONFIG_TSI108_I2C */ -- cgit v1.1 From c1fbe4103a0d6c8957f912af902d705ba67836f2 Mon Sep 17 00:00:00 2001 From: roy zang Date: Thu, 2 Nov 2006 19:14:48 +0800 Subject: This patch comes from Yuli's posted patch on 8/8/2006 titled "CFI Driver Little-Endian write Issue". http://sourceforge.net/mailarchive/message.php?msg_id=36311999 If that patch applied, please discard this one. Until now , I do not see his patch is applied. So please apply this one. Signed-off-by: Yuli Barcohen Signed-off-by: Roy Zang --- drivers/cfi_flash.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/cfi_flash.c b/drivers/cfi_flash.c index fd0a186..33a5822 100644 --- a/drivers/cfi_flash.c +++ b/drivers/cfi_flash.c @@ -2,9 +2,12 @@ * (C) Copyright 2002-2004 * Brad Kemp, Seranoa Networks, Brad.Kemp@seranoa.com * - * Copyright (C) 2003 Arabella Software Ltd. + * Copyright (C) 2003, 2006 Arabella Software Ltd. * Yuli Barcohen * Modified to work with AMD flashes + * Added support for byte lanes swap + * Added support for 32-bit chips consisting of two 16-bit devices + * (for example, S70GL256M00) * * Copyright (C) 2004 * Ed Okerson @@ -45,10 +48,13 @@ /* #define DEBUG */ #include + +#ifdef CFG_FLASH_CFI_DRIVER + +#include #include #include #include -#ifdef CFG_FLASH_CFI_DRIVER /* * This file implements a Common Flash Interface (CFI) driver for U-Boot. @@ -71,6 +77,10 @@ * Verify erase and program timeouts. */ +#if defined(__LITTLE_ENDIAN) && !defined(CFG_FLASH_CFI_SWAP) +#define CFG_FLASH_CFI_SWAP +#endif + #ifndef CFG_FLASH_BANKS_LIST #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE } #endif @@ -268,7 +278,7 @@ inline uchar flash_read_uchar (flash_info_t * info, uint offset) uchar *cp; cp = flash_make_addr (info, 0, offset); -#if defined(__LITTLE_ENDIAN) +#if defined(CFG_FLASH_CFI_SWAP) return (cp[0]); #else return (cp[info->portwidth - 1]); @@ -295,7 +305,7 @@ ushort flash_read_ushort (flash_info_t * info, flash_sect_t sect, uint offset) debug ("addr[%x] = 0x%x\n", x, addr[x]); } #endif -#if defined(__LITTLE_ENDIAN) +#if defined(CFG_FLASH_CFI_SWAP) retval = ((addr[(info->portwidth)] << 8) | addr[0]); #else retval = ((addr[(2 * info->portwidth) - 1] << 8) | @@ -327,7 +337,7 @@ ulong flash_read_long (flash_info_t * info, flash_sect_t sect, uint offset) debug ("addr[%x] = 0x%x\n", x, addr[x]); } #endif -#if defined(__LITTLE_ENDIAN) +#if defined(CFG_FLASH_CFI_SWAP) retval = (addr[0] << 16) | (addr[(info->portwidth)] << 24) | (addr[(2 * info->portwidth)]) | (addr[(3 * info->portwidth)] << 8); #else @@ -892,12 +902,22 @@ static void flash_make_cmd (flash_info_t * info, uchar cmd, void *cmdbuf) int i; uchar *cp = (uchar *) cmdbuf; -#if defined(__LITTLE_ENDIAN) +#if defined(CFG_FLASH_CFI_SWAP) for (i = info->portwidth; i > 0; i--) #else for (i = 1; i <= info->portwidth; i++) #endif *cp++ = (i & (info->chipwidth - 1)) ? '\0' : cmd; +#ifdef CFG_FLASH_CFI_2x16 + if ((info->portwidth == FLASH_CFI_32BIT) && (info->chipwidth == FLASH_CFI_BY16)) + { + uchar tmp; + cp = (uchar *) cmdbuf; + tmp = cp[1]; + cp[1] = cp[2]; + cp[2] = tmp; + } +#endif /* CFG_FLASH_CFI_2x16 */ } /* -- cgit v1.1 From ee311214e0d216f904feea269599d0934bf71f23 Mon Sep 17 00:00:00 2001 From: roy zang Date: Fri, 1 Dec 2006 11:47:36 +0800 Subject: Clean up the code according to codestyle: (1) remove some C++ comments. (2) remove trailing white space. (3) remove trailing empty line. (4) Indentation by table. (5) remove {} in one line condition. (6) add space before '(' in function call. Remove some weird printf () output. Add necessary comments. Modified Makefile to support building in a separate directory. --- drivers/tsi108_eth.c | 835 +++++++++++++++++++++++++-------------------------- drivers/tsi108_i2c.c | 60 ++-- drivers/tsi108_pci.c | 34 +-- 3 files changed, 460 insertions(+), 469 deletions(-) (limited to 'drivers') diff --git a/drivers/tsi108_eth.c b/drivers/tsi108_eth.c index d95a047..47341be 100644 --- a/drivers/tsi108_eth.c +++ b/drivers/tsi108_eth.c @@ -46,7 +46,9 @@ #endif #if TSI108_ETH_DEBUG > 0 -#define debug_lev(lev, fmt, args...) if (lev <= TSI108_ETH_DEBUG) printf("%s %d: " fmt, __FUNCTION__, __LINE__, ##args) +#define debug_lev(lev, fmt, args...) \ +if (lev <= TSI108_ETH_DEBUG) \ +printf ("%s %d: " fmt, __FUNCTION__, __LINE__, ##args) #else #define debug_lev(lev, fmt, args...) do{}while(0) #endif @@ -54,322 +56,322 @@ #define RX_PRINT_ERRORS #define TX_PRINT_ERRORS -#define ETH_BASE (CFG_TSI108_CSR_BASE + 0x6000) +#define ETH_BASE (CFG_TSI108_CSR_BASE + 0x6000) -#define ETH_PORT_OFFSET 0x400 +#define ETH_PORT_OFFSET 0x400 #define __REG32(base, offset) (*((volatile u32 *)((char *)(base) + (offset)))) -#define reg_MAC_CONFIG_1(base) __REG32(base, 0x00000000) -#define MAC_CONFIG_1_TX_ENABLE (0x00000001) -#define MAC_CONFIG_1_SYNC_TX_ENABLE (0x00000002) -#define MAC_CONFIG_1_RX_ENABLE (0x00000004) -#define MAC_CONFIG_1_SYNC_RX_ENABLE (0x00000008) -#define MAC_CONFIG_1_TX_FLOW_CONTROL (0x00000010) -#define MAC_CONFIG_1_RX_FLOW_CONTROL (0x00000020) -#define MAC_CONFIG_1_LOOP_BACK (0x00000100) -#define MAC_CONFIG_1_RESET_TX_FUNCTION (0x00010000) -#define MAC_CONFIG_1_RESET_RX_FUNCTION (0x00020000) -#define MAC_CONFIG_1_RESET_TX_MAC (0x00040000) -#define MAC_CONFIG_1_RESET_RX_MAC (0x00080000) -#define MAC_CONFIG_1_SIM_RESET (0x40000000) -#define MAC_CONFIG_1_SOFT_RESET (0x80000000) - -#define reg_MAC_CONFIG_2(base) __REG32(base, 0x00000004) -#define MAC_CONFIG_2_FULL_DUPLEX (0x00000001) -#define MAC_CONFIG_2_CRC_ENABLE (0x00000002) -#define MAC_CONFIG_2_PAD_CRC (0x00000004) -#define MAC_CONFIG_2_LENGTH_CHECK (0x00000010) -#define MAC_CONFIG_2_HUGE_FRAME (0x00000020) -#define MAC_CONFIG_2_INTERFACE_MODE(val) (((val) & 0x3) << 8) -#define MAC_CONFIG_2_PREAMBLE_LENGTH(val) (((val) & 0xf) << 12) -#define INTERFACE_MODE_NIBBLE 1 /* 10/100 Mb/s MII) */ -#define INTERFACE_MODE_BYTE 2 /* 1000 Mb/s GMII/TBI */ - -#define reg_MAXIMUM_FRAME_LENGTH(base) __REG32(base, 0x00000010) - -#define reg_MII_MGMT_CONFIG(base) __REG32(base, 0x00000020) -#define MII_MGMT_CONFIG_MGMT_CLOCK_SELECT(val) ((val) & 0x7) -#define MII_MGMT_CONFIG_NO_PREAMBLE (0x00000010) -#define MII_MGMT_CONFIG_SCAN_INCREMENT (0x00000020) -#define MII_MGMT_CONFIG_RESET_MGMT (0x80000000) - -#define reg_MII_MGMT_COMMAND(base) __REG32(base, 0x00000024) -#define MII_MGMT_COMMAND_READ_CYCLE (0x00000001) -#define MII_MGMT_COMMAND_SCAN_CYCLE (0x00000002) - -#define reg_MII_MGMT_ADDRESS(base) __REG32(base, 0x00000028) -#define reg_MII_MGMT_CONTROL(base) __REG32(base, 0x0000002c) -#define reg_MII_MGMT_STATUS(base) __REG32(base, 0x00000030) - -#define reg_MII_MGMT_INDICATORS(base) __REG32(base, 0x00000034) -#define MII_MGMT_INDICATORS_BUSY (0x00000001) -#define MII_MGMT_INDICATORS_SCAN (0x00000002) -#define MII_MGMT_INDICATORS_NOT_VALID (0x00000004) - -#define reg_INTERFACE_STATUS(base) __REG32(base, 0x0000003c) -#define INTERFACE_STATUS_LINK_FAIL (0x00000008) -#define INTERFACE_STATUS_EXCESS_DEFER (0x00000200) - -#define reg_STATION_ADDRESS_1(base) __REG32(base, 0x00000040) -#define reg_STATION_ADDRESS_2(base) __REG32(base, 0x00000044) - -#define reg_PORT_CONTROL(base) __REG32(base, 0x00000200) -#define PORT_CONTROL_PRI (0x00000001) -#define PORT_CONTROL_BPT (0x00010000) -#define PORT_CONTROL_SPD (0x00040000) -#define PORT_CONTROL_RBC (0x00080000) -#define PORT_CONTROL_PRB (0x00200000) -#define PORT_CONTROL_DIS (0x00400000) -#define PORT_CONTROL_TBI (0x00800000) -#define PORT_CONTROL_STE (0x10000000) -#define PORT_CONTROL_ZOR (0x20000000) -#define PORT_CONTROL_CLR (0x40000000) -#define PORT_CONTROL_SRT (0x80000000) - -#define reg_TX_CONFIG(base) __REG32(base, 0x00000220) -#define TX_CONFIG_START_Q (0x00000003) -#define TX_CONFIG_EHP (0x00400000) -#define TX_CONFIG_CHP (0x00800000) -#define TX_CONFIG_RST (0x80000000) - -#define reg_TX_CONTROL(base) __REG32(base, 0x00000224) -#define TX_CONTROL_GO (0x00008000) -#define TX_CONTROL_MP (0x01000000) -#define TX_CONTROL_EAI (0x20000000) -#define TX_CONTROL_ABT (0x40000000) -#define TX_CONTROL_EII (0x80000000) - -#define reg_TX_STATUS(base) __REG32(base, 0x00000228) -#define TX_STATUS_QUEUE_USABLE (0x0000000f) -#define TX_STATUS_CURR_Q (0x00000300) -#define TX_STATUS_ACT (0x00008000) -#define TX_STATUS_QUEUE_IDLE (0x000f0000) -#define TX_STATUS_EOQ_PENDING (0x0f000000) - -#define reg_TX_EXTENDED_STATUS(base) __REG32(base, 0x0000022c) -#define TX_EXTENDED_STATUS_END_OF_QUEUE_CONDITION (0x0000000f) -#define TX_EXTENDED_STATUS_END_OF_FRAME_CONDITION (0x00000f00) -#define TX_EXTENDED_STATUS_DESCRIPTOR_INTERRUPT_CONDITION (0x000f0000) -#define TX_EXTENDED_STATUS_ERROR_FLAG (0x0f000000) - -#define reg_TX_THRESHOLDS(base) __REG32(base, 0x00000230) +#define reg_MAC_CONFIG_1(base) __REG32(base, 0x00000000) +#define MAC_CONFIG_1_TX_ENABLE (0x00000001) +#define MAC_CONFIG_1_SYNC_TX_ENABLE (0x00000002) +#define MAC_CONFIG_1_RX_ENABLE (0x00000004) +#define MAC_CONFIG_1_SYNC_RX_ENABLE (0x00000008) +#define MAC_CONFIG_1_TX_FLOW_CONTROL (0x00000010) +#define MAC_CONFIG_1_RX_FLOW_CONTROL (0x00000020) +#define MAC_CONFIG_1_LOOP_BACK (0x00000100) +#define MAC_CONFIG_1_RESET_TX_FUNCTION (0x00010000) +#define MAC_CONFIG_1_RESET_RX_FUNCTION (0x00020000) +#define MAC_CONFIG_1_RESET_TX_MAC (0x00040000) +#define MAC_CONFIG_1_RESET_RX_MAC (0x00080000) +#define MAC_CONFIG_1_SIM_RESET (0x40000000) +#define MAC_CONFIG_1_SOFT_RESET (0x80000000) + +#define reg_MAC_CONFIG_2(base) __REG32(base, 0x00000004) +#define MAC_CONFIG_2_FULL_DUPLEX (0x00000001) +#define MAC_CONFIG_2_CRC_ENABLE (0x00000002) +#define MAC_CONFIG_2_PAD_CRC (0x00000004) +#define MAC_CONFIG_2_LENGTH_CHECK (0x00000010) +#define MAC_CONFIG_2_HUGE_FRAME (0x00000020) +#define MAC_CONFIG_2_INTERFACE_MODE(val) (((val) & 0x3) << 8) +#define MAC_CONFIG_2_PREAMBLE_LENGTH(val) (((val) & 0xf) << 12) +#define INTERFACE_MODE_NIBBLE 1 /* 10/100 Mb/s MII) */ +#define INTERFACE_MODE_BYTE 2 /* 1000 Mb/s GMII/TBI */ + +#define reg_MAXIMUM_FRAME_LENGTH(base) __REG32(base, 0x00000010) + +#define reg_MII_MGMT_CONFIG(base) __REG32(base, 0x00000020) +#define MII_MGMT_CONFIG_MGMT_CLOCK_SELECT(val) ((val) & 0x7) +#define MII_MGMT_CONFIG_NO_PREAMBLE (0x00000010) +#define MII_MGMT_CONFIG_SCAN_INCREMENT (0x00000020) +#define MII_MGMT_CONFIG_RESET_MGMT (0x80000000) + +#define reg_MII_MGMT_COMMAND(base) __REG32(base, 0x00000024) +#define MII_MGMT_COMMAND_READ_CYCLE (0x00000001) +#define MII_MGMT_COMMAND_SCAN_CYCLE (0x00000002) + +#define reg_MII_MGMT_ADDRESS(base) __REG32(base, 0x00000028) +#define reg_MII_MGMT_CONTROL(base) __REG32(base, 0x0000002c) +#define reg_MII_MGMT_STATUS(base) __REG32(base, 0x00000030) + +#define reg_MII_MGMT_INDICATORS(base) __REG32(base, 0x00000034) +#define MII_MGMT_INDICATORS_BUSY (0x00000001) +#define MII_MGMT_INDICATORS_SCAN (0x00000002) +#define MII_MGMT_INDICATORS_NOT_VALID (0x00000004) + +#define reg_INTERFACE_STATUS(base) __REG32(base, 0x0000003c) +#define INTERFACE_STATUS_LINK_FAIL (0x00000008) +#define INTERFACE_STATUS_EXCESS_DEFER (0x00000200) + +#define reg_STATION_ADDRESS_1(base) __REG32(base, 0x00000040) +#define reg_STATION_ADDRESS_2(base) __REG32(base, 0x00000044) + +#define reg_PORT_CONTROL(base) __REG32(base, 0x00000200) +#define PORT_CONTROL_PRI (0x00000001) +#define PORT_CONTROL_BPT (0x00010000) +#define PORT_CONTROL_SPD (0x00040000) +#define PORT_CONTROL_RBC (0x00080000) +#define PORT_CONTROL_PRB (0x00200000) +#define PORT_CONTROL_DIS (0x00400000) +#define PORT_CONTROL_TBI (0x00800000) +#define PORT_CONTROL_STE (0x10000000) +#define PORT_CONTROL_ZOR (0x20000000) +#define PORT_CONTROL_CLR (0x40000000) +#define PORT_CONTROL_SRT (0x80000000) + +#define reg_TX_CONFIG(base) __REG32(base, 0x00000220) +#define TX_CONFIG_START_Q (0x00000003) +#define TX_CONFIG_EHP (0x00400000) +#define TX_CONFIG_CHP (0x00800000) +#define TX_CONFIG_RST (0x80000000) + +#define reg_TX_CONTROL(base) __REG32(base, 0x00000224) +#define TX_CONTROL_GO (0x00008000) +#define TX_CONTROL_MP (0x01000000) +#define TX_CONTROL_EAI (0x20000000) +#define TX_CONTROL_ABT (0x40000000) +#define TX_CONTROL_EII (0x80000000) + +#define reg_TX_STATUS(base) __REG32(base, 0x00000228) +#define TX_STATUS_QUEUE_USABLE (0x0000000f) +#define TX_STATUS_CURR_Q (0x00000300) +#define TX_STATUS_ACT (0x00008000) +#define TX_STATUS_QUEUE_IDLE (0x000f0000) +#define TX_STATUS_EOQ_PENDING (0x0f000000) + +#define reg_TX_EXTENDED_STATUS(base) __REG32(base, 0x0000022c) +#define TX_EXTENDED_STATUS_END_OF_QUEUE_CONDITION (0x0000000f) +#define TX_EXTENDED_STATUS_END_OF_FRAME_CONDITION (0x00000f00) +#define TX_EXTENDED_STATUS_DESCRIPTOR_INTERRUPT_CONDITION (0x000f0000) +#define TX_EXTENDED_STATUS_ERROR_FLAG (0x0f000000) + +#define reg_TX_THRESHOLDS(base) __REG32(base, 0x00000230) #define reg_TX_DIAGNOSTIC_ADDR(base) __REG32(base, 0x00000270) -#define TX_DIAGNOSTIC_ADDR_INDEX (0x0000007f) -#define TX_DIAGNOSTIC_ADDR_DFR (0x40000000) -#define TX_DIAGNOSTIC_ADDR_AI (0x80000000) - -#define reg_TX_DIAGNOSTIC_DATA(base) __REG32(base, 0x00000274) - -#define reg_TX_ERROR_STATUS(base) __REG32(base, 0x00000278) -#define TX_ERROR_STATUS (0x00000278) -#define TX_ERROR_STATUS_QUEUE_0_ERROR_RESPONSE (0x0000000f) -#define TX_ERROR_STATUS_TEA_ON_QUEUE_0 (0x00000010) -#define TX_ERROR_STATUS_RER_ON_QUEUE_0 (0x00000020) -#define TX_ERROR_STATUS_TER_ON_QUEUE_0 (0x00000040) -#define TX_ERROR_STATUS_DER_ON_QUEUE_0 (0x00000080) -#define TX_ERROR_STATUS_QUEUE_1_ERROR_RESPONSE (0x00000f00) -#define TX_ERROR_STATUS_TEA_ON_QUEUE_1 (0x00001000) -#define TX_ERROR_STATUS_RER_ON_QUEUE_1 (0x00002000) -#define TX_ERROR_STATUS_TER_ON_QUEUE_1 (0x00004000) -#define TX_ERROR_STATUS_DER_ON_QUEUE_1 (0x00008000) -#define TX_ERROR_STATUS_QUEUE_2_ERROR_RESPONSE (0x000f0000) -#define TX_ERROR_STATUS_TEA_ON_QUEUE_2 (0x00100000) -#define TX_ERROR_STATUS_RER_ON_QUEUE_2 (0x00200000) -#define TX_ERROR_STATUS_TER_ON_QUEUE_2 (0x00400000) -#define TX_ERROR_STATUS_DER_ON_QUEUE_2 (0x00800000) -#define TX_ERROR_STATUS_QUEUE_3_ERROR_RESPONSE (0x0f000000) -#define TX_ERROR_STATUS_TEA_ON_QUEUE_3 (0x10000000) -#define TX_ERROR_STATUS_RER_ON_QUEUE_3 (0x20000000) -#define TX_ERROR_STATUS_TER_ON_QUEUE_3 (0x40000000) -#define TX_ERROR_STATUS_DER_ON_QUEUE_3 (0x80000000) - -#define reg_TX_QUEUE_0_CONFIG(base) __REG32(base, 0x00000280) -#define TX_QUEUE_0_CONFIG_OCN_PORT (0x0000003f) -#define TX_QUEUE_0_CONFIG_BSWP (0x00000400) -#define TX_QUEUE_0_CONFIG_WSWP (0x00000800) -#define TX_QUEUE_0_CONFIG_AM (0x00004000) -#define TX_QUEUE_0_CONFIG_GVI (0x00008000) -#define TX_QUEUE_0_CONFIG_EEI (0x00010000) -#define TX_QUEUE_0_CONFIG_ELI (0x00020000) -#define TX_QUEUE_0_CONFIG_ENI (0x00040000) -#define TX_QUEUE_0_CONFIG_ESI (0x00080000) -#define TX_QUEUE_0_CONFIG_EDI (0x00100000) - -#define reg_TX_QUEUE_0_BUF_CONFIG(base) __REG32(base, 0x00000284) -#define TX_QUEUE_0_BUF_CONFIG_OCN_PORT (0x0000003f) -#define TX_QUEUE_0_BUF_CONFIG_BURST (0x00000300) -#define TX_QUEUE_0_BUF_CONFIG_BSWP (0x00000400) -#define TX_QUEUE_0_BUF_CONFIG_WSWP (0x00000800) - -#define OCN_PORT_HLP 0 /* HLP Interface */ -#define OCN_PORT_PCI_X 1 /* PCI-X Interface */ +#define TX_DIAGNOSTIC_ADDR_INDEX (0x0000007f) +#define TX_DIAGNOSTIC_ADDR_DFR (0x40000000) +#define TX_DIAGNOSTIC_ADDR_AI (0x80000000) + +#define reg_TX_DIAGNOSTIC_DATA(base) __REG32(base, 0x00000274) + +#define reg_TX_ERROR_STATUS(base) __REG32(base, 0x00000278) +#define TX_ERROR_STATUS (0x00000278) +#define TX_ERROR_STATUS_QUEUE_0_ERROR_RESPONSE (0x0000000f) +#define TX_ERROR_STATUS_TEA_ON_QUEUE_0 (0x00000010) +#define TX_ERROR_STATUS_RER_ON_QUEUE_0 (0x00000020) +#define TX_ERROR_STATUS_TER_ON_QUEUE_0 (0x00000040) +#define TX_ERROR_STATUS_DER_ON_QUEUE_0 (0x00000080) +#define TX_ERROR_STATUS_QUEUE_1_ERROR_RESPONSE (0x00000f00) +#define TX_ERROR_STATUS_TEA_ON_QUEUE_1 (0x00001000) +#define TX_ERROR_STATUS_RER_ON_QUEUE_1 (0x00002000) +#define TX_ERROR_STATUS_TER_ON_QUEUE_1 (0x00004000) +#define TX_ERROR_STATUS_DER_ON_QUEUE_1 (0x00008000) +#define TX_ERROR_STATUS_QUEUE_2_ERROR_RESPONSE (0x000f0000) +#define TX_ERROR_STATUS_TEA_ON_QUEUE_2 (0x00100000) +#define TX_ERROR_STATUS_RER_ON_QUEUE_2 (0x00200000) +#define TX_ERROR_STATUS_TER_ON_QUEUE_2 (0x00400000) +#define TX_ERROR_STATUS_DER_ON_QUEUE_2 (0x00800000) +#define TX_ERROR_STATUS_QUEUE_3_ERROR_RESPONSE (0x0f000000) +#define TX_ERROR_STATUS_TEA_ON_QUEUE_3 (0x10000000) +#define TX_ERROR_STATUS_RER_ON_QUEUE_3 (0x20000000) +#define TX_ERROR_STATUS_TER_ON_QUEUE_3 (0x40000000) +#define TX_ERROR_STATUS_DER_ON_QUEUE_3 (0x80000000) + +#define reg_TX_QUEUE_0_CONFIG(base) __REG32(base, 0x00000280) +#define TX_QUEUE_0_CONFIG_OCN_PORT (0x0000003f) +#define TX_QUEUE_0_CONFIG_BSWP (0x00000400) +#define TX_QUEUE_0_CONFIG_WSWP (0x00000800) +#define TX_QUEUE_0_CONFIG_AM (0x00004000) +#define TX_QUEUE_0_CONFIG_GVI (0x00008000) +#define TX_QUEUE_0_CONFIG_EEI (0x00010000) +#define TX_QUEUE_0_CONFIG_ELI (0x00020000) +#define TX_QUEUE_0_CONFIG_ENI (0x00040000) +#define TX_QUEUE_0_CONFIG_ESI (0x00080000) +#define TX_QUEUE_0_CONFIG_EDI (0x00100000) + +#define reg_TX_QUEUE_0_BUF_CONFIG(base) __REG32(base, 0x00000284) +#define TX_QUEUE_0_BUF_CONFIG_OCN_PORT (0x0000003f) +#define TX_QUEUE_0_BUF_CONFIG_BURST (0x00000300) +#define TX_QUEUE_0_BUF_CONFIG_BSWP (0x00000400) +#define TX_QUEUE_0_BUF_CONFIG_WSWP (0x00000800) + +#define OCN_PORT_HLP 0 /* HLP Interface */ +#define OCN_PORT_PCI_X 1 /* PCI-X Interface */ #define OCN_PORT_PROCESSOR_MASTER 2 /* Processor Interface (master) */ -#define OCN_PORT_PROCESSOR_SLAVE 3 /* Processor Interface (slave) */ -#define OCN_PORT_MEMORY 4 /* Memory Controller */ -#define OCN_PORT_DMA 5 /* DMA Controller */ -#define OCN_PORT_ETHERNET 6 /* Ethernet Controller */ -#define OCN_PORT_PRINT 7 /* Print Engine Interface */ - -#define reg_TX_QUEUE_0_PTR_LOW(base) __REG32(base, 0x00000288) - -#define reg_TX_QUEUE_0_PTR_HIGH(base) __REG32(base, 0x0000028c) -#define TX_QUEUE_0_PTR_HIGH_VALID (0x80000000) - -#define reg_RX_CONFIG(base) __REG32(base, 0x00000320) -#define RX_CONFIG_DEF_Q (0x00000003) -#define RX_CONFIG_EMF (0x00000100) -#define RX_CONFIG_EUF (0x00000200) -#define RX_CONFIG_BFE (0x00000400) -#define RX_CONFIG_MFE (0x00000800) -#define RX_CONFIG_UFE (0x00001000) -#define RX_CONFIG_SE (0x00002000) -#define RX_CONFIG_ABF (0x00200000) -#define RX_CONFIG_APE (0x00400000) -#define RX_CONFIG_CHP (0x00800000) -#define RX_CONFIG_RST (0x80000000) - -#define reg_RX_CONTROL(base) __REG32(base, 0x00000324) -#define GE_E0_RX_CONTROL_QUEUE_ENABLES (0x0000000f) -#define GE_E0_RX_CONTROL_GO (0x00008000) -#define GE_E0_RX_CONTROL_EAI (0x20000000) -#define GE_E0_RX_CONTROL_ABT (0x40000000) -#define GE_E0_RX_CONTROL_EII (0x80000000) - -#define reg_RX_EXTENDED_STATUS(base) __REG32(base, 0x0000032c) -#define RX_EXTENDED_STATUS (0x0000032c) -#define RX_EXTENDED_STATUS_EOQ (0x0000000f) -#define RX_EXTENDED_STATUS_EOQ_0 (0x00000001) -#define RX_EXTENDED_STATUS_EOF (0x00000f00) -#define RX_EXTENDED_STATUS_DESCRIPTOR_INTERRUPT_CONDITION (0x000f0000) -#define RX_EXTENDED_STATUS_ERROR_FLAG (0x0f000000) - -#define reg_RX_THRESHOLDS(base) __REG32(base, 0x00000330) - -#define reg_RX_DIAGNOSTIC_ADDR(base) __REG32(base, 0x00000370) -#define RX_DIAGNOSTIC_ADDR_INDEX (0x0000007f) -#define RX_DIAGNOSTIC_ADDR_DFR (0x40000000) -#define RX_DIAGNOSTIC_ADDR_AI (0x80000000) - -#define reg_RX_DIAGNOSTIC_DATA(base) __REG32(base, 0x00000374) - -#define reg_RX_QUEUE_0_CONFIG(base) __REG32(base, 0x00000380) -#define RX_QUEUE_0_CONFIG_OCN_PORT (0x0000003f) -#define RX_QUEUE_0_CONFIG_BSWP (0x00000400) -#define RX_QUEUE_0_CONFIG_WSWP (0x00000800) -#define RX_QUEUE_0_CONFIG_AM (0x00004000) -#define RX_QUEUE_0_CONFIG_EEI (0x00010000) -#define RX_QUEUE_0_CONFIG_ELI (0x00020000) -#define RX_QUEUE_0_CONFIG_ENI (0x00040000) -#define RX_QUEUE_0_CONFIG_ESI (0x00080000) -#define RX_QUEUE_0_CONFIG_EDI (0x00100000) - -#define reg_RX_QUEUE_0_BUF_CONFIG(base) __REG32(base, 0x00000384) -#define RX_QUEUE_0_BUF_CONFIG_OCN_PORT (0x0000003f) -#define RX_QUEUE_0_BUF_CONFIG_BURST (0x00000300) -#define RX_QUEUE_0_BUF_CONFIG_BSWP (0x00000400) -#define RX_QUEUE_0_BUF_CONFIG_WSWP (0x00000800) - -#define reg_RX_QUEUE_0_PTR_LOW(base) __REG32(base, 0x00000388) - -#define reg_RX_QUEUE_0_PTR_HIGH(base) __REG32(base, 0x0000038c) -#define RX_QUEUE_0_PTR_HIGH_VALID (0x80000000) +#define OCN_PORT_PROCESSOR_SLAVE 3 /* Processor Interface (slave) */ +#define OCN_PORT_MEMORY 4 /* Memory Controller */ +#define OCN_PORT_DMA 5 /* DMA Controller */ +#define OCN_PORT_ETHERNET 6 /* Ethernet Controller */ +#define OCN_PORT_PRINT 7 /* Print Engine Interface */ + +#define reg_TX_QUEUE_0_PTR_LOW(base) __REG32(base, 0x00000288) + +#define reg_TX_QUEUE_0_PTR_HIGH(base) __REG32(base, 0x0000028c) +#define TX_QUEUE_0_PTR_HIGH_VALID (0x80000000) + +#define reg_RX_CONFIG(base) __REG32(base, 0x00000320) +#define RX_CONFIG_DEF_Q (0x00000003) +#define RX_CONFIG_EMF (0x00000100) +#define RX_CONFIG_EUF (0x00000200) +#define RX_CONFIG_BFE (0x00000400) +#define RX_CONFIG_MFE (0x00000800) +#define RX_CONFIG_UFE (0x00001000) +#define RX_CONFIG_SE (0x00002000) +#define RX_CONFIG_ABF (0x00200000) +#define RX_CONFIG_APE (0x00400000) +#define RX_CONFIG_CHP (0x00800000) +#define RX_CONFIG_RST (0x80000000) + +#define reg_RX_CONTROL(base) __REG32(base, 0x00000324) +#define GE_E0_RX_CONTROL_QUEUE_ENABLES (0x0000000f) +#define GE_E0_RX_CONTROL_GO (0x00008000) +#define GE_E0_RX_CONTROL_EAI (0x20000000) +#define GE_E0_RX_CONTROL_ABT (0x40000000) +#define GE_E0_RX_CONTROL_EII (0x80000000) + +#define reg_RX_EXTENDED_STATUS(base) __REG32(base, 0x0000032c) +#define RX_EXTENDED_STATUS (0x0000032c) +#define RX_EXTENDED_STATUS_EOQ (0x0000000f) +#define RX_EXTENDED_STATUS_EOQ_0 (0x00000001) +#define RX_EXTENDED_STATUS_EOF (0x00000f00) +#define RX_EXTENDED_STATUS_DESCRIPTOR_INTERRUPT_CONDITION (0x000f0000) +#define RX_EXTENDED_STATUS_ERROR_FLAG (0x0f000000) + +#define reg_RX_THRESHOLDS(base) __REG32(base, 0x00000330) + +#define reg_RX_DIAGNOSTIC_ADDR(base) __REG32(base, 0x00000370) +#define RX_DIAGNOSTIC_ADDR_INDEX (0x0000007f) +#define RX_DIAGNOSTIC_ADDR_DFR (0x40000000) +#define RX_DIAGNOSTIC_ADDR_AI (0x80000000) + +#define reg_RX_DIAGNOSTIC_DATA(base) __REG32(base, 0x00000374) + +#define reg_RX_QUEUE_0_CONFIG(base) __REG32(base, 0x00000380) +#define RX_QUEUE_0_CONFIG_OCN_PORT (0x0000003f) +#define RX_QUEUE_0_CONFIG_BSWP (0x00000400) +#define RX_QUEUE_0_CONFIG_WSWP (0x00000800) +#define RX_QUEUE_0_CONFIG_AM (0x00004000) +#define RX_QUEUE_0_CONFIG_EEI (0x00010000) +#define RX_QUEUE_0_CONFIG_ELI (0x00020000) +#define RX_QUEUE_0_CONFIG_ENI (0x00040000) +#define RX_QUEUE_0_CONFIG_ESI (0x00080000) +#define RX_QUEUE_0_CONFIG_EDI (0x00100000) + +#define reg_RX_QUEUE_0_BUF_CONFIG(base) __REG32(base, 0x00000384) +#define RX_QUEUE_0_BUF_CONFIG_OCN_PORT (0x0000003f) +#define RX_QUEUE_0_BUF_CONFIG_BURST (0x00000300) +#define RX_QUEUE_0_BUF_CONFIG_BSWP (0x00000400) +#define RX_QUEUE_0_BUF_CONFIG_WSWP (0x00000800) + +#define reg_RX_QUEUE_0_PTR_LOW(base) __REG32(base, 0x00000388) + +#define reg_RX_QUEUE_0_PTR_HIGH(base) __REG32(base, 0x0000038c) +#define RX_QUEUE_0_PTR_HIGH_VALID (0x80000000) /* * PHY register definitions */ /* the first 15 PHY registers are standard. */ -#define PHY_CTRL_REG 0 /* Control Register */ -#define PHY_STATUS_REG 1 /* Status Regiser */ -#define PHY_ID1_REG 2 /* Phy Id Reg (word 1) */ -#define PHY_ID2_REG 3 /* Phy Id Reg (word 2) */ -#define PHY_AN_ADV_REG 4 /* Autoneg Advertisement */ -#define PHY_LP_ABILITY_REG 5 /* Link Partner Ability (Base Page) */ -#define PHY_AUTONEG_EXP_REG 6 /* Autoneg Expansion Reg */ -#define PHY_NEXT_PAGE_TX_REG 7 /* Next Page TX */ -#define PHY_LP_NEXT_PAGE_REG 8 /* Link Partner Next Page */ -#define PHY_1000T_CTRL_REG 9 /* 1000Base-T Control Reg */ -#define PHY_1000T_STATUS_REG 10 /* 1000Base-T Status Reg */ -#define PHY_EXT_STATUS_REG 11 /* Extended Status Reg */ +#define PHY_CTRL_REG 0 /* Control Register */ +#define PHY_STATUS_REG 1 /* Status Regiser */ +#define PHY_ID1_REG 2 /* Phy Id Reg (word 1) */ +#define PHY_ID2_REG 3 /* Phy Id Reg (word 2) */ +#define PHY_AN_ADV_REG 4 /* Autoneg Advertisement */ +#define PHY_LP_ABILITY_REG 5 /* Link Partner Ability (Base Page) */ +#define PHY_AUTONEG_EXP_REG 6 /* Autoneg Expansion Reg */ +#define PHY_NEXT_PAGE_TX_REG 7 /* Next Page TX */ +#define PHY_LP_NEXT_PAGE_REG 8 /* Link Partner Next Page */ +#define PHY_1000T_CTRL_REG 9 /* 1000Base-T Control Reg */ +#define PHY_1000T_STATUS_REG 10 /* 1000Base-T Status Reg */ +#define PHY_EXT_STATUS_REG 11 /* Extended Status Reg */ /* * PHY Register bit masks. */ -#define PHY_CTRL_RESET (1 << 15) -#define PHY_CTRL_LOOPBACK (1 << 14) -#define PHY_CTRL_SPEED0 (1 << 13) -#define PHY_CTRL_AN_EN (1 << 12) -#define PHY_CTRL_PWR_DN (1 << 11) -#define PHY_CTRL_ISOLATE (1 << 10) -#define PHY_CTRL_RESTART_AN (1 << 9) -#define PHY_CTRL_FULL_DUPLEX (1 << 8) -#define PHY_CTRL_CT_EN (1 << 7) -#define PHY_CTRL_SPEED1 (1 << 6) - -#define PHY_STAT_100BASE_T4 (1 << 15) -#define PHY_STAT_100BASE_X_FD (1 << 14) -#define PHY_STAT_100BASE_X_HD (1 << 13) -#define PHY_STAT_10BASE_T_FD (1 << 12) -#define PHY_STAT_10BASE_T_HD (1 << 11) -#define PHY_STAT_100BASE_T2_FD (1 << 10) -#define PHY_STAT_100BASE_T2_HD (1 << 9) -#define PHY_STAT_EXT_STAT (1 << 8) -#define PHY_STAT_RESERVED (1 << 7) -#define PHY_STAT_MFPS (1 << 6) /* Management Frames Preamble Suppression */ -#define PHY_STAT_AN_COMPLETE (1 << 5) -#define PHY_STAT_REM_FAULT (1 << 4) -#define PHY_STAT_AN_CAP (1 << 3) -#define PHY_STAT_LINK_UP (1 << 2) -#define PHY_STAT_JABBER (1 << 1) -#define PHY_STAT_EXT_CAP (1 << 0) - -#define TBI_CONTROL_2 0x11 -#define TBI_CONTROL_2_ENABLE_COMMA_DETECT 0x0001 -#define TBI_CONTROL_2_ENABLE_WRAP 0x0002 -#define TBI_CONTROL_2_G_MII_MODE 0x0010 -#define TBI_CONTROL_2_RECEIVE_CLOCK_SELECT 0x0020 -#define TBI_CONTROL_2_AUTO_NEGOTIATION_SENSE 0x0100 -#define TBI_CONTROL_2_DISABLE_TRANSMIT_RUNNING_DISPARITY 0x1000 -#define TBI_CONTROL_2_DISABLE_RECEIVE_RUNNING_DISPARITY 0x2000 -#define TBI_CONTROL_2_SHORTCUT_LINK_TIMER 0x4000 -#define TBI_CONTROL_2_SOFT_RESET 0x8000 +#define PHY_CTRL_RESET (1 << 15) +#define PHY_CTRL_LOOPBACK (1 << 14) +#define PHY_CTRL_SPEED0 (1 << 13) +#define PHY_CTRL_AN_EN (1 << 12) +#define PHY_CTRL_PWR_DN (1 << 11) +#define PHY_CTRL_ISOLATE (1 << 10) +#define PHY_CTRL_RESTART_AN (1 << 9) +#define PHY_CTRL_FULL_DUPLEX (1 << 8) +#define PHY_CTRL_CT_EN (1 << 7) +#define PHY_CTRL_SPEED1 (1 << 6) + +#define PHY_STAT_100BASE_T4 (1 << 15) +#define PHY_STAT_100BASE_X_FD (1 << 14) +#define PHY_STAT_100BASE_X_HD (1 << 13) +#define PHY_STAT_10BASE_T_FD (1 << 12) +#define PHY_STAT_10BASE_T_HD (1 << 11) +#define PHY_STAT_100BASE_T2_FD (1 << 10) +#define PHY_STAT_100BASE_T2_HD (1 << 9) +#define PHY_STAT_EXT_STAT (1 << 8) +#define PHY_STAT_RESERVED (1 << 7) +#define PHY_STAT_MFPS (1 << 6) /* Management Frames Preamble Suppression */ +#define PHY_STAT_AN_COMPLETE (1 << 5) +#define PHY_STAT_REM_FAULT (1 << 4) +#define PHY_STAT_AN_CAP (1 << 3) +#define PHY_STAT_LINK_UP (1 << 2) +#define PHY_STAT_JABBER (1 << 1) +#define PHY_STAT_EXT_CAP (1 << 0) + +#define TBI_CONTROL_2 0x11 +#define TBI_CONTROL_2_ENABLE_COMMA_DETECT 0x0001 +#define TBI_CONTROL_2_ENABLE_WRAP 0x0002 +#define TBI_CONTROL_2_G_MII_MODE 0x0010 +#define TBI_CONTROL_2_RECEIVE_CLOCK_SELECT 0x0020 +#define TBI_CONTROL_2_AUTO_NEGOTIATION_SENSE 0x0100 +#define TBI_CONTROL_2_DISABLE_TRANSMIT_RUNNING_DISPARITY 0x1000 +#define TBI_CONTROL_2_DISABLE_RECEIVE_RUNNING_DISPARITY 0x2000 +#define TBI_CONTROL_2_SHORTCUT_LINK_TIMER 0x4000 +#define TBI_CONTROL_2_SOFT_RESET 0x8000 /* marvel specific */ -#define MV1111_EXT_CTRL1_REG 16 /* PHY Specific Control Reg */ -#define MV1111_SPEC_STAT_REG 17 /* PHY Specific Status Reg */ -#define MV1111_EXT_CTRL2_REG 20 /* Extended PHY Specific Control Reg */ +#define MV1111_EXT_CTRL1_REG 16 /* PHY Specific Control Reg */ +#define MV1111_SPEC_STAT_REG 17 /* PHY Specific Status Reg */ +#define MV1111_EXT_CTRL2_REG 20 /* Extended PHY Specific Control Reg */ /* * MARVELL 88E1111 PHY register bit masks */ /* PHY Specific Status Register (MV1111_EXT_CTRL1_REG) */ -#define SPEC_STAT_SPEED_MASK (3 << 14) -#define SPEC_STAT_FULL_DUP (1 << 13) -#define SPEC_STAT_PAGE_RCVD (1 << 12) -#define SPEC_STAT_RESOLVED (1 << 11) /* Speed and Duplex Resolved */ -#define SPEC_STAT_LINK_UP (1 << 10) -#define SPEC_STAT_CABLE_LEN_MASK (7 << 7) /* Cable Length (100/1000 modes only) */ -#define SPEC_STAT_MDIX (1 << 6) -#define SPEC_STAT_POLARITY (1 << 1) -#define SPEC_STAT_JABBER (1 << 0) +#define SPEC_STAT_SPEED_MASK (3 << 14) +#define SPEC_STAT_FULL_DUP (1 << 13) +#define SPEC_STAT_PAGE_RCVD (1 << 12) +#define SPEC_STAT_RESOLVED (1 << 11) /* Speed and Duplex Resolved */ +#define SPEC_STAT_LINK_UP (1 << 10) +#define SPEC_STAT_CABLE_LEN_MASK (7 << 7)/* Cable Length (100/1000 modes only) */ +#define SPEC_STAT_MDIX (1 << 6) +#define SPEC_STAT_POLARITY (1 << 1) +#define SPEC_STAT_JABBER (1 << 0) -#define SPEED_1000 (2 << 14) -#define SPEED_100 (1 << 14) -#define SPEED_10 (0 << 14) +#define SPEED_1000 (2 << 14) +#define SPEED_100 (1 << 14) +#define SPEED_10 (0 << 14) -#define TBI_ADDR 0x1E /* Ten Bit Interface address */ +#define TBI_ADDR 0x1E /* Ten Bit Interface address */ /* negotiated link parameters */ -#define LINK_SPEED_UNKNOWN 0 -#define LINK_SPEED_10 1 -#define LINK_SPEED_100 2 -#define LINK_SPEED_1000 3 +#define LINK_SPEED_UNKNOWN 0 +#define LINK_SPEED_10 1 +#define LINK_SPEED_100 2 +#define LINK_SPEED_1000 3 -#define LINK_DUPLEX_UNKNOWN 0 -#define LINK_DUPLEX_HALF 1 -#define LINK_DUPLEX_FULL 2 +#define LINK_DUPLEX_UNKNOWN 0 +#define LINK_DUPLEX_HALF 1 +#define LINK_DUPLEX_FULL 2 static unsigned int phy_address[] = { 8, 9 }; @@ -390,56 +392,56 @@ struct dma_descriptor { }; /* last next descriptor address flag */ -#define DMA_DESCR_LAST (1 << 31) +#define DMA_DESCR_LAST (1 << 31) /* TX DMA descriptor config status bits */ -#define DMA_DESCR_TX_EOF (1 << 0) /* end of frame */ -#define DMA_DESCR_TX_SOF (1 << 1) /* start of frame */ -#define DMA_DESCR_TX_PFVLAN (1 << 2) -#define DMA_DESCR_TX_HUGE (1 << 3) -#define DMA_DESCR_TX_PAD (1 << 4) -#define DMA_DESCR_TX_CRC (1 << 5) -#define DMA_DESCR_TX_DESCR_INT (1 << 14) -#define DMA_DESCR_TX_RETRY_COUNT 0x000F0000 -#define DMA_DESCR_TX_ONE_COLLISION (1 << 20) -#define DMA_DESCR_TX_LATE_COLLISION (1 << 24) -#define DMA_DESCR_TX_UNDERRUN (1 << 25) -#define DMA_DESCR_TX_RETRY_LIMIT (1 << 26) -#define DMA_DESCR_TX_OK (1 << 30) -#define DMA_DESCR_TX_OWNER (1 << 31) +#define DMA_DESCR_TX_EOF (1 << 0) /* end of frame */ +#define DMA_DESCR_TX_SOF (1 << 1) /* start of frame */ +#define DMA_DESCR_TX_PFVLAN (1 << 2) +#define DMA_DESCR_TX_HUGE (1 << 3) +#define DMA_DESCR_TX_PAD (1 << 4) +#define DMA_DESCR_TX_CRC (1 << 5) +#define DMA_DESCR_TX_DESCR_INT (1 << 14) +#define DMA_DESCR_TX_RETRY_COUNT 0x000F0000 +#define DMA_DESCR_TX_ONE_COLLISION (1 << 20) +#define DMA_DESCR_TX_LATE_COLLISION (1 << 24) +#define DMA_DESCR_TX_UNDERRUN (1 << 25) +#define DMA_DESCR_TX_RETRY_LIMIT (1 << 26) +#define DMA_DESCR_TX_OK (1 << 30) +#define DMA_DESCR_TX_OWNER (1 << 31) /* RX DMA descriptor status bits */ -#define DMA_DESCR_RX_EOF (1 << 0) -#define DMA_DESCR_RX_SOF (1 << 1) -#define DMA_DESCR_RX_VTF (1 << 2) -#define DMA_DESCR_RX_FRAME_IS_TYPE (1 << 3) -#define DMA_DESCR_RX_SHORT_FRAME (1 << 4) -#define DMA_DESCR_RX_HASH_MATCH (1 << 7) -#define DMA_DESCR_RX_BAD_FRAME (1 << 8) -#define DMA_DESCR_RX_OVERRUN (1 << 9) -#define DMA_DESCR_RX_MAX_FRAME_LEN (1 << 11) -#define DMA_DESCR_RX_CRC_ERROR (1 << 12) -#define DMA_DESCR_RX_DESCR_INT (1 << 13) -#define DMA_DESCR_RX_OWNER (1 << 15) - -#define RX_BUFFER_SIZE PKTSIZE -#define NUM_RX_DESC PKTBUFSRX +#define DMA_DESCR_RX_EOF (1 << 0) +#define DMA_DESCR_RX_SOF (1 << 1) +#define DMA_DESCR_RX_VTF (1 << 2) +#define DMA_DESCR_RX_FRAME_IS_TYPE (1 << 3) +#define DMA_DESCR_RX_SHORT_FRAME (1 << 4) +#define DMA_DESCR_RX_HASH_MATCH (1 << 7) +#define DMA_DESCR_RX_BAD_FRAME (1 << 8) +#define DMA_DESCR_RX_OVERRUN (1 << 9) +#define DMA_DESCR_RX_MAX_FRAME_LEN (1 << 11) +#define DMA_DESCR_RX_CRC_ERROR (1 << 12) +#define DMA_DESCR_RX_DESCR_INT (1 << 13) +#define DMA_DESCR_RX_OWNER (1 << 15) + +#define RX_BUFFER_SIZE PKTSIZE +#define NUM_RX_DESC PKTBUFSRX static struct dma_descriptor tx_descriptor __attribute__ ((aligned(32))); static struct dma_descriptor rx_descr_array[NUM_RX_DESC] - __attribute__ ((aligned(32))); + __attribute__ ((aligned(32))); static struct dma_descriptor *rx_descr_current; -static int tsi108_eth_probe(struct eth_device *dev, bd_t * bis); -static int tsi108_eth_send(struct eth_device *dev, +static int tsi108_eth_probe (struct eth_device *dev, bd_t * bis); +static int tsi108_eth_send (struct eth_device *dev, volatile void *packet, int length); -static int tsi108_eth_recv(struct eth_device *dev); -static void tsi108_eth_halt(struct eth_device *dev); -static unsigned int read_phy(unsigned int base, +static int tsi108_eth_recv (struct eth_device *dev); +static void tsi108_eth_halt (struct eth_device *dev); +static unsigned int read_phy (unsigned int base, unsigned int phy_addr, unsigned int phy_reg); -static void write_phy(unsigned int base, +static void write_phy (unsigned int base, unsigned int phy_addr, unsigned int phy_reg, unsigned int phy_data); @@ -447,15 +449,15 @@ static void write_phy(unsigned int base, /* * print phy debug infomation */ -static void dump_phy_regs(unsigned int phy_addr) +static void dump_phy_regs (unsigned int phy_addr) { int i; - printf("PHY %d registers\n", phy_addr); + printf ("PHY %d registers\n", phy_addr); for (i = 0; i <= 30; i++) { - printf("%2d 0x%04x\n", i, read_phy(ETH_BASE, phy_addr, i)); + printf ("%2d 0x%04x\n", i, read_phy (ETH_BASE, phy_addr, i)); } - printf("\n"); + printf ("\n"); } #else @@ -466,27 +468,27 @@ static void dump_phy_regs(unsigned int phy_addr) /* * print debug infomation */ -static void tx_diag_regs(unsigned int base) +static void tx_diag_regs (unsigned int base) { int i; unsigned long dummy; - printf("TX diagnostics registers\n"); + printf ("TX diagnostics registers\n"); reg_TX_DIAGNOSTIC_ADDR(base) = 0x00 | TX_DIAGNOSTIC_ADDR_AI; - udelay(1000); + udelay (1000); dummy = reg_TX_DIAGNOSTIC_DATA(base); for (i = 0x00; i <= 0x05; i++) { - udelay(1000); - printf("0x%02x 0x%08x\n", i, reg_TX_DIAGNOSTIC_DATA(base)); + udelay (1000); + printf ("0x%02x 0x%08x\n", i, reg_TX_DIAGNOSTIC_DATA(base)); } reg_TX_DIAGNOSTIC_ADDR(base) = 0x40 | TX_DIAGNOSTIC_ADDR_AI; - udelay(1000); + udelay (1000); dummy = reg_TX_DIAGNOSTIC_DATA(base); for (i = 0x40; i <= 0x47; i++) { - udelay(1000); - printf("0x%02x 0x%08x\n", i, reg_TX_DIAGNOSTIC_DATA(base)); + udelay (1000); + printf ("0x%02x 0x%08x\n", i, reg_TX_DIAGNOSTIC_DATA(base)); } - printf("\n"); + printf ("\n"); } #else @@ -497,27 +499,27 @@ static void tx_diag_regs(unsigned int base) /* * print debug infomation */ -static void rx_diag_regs(unsigned int base) +static void rx_diag_regs (unsigned int base) { int i; unsigned long dummy; - printf("RX diagnostics registers\n"); + printf ("RX diagnostics registers\n"); reg_RX_DIAGNOSTIC_ADDR(base) = 0x00 | RX_DIAGNOSTIC_ADDR_AI; - udelay(1000); + udelay (1000); dummy = reg_RX_DIAGNOSTIC_DATA(base); for (i = 0x00; i <= 0x05; i++) { - udelay(1000); - printf("0x%02x 0x%08x\n", i, reg_RX_DIAGNOSTIC_DATA(base)); + udelay (1000); + printf ("0x%02x 0x%08x\n", i, reg_RX_DIAGNOSTIC_DATA(base)); } reg_RX_DIAGNOSTIC_ADDR(base) = 0x40 | RX_DIAGNOSTIC_ADDR_AI; - udelay(1000); + udelay (1000); dummy = reg_RX_DIAGNOSTIC_DATA(base); for (i = 0x08; i <= 0x0a; i++) { - udelay(1000); - printf("0x%02x 0x%08x\n", i, reg_RX_DIAGNOSTIC_DATA(base)); + udelay (1000); + printf ("0x%02x 0x%08x\n", i, reg_RX_DIAGNOSTIC_DATA(base)); } - printf("\n"); + printf ("\n"); } #else @@ -528,15 +530,15 @@ static void rx_diag_regs(unsigned int base) /* * print debug infomation */ -static void debug_mii_regs(unsigned int base) +static void debug_mii_regs (unsigned int base) { - printf("MII_MGMT_CONFIG 0x%08x\n", reg_MII_MGMT_CONFIG(base)); - printf("MII_MGMT_COMMAND 0x%08x\n", reg_MII_MGMT_COMMAND(base)); - printf("MII_MGMT_ADDRESS 0x%08x\n", reg_MII_MGMT_ADDRESS(base)); - printf("MII_MGMT_CONTROL 0x%08x\n", reg_MII_MGMT_CONTROL(base)); - printf("MII_MGMT_STATUS 0x%08x\n", reg_MII_MGMT_STATUS(base)); - printf("MII_MGMT_INDICATORS 0x%08x\n", reg_MII_MGMT_INDICATORS(base)); - printf("\n"); + printf ("MII_MGMT_CONFIG 0x%08x\n", reg_MII_MGMT_CONFIG(base)); + printf ("MII_MGMT_COMMAND 0x%08x\n", reg_MII_MGMT_COMMAND(base)); + printf ("MII_MGMT_ADDRESS 0x%08x\n", reg_MII_MGMT_ADDRESS(base)); + printf ("MII_MGMT_CONTROL 0x%08x\n", reg_MII_MGMT_CONTROL(base)); + printf ("MII_MGMT_STATUS 0x%08x\n", reg_MII_MGMT_STATUS(base)); + printf ("MII_MGMT_INDICATORS 0x%08x\n", reg_MII_MGMT_INDICATORS(base)); + printf ("\n"); } #else @@ -546,15 +548,15 @@ static void debug_mii_regs(unsigned int base) /* * Wait until the phy bus is non-busy */ -static void phy_wait(unsigned int base, unsigned int condition) +static void phy_wait (unsigned int base, unsigned int condition) { int timeout; timeout = 0; while (reg_MII_MGMT_INDICATORS(base) & condition) { - udelay(10); + udelay (10); if (++timeout > 10000) { - printf("ERROR: timeout waiting for phy bus (%d)\n", + printf ("ERROR: timeout waiting for phy bus (%d)\n", condition); break; } @@ -564,12 +566,12 @@ static void phy_wait(unsigned int base, unsigned int condition) /* * read phy register */ -static unsigned int read_phy(unsigned int base, +static unsigned int read_phy (unsigned int base, unsigned int phy_addr, unsigned int phy_reg) { unsigned int value; - phy_wait(base, MII_MGMT_INDICATORS_BUSY); + phy_wait (base, MII_MGMT_INDICATORS_BUSY); reg_MII_MGMT_ADDRESS(base) = (phy_addr << 8) | phy_reg; @@ -580,7 +582,7 @@ static unsigned int read_phy(unsigned int base, reg_MII_MGMT_COMMAND(base) = MII_MGMT_COMMAND_READ_CYCLE; /* wait for the read to complete */ - phy_wait(base, + phy_wait (base, MII_MGMT_INDICATORS_NOT_VALID | MII_MGMT_INDICATORS_BUSY); value = reg_MII_MGMT_STATUS(base); @@ -593,11 +595,11 @@ static unsigned int read_phy(unsigned int base, /* * write phy register */ -static void write_phy(unsigned int base, +static void write_phy (unsigned int base, unsigned int phy_addr, unsigned int phy_reg, unsigned int phy_data) { - phy_wait(base, MII_MGMT_INDICATORS_BUSY); + phy_wait (base, MII_MGMT_INDICATORS_BUSY); reg_MII_MGMT_ADDRESS(base) = (phy_addr << 8) | phy_reg; @@ -611,7 +613,7 @@ static void write_phy(unsigned int base, /* * configure the marvell 88e1111 phy */ -static int marvell_88e_phy_config(struct eth_device *dev, int *speed, +static int marvell_88e_phy_config (struct eth_device *dev, int *speed, int *duplex) { unsigned long base; @@ -630,40 +632,39 @@ static int marvell_88e_phy_config(struct eth_device *dev, int *speed, phy_addr = (unsigned long)dev->priv; /* Take the PHY out of reset. */ - write_phy(ETH_BASE, phy_addr, PHY_CTRL_REG, PHY_CTRL_RESET); + write_phy (ETH_BASE, phy_addr, PHY_CTRL_REG, PHY_CTRL_RESET); /* Wait for the reset process to complete. */ - udelay(10); + udelay (10); timeout = 0; while ((phy_status = - read_phy(ETH_BASE, phy_addr, PHY_CTRL_REG)) & PHY_CTRL_RESET) { - udelay(10); + read_phy (ETH_BASE, phy_addr, PHY_CTRL_REG)) & PHY_CTRL_RESET) { + udelay (10); if (++timeout > 10000) { - printf("ERROR: timeout waiting for phy reset\n"); + printf ("ERROR: timeout waiting for phy reset\n"); break; } } /* TBI Configuration. */ - write_phy(base, TBI_ADDR, TBI_CONTROL_2, TBI_CONTROL_2_G_MII_MODE | + write_phy (base, TBI_ADDR, TBI_CONTROL_2, TBI_CONTROL_2_G_MII_MODE | TBI_CONTROL_2_RECEIVE_CLOCK_SELECT); /* Wait for the link to be established. */ timeout = 0; do { - udelay(20000); - phy_status = read_phy(ETH_BASE, phy_addr, PHY_STATUS_REG); + udelay (20000); + phy_status = read_phy (ETH_BASE, phy_addr, PHY_STATUS_REG); if (++timeout > 100) { debug_lev(1, "ERROR: unable to establish link!!!\n"); break; } } while ((phy_status & PHY_STAT_LINK_UP) == 0); - if ((phy_status & PHY_STAT_LINK_UP) == 0) { + if ((phy_status & PHY_STAT_LINK_UP) == 0) return 0; - } value = 0; - phy_spec_status = read_phy(ETH_BASE, phy_addr, MV1111_SPEC_STAT_REG); + phy_spec_status = read_phy (ETH_BASE, phy_addr, MV1111_SPEC_STAT_REG); if (phy_spec_status & SPEC_STAT_RESOLVED) { switch (phy_spec_status & SPEC_STAT_SPEED_MASK) { case SPEED_1000: @@ -681,45 +682,41 @@ static int marvell_88e_phy_config(struct eth_device *dev, int *speed, if (phy_spec_status & SPEC_STAT_FULL_DUP) { phy_duplex = LINK_DUPLEX_FULL; value |= PHY_CTRL_FULL_DUPLEX; - } else { + } else phy_duplex = LINK_DUPLEX_HALF; - } } /* set TBI speed */ - write_phy(base, TBI_ADDR, PHY_CTRL_REG, value); - write_phy(base, TBI_ADDR, PHY_AN_ADV_REG, 0x0060); + write_phy (base, TBI_ADDR, PHY_CTRL_REG, value); + write_phy (base, TBI_ADDR, PHY_AN_ADV_REG, 0x0060); #if TSI108_ETH_DEBUG > 0 - printf("%s link is up", dev->name); - phy_spec_status = read_phy(ETH_BASE, phy_addr, MV1111_SPEC_STAT_REG); + printf ("%s link is up", dev->name); + phy_spec_status = read_phy (ETH_BASE, phy_addr, MV1111_SPEC_STAT_REG); if (phy_spec_status & SPEC_STAT_RESOLVED) { switch (phy_speed) { case LINK_SPEED_1000: - printf(", 1000 Mbps"); + printf (", 1000 Mbps"); break; case LINK_SPEED_100: - printf(", 100 Mbps"); + printf (", 100 Mbps"); break; case LINK_SPEED_10: - printf(", 10 Mbps"); + printf (", 10 Mbps"); break; } - if (phy_duplex == LINK_DUPLEX_FULL) { - printf(", Full duplex"); - } else { - printf(", Half duplex"); - } + if (phy_duplex == LINK_DUPLEX_FULL) + printf (", Full duplex"); + else + printf (", Half duplex"); } - printf("\n"); + printf ("\n"); #endif - dump_phy_regs(TBI_ADDR); - if (speed) { + dump_phy_regs (TBI_ADDR); + if (speed) *speed = phy_speed; - } - if (duplex) { + if (duplex) *duplex = phy_duplex; - } return 1; } @@ -729,7 +726,7 @@ static int marvell_88e_phy_config(struct eth_device *dev, int *speed, * * register the tsi108 ethernet controllers with the multi-ethernet system */ -int tsi108_eth_initialize(bd_t * bis) +int tsi108_eth_initialize (bd_t * bis) { struct eth_device *dev; int index; @@ -737,7 +734,7 @@ int tsi108_eth_initialize(bd_t * bis) for (index = 0; index < CONFIG_TSI108_ETH_NUM_PORTS; index++) { dev = (struct eth_device *)malloc(sizeof(struct eth_device)); - sprintf(dev->name, "TSI108_eth%d", index); + sprintf (dev->name, "TSI108_eth%d", index); dev->iobase = ETH_BASE + (index * ETH_PORT_OFFSET); dev->priv = (void *)(phy_address[index]); @@ -754,7 +751,7 @@ int tsi108_eth_initialize(bd_t * bis) /* * probe for and initialize a single ethernet interface */ -static int tsi108_eth_probe(struct eth_device *dev, bd_t * bis) +static int tsi108_eth_probe (struct eth_device *dev, bd_t * bis) { unsigned long base; unsigned long value; @@ -794,25 +791,23 @@ static int tsi108_eth_probe(struct eth_device *dev, bd_t * bis) reg_STATION_ADDRESS_2(base) = (dev->enetaddr[1] << 24) | (dev->enetaddr[0] << 16); - if (marvell_88e_phy_config(dev, &speed, &duplex) == 0) { + if (marvell_88e_phy_config(dev, &speed, &duplex) == 0) return 0; - } value = MAC_CONFIG_2_PREAMBLE_LENGTH(7) | MAC_CONFIG_2_PAD_CRC | MAC_CONFIG_2_CRC_ENABLE; - if (speed == LINK_SPEED_1000) { + if (speed == LINK_SPEED_1000) value |= MAC_CONFIG_2_INTERFACE_MODE(INTERFACE_MODE_BYTE); - } else { + else { value |= MAC_CONFIG_2_INTERFACE_MODE(INTERFACE_MODE_NIBBLE); reg_PORT_CONTROL(base) |= PORT_CONTROL_SPD; } if (duplex == LINK_DUPLEX_FULL) { value |= MAC_CONFIG_2_FULL_DUPLEX; reg_PORT_CONTROL(base) &= ~PORT_CONTROL_BPT; - } else { + } else reg_PORT_CONTROL(base) |= PORT_CONTROL_BPT; - } reg_MAC_CONFIG_2(base) = value; reg_RX_CONFIG(base) = RX_CONFIG_SE; @@ -875,7 +870,7 @@ static int tsi108_eth_probe(struct eth_device *dev, bd_t * bis) /* * send a packet */ -static int tsi108_eth_send(struct eth_device *dev, +static int tsi108_eth_send (struct eth_device *dev, volatile void *packet, int length) { unsigned long base; @@ -894,9 +889,8 @@ static int tsi108_eth_send(struct eth_device *dev, (unsigned long)tx_descr + sizeof(struct dma_descriptor)); - if (timeout != 0) { - udelay(15); - } + if (timeout != 0) + udelay (15); if (++timeout > 10000) { tx_diag_regs(base); debug_lev(1, @@ -908,7 +902,7 @@ static int tsi108_eth_send(struct eth_device *dev, status = le32_to_cpu(tx_descr->config_status); if ((status & DMA_DESCR_TX_OK) == 0) { #ifdef TX_PRINT_ERRORS - printf("TX packet error: 0x%08x\n %s%s%s%s\n", status, + printf ("TX packet error: 0x%08x\n %s%s%s%s\n", status, status & DMA_DESCR_TX_OK ? "tx error, " : "", status & DMA_DESCR_TX_RETRY_LIMIT ? "retry limit reached, " : "", @@ -918,7 +912,7 @@ static int tsi108_eth_send(struct eth_device *dev, #endif } - debug_lev(9, "sending packet %d\n", length); + debug_lev (9, "sending packet %d\n", length); tx_descr->start_addr0 = cpu_to_le32((vuint32) packet); tx_descr->start_addr1 = 0; tx_descr->next_descr_addr0 = 0; @@ -946,7 +940,7 @@ static int tsi108_eth_send(struct eth_device *dev, /* * Check for received packets and send them up the protocal stack */ -static int tsi108_eth_recv(struct eth_device *dev) +static int tsi108_eth_recv (struct eth_device *dev) { struct dma_descriptor *rx_descr; unsigned long base; @@ -957,7 +951,7 @@ static int tsi108_eth_recv(struct eth_device *dev) base = dev->iobase; /* make sure we see the changes made by the DMA engine */ - invalidate_dcache_range((unsigned long)rx_descr_array, + invalidate_dcache_range ((unsigned long)rx_descr_array, (unsigned long)rx_descr_array + sizeof(rx_descr_array)); @@ -968,7 +962,7 @@ static int tsi108_eth_recv(struct eth_device *dev) status = le32_to_cpu(rx_descr->config_status); if (status & DMA_DESCR_RX_BAD_FRAME) { #ifdef RX_PRINT_ERRORS - printf("RX packet error: 0x%08x\n %s%s%s%s%s%s\n", + printf ("RX packet error: 0x%08x\n %s%s%s%s%s%s\n", status, status & DMA_DESCR_RX_FRAME_IS_TYPE ? "too big, " : "", @@ -989,24 +983,23 @@ static int tsi108_eth_recv(struct eth_device *dev) /*** process packet ***/ buffer = (volatile uchar - *)(le32_to_cpu(rx_descr->start_addr0)); - NetReceive(buffer, length); + *)(le32_to_cpu (rx_descr->start_addr0)); + NetReceive (buffer, length); - invalidate_dcache_range((unsigned long)buffer, + invalidate_dcache_range ((unsigned long)buffer, (unsigned long)buffer + RX_BUFFER_SIZE); } /* Give this buffer back to the DMA engine */ rx_descr->vlan_byte_count = 0; - rx_descr->config_status = cpu_to_le32((RX_BUFFER_SIZE << 16) | + rx_descr->config_status = cpu_to_le32 ((RX_BUFFER_SIZE << 16) | DMA_DESCR_RX_OWNER); /* move descriptor pointer forward */ rx_descr = (struct dma_descriptor - *)(le32_to_cpu(rx_descr->next_descr_addr0)); - if (rx_descr == 0) { + *)(le32_to_cpu (rx_descr->next_descr_addr0)); + if (rx_descr == 0) rx_descr = &rx_descr_array[0]; - } } /* remember where we are for next time */ rx_descr_current = rx_descr; @@ -1026,7 +1019,7 @@ static int tsi108_eth_recv(struct eth_device *dev) /* * disable an ethernet interface */ -static void tsi108_eth_halt(struct eth_device *dev) +static void tsi108_eth_halt (struct eth_device *dev) { unsigned long base; diff --git a/drivers/tsi108_i2c.c b/drivers/tsi108_i2c.c index 08e5e3b..c100cb8 100644 --- a/drivers/tsi108_i2c.c +++ b/drivers/tsi108_i2c.c @@ -23,19 +23,18 @@ */ #include +#include #ifdef CONFIG_TSI108_I2C - -#include #include #if (CONFIG_COMMANDS & CFG_CMD_I2C) -#define I2C_DELAY 100000 +#define I2C_DELAY 100000 #undef DEBUG_I2C #ifdef DEBUG_I2C -#define DPRINT(x) printf(x) +#define DPRINT(x) printf (x) #else #define DPRINT(x) #endif @@ -43,7 +42,7 @@ /* All functions assume that Tsi108 I2C block is the only master on the bus */ /* I2C read helper function */ -static int i2c_read_byte( +static int i2c_read_byte ( uint i2c_chan, /* I2C channel number: 0 - main, 1 - SDC SPD */ uchar chip_addr,/* I2C device address on the bus */ uint byte_addr, /* Byte address within I2C device */ @@ -55,19 +54,17 @@ static int i2c_read_byte( u32 op_status = TSI108_I2C_TIMEOUT_ERR; u32 chan_offset = TSI108_I2C_OFFSET; - DPRINT(("I2C read_byte() %d 0x%02x 0x%02x\n", + DPRINT (("I2C read_byte() %d 0x%02x 0x%02x\n", i2c_chan, chip_addr, byte_addr)); - if (0 != i2c_chan) { + if (0 != i2c_chan) chan_offset = TSI108_I2C_SDRAM_OFFSET; - } /* Check if I2C operation is in progress */ temp = *(u32 *) (CFG_TSI108_CSR_BASE + chan_offset + I2C_CNTRL2); if (0 == (temp & (I2C_CNTRL2_RD_STATUS | I2C_CNTRL2_WR_STATUS | - I2C_CNTRL2_START)) - ) { + I2C_CNTRL2_START))) { /* Set device address and operation (read = 0) */ temp = (byte_addr << 16) | ((chip_addr & 0x07) << 8) | ((chip_addr >> 3) & 0x0F); @@ -75,7 +72,7 @@ static int i2c_read_byte( temp; /* Issue the read command - * (at this moment all other parameters are 0 + * (at this moment all other parameters are 0 * (size = 1 byte, lane = 0) */ @@ -108,7 +105,7 @@ static int i2c_read_byte( /* report HW error */ op_status = TSI108_I2C_IF_ERROR; - DPRINT(("I2C HW error reported: 0x%02x\n", temp)); + DPRINT (("I2C HW error reported: 0x%02x\n", temp)); } break; @@ -117,20 +114,20 @@ static int i2c_read_byte( } else { op_status = TSI108_I2C_IF_BUSY; - DPRINT(("I2C Transaction start failed: 0x%02x\n", temp)); + DPRINT (("I2C Transaction start failed: 0x%02x\n", temp)); } - DPRINT(("I2C read_byte() status: 0x%02x\n", op_status)); + DPRINT (("I2C read_byte() status: 0x%02x\n", op_status)); return op_status; } -/* +/* * I2C Read interface as defined in "include/i2c.h" : * chip_addr: I2C chip address, range 0..127 * (to read from SPD channel EEPROM use (0xD0 ... 0xD7) * NOTE: The bit 7 in the chip_addr serves as a channel select. * This hack is for enabling "isdram" command on Tsi108 boards - * without changes to common code. Used for I2C reads only. + * without changes to common code. Used for I2C reads only. * byte_addr: Memory or register address within the chip * alen: Number of bytes to use for addr (typically 1, 2 for larger * memories, 0 for register type devices with only one @@ -141,7 +138,8 @@ static int i2c_read_byte( * Returns: 0 on success, not 0 on failure */ -int i2c_read(uchar chip_addr, uint byte_addr, int alen, uchar * buffer, int len) +int i2c_read (uchar chip_addr, uint byte_addr, int alen, + uchar * buffer, int len) { u32 op_status = TSI108_I2C_PARAM_ERR; u32 i2c_if = 0; @@ -159,20 +157,20 @@ int i2c_read(uchar chip_addr, uint byte_addr, int alen, uchar * buffer, int len) buffer++); if (TSI108_I2C_SUCCESS != op_status) { - DPRINT(("I2C read_byte() failed: 0x%02x (%d left)\n", op_status, len)); + DPRINT (("I2C read_byte() failed: 0x%02x (%d left)\n", op_status, len)); break; } } } - DPRINT(("I2C read() status: 0x%02x\n", op_status)); + DPRINT (("I2C read() status: 0x%02x\n", op_status)); return op_status; } /* I2C write helper function */ -static int i2c_write_byte(uchar chip_addr,/* I2C device address on the bus */ +static int i2c_write_byte (uchar chip_addr,/* I2C device address on the bus */ uint byte_addr, /* Byte address within I2C device */ uchar * buffer /* pointer to data buffer */ ) @@ -210,7 +208,7 @@ static int i2c_write_byte(uchar chip_addr,/* I2C device address on the bus */ /* Wait until operation completed */ do { - // Read I2C operation status + /* Read I2C operation status */ temp = *(u32 *) (CFG_TSI108_CSR_BASE + TSI108_I2C_OFFSET + I2C_CNTRL2); @@ -227,7 +225,7 @@ static int i2c_write_byte(uchar chip_addr,/* I2C device address on the bus */ /* report detected HW error */ op_status = TSI108_I2C_IF_ERROR; - DPRINT(("I2C HW error reported: 0x%02x\n", temp)); + DPRINT (("I2C HW error reported: 0x%02x\n", temp)); } break; @@ -237,13 +235,13 @@ static int i2c_write_byte(uchar chip_addr,/* I2C device address on the bus */ } else { op_status = TSI108_I2C_IF_BUSY; - DPRINT(("I2C Transaction start failed: 0x%02x\n", temp)); + DPRINT (("I2C Transaction start failed: 0x%02x\n", temp)); } return op_status; } -/* +/* * I2C Write interface as defined in "include/i2c.h" : * chip_addr: I2C chip address, range 0..127 * byte_addr: Memory or register address within the chip @@ -256,7 +254,7 @@ static int i2c_write_byte(uchar chip_addr,/* I2C device address on the bus */ * Returns: 0 on success, not 0 on failure */ -int i2c_write(uchar chip_addr, uint byte_addr, int alen, uchar * buffer, +int i2c_write (uchar chip_addr, uint byte_addr, int alen, uchar * buffer, int len) { u32 op_status = TSI108_I2C_PARAM_ERR; @@ -265,10 +263,10 @@ int i2c_write(uchar chip_addr, uint byte_addr, int alen, uchar * buffer, if (chip_addr <= 0x7F && (byte_addr + len) <= (0x01 << (alen * 8))) { while (len--) { op_status = - i2c_write_byte(chip_addr, byte_addr++, buffer++); + i2c_write_byte (chip_addr, byte_addr++, buffer++); if (TSI108_I2C_SUCCESS != op_status) { - DPRINT(("I2C write_byte() failed: 0x%02x (%d left)\n", op_status, len)); + DPRINT (("I2C write_byte() failed: 0x%02x (%d left)\n", op_status, len)); break; } @@ -278,13 +276,13 @@ int i2c_write(uchar chip_addr, uint byte_addr, int alen, uchar * buffer, return op_status; } -/* +/* * I2C interface function as defined in "include/i2c.h". * Probe the given I2C chip address by reading single byte from offset 0. * Returns 0 if a chip responded, not 0 on failure. */ -int i2c_probe(uchar chip) +int i2c_probe (uchar chip) { u32 tmp; @@ -293,8 +291,8 @@ int i2c_probe(uchar chip) * The Tsi108 HW doesn't support sending just the chip address * and checkong for an back. */ - return i2c_read(chip, 0, 1, (char *)&tmp, 1); + return i2c_read (chip, 0, 1, (char *)&tmp, 1); } -#endif /* (CONFIG_COMMANDS & CFG_CMD_I2C) */ +#endif /* (CONFIG_COMMANDS & CFG_CMD_I2C) */ #endif /* CONFIG_TSI108_I2C */ diff --git a/drivers/tsi108_pci.c b/drivers/tsi108_pci.c index f374ede..9f606df 100644 --- a/drivers/tsi108_pci.c +++ b/drivers/tsi108_pci.c @@ -36,7 +36,7 @@ struct pci_controller local_hose; -void tsi108_clear_pci_error(void) +void tsi108_clear_pci_error (void) { u32 err_stat, err_addr, pci_stat; @@ -79,11 +79,11 @@ void tsi108_clear_pci_error(void) return; } -unsigned int __get_pci_config_dword(u32 addr) +unsigned int __get_pci_config_dword (u32 addr) { unsigned int retval; - __asm__ __volatile__(" lwbrx %0,0,%1\n" + __asm__ __volatile__ (" lwbrx %0,0,%1\n" "1: eieio\n" "2:\n" ".section .fixup,\"ax\"\n" @@ -97,53 +97,53 @@ unsigned int __get_pci_config_dword(u32 addr) return (retval); } -static int tsi108_read_config_dword(struct pci_controller *hose, +static int tsi108_read_config_dword (struct pci_controller *hose, pci_dev_t dev, int offset, u32 * value) { dev &= (CFG_PCI_CFG_SIZE - 1); dev |= (CFG_PCI_CFG_BASE | (offset & 0xfc)); *value = __get_pci_config_dword(dev); if (0xFFFFFFFF == *value) - tsi108_clear_pci_error(); + tsi108_clear_pci_error (); return 0; } -static int tsi108_write_config_dword(struct pci_controller *hose, +static int tsi108_write_config_dword (struct pci_controller *hose, pci_dev_t dev, int offset, u32 value) { dev &= (CFG_PCI_CFG_SIZE - 1); dev |= (CFG_PCI_CFG_BASE | (offset & 0xfc)); - out_le32((volatile unsigned *)dev, value); + out_le32 ((volatile unsigned *)dev, value); return 0; } -void pci_init_board(void) +void pci_init_board (void) { struct pci_controller *hose = (struct pci_controller *)&local_hose; hose->first_busno = 0; hose->last_busno = 0xff; - pci_set_region(hose->regions + 0, + pci_set_region (hose->regions + 0, CFG_PCI_MEMORY_BUS, CFG_PCI_MEMORY_PHYS, CFG_PCI_MEMORY_SIZE, PCI_REGION_MEM | PCI_REGION_MEMORY); /* PCI memory space */ - pci_set_region(hose->regions + 1, + pci_set_region (hose->regions + 1, CFG_PCI_MEM_BUS, CFG_PCI_MEM_PHYS, CFG_PCI_MEM_SIZE, PCI_REGION_MEM); /* PCI I/O space */ - pci_set_region(hose->regions + 2, + pci_set_region (hose->regions + 2, CFG_PCI_IO_BUS, CFG_PCI_IO_PHYS, CFG_PCI_IO_SIZE, PCI_REGION_IO); hose->region_count = 3; - pci_set_ops(hose, + pci_set_ops (hose, pci_hose_read_config_byte_via_dword, pci_hose_read_config_word_via_dword, tsi108_read_config_dword, @@ -151,22 +151,22 @@ void pci_init_board(void) pci_hose_write_config_word_via_dword, tsi108_write_config_dword); - pci_register_hose(hose); + pci_register_hose (hose); - hose->last_busno = pci_hose_scan(hose); + hose->last_busno = pci_hose_scan (hose); - debug("Done PCI initialization\n"); + debug ("Done PCI initialization\n"); return; } #ifdef CONFIG_OF_FLAT_TREE void -ft_pci_setup(void *blob, bd_t *bd) +ft_pci_setup (void *blob, bd_t *bd) { u32 *p; int len; - p = (u32 *)ft_get_prop(blob, "/" OF_TSI "/pci@1000/bus-range", &len); + p = (u32 *)ft_get_prop (blob, "/" OF_TSI "/pci@1000/bus-range", &len); if (p != NULL) { p[0] = local_hose.first_busno; p[1] = local_hose.last_busno; -- cgit v1.1 From 647d3c3eed0da1d1505eecabe0b0fab96f956e68 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 4 Mar 2007 01:36:05 +0100 Subject: Some code cleanup. --- drivers/tsi108_i2c.c | 37 +++++++++++-------------------------- 1 file changed, 11 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/tsi108_i2c.c b/drivers/tsi108_i2c.c index c100cb8..eb52cb6 100644 --- a/drivers/tsi108_i2c.c +++ b/drivers/tsi108_i2c.c @@ -82,15 +82,10 @@ static int i2c_read_byte ( /* Wait until operation completed */ do { /* Read I2C operation status */ - temp = - *(u32 *) (CFG_TSI108_CSR_BASE + chan_offset + - I2C_CNTRL2); - - if (0 == - (temp & (I2C_CNTRL2_RD_STATUS | I2C_CNTRL2_START))) - { - if (0 == - (temp & + temp = *(u32 *) (CFG_TSI108_CSR_BASE + chan_offset + I2C_CNTRL2); + + if (0 == (temp & (I2C_CNTRL2_RD_STATUS | I2C_CNTRL2_START))) { + if (0 == (temp & (I2C_CNTRL2_I2C_CFGERR | I2C_CNTRL2_I2C_TO_ERR)) ) { @@ -152,9 +147,7 @@ int i2c_read (uchar chip_addr, uint byte_addr, int alen, /* Check for valid I2C address */ if (chip_addr <= 0x7F && (byte_addr + len) <= (0x01 << (alen * 8))) { while (len--) { - op_status = - i2c_read_byte(i2c_if, chip_addr, byte_addr++, - buffer++); + op_status = i2c_read_byte(i2c_if, chip_addr, byte_addr++, buffer++); if (TSI108_I2C_SUCCESS != op_status) { DPRINT (("I2C read_byte() failed: 0x%02x (%d left)\n", op_status, len)); @@ -182,10 +175,7 @@ static int i2c_write_byte (uchar chip_addr,/* I2C device address on the bus */ /* Check if I2C operation is in progress */ temp = *(u32 *) (CFG_TSI108_CSR_BASE + TSI108_I2C_OFFSET + I2C_CNTRL2); - if (0 == - (temp & - (I2C_CNTRL2_RD_STATUS | I2C_CNTRL2_WR_STATUS | I2C_CNTRL2_START))) - { + if (0 == (temp & (I2C_CNTRL2_RD_STATUS | I2C_CNTRL2_WR_STATUS | I2C_CNTRL2_START))) { /* Place data into the I2C Tx Register */ *(u32 *) (CFG_TSI108_CSR_BASE + TSI108_I2C_OFFSET + I2C_TX_DATA) = (u32) * buffer; @@ -200,7 +190,7 @@ static int i2c_write_byte (uchar chip_addr,/* I2C device address on the bus */ /* Issue the write command (at this moment all other parameters * are 0 (size = 1 byte, lane = 0) */ - + *(u32 *) (CFG_TSI108_CSR_BASE + TSI108_I2C_OFFSET + I2C_CNTRL2) = (I2C_CNTRL2_START); @@ -209,15 +199,10 @@ static int i2c_write_byte (uchar chip_addr,/* I2C device address on the bus */ /* Wait until operation completed */ do { /* Read I2C operation status */ - temp = - *(u32 *) (CFG_TSI108_CSR_BASE + TSI108_I2C_OFFSET + - I2C_CNTRL2); - - if (0 == - (temp & (I2C_CNTRL2_WR_STATUS | I2C_CNTRL2_START))) - { - if (0 == - (temp & + temp = *(u32 *) (CFG_TSI108_CSR_BASE + TSI108_I2C_OFFSET + I2C_CNTRL2); + + if (0 == (temp & (I2C_CNTRL2_WR_STATUS | I2C_CNTRL2_START))) { + if (0 == (temp & (I2C_CNTRL2_I2C_CFGERR | I2C_CNTRL2_I2C_TO_ERR))) { op_status = TSI108_I2C_SUCCESS; -- cgit v1.1 From df548d3c3e2bbc40258713167859ffc2ce99a900 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Sun, 19 Nov 2006 18:06:53 +0100 Subject: AVR32: Resource management rewrite Rewrite the resource management code (i.e. I/O memory, clock gating, gpio) so it doesn't depend on any global state. This is necessary because this code is heavily used before relocation to RAM, so we can't write to any global variables. As an added bonus, this makes u-boot's memory footprint a bit smaller, although some functionality has been left out; all clocks are enabled all the time, and there's no checking for gpio line conflicts. Signed-off-by: Haavard Skinnemoen --- drivers/atmel_usart.c | 48 ++++++++++++++++++++++++++++++------------------ drivers/atmel_usart.h | 8 ++++---- 2 files changed, 34 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/atmel_usart.c b/drivers/atmel_usart.c index 41c3768..f35b997 100644 --- a/drivers/atmel_usart.c +++ b/drivers/atmel_usart.c @@ -19,7 +19,22 @@ #ifdef CONFIG_ATMEL_USART #include -#include +#include +#include + +#if defined(CONFIG_USART0) +# define USART_ID 0 +# define USART_BASE USART0_BASE +#elif defined(CONFIG_USART1) +# define USART_ID 1 +# define USART_BASE USART1_BASE +#elif defined(CONFIG_USART2) +# define USART_ID 2 +# define USART_BASE USART2_BASE +#elif defined(CONFIG_USART3) +# define USART_ID 3 +# define USART_BASE USART3_BASE +#endif #include "atmel_usart.h" @@ -35,26 +50,23 @@ void serial_setbrg(void) * Baud Rate = -------------- * 16 * CD */ - usart_hz = pm_get_clock_freq(gd->console_uart->resource[0].u.clock.id); + usart_hz = get_usart_clk_rate(USART_ID); divisor = (usart_hz / 16 + gd->baudrate / 2) / gd->baudrate; - usart3_writel(gd->console_uart, BRGR, USART3_BF(CD, divisor)); + usart3_writel(BRGR, USART3_BF(CD, divisor)); } int serial_init(void) { - usart3_writel(gd->console_uart, CR, - USART3_BIT(RSTRX) | USART3_BIT(RSTTX)); + usart3_writel(CR, USART3_BIT(RSTRX) | USART3_BIT(RSTTX)); serial_setbrg(); - usart3_writel(gd->console_uart, CR, - USART3_BIT(RXEN) | USART3_BIT(TXEN)); - usart3_writel(gd->console_uart, MR, - USART3_BF(USART_MODE, USART3_USART_MODE_NORMAL) - | USART3_BF(USCLKS, USART3_USCLKS_MCK) - | USART3_BF(CHRL, USART3_CHRL_8) - | USART3_BF(PAR, USART3_PAR_NONE) - | USART3_BF(NBSTOP, USART3_NBSTOP_1)); + usart3_writel(CR, USART3_BIT(RXEN) | USART3_BIT(TXEN)); + usart3_writel(MR, (USART3_BF(USART_MODE, USART3_USART_MODE_NORMAL) + | USART3_BF(USCLKS, USART3_USCLKS_MCK) + | USART3_BF(CHRL, USART3_CHRL_8) + | USART3_BF(PAR, USART3_PAR_NONE) + | USART3_BF(NBSTOP, USART3_NBSTOP_1))); return 0; } @@ -64,8 +76,8 @@ void serial_putc(char c) if (c == '\n') serial_putc('\r'); - while (!(usart3_readl(gd->console_uart, CSR) & USART3_BIT(TXRDY))) ; - usart3_writel(gd->console_uart, THR, c); + while (!(usart3_readl(CSR) & USART3_BIT(TXRDY))) ; + usart3_writel(THR, c); } void serial_puts(const char *s) @@ -76,13 +88,13 @@ void serial_puts(const char *s) int serial_getc(void) { - while (!(usart3_readl(gd->console_uart, CSR) & USART3_BIT(RXRDY))) ; - return usart3_readl(gd->console_uart, RHR); + while (!(usart3_readl(CSR) & USART3_BIT(RXRDY))) ; + return usart3_readl(RHR); } int serial_tstc(void) { - return (usart3_readl(gd->console_uart, CSR) & USART3_BIT(RXRDY)) != 0; + return (usart3_readl(CSR) & USART3_BIT(RXRDY)) != 0; } #endif /* CONFIG_ATMEL_USART */ diff --git a/drivers/atmel_usart.h b/drivers/atmel_usart.h index fad90a8..af3773a 100644 --- a/drivers/atmel_usart.h +++ b/drivers/atmel_usart.h @@ -306,9 +306,9 @@ | USART3_BF(name,value)) /* Register access macros */ -#define usart3_readl(port,reg) \ - readl((port)->regs + USART3_##reg) -#define usart3_writel(port,reg,value) \ - writel((value), (port)->regs + USART3_##reg) +#define usart3_readl(reg) \ + readl((void *)USART_BASE + USART3_##reg) +#define usart3_writel(reg,value) \ + writel((value), (void *)USART_BASE + USART3_##reg) #endif /* __DRIVERS_ATMEL_USART_H__ */ -- cgit v1.1 From 5c1fe1ffffd1750a7e47e5a2e2cd600c00e4f009 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Fri, 20 Jan 2006 10:03:34 +0100 Subject: Atmel MACB ethernet driver Driver for the Atmel MACB on-chip ethernet controller. This driver has been tested on the ATSTK1000 board with a AT32AP7000 CPU. It should probably work on AT91SAM926x as well with some minor modifications. Hardware documentation can be found in the AT32AP7000 data sheet, which can be downloaded from http://www.atmel.com/dyn/products/datasheets.asp?family_id=682 Signed-off-by: Haavard Skinnemoen --- drivers/Makefile | 2 +- drivers/macb.c | 575 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ drivers/macb.h | 269 ++++++++++++++++++++++++++ 3 files changed, 845 insertions(+), 1 deletion(-) create mode 100644 drivers/macb.c create mode 100644 drivers/macb.h (limited to 'drivers') diff --git a/drivers/Makefile b/drivers/Makefile index fffc22a..2eac7c8 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -32,7 +32,7 @@ COBJS = 3c589.o 5701rls.o ali512x.o atmel_usart.o \ cs8900.o ct69000.o dataflash.o dc2114x.o dm9000x.o \ e1000.o eepro100.o \ i8042.o inca-ip_sw.o keyboard.o \ - lan91c96.o \ + lan91c96.o macb.o \ natsemi.o ne2000.o netarm_eth.o netconsole.o \ ns16550.o ns8382x.o ns87308.o ns7520_eth.o omap1510_i2c.o \ omap24xx_i2c.o pci.o pci_auto.o pci_indirect.o \ diff --git a/drivers/macb.c b/drivers/macb.c new file mode 100644 index 0000000..186ab19 --- /dev/null +++ b/drivers/macb.c @@ -0,0 +1,575 @@ +/* + * Copyright (C) 2005-2006 Atmel Corporation + * + * 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 + +#if defined(CONFIG_MACB) && (CONFIG_COMMANDS & (CFG_CMD_NET | CFG_CMD_MII)) + +/* + * The u-boot networking stack is a little weird. It seems like the + * networking core allocates receive buffers up front without any + * regard to the hardware that's supposed to actually receive those + * packets. + * + * The MACB receives packets into 128-byte receive buffers, so the + * buffers allocated by the core isn't very practical to use. We'll + * allocate our own, but we need one such buffer in case a packet + * wraps around the DMA ring so that we have to copy it. + * + * Therefore, define CFG_RX_ETH_BUFFER to 1 in the board-specific + * configuration header. This way, the core allocates one RX buffer + * and one TX buffer, each of which can hold a ethernet packet of + * maximum size. + * + * For some reason, the networking core unconditionally specifies a + * 32-byte packet "alignment" (which really should be called + * "padding"). MACB shouldn't need that, but we'll refrain from any + * core modifications here... + */ + +#include +#include + +#include +#include +#include +#include + +#include "macb.h" + +#define CFG_MACB_RX_BUFFER_SIZE 4096 +#define CFG_MACB_RX_RING_SIZE (CFG_MACB_RX_BUFFER_SIZE / 128) +#define CFG_MACB_TX_RING_SIZE 16 +#define CFG_MACB_TX_TIMEOUT 1000 +#define CFG_MACB_AUTONEG_TIMEOUT 5000000 + +struct macb_dma_desc { + u32 addr; + u32 ctrl; +}; + +#define RXADDR_USED 0x00000001 +#define RXADDR_WRAP 0x00000002 + +#define RXBUF_FRMLEN_MASK 0x00000fff +#define RXBUF_FRAME_START 0x00004000 +#define RXBUF_FRAME_END 0x00008000 +#define RXBUF_TYPEID_MATCH 0x00400000 +#define RXBUF_ADDR4_MATCH 0x00800000 +#define RXBUF_ADDR3_MATCH 0x01000000 +#define RXBUF_ADDR2_MATCH 0x02000000 +#define RXBUF_ADDR1_MATCH 0x04000000 +#define RXBUF_BROADCAST 0x80000000 + +#define TXBUF_FRMLEN_MASK 0x000007ff +#define TXBUF_FRAME_END 0x00008000 +#define TXBUF_NOCRC 0x00010000 +#define TXBUF_EXHAUSTED 0x08000000 +#define TXBUF_UNDERRUN 0x10000000 +#define TXBUF_MAXRETRY 0x20000000 +#define TXBUF_WRAP 0x40000000 +#define TXBUF_USED 0x80000000 + +struct macb_device { + void *regs; + + unsigned int rx_tail; + unsigned int tx_head; + unsigned int tx_tail; + + void *rx_buffer; + void *tx_buffer; + struct macb_dma_desc *rx_ring; + struct macb_dma_desc *tx_ring; + + unsigned long rx_buffer_dma; + unsigned long rx_ring_dma; + unsigned long tx_ring_dma; + + const struct device *dev; + struct eth_device netdev; + unsigned short phy_addr; +}; +#define to_macb(_nd) container_of(_nd, struct macb_device, netdev) + +static void macb_mdio_write(struct macb_device *macb, u8 reg, u16 value) +{ + unsigned long netctl; + unsigned long netstat; + unsigned long frame; + + netctl = macb_readl(macb, NCR); + netctl |= MACB_BIT(MPE); + macb_writel(macb, NCR, netctl); + + frame = (MACB_BF(SOF, 1) + | MACB_BF(RW, 1) + | MACB_BF(PHYA, macb->phy_addr) + | MACB_BF(REGA, reg) + | MACB_BF(CODE, 2) + | MACB_BF(DATA, value)); + macb_writel(macb, MAN, frame); + + do { + netstat = macb_readl(macb, NSR); + } while (!(netstat & MACB_BIT(IDLE))); + + netctl = macb_readl(macb, NCR); + netctl &= ~MACB_BIT(MPE); + macb_writel(macb, NCR, netctl); +} + +static u16 macb_mdio_read(struct macb_device *macb, u8 reg) +{ + unsigned long netctl; + unsigned long netstat; + unsigned long frame; + + netctl = macb_readl(macb, NCR); + netctl |= MACB_BIT(MPE); + macb_writel(macb, NCR, netctl); + + frame = (MACB_BF(SOF, 1) + | MACB_BF(RW, 2) + | MACB_BF(PHYA, macb->phy_addr) + | MACB_BF(REGA, reg) + | MACB_BF(CODE, 2)); + macb_writel(macb, MAN, frame); + + do { + netstat = macb_readl(macb, NSR); + } while (!(netstat & MACB_BIT(IDLE))); + + frame = macb_readl(macb, MAN); + + netctl = macb_readl(macb, NCR); + netctl &= ~MACB_BIT(MPE); + macb_writel(macb, NCR, netctl); + + return MACB_BFEXT(DATA, frame); +} + +#if (CONFIG_COMMANDS & CFG_CMD_NET) + +static int macb_send(struct eth_device *netdev, volatile void *packet, + int length) +{ + struct macb_device *macb = to_macb(netdev); + unsigned long paddr, ctrl; + unsigned int tx_head = macb->tx_head; + int i; + + paddr = dma_map_single(packet, length, DMA_TO_DEVICE); + + ctrl = length & TXBUF_FRMLEN_MASK; + ctrl |= TXBUF_FRAME_END; + if (tx_head == (CFG_MACB_TX_RING_SIZE - 1)) { + ctrl |= TXBUF_WRAP; + macb->tx_head = 0; + } else + macb->tx_head++; + + macb->tx_ring[tx_head].ctrl = ctrl; + macb->tx_ring[tx_head].addr = paddr; + macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(TSTART)); + + /* + * I guess this is necessary because the networking core may + * re-use the transmit buffer as soon as we return... + */ + i = 0; + while (!(macb->tx_ring[tx_head].ctrl & TXBUF_USED)) { + if (i > CFG_MACB_TX_TIMEOUT) { + printf("%s: TX timeout\n", netdev->name); + break; + } + udelay(1); + i++; + } + + dma_unmap_single(packet, length, paddr); + + if (i <= CFG_MACB_TX_TIMEOUT) { + ctrl = macb->tx_ring[tx_head].ctrl; + if (ctrl & TXBUF_UNDERRUN) + printf("%s: TX underrun\n", netdev->name); + if (ctrl & TXBUF_EXHAUSTED) + printf("%s: TX buffers exhausted in mid frame\n", + netdev->name); + } + + /* No one cares anyway */ + return 0; +} + +static void reclaim_rx_buffers(struct macb_device *macb, + unsigned int new_tail) +{ + unsigned int i; + + i = macb->rx_tail; + while (i > new_tail) { + macb->rx_ring[i].addr &= ~RXADDR_USED; + i++; + if (i > CFG_MACB_RX_RING_SIZE) + i = 0; + } + + while (i < new_tail) { + macb->rx_ring[i].addr &= ~RXADDR_USED; + i++; + } + + macb->rx_tail = new_tail; +} + +static int macb_recv(struct eth_device *netdev) +{ + struct macb_device *macb = to_macb(netdev); + unsigned int rx_tail = macb->rx_tail; + void *buffer; + int length; + int wrapped = 0; + u32 status; + + for (;;) { + if (!(macb->rx_ring[rx_tail].addr & RXADDR_USED)) + return -1; + + status = macb->rx_ring[rx_tail].ctrl; + if (status & RXBUF_FRAME_START) { + if (rx_tail != macb->rx_tail) + reclaim_rx_buffers(macb, rx_tail); + wrapped = 0; + } + + if (status & RXBUF_FRAME_END) { + buffer = macb->rx_buffer + 128 * macb->rx_tail; + length = status & RXBUF_FRMLEN_MASK; + if (wrapped) { + unsigned int headlen, taillen; + + headlen = 128 * (CFG_MACB_RX_RING_SIZE + - macb->rx_tail); + taillen = length - headlen; + memcpy((void *)NetRxPackets[0], + buffer, headlen); + memcpy((void *)NetRxPackets[0] + headlen, + macb->rx_buffer, taillen); + buffer = (void *)NetRxPackets[0]; + } + + NetReceive(buffer, length); + if (++rx_tail >= CFG_MACB_RX_RING_SIZE) + rx_tail = 0; + reclaim_rx_buffers(macb, rx_tail); + } else { + if (++rx_tail >= CFG_MACB_RX_RING_SIZE) { + wrapped = 1; + rx_tail = 0; + } + } + } + + return 0; +} + +static int macb_phy_init(struct macb_device *macb) +{ + struct eth_device *netdev = &macb->netdev; + u32 ncfgr; + u16 phy_id, status, adv, lpa; + int media, speed, duplex; + int i; + + /* Check if the PHY is up to snuff... */ + phy_id = macb_mdio_read(macb, MII_PHYSID1); + if (phy_id == 0xffff) { + printf("%s: No PHY present\n", netdev->name); + return 0; + } + + adv = ADVERTISE_CSMA | ADVERTISE_ALL; + macb_mdio_write(macb, MII_ADVERTISE, adv); + printf("%s: Starting autonegotiation...\n", netdev->name); + macb_mdio_write(macb, MII_BMCR, (BMCR_ANENABLE + | BMCR_ANRESTART)); + +#if 0 + for (i = 0; i < 9; i++) + printf("mii%d: 0x%04x\n", i, macb_mdio_read(macb, i)); +#endif + + for (i = 0; i < CFG_MACB_AUTONEG_TIMEOUT / 100; i++) { + status = macb_mdio_read(macb, MII_BMSR); + if (status & BMSR_ANEGCOMPLETE) + break; + udelay(100); + } + + if (status & BMSR_ANEGCOMPLETE) + printf("%s: Autonegotiation complete\n", netdev->name); + else + printf("%s: Autonegotiation timed out (status=0x%04x)\n", + netdev->name, status); + + if (!(status & BMSR_LSTATUS)) { + for (i = 0; i < CFG_MACB_AUTONEG_TIMEOUT / 100; i++) { + udelay(100); + status = macb_mdio_read(macb, MII_BMSR); + if (status & BMSR_LSTATUS) + break; + } + } + + if (!(status & BMSR_LSTATUS)) { + printf("%s: link down (status: 0x%04x)\n", + netdev->name, status); + return 0; + } else { + lpa = macb_mdio_read(macb, MII_LPA); + media = mii_nway_result(lpa & adv); + speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF) + ? 1 : 0); + duplex = (media & ADVERTISE_FULL) ? 1 : 0; + printf("%s: link up, %sMbps %s-duplex (lpa: 0x%04x)\n", + netdev->name, + speed ? "100" : "10", + duplex ? "full" : "half", + lpa); + + ncfgr = macb_readl(macb, NCFGR); + ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD)); + if (speed) + ncfgr |= MACB_BIT(SPD); + if (duplex) + ncfgr |= MACB_BIT(FD); + macb_writel(macb, NCFGR, ncfgr); + return 1; + } +} + +static int macb_init(struct eth_device *netdev, bd_t *bd) +{ + struct macb_device *macb = to_macb(netdev); + unsigned long paddr; + u32 hwaddr_bottom; + u16 hwaddr_top; + int i; + + /* + * macb_halt should have been called at some point before now, + * so we'll assume the controller is idle. + */ + + /* initialize DMA descriptors */ + paddr = macb->rx_buffer_dma; + for (i = 0; i < CFG_MACB_RX_RING_SIZE; i++) { + if (i == (CFG_MACB_RX_RING_SIZE - 1)) + paddr |= RXADDR_WRAP; + macb->rx_ring[i].addr = paddr; + macb->rx_ring[i].ctrl = 0; + paddr += 128; + } + for (i = 0; i < CFG_MACB_TX_RING_SIZE; i++) { + macb->tx_ring[i].addr = 0; + if (i == (CFG_MACB_TX_RING_SIZE - 1)) + macb->tx_ring[i].ctrl = TXBUF_USED | TXBUF_WRAP; + else + macb->tx_ring[i].ctrl = TXBUF_USED; + } + macb->rx_tail = macb->tx_head = macb->tx_tail = 0; + + macb_writel(macb, RBQP, macb->rx_ring_dma); + macb_writel(macb, TBQP, macb->tx_ring_dma); + + /* set hardware address */ + hwaddr_bottom = cpu_to_le32(*((u32 *)netdev->enetaddr)); + macb_writel(macb, SA1B, hwaddr_bottom); + hwaddr_top = cpu_to_le16(*((u16 *)(netdev->enetaddr + 4))); + macb_writel(macb, SA1T, hwaddr_top); + + /* choose RMII or MII mode. This depends on the board */ +#ifdef CONFIG_RMII + macb_writel(macb, USRIO, 0); +#else + macb_writel(macb, USRIO, MACB_BIT(MII)); +#endif + + if (!macb_phy_init(macb)) + return 0; + + /* Enable TX and RX */ + macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE)); + + return 1; +} + +static void macb_halt(struct eth_device *netdev) +{ + struct macb_device *macb = to_macb(netdev); + u32 ncr, tsr; + + /* Halt the controller and wait for any ongoing transmission to end. */ + ncr = macb_readl(macb, NCR); + ncr |= MACB_BIT(THALT); + macb_writel(macb, NCR, ncr); + + do { + tsr = macb_readl(macb, TSR); + } while (tsr & MACB_BIT(TGO)); + + /* Disable TX and RX, and clear statistics */ + macb_writel(macb, NCR, MACB_BIT(CLRSTAT)); +} + +int macb_eth_initialize(int id, void *regs, unsigned int phy_addr) +{ + struct macb_device *macb; + struct eth_device *netdev; + unsigned long macb_hz; + u32 ncfgr; + + macb = malloc(sizeof(struct macb_device)); + if (!macb) { + printf("Error: Failed to allocate memory for MACB%d\n", id); + return -1; + } + memset(macb, 0, sizeof(struct macb_device)); + + netdev = &macb->netdev; + + macb->rx_buffer = dma_alloc_coherent(CFG_MACB_RX_BUFFER_SIZE, + &macb->rx_buffer_dma); + macb->rx_ring = dma_alloc_coherent(CFG_MACB_RX_RING_SIZE + * sizeof(struct macb_dma_desc), + &macb->rx_ring_dma); + macb->tx_ring = dma_alloc_coherent(CFG_MACB_TX_RING_SIZE + * sizeof(struct macb_dma_desc), + &macb->tx_ring_dma); + + macb->regs = regs; + macb->phy_addr = phy_addr; + + sprintf(netdev->name, "macb%d", id); + netdev->init = macb_init; + netdev->halt = macb_halt; + netdev->send = macb_send; + netdev->recv = macb_recv; + + /* + * Do some basic initialization so that we at least can talk + * to the PHY + */ + macb_hz = get_macb_pclk_rate(id); + if (macb_hz < 20000000) + ncfgr = MACB_BF(CLK, MACB_CLK_DIV8); + else if (macb_hz < 40000000) + ncfgr = MACB_BF(CLK, MACB_CLK_DIV16); + else if (macb_hz < 80000000) + ncfgr = MACB_BF(CLK, MACB_CLK_DIV32); + else + ncfgr = MACB_BF(CLK, MACB_CLK_DIV64); + + macb_writel(macb, NCFGR, ncfgr); + + eth_register(netdev); + + return 0; +} + +#endif /* (CONFIG_COMMANDS & CFG_CMD_NET) */ + +#if (CONFIG_COMMANDS & CFG_CMD_MII) + +int miiphy_read(unsigned char addr, unsigned char reg, unsigned short *value) +{ + unsigned long netctl; + unsigned long netstat; + unsigned long frame; + int iflag; + + iflag = disable_interrupts(); + netctl = macb_readl(&macb, EMACB_NCR); + netctl |= MACB_BIT(MPE); + macb_writel(&macb, EMACB_NCR, netctl); + if (iflag) + enable_interrupts(); + + frame = (MACB_BF(SOF, 1) + | MACB_BF(RW, 2) + | MACB_BF(PHYA, addr) + | MACB_BF(REGA, reg) + | MACB_BF(CODE, 2)); + macb_writel(&macb, EMACB_MAN, frame); + + do { + netstat = macb_readl(&macb, EMACB_NSR); + } while (!(netstat & MACB_BIT(IDLE))); + + frame = macb_readl(&macb, EMACB_MAN); + *value = MACB_BFEXT(DATA, frame); + + iflag = disable_interrupts(); + netctl = macb_readl(&macb, EMACB_NCR); + netctl &= ~MACB_BIT(MPE); + macb_writel(&macb, EMACB_NCR, netctl); + if (iflag) + enable_interrupts(); + + return 0; +} + +int miiphy_write(unsigned char addr, unsigned char reg, unsigned short value) +{ + unsigned long netctl; + unsigned long netstat; + unsigned long frame; + int iflag; + + iflag = disable_interrupts(); + netctl = macb_readl(&macb, EMACB_NCR); + netctl |= MACB_BIT(MPE); + macb_writel(&macb, EMACB_NCR, netctl); + if (iflag) + enable_interrupts(); + + frame = (MACB_BF(SOF, 1) + | MACB_BF(RW, 1) + | MACB_BF(PHYA, addr) + | MACB_BF(REGA, reg) + | MACB_BF(CODE, 2) + | MACB_BF(DATA, value)); + macb_writel(&macb, EMACB_MAN, frame); + + do { + netstat = macb_readl(&macb, EMACB_NSR); + } while (!(netstat & MACB_BIT(IDLE))); + + iflag = disable_interrupts(); + netctl = macb_readl(&macb, EMACB_NCR); + netctl &= ~MACB_BIT(MPE); + macb_writel(&macb, EMACB_NCR, netctl); + if (iflag) + enable_interrupts(); + + return 0; +} + +#endif /* (CONFIG_COMMANDS & CFG_CMD_MII) */ + +#endif /* CONFIG_MACB */ diff --git a/drivers/macb.h b/drivers/macb.h new file mode 100644 index 0000000..c778e4e --- /dev/null +++ b/drivers/macb.h @@ -0,0 +1,269 @@ +/* + * Copyright (C) 2005-2006 Atmel Corporation + * + * 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 __DRIVERS_MACB_H__ +#define __DRIVERS_MACB_H__ + +/* MACB register offsets */ +#define MACB_NCR 0x0000 +#define MACB_NCFGR 0x0004 +#define MACB_NSR 0x0008 +#define MACB_TSR 0x0014 +#define MACB_RBQP 0x0018 +#define MACB_TBQP 0x001c +#define MACB_RSR 0x0020 +#define MACB_ISR 0x0024 +#define MACB_IER 0x0028 +#define MACB_IDR 0x002c +#define MACB_IMR 0x0030 +#define MACB_MAN 0x0034 +#define MACB_PTR 0x0038 +#define MACB_PFR 0x003c +#define MACB_FTO 0x0040 +#define MACB_SCF 0x0044 +#define MACB_MCF 0x0048 +#define MACB_FRO 0x004c +#define MACB_FCSE 0x0050 +#define MACB_ALE 0x0054 +#define MACB_DTF 0x0058 +#define MACB_LCOL 0x005c +#define MACB_EXCOL 0x0060 +#define MACB_TUND 0x0064 +#define MACB_CSE 0x0068 +#define MACB_RRE 0x006c +#define MACB_ROVR 0x0070 +#define MACB_RSE 0x0074 +#define MACB_ELE 0x0078 +#define MACB_RJA 0x007c +#define MACB_USF 0x0080 +#define MACB_STE 0x0084 +#define MACB_RLE 0x0088 +#define MACB_TPF 0x008c +#define MACB_HRB 0x0090 +#define MACB_HRT 0x0094 +#define MACB_SA1B 0x0098 +#define MACB_SA1T 0x009c +#define MACB_SA2B 0x00a0 +#define MACB_SA2T 0x00a4 +#define MACB_SA3B 0x00a8 +#define MACB_SA3T 0x00ac +#define MACB_SA4B 0x00b0 +#define MACB_SA4T 0x00b4 +#define MACB_TID 0x00b8 +#define MACB_TPQ 0x00bc +#define MACB_USRIO 0x00c0 +#define MACB_WOL 0x00c4 + +/* Bitfields in NCR */ +#define MACB_LB_OFFSET 0 +#define MACB_LB_SIZE 1 +#define MACB_LLB_OFFSET 1 +#define MACB_LLB_SIZE 1 +#define MACB_RE_OFFSET 2 +#define MACB_RE_SIZE 1 +#define MACB_TE_OFFSET 3 +#define MACB_TE_SIZE 1 +#define MACB_MPE_OFFSET 4 +#define MACB_MPE_SIZE 1 +#define MACB_CLRSTAT_OFFSET 5 +#define MACB_CLRSTAT_SIZE 1 +#define MACB_INCSTAT_OFFSET 6 +#define MACB_INCSTAT_SIZE 1 +#define MACB_WESTAT_OFFSET 7 +#define MACB_WESTAT_SIZE 1 +#define MACB_BP_OFFSET 8 +#define MACB_BP_SIZE 1 +#define MACB_TSTART_OFFSET 9 +#define MACB_TSTART_SIZE 1 +#define MACB_THALT_OFFSET 10 +#define MACB_THALT_SIZE 1 +#define MACB_NCR_TPF_OFFSET 11 +#define MACB_NCR_TPF_SIZE 1 +#define MACB_TZQ_OFFSET 12 +#define MACB_TZQ_SIZE 1 + +/* Bitfields in NCFGR */ +#define MACB_SPD_OFFSET 0 +#define MACB_SPD_SIZE 1 +#define MACB_FD_OFFSET 1 +#define MACB_FD_SIZE 1 +#define MACB_BIT_RATE_OFFSET 2 +#define MACB_BIT_RATE_SIZE 1 +#define MACB_JFRAME_OFFSET 3 +#define MACB_JFRAME_SIZE 1 +#define MACB_CAF_OFFSET 4 +#define MACB_CAF_SIZE 1 +#define MACB_NBC_OFFSET 5 +#define MACB_NBC_SIZE 1 +#define MACB_NCFGR_MTI_OFFSET 6 +#define MACB_NCFGR_MTI_SIZE 1 +#define MACB_UNI_OFFSET 7 +#define MACB_UNI_SIZE 1 +#define MACB_BIG_OFFSET 8 +#define MACB_BIG_SIZE 1 +#define MACB_EAE_OFFSET 9 +#define MACB_EAE_SIZE 1 +#define MACB_CLK_OFFSET 10 +#define MACB_CLK_SIZE 2 +#define MACB_RTY_OFFSET 12 +#define MACB_RTY_SIZE 1 +#define MACB_PAE_OFFSET 13 +#define MACB_PAE_SIZE 1 +#define MACB_RBOF_OFFSET 14 +#define MACB_RBOF_SIZE 2 +#define MACB_RLCE_OFFSET 16 +#define MACB_RLCE_SIZE 1 +#define MACB_DRFCS_OFFSET 17 +#define MACB_DRFCS_SIZE 1 +#define MACB_EFRHD_OFFSET 18 +#define MACB_EFRHD_SIZE 1 +#define MACB_IRXFCS_OFFSET 19 +#define MACB_IRXFCS_SIZE 1 + +/* Bitfields in NSR */ +#define MACB_NSR_LINK_OFFSET 0 +#define MACB_NSR_LINK_SIZE 1 +#define MACB_MDIO_OFFSET 1 +#define MACB_MDIO_SIZE 1 +#define MACB_IDLE_OFFSET 2 +#define MACB_IDLE_SIZE 1 + +/* Bitfields in TSR */ +#define MACB_UBR_OFFSET 0 +#define MACB_UBR_SIZE 1 +#define MACB_COL_OFFSET 1 +#define MACB_COL_SIZE 1 +#define MACB_TSR_RLE_OFFSET 2 +#define MACB_TSR_RLE_SIZE 1 +#define MACB_TGO_OFFSET 3 +#define MACB_TGO_SIZE 1 +#define MACB_BEX_OFFSET 4 +#define MACB_BEX_SIZE 1 +#define MACB_COMP_OFFSET 5 +#define MACB_COMP_SIZE 1 +#define MACB_UND_OFFSET 6 +#define MACB_UND_SIZE 1 + +/* Bitfields in RSR */ +#define MACB_BNA_OFFSET 0 +#define MACB_BNA_SIZE 1 +#define MACB_REC_OFFSET 1 +#define MACB_REC_SIZE 1 +#define MACB_OVR_OFFSET 2 +#define MACB_OVR_SIZE 1 + +/* Bitfields in ISR/IER/IDR/IMR */ +#define MACB_MFD_OFFSET 0 +#define MACB_MFD_SIZE 1 +#define MACB_RCOMP_OFFSET 1 +#define MACB_RCOMP_SIZE 1 +#define MACB_RXUBR_OFFSET 2 +#define MACB_RXUBR_SIZE 1 +#define MACB_TXUBR_OFFSET 3 +#define MACB_TXUBR_SIZE 1 +#define MACB_ISR_TUND_OFFSET 4 +#define MACB_ISR_TUND_SIZE 1 +#define MACB_ISR_RLE_OFFSET 5 +#define MACB_ISR_RLE_SIZE 1 +#define MACB_TXERR_OFFSET 6 +#define MACB_TXERR_SIZE 1 +#define MACB_TCOMP_OFFSET 7 +#define MACB_TCOMP_SIZE 1 +#define MACB_ISR_LINK_OFFSET 9 +#define MACB_ISR_LINK_SIZE 1 +#define MACB_ISR_ROVR_OFFSET 10 +#define MACB_ISR_ROVR_SIZE 1 +#define MACB_HRESP_OFFSET 11 +#define MACB_HRESP_SIZE 1 +#define MACB_PFR_OFFSET 12 +#define MACB_PFR_SIZE 1 +#define MACB_PTZ_OFFSET 13 +#define MACB_PTZ_SIZE 1 + +/* Bitfields in MAN */ +#define MACB_DATA_OFFSET 0 +#define MACB_DATA_SIZE 16 +#define MACB_CODE_OFFSET 16 +#define MACB_CODE_SIZE 2 +#define MACB_REGA_OFFSET 18 +#define MACB_REGA_SIZE 5 +#define MACB_PHYA_OFFSET 23 +#define MACB_PHYA_SIZE 5 +#define MACB_RW_OFFSET 28 +#define MACB_RW_SIZE 2 +#define MACB_SOF_OFFSET 30 +#define MACB_SOF_SIZE 2 + +/* Bitfields in USRIO */ +#define MACB_MII_OFFSET 0 +#define MACB_MII_SIZE 1 +#define MACB_EAM_OFFSET 1 +#define MACB_EAM_SIZE 1 +#define MACB_TX_PAUSE_OFFSET 2 +#define MACB_TX_PAUSE_SIZE 1 +#define MACB_TX_PAUSE_ZERO_OFFSET 3 +#define MACB_TX_PAUSE_ZERO_SIZE 1 + +/* Bitfields in WOL */ +#define MACB_IP_OFFSET 0 +#define MACB_IP_SIZE 16 +#define MACB_MAG_OFFSET 16 +#define MACB_MAG_SIZE 1 +#define MACB_ARP_OFFSET 17 +#define MACB_ARP_SIZE 1 +#define MACB_SA1_OFFSET 18 +#define MACB_SA1_SIZE 1 +#define MACB_WOL_MTI_OFFSET 19 +#define MACB_WOL_MTI_SIZE 1 + +/* Constants for CLK */ +#define MACB_CLK_DIV8 0 +#define MACB_CLK_DIV16 1 +#define MACB_CLK_DIV32 2 +#define MACB_CLK_DIV64 3 + +/* Constants for MAN register */ +#define MACB_MAN_SOF 1 +#define MACB_MAN_WRITE 1 +#define MACB_MAN_READ 2 +#define MACB_MAN_CODE 2 + +/* Bit manipulation macros */ +#define MACB_BIT(name) \ + (1 << MACB_##name##_OFFSET) +#define MACB_BF(name,value) \ + (((value) & ((1 << MACB_##name##_SIZE) - 1)) \ + << MACB_##name##_OFFSET) +#define MACB_BFEXT(name,value)\ + (((value) >> MACB_##name##_OFFSET) \ + & ((1 << MACB_##name##_SIZE) - 1)) +#define MACB_BFINS(name,value,old) \ + (((old) & ~(((1 << MACB_##name##_SIZE) - 1) \ + << MACB_##name##_OFFSET)) \ + | MACB_BF(name,value)) + +/* Register access macros */ +#define macb_readl(port,reg) \ + readl((port)->regs + MACB_##reg) +#define macb_writel(port,reg,value) \ + writel((value), (port)->regs + MACB_##reg) + +#endif /* __DRIVERS_MACB_H__ */ -- cgit v1.1 From 2a26ec4732efd7a308d0bbc97714c1d75ef1173b Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Wed, 18 Apr 2007 17:07:26 +0200 Subject: Cleanup, update CHANGELOG Sigend-off-by: Wolfgang Denk --- drivers/Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/Makefile b/drivers/Makefile index df9fbf2..d68cba6 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -35,8 +35,8 @@ COBJS = 3c589.o 5701rls.o ali512x.o atmel_usart.o \ lan91c96.o macb.o \ natsemi.o ne2000.o netarm_eth.o netconsole.o \ ns16550.o ns8382x.o ns87308.o ns7520_eth.o omap1510_i2c.o \ - omap24xx_i2c.o pci.o pci_auto.o pci_indirect.o tsi108_pci.o\ - tsi108_i2c.o pcnet.o plb2800_eth.o \ + omap24xx_i2c.o pci.o pci_auto.o pci_indirect.o \ + pcnet.o plb2800_eth.o \ ps2ser.o ps2mult.o pc_keyb.o \ rtl8019.o rtl8139.o rtl8169.o \ s3c4510b_eth.o s3c4510b_uart.o \ @@ -45,7 +45,8 @@ COBJS = 3c589.o 5701rls.o ali512x.o atmel_usart.o \ serial_pl010.o serial_pl011.o serial_xuartlite.o \ sl811_usb.o sm501.o smc91111.o smiLynxEM.o \ status_led.o sym53c8xx.o systemace.o ahci.o \ - ti_pci1410a.o tigon3.o tsec.o tsi108_eth.o\ + ti_pci1410a.o tigon3.o tsec.o \ + tsi108_eth.o tsi108_i2c.o tsi108_pci.o \ usbdcore.o usbdcore_ep0.o usbdcore_omap1510.o usbtty.o \ videomodes.o w83c553f.o \ ks8695eth.o \ -- cgit v1.1