* Patch by Dan Malek, 07 Apr 2004:

- Add support for RPC/STx GP3, Motorola 8560 board
  - Update 85xx TSEC driver so it searches MII for first available PHY
    and uses that one.
  - Add functions to support console MII commands.

* Patch by Tolunay Orkun, 07 Apr 2004:
  Move  initialization of bi_iic_fast[]
  from board_init_f() to board_init_r()

* Patch by Yasushi Shoji, 07 Apr 2004:
  Cleanup microblaze port

* Patch by Sangmoon Kim, 07 Apr 2004:
  Add auto SDRAM module detection for Debris board
This commit is contained in:
wdenk
2004-04-18 21:45:42 +00:00
parent d4326aca18
commit 7abf0c5886
20 changed files with 2006 additions and 92 deletions

View File

@@ -49,9 +49,12 @@ static int tsec_send(struct eth_device* dev, volatile void *packet, int length);
static int tsec_recv(struct eth_device* dev);
static int tsec_init(struct eth_device* dev, bd_t * bd);
static void tsec_halt(struct eth_device* dev);
static void init_registers(volatile tsec_t *regs);
static void startup_tsec(volatile tsec_t *regs);
static void init_phy(volatile tsec_t *regs);
static void init_registers(tsec_t *regs);
static void startup_tsec(tsec_t *regs);
static void init_phy(tsec_t *regs);
uint read_phy_reg(tsec_t *regbase, uint phyid, uint offset);
static int phy_id = -1;
/* Initialize device structure. returns 0 on failure, 1 on
* success */
@@ -59,6 +62,7 @@ int tsec_initialize(bd_t *bis)
{
struct eth_device* dev;
int i;
tsec_t *regs = (tsec_t *)(TSEC_BASE_ADDR);
dev = (struct eth_device*) malloc(sizeof *dev);
@@ -67,7 +71,7 @@ int tsec_initialize(bd_t *bis)
memset(dev, 0, sizeof *dev);
sprintf(dev->name, "MOTOROLA ETHERNET");
sprintf(dev->name, "MOTO ETHERNET");
dev->iobase = 0;
dev->priv = 0;
dev->init = tsec_init;
@@ -81,6 +85,45 @@ int tsec_initialize(bd_t *bis)
eth_register(dev);
/* Reconfigure the PHY to advertise everything here
* so that it works with both gigabit and 10/100 */
#ifdef CONFIG_PHY_M88E1011
/* Assign a Physical address to the TBI */
regs->tbipa=TBIPA_VALUE;
/* reset the management interface */
regs->miimcfg=MIIMCFG_RESET;
regs->miimcfg=MIIMCFG_INIT_VALUE;
/* Wait until the bus is free */
while(regs->miimind & MIIMIND_BUSY);
/* Locate PHYs. Skip TBIPA, which we know is 31.
*/
for (i=0; i<31; i++) {
if (read_phy_reg(regs, i, 2) == 0x141) {
if (phy_id == -1)
phy_id = i;
#ifdef TSEC_DEBUG
printf("Found Marvell PHY at 0x%02x\n", i);
#endif
}
}
#ifdef TSEC_DEBUG
printf("Using PHY ID 0x%02x\n", phy_id);
#endif
write_phy_reg(regs, phy_id, MIIM_CONTROL, MIIM_CONTROL_RESET);
RESET_ERRATA(regs, phy_id);
/* Configure the PHY to advertise gbit and 10/100 */
write_phy_reg(regs, phy_id, MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT);
write_phy_reg(regs, phy_id, MIIM_ANAR, MIIM_ANAR_INIT);
/* Reset the PHY so the new settings take effect */
write_phy_reg(regs, phy_id, MIIM_CONTROL, MIIM_CONTROL_RESET);
#endif
return 1;
}
@@ -89,12 +132,12 @@ int tsec_initialize(bd_t *bis)
* and brings the interface up */
int tsec_init(struct eth_device* dev, bd_t * bd)
{
volatile tsec_t *regs;
tsec_t *regs;
uint tempval;
char tmpbuf[MAC_ADDR_LEN];
int i;
regs = (volatile tsec_t *)(TSEC_BASE_ADDR);
regs = (tsec_t *)(TSEC_BASE_ADDR);
/* Make sure the controller is stopped */
tsec_halt(dev);
@@ -146,7 +189,7 @@ int tsec_init(struct eth_device* dev, bd_t * bd)
/* and then passes those bits on to the variable specified in */
/* value */
/* Before it does the read, it needs to clear the command field */
uint read_phy_reg(volatile tsec_t *regbase, uint phyid, uint offset)
uint read_phy_reg(tsec_t *regbase, uint phyid, uint offset)
{
uint value;
@@ -173,7 +216,7 @@ uint read_phy_reg(volatile tsec_t *regbase, uint phyid, uint offset)
}
/* Setup the PHY */
static void init_phy(volatile tsec_t *regs)
static void init_phy(tsec_t *regs)
{
uint testval;
unsigned int timeout = TSEC_TIMEOUT;
@@ -198,17 +241,17 @@ static void init_phy(volatile tsec_t *regs)
#endif
/* Set the PHY to gigabit, full duplex, Auto-negotiate */
write_phy_reg(regs, 0, MIIM_CONTROL, MIIM_CONTROL_INIT);
write_phy_reg(regs, phy_id, MIIM_CONTROL, MIIM_CONTROL_INIT);
/* Wait until TBI_STATUS indicates AN is done */
/* Wait until STATUS indicates Auto-Negotiation is done */
DBGPRINT("Waiting for Auto-negotiation to complete\n");
testval=read_phy_reg(regs, 0, MIIM_TBI_STATUS);
testval=read_phy_reg(regs, phy_id, MIIM_STATUS);
while((!(testval & MIIM_TBI_STATUS_AN_DONE))&& timeout--) {
testval=read_phy_reg(regs, 0, MIIM_TBI_STATUS);
while((!(testval & MIIM_STATUS_AN_DONE))&& timeout--) {
testval=read_phy_reg(regs, phy_id, MIIM_STATUS);
}
if(testval & MIIM_TBI_STATUS_AN_DONE)
if(testval & MIIM_STATUS_AN_DONE)
DBGPRINT("Auto-negotiation done\n");
else
DBGPRINT("Auto-negotiation timed-out.\n");
@@ -216,7 +259,7 @@ static void init_phy(volatile tsec_t *regs)
#ifdef CONFIG_PHY_CIS8201
/* Find out what duplexity (duplicity?) we have */
/* Read it twice to make sure */
testval=read_phy_reg(regs, 0, MIIM_AUX_CONSTAT);
testval=read_phy_reg(regs, phy_id, MIIM_AUX_CONSTAT);
if(testval & MIIM_AUXCONSTAT_DUPLEX) {
DBGPRINT("Enet starting in full duplex\n");
@@ -246,17 +289,17 @@ static void init_phy(volatile tsec_t *regs)
#ifdef CONFIG_PHY_M88E1011
/* Read the PHY to see what speed and duplex we are */
testval=read_phy_reg(regs, 0, MIIM_PHY_STATUS);
testval=read_phy_reg(regs, phy_id, MIIM_PHY_STATUS);
timeout = TSEC_TIMEOUT;
while((!(testval & MIIM_PHYSTAT_SPDDONE)) && timeout--) {
testval = read_phy_reg(regs,0,MIIM_PHY_STATUS);
testval = read_phy_reg(regs,phy_id,MIIM_PHY_STATUS);
}
if(!(testval & MIIM_PHYSTAT_SPDDONE))
DBGPRINT("Enet: Speed not resolved\n");
testval=read_phy_reg(regs, 0, MIIM_PHY_STATUS);
testval=read_phy_reg(regs, phy_id, MIIM_PHY_STATUS);
if(testval & MIIM_PHYSTAT_DUPLEX) {
DBGPRINT("Enet starting in Full Duplex\n");
regs->maccfg2 |= MACCFG2_FULL_DUPLEX;
@@ -280,7 +323,7 @@ static void init_phy(volatile tsec_t *regs)
}
static void init_registers(volatile tsec_t *regs)
static void init_registers(tsec_t *regs)
{
/* Clear IEVENT */
regs->ievent = IEVENT_INIT_CLEAR;
@@ -322,7 +365,7 @@ static void init_registers(volatile tsec_t *regs)
}
static void startup_tsec(volatile tsec_t *regs)
static void startup_tsec(tsec_t *regs)
{
int i;
@@ -363,7 +406,7 @@ static int tsec_send(struct eth_device* dev, volatile void *packet, int length)
{
int i;
int result = 0;
volatile tsec_t * regs = (volatile tsec_t *)(TSEC_BASE_ADDR);
tsec_t * regs = (tsec_t *)(TSEC_BASE_ADDR);
/* Find an empty buffer descriptor */
for(i=0; rtx.txbd[txIdx].status & TXBD_READY; i++) {
@@ -397,7 +440,7 @@ static int tsec_send(struct eth_device* dev, volatile void *packet, int length)
static int tsec_recv(struct eth_device* dev)
{
int length;
volatile tsec_t *regs = (volatile tsec_t *)(TSEC_BASE_ADDR);
tsec_t *regs = (tsec_t *)(TSEC_BASE_ADDR);
while(!(rtx.rxbd[rxIdx].status & RXBD_EMPTY)) {
@@ -428,7 +471,7 @@ static int tsec_recv(struct eth_device* dev)
static void tsec_halt(struct eth_device* dev)
{
volatile tsec_t *regs = (volatile tsec_t *)(TSEC_BASE_ADDR);
tsec_t *regs = (tsec_t *)(TSEC_BASE_ADDR);
regs->dmactrl &= ~(DMACTRL_GRS | DMACTRL_GTS);
regs->dmactrl |= (DMACTRL_GRS | DMACTRL_GTS);
@@ -438,4 +481,44 @@ static void tsec_halt(struct eth_device* dev)
regs->maccfg1 &= ~(MACCFG1_TX_EN | MACCFG1_RX_EN);
}
#ifndef CONFIG_BITBANGMII
/*
* Read a MII PHY register.
*
* Returns:
* 0 on success
*/
int miiphy_read(unsigned char addr,
unsigned char reg,
unsigned short *value)
{
tsec_t *regs;
unsigned short rv;
regs = (tsec_t *)(TSEC_BASE_ADDR);
rv = (unsigned short)read_phy_reg(regs, addr, reg);
*value = rv;
return 0;
}
/*
* Write a MII PHY register.
*
* Returns:
* 0 on success
*/
int miiphy_write(unsigned char addr,
unsigned char reg,
unsigned short value)
{
tsec_t *regs;
regs = (tsec_t *)(TSEC_BASE_ADDR);
write_phy_reg(regs, addr, reg, value);
return 0;
}
#endif /* CONFIG_BITBANGMII */
#endif /* CONFIG_TSEC_ENET */

View File

@@ -19,6 +19,9 @@
#include <net.h>
#include <mpc85xx.h>
/* TSEC1 is offset 0x24000, TSEC2 is offset 0x25000
#define TSEC_BASE_ADDR (CFG_IMMR + 0x25000)
*/
#define TSEC_BASE_ADDR (CFG_IMMR + 0x24000)
#define TSEC_MEM_SIZE 0x01000
@@ -56,16 +59,16 @@
#define MIIMIND_BUSY 0x00000001
#define MIIMIND_NOTVALID 0x00000004
#define MIIM_TBICON 0x11
#define MIIM_TBICON_GMII 0x00000010
#define MIIM_TBICON_AN 0x00000100
#define MIIM_CONTROL 0x00
#define MIIM_CONTROL_INIT 0x00001140
#define MIIM_ANEN 0x00001000
#define MIIM_CONTROL_RESET 0x00009140
#define MIIM_TBI_STATUS 0x1
#define MIIM_TBI_STATUS_AN_DONE 0x00000020
#define MIIM_STATUS 0x1
#define MIIM_STATUS_AN_DONE 0x00000020
#define MIIM_GBIT_CONTROL 0x9
#define MIIM_GBIT_CONTROL_INIT 0xe00
#define MIIM_TBI_ANEX 0x6
#define MIIM_TBI_ANEX_NP 0x00000004
@@ -89,11 +92,11 @@
#endif
#ifdef CONFIG_PHY_M88E1011
#define MIIM_ANAR 0x04
#define MIIM_ANAR_ADVERTISEMENT 0x01e1
#define MIIM_ANAR 0x4
#define MIIM_ANAR_INIT 0x1e1
#define MIIM_GBIT_CON 0x09
#define MIIM_GBIT_CON_ADVERT 0x1e00
#define MIIM_GBIT_CON_ADVERT 0x0e00
#define MIIM_PHY_STATUS 0x11
#define MIIM_PHYSTAT_SPEED 0xc000
@@ -130,6 +133,15 @@
} while(0)
/* This works around errata in reseting the PHY */
#define RESET_ERRATA(regs, ID) do { \
write_phy_reg(regs, (ID), 0x1d, 0x1f); \
write_phy_reg(regs, (ID), 0x1e, 0x200c); \
write_phy_reg(regs, (ID), 0x1d, 0x5); \
write_phy_reg(regs, (ID), 0x1e, 0x0); \
write_phy_reg(regs, (ID), 0x1e, 0x100); \
} while(0)
#define IEVENT_INIT_CLEAR 0xffffffff
#define IEVENT_BABR 0x80000000
#define IEVENT_RXC 0x40000000