* terms of the GNU Public License, Version 2, incorporated
* herein by reference.
*
- * Copyright 2004-2010 Freescale Semiconductor, Inc.
+ * Copyright 2004-2011 Freescale Semiconductor, Inc.
* (C) Copyright 2003, Motorola, Inc.
* author Andy Fleming
*
static int tsec_init(struct eth_device *dev, bd_t * bd);
static int tsec_initialize(bd_t * bis, struct tsec_info_struct *tsec_info);
static void tsec_halt(struct eth_device *dev);
-static void init_registers(volatile tsec_t * regs);
+static void init_registers(tsec_t *regs);
static void startup_tsec(struct eth_device *dev);
static int init_phy(struct eth_device *dev);
void write_phy_reg(struct tsec_private *priv, uint regnum, uint value);
eth_register(dev);
/* Reset the MAC */
- priv->regs->maccfg1 |= MACCFG1_SOFT_RESET;
+ setbits_be32(&priv->regs->maccfg1, MACCFG1_SOFT_RESET);
udelay(2); /* Soft Reset must be asserted for 3 TX clocks */
- priv->regs->maccfg1 &= ~(MACCFG1_SOFT_RESET);
+ clrbits_be32(&priv->regs->maccfg1, MACCFG1_SOFT_RESET);
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \
&& !defined(BITBANGMII)
char tmpbuf[MAC_ADDR_LEN];
int i;
struct tsec_private *priv = (struct tsec_private *)dev->priv;
- volatile tsec_t *regs = priv->regs;
+ tsec_t *regs = priv->regs;
/* Make sure the controller is stopped */
tsec_halt(dev);
/* Init MACCFG2. Defaults to GMII */
- regs->maccfg2 = MACCFG2_INIT_SETTINGS;
+ out_be32(®s->maccfg2, MACCFG2_INIT_SETTINGS);
/* Init ECNTRL */
- regs->ecntrl = ECNTRL_INIT_SETTINGS;
+ out_be32(®s->ecntrl, ECNTRL_INIT_SETTINGS);
/* Copy the station address into the address registers.
* Backwards, because little endian MACS are dumb */
tempval = (tmpbuf[0] << 24) | (tmpbuf[1] << 16) | (tmpbuf[2] << 8) |
tmpbuf[3];
- regs->macstnaddr1 = tempval;
+ out_be32(®s->macstnaddr1, tempval);
tempval = *((uint *) (tmpbuf + 4));
- regs->macstnaddr2 = tempval;
+ out_be32(®s->macstnaddr2, tempval);
/* reset the indices to zero */
rxIdx = 0;
}
/* Writes the given phy's reg with value, using the specified MDIO regs */
-static void tsec_local_mdio_write(volatile tsec_mdio_t *phyregs, uint addr,
+static void tsec_local_mdio_write(tsec_mdio_t *phyregs, uint addr,
uint reg, uint value)
{
int timeout = 1000000;
- phyregs->miimadd = (addr << 8) | reg;
- phyregs->miimcon = value;
- asm("sync");
+ out_be32(&phyregs->miimadd, (addr << 8) | reg);
+ out_be32(&phyregs->miimcon, value);
timeout = 1000000;
- while ((phyregs->miimind & MIIMIND_BUSY) && timeout--) ;
+ while ((in_be32(&phyregs->miimind) & MIIMIND_BUSY) && timeout--)
+ ;
}
* notvalid bit cleared), and the bus to cease activity (miimind
* busy bit cleared), and then returns the value
*/
-static uint tsec_local_mdio_read(volatile tsec_mdio_t *phyregs,
- uint phyid, uint regnum)
+static uint tsec_local_mdio_read(tsec_mdio_t *phyregs, uint phyid, uint regnum)
{
uint value;
/* Put the address of the phy, and the register
* number into MIIMADD */
- phyregs->miimadd = (phyid << 8) | regnum;
+ out_be32(&phyregs->miimadd, (phyid << 8) | regnum);
/* Clear the command register, and wait */
- phyregs->miimcom = 0;
- asm("sync");
+ out_be32(&phyregs->miimcom, 0);
/* Initiate a read command, and wait */
- phyregs->miimcom = MIIM_READ_COMMAND;
- asm("sync");
+ out_be32(&phyregs->miimcom, MIIM_READ_COMMAND);
/* Wait for the the indication that the read is done */
- while ((phyregs->miimind & (MIIMIND_NOTVALID | MIIMIND_BUSY))) ;
+ while ((in_be32(&phyregs->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY)))
+ ;
/* Grab the value read from the PHY */
- value = phyregs->miimstat;
+ value = in_be32(&phyregs->miimstat);
return value;
}
{
struct tsec_private *priv = (struct tsec_private *)dev->priv;
struct phy_info *curphy;
- volatile tsec_t *regs = priv->regs;
+ tsec_t *regs = priv->regs;
/* Assign a Physical address to the TBI */
- regs->tbipa = CONFIG_SYS_TBIPA_VALUE;
- asm("sync");
+ out_be32(®s->tbipa, CONFIG_SYS_TBIPA_VALUE);
/* Reset MII (due to new addresses) */
- priv->phyregs->miimcfg = MIIMCFG_RESET;
- asm("sync");
- priv->phyregs->miimcfg = MIIMCFG_INIT_VALUE;
- asm("sync");
- while (priv->phyregs->miimind & MIIMIND_BUSY) ;
+ out_be32(&priv->phyregs->miimcfg, MIIMCFG_RESET);
+ out_be32(&priv->phyregs->miimcfg, MIIMCFG_INIT_VALUE);
+ while (in_be32(&priv->phyregs->miimind) & MIIMIND_BUSY)
+ ;
/* Get the cmd structure corresponding to the attached
* PHY */
return 0;
}
- if (regs->ecntrl & ECNTRL_SGMII_MODE)
+ if (in_be32(®s->ecntrl) & ECNTRL_SGMII_MODE)
tsec_configure_serdes(priv);
priv->phyinfo = curphy;
static uint mii_cis8204_fixled(uint mii_reg, struct tsec_private * priv)
{
uint phyid;
- volatile tsec_mdio_t *regbase = priv->phyregs;
+ tsec_mdio_t *regbase = priv->phyregs;
int timeout = 1000000;
for (phyid = 0; phyid < 4; phyid++) {
- regbase->miimadd = (phyid << 8) | mii_reg;
- regbase->miimcon = MIIM_CIS8204_SLEDCON_INIT;
- asm("sync");
+ out_be32(®base->miimadd, (phyid << 8) | mii_reg);
+ out_be32(®base->miimcon, MIIM_CIS8204_SLEDCON_INIT);
timeout = 1000000;
- while ((regbase->miimind & MIIMIND_BUSY) && timeout--) ;
+ while ((in_be32(®base->miimind) & MIIMIND_BUSY) && timeout--)
+ ;
}
return MIIM_CIS8204_SLEDCON_INIT;
* those we don't care about (unless zero is bad, in which case,
* choose a more appropriate value)
*/
-static void init_registers(volatile tsec_t * regs)
+static void init_registers(tsec_t *regs)
{
/* Clear IEVENT */
- regs->ievent = IEVENT_INIT_CLEAR;
-
- regs->imask = IMASK_INIT_CLEAR;
-
- regs->hash.iaddr0 = 0;
- regs->hash.iaddr1 = 0;
- regs->hash.iaddr2 = 0;
- regs->hash.iaddr3 = 0;
- regs->hash.iaddr4 = 0;
- regs->hash.iaddr5 = 0;
- regs->hash.iaddr6 = 0;
- regs->hash.iaddr7 = 0;
-
- regs->hash.gaddr0 = 0;
- regs->hash.gaddr1 = 0;
- regs->hash.gaddr2 = 0;
- regs->hash.gaddr3 = 0;
- regs->hash.gaddr4 = 0;
- regs->hash.gaddr5 = 0;
- regs->hash.gaddr6 = 0;
- regs->hash.gaddr7 = 0;
-
- regs->rctrl = 0x00000000;
+ out_be32(®s->ievent, IEVENT_INIT_CLEAR);
+
+ out_be32(®s->imask, IMASK_INIT_CLEAR);
+
+ out_be32(®s->hash.iaddr0, 0);
+ out_be32(®s->hash.iaddr1, 0);
+ out_be32(®s->hash.iaddr2, 0);
+ out_be32(®s->hash.iaddr3, 0);
+ out_be32(®s->hash.iaddr4, 0);
+ out_be32(®s->hash.iaddr5, 0);
+ out_be32(®s->hash.iaddr6, 0);
+ out_be32(®s->hash.iaddr7, 0);
+
+ out_be32(®s->hash.gaddr0, 0);
+ out_be32(®s->hash.gaddr1, 0);
+ out_be32(®s->hash.gaddr2, 0);
+ out_be32(®s->hash.gaddr3, 0);
+ out_be32(®s->hash.gaddr4, 0);
+ out_be32(®s->hash.gaddr5, 0);
+ out_be32(®s->hash.gaddr6, 0);
+ out_be32(®s->hash.gaddr7, 0);
+
+ out_be32(®s->rctrl, 0x00000000);
/* Init RMON mib registers */
memset((void *)&(regs->rmon), 0, sizeof(rmon_mib_t));
- regs->rmon.cam1 = 0xffffffff;
- regs->rmon.cam2 = 0xffffffff;
+ out_be32(®s->rmon.cam1, 0xffffffff);
+ out_be32(®s->rmon.cam2, 0xffffffff);
- regs->mrblr = MRBLR_INIT_SETTINGS;
+ out_be32(®s->mrblr, MRBLR_INIT_SETTINGS);
- regs->minflr = MINFLR_INIT_SETTINGS;
+ out_be32(®s->minflr, MINFLR_INIT_SETTINGS);
- regs->attr = ATTR_INIT_SETTINGS;
- regs->attreli = ATTRELI_INIT_SETTINGS;
+ out_be32(®s->attr, ATTR_INIT_SETTINGS);
+ out_be32(®s->attreli, ATTRELI_INIT_SETTINGS);
}
static void adjust_link(struct eth_device *dev)
{
struct tsec_private *priv = (struct tsec_private *)dev->priv;
- volatile tsec_t *regs = priv->regs;
+ tsec_t *regs = priv->regs;
+ u32 ecntrl, maccfg2;
- if (priv->link) {
- if (priv->duplexity != 0)
- regs->maccfg2 |= MACCFG2_FULL_DUPLEX;
- else
- regs->maccfg2 &= ~(MACCFG2_FULL_DUPLEX);
+ if (!priv->link) {
+ printf("%s: No link.\n", dev->name);
+ return;
+ }
- switch (priv->speed) {
- case 1000:
- regs->maccfg2 = ((regs->maccfg2 & ~(MACCFG2_IF))
- | MACCFG2_GMII);
- break;
- case 100:
- case 10:
- regs->maccfg2 = ((regs->maccfg2 & ~(MACCFG2_IF))
- | MACCFG2_MII);
+ /* clear all bits relative with interface mode */
+ ecntrl = in_be32(®s->ecntrl);
+ ecntrl &= ~ECNTRL_R100;
- /* Set R100 bit in all modes although
- * it is only used in RGMII mode
- */
- if (priv->speed == 100)
- regs->ecntrl |= ECNTRL_R100;
- else
- regs->ecntrl &= ~(ECNTRL_R100);
- break;
- default:
- printf("%s: Speed was bad\n", dev->name);
- break;
- }
+ maccfg2 = in_be32(®s->maccfg2);
+ maccfg2 &= ~(MACCFG2_IF | MACCFG2_FULL_DUPLEX);
- printf("Speed: %d, %s duplex%s\n", priv->speed,
- (priv->duplexity) ? "full" : "half",
- (priv->flags & TSEC_FIBER) ? ", fiber mode" : "");
+ if (priv->duplexity)
+ maccfg2 |= MACCFG2_FULL_DUPLEX;
- } else {
- printf("%s: No link.\n", dev->name);
+ switch (priv->speed) {
+ case 1000:
+ maccfg2 |= MACCFG2_GMII;
+ break;
+ case 100:
+ case 10:
+ maccfg2 |= MACCFG2_MII;
+
+ /* Set R100 bit in all modes although
+ * it is only used in RGMII mode
+ */
+ if (priv->speed == 100)
+ ecntrl |= ECNTRL_R100;
+ break;
+ default:
+ printf("%s: Speed was bad\n", dev->name);
+ break;
}
+
+ out_be32(®s->ecntrl, ecntrl);
+ out_be32(®s->maccfg2, maccfg2);
+
+ printf("Speed: %d, %s duplex%s\n", priv->speed,
+ (priv->duplexity) ? "full" : "half",
+ (priv->flags & TSEC_FIBER) ? ", fiber mode" : "");
}
/* Set up the buffers and their descriptors, and bring up the
{
int i;
struct tsec_private *priv = (struct tsec_private *)dev->priv;
- volatile tsec_t *regs = priv->regs;
+ tsec_t *regs = priv->regs;
/* Point to the buffer descriptors */
- regs->tbase = (unsigned int)(&rtx.txbd[txIdx]);
- regs->rbase = (unsigned int)(&rtx.rxbd[rxIdx]);
+ out_be32(®s->tbase, (unsigned int)(&rtx.txbd[txIdx]));
+ out_be32(®s->rbase, (unsigned int)(&rtx.rxbd[rxIdx]));
/* Initialize the Rx Buffer descriptors */
for (i = 0; i < PKTBUFSRX; i++) {
adjust_link(dev);
/* Enable Transmit and Receive */
- regs->maccfg1 |= (MACCFG1_RX_EN | MACCFG1_TX_EN);
+ setbits_be32(®s->maccfg1, MACCFG1_RX_EN | MACCFG1_TX_EN);
/* Tell the DMA it is clear to go */
- regs->dmactrl |= DMACTRL_INIT_SETTINGS;
- regs->tstat = TSTAT_CLEAR_THALT;
- regs->rstat = RSTAT_CLEAR_RHALT;
- regs->dmactrl &= ~(DMACTRL_GRS | DMACTRL_GTS);
+ setbits_be32(®s->dmactrl, DMACTRL_INIT_SETTINGS);
+ out_be32(®s->tstat, TSTAT_CLEAR_THALT);
+ out_be32(®s->rstat, RSTAT_CLEAR_RHALT);
+ clrbits_be32(®s->dmactrl, DMACTRL_GRS | DMACTRL_GTS);
}
/* This returns the status bits of the device. The return value
int i;
int result = 0;
struct tsec_private *priv = (struct tsec_private *)dev->priv;
- volatile tsec_t *regs = priv->regs;
+ tsec_t *regs = priv->regs;
/* Find an empty buffer descriptor */
for (i = 0; rtx.txbd[txIdx].status & TXBD_READY; i++) {
(TXBD_READY | TXBD_LAST | TXBD_CRC | TXBD_INTERRUPT);
/* Tell the DMA to go */
- regs->tstat = TSTAT_CLEAR_THALT;
+ out_be32(®s->tstat, TSTAT_CLEAR_THALT);
/* Wait for buffer to be transmitted */
for (i = 0; rtx.txbd[txIdx].status & TXBD_READY; i++) {
{
int length;
struct tsec_private *priv = (struct tsec_private *)dev->priv;
- volatile tsec_t *regs = priv->regs;
+ tsec_t *regs = priv->regs;
while (!(rtx.rxbd[rxIdx].status & RXBD_EMPTY)) {
rxIdx = (rxIdx + 1) % PKTBUFSRX;
}
- if (regs->ievent & IEVENT_BSY) {
- regs->ievent = IEVENT_BSY;
- regs->rstat = RSTAT_CLEAR_RHALT;
+ if (in_be32(®s->ievent) & IEVENT_BSY) {
+ out_be32(®s->ievent, IEVENT_BSY);
+ out_be32(®s->rstat, RSTAT_CLEAR_RHALT);
}
return -1;
static void tsec_halt(struct eth_device *dev)
{
struct tsec_private *priv = (struct tsec_private *)dev->priv;
- volatile tsec_t *regs = priv->regs;
+ tsec_t *regs = priv->regs;
- regs->dmactrl &= ~(DMACTRL_GRS | DMACTRL_GTS);
- regs->dmactrl |= (DMACTRL_GRS | DMACTRL_GTS);
+ clrbits_be32(®s->dmactrl, DMACTRL_GRS | DMACTRL_GTS);
+ setbits_be32(®s->dmactrl, DMACTRL_GRS | DMACTRL_GTS);
- while ((regs->ievent & (IEVENT_GRSC | IEVENT_GTSC))
- != (IEVENT_GRSC | IEVENT_GTSC)) ;
+ while ((in_be32(®s->ievent) & (IEVENT_GRSC | IEVENT_GTSC))
+ != (IEVENT_GRSC | IEVENT_GTSC))
+ ;
- regs->maccfg1 &= ~(MACCFG1_TX_EN | MACCFG1_RX_EN);
+ clrbits_be32(®s->maccfg1, MACCFG1_TX_EN | MACCFG1_RX_EN);
/* Shut down the PHY, as needed */
if(priv->phyinfo)
{
int i;
uint result;
- volatile tsec_mdio_t *phyregs = priv->phyregs;
+ tsec_mdio_t *phyregs = priv->phyregs;
- phyregs->miimcfg = MIIMCFG_RESET;
+ out_be32(&phyregs->miimcfg, MIIMCFG_RESET);
- phyregs->miimcfg = MIIMCFG_INIT_VALUE;
+ out_be32(&phyregs->miimcfg, MIIMCFG_INIT_VALUE);
- while (phyregs->miimind & MIIMIND_BUSY) ;
+ while (in_be32(&phyregs->miimind) & MIIMIND_BUSY)
+ ;
for (i = 0; cmd->mii_reg != miim_end; i++) {
if (cmd->mii_data == miim_read) {