X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fnet%2Fsh_eth.c;h=e6fc8c8bf6e44f5cb2e7cebf6b9866681aaac8ef;hb=01fac041cb32408a4fc5f4617381da6ec609a8dc;hp=27d040125eef311df3d22a03b5024764ca5c65fb;hpb=1086c5d6f8541460f0f10e4a302d8aac27e0e6e0;p=u-boot diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index 27d040125e..e6fc8c8bf6 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -1,8 +1,8 @@ /* - * sh_eth.c - Driver for Renesas SH7763's ethernet controler. + * sh_eth.c - Driver for Renesas ethernet controler. * - * Copyright (C) 2008 Renesas Solutions Corp. - * Copyright (c) 2008 Nobuhiro Iwamatsu + * Copyright (C) 2008, 2011 Renesas Solutions Corp. + * Copyright (c) 2008, 2011 Nobuhiro Iwamatsu * Copyright (c) 2007 Carlos Munoz * * This program is free software; you can redistribute it and/or modify @@ -44,9 +44,9 @@ #define flush_cache_wback(...) #endif -#define SH_ETH_PHY_DELAY 50000 +#define TIMEOUT_CNT 1000 -int sh_eth_send(struct eth_device *dev, volatile void *packet, int len) +int sh_eth_send(struct eth_device *dev, void *packet, int len) { struct sh_eth_dev *eth = dev->priv; int port = eth->port, ret = 0, timeout; @@ -59,7 +59,7 @@ int sh_eth_send(struct eth_device *dev, volatile void *packet, int len) } /* packet must be a 4 byte boundary */ - if ((int)packet & (4 - 1)) { + if ((int)packet & 3) { printf(SHETHER_NAME ": %s: packet not 4 byte alligned\n", __func__); ret = -EFAULT; goto err; @@ -76,11 +76,11 @@ int sh_eth_send(struct eth_device *dev, volatile void *packet, int len) port_info->tx_desc_cur->td0 = TD_TACT | TD_TFP; /* Restart the transmitter if disabled */ - if (!(inl(EDTRR(port)) & EDTRR_TRNS)) - outl(EDTRR_TRNS, EDTRR(port)); + if (!(sh_eth_read(eth, EDTRR) & EDTRR_TRNS)) + sh_eth_write(eth, EDTRR_TRNS, EDTRR); /* Wait until packet is transmitted */ - timeout = 1000; + timeout = TIMEOUT_CNT; while (port_info->tx_desc_cur->td0 & TD_TACT && timeout--) udelay(100); @@ -94,7 +94,6 @@ int sh_eth_send(struct eth_device *dev, volatile void *packet, int len) if (port_info->tx_desc_cur >= port_info->tx_desc_base + NUM_TX_DESC) port_info->tx_desc_cur = port_info->tx_desc_base; - return ret; err: return ret; } @@ -104,15 +103,15 @@ int sh_eth_recv(struct eth_device *dev) struct sh_eth_dev *eth = dev->priv; int port = eth->port, len = 0; struct sh_eth_info *port_info = ð->port_info[port]; - volatile u8 *packet; + uchar *packet; /* Check if the rx descriptor is ready */ if (!(port_info->rx_desc_cur->rd0 & RD_RACT)) { /* Check for errors */ if (!(port_info->rx_desc_cur->rd0 & RD_RFE)) { len = port_info->rx_desc_cur->rd1 & 0xffff; - packet = (volatile u8 *) - ADDR_TO_P2(port_info->rx_desc_cur->rd2); + packet = (uchar *) + ADDR_TO_P2(port_info->rx_desc_cur->rd2); NetReceive(packet, len); } @@ -130,40 +129,38 @@ int sh_eth_recv(struct eth_device *dev) } /* Restart the receiver if disabled */ - if (!(inl(EDRRR(port)) & EDRRR_R)) - outl(EDRRR_R, EDRRR(port)); + if (!(sh_eth_read(eth, EDRRR) & EDRRR_R)) + sh_eth_write(eth, EDRRR_R, EDRRR); return len; } -#define EDMR_INIT_CNT 1000 static int sh_eth_reset(struct sh_eth_dev *eth) { - int port = eth->port; -#if defined(CONFIG_CPU_SH7763) +#if defined(SH_ETH_TYPE_GETHER) int ret = 0, i; /* Start e-dmac transmitter and receiver */ - outl(EDSR_ENALL, EDSR(port)); + sh_eth_write(eth, EDSR_ENALL, EDSR); /* Perform a software reset and wait for it to complete */ - outl(EDMR_SRST, EDMR(port)); - for (i = 0; i < EDMR_INIT_CNT; i++) { - if (!(inl(EDMR(port)) & EDMR_SRST)) + sh_eth_write(eth, EDMR_SRST, EDMR); + for (i = 0; i < TIMEOUT_CNT ; i++) { + if (!(sh_eth_read(eth, EDMR) & EDMR_SRST)) break; udelay(1000); } - if (i == EDMR_INIT_CNT) { + if (i == TIMEOUT_CNT) { printf(SHETHER_NAME ": Software reset timeout\n"); ret = -EIO; } return ret; #else - outl(inl(EDMR(port)) | EDMR_SRST, EDMR(port)); + sh_eth_write(eth, sh_eth_read(eth, EDMR) | EDMR_SRST, EDMR); udelay(3000); - outl(inl(EDMR(port)) & ~EDMR_SRST, EDMR(port)); + sh_eth_write(eth, sh_eth_read(eth, EDMR) & ~EDMR_SRST, EDMR); return 0; #endif @@ -209,11 +206,11 @@ static int sh_eth_tx_desc_init(struct sh_eth_dev *eth) /* Point the controller to the tx descriptor list. Must use physical addresses */ - outl(ADDR_TO_PHY(port_info->tx_desc_base), TDLAR(port)); -#if defined(CONFIG_CPU_SH7763) - outl(ADDR_TO_PHY(port_info->tx_desc_base), TDFAR(port)); - outl(ADDR_TO_PHY(cur_tx_desc), TDFXR(port)); - outl(0x01, TDFFR(port));/* Last discriptor bit */ + sh_eth_write(eth, ADDR_TO_PHY(port_info->tx_desc_base), TDLAR); +#if defined(SH_ETH_TYPE_GETHER) + sh_eth_write(eth, ADDR_TO_PHY(port_info->tx_desc_base), TDFAR); + sh_eth_write(eth, ADDR_TO_PHY(cur_tx_desc), TDFXR); + sh_eth_write(eth, 0x01, TDFFR);/* Last discriptor bit */ #endif err: @@ -277,11 +274,11 @@ static int sh_eth_rx_desc_init(struct sh_eth_dev *eth) cur_rx_desc->rd0 |= RD_RDLE; /* Point the controller to the rx descriptor list */ - outl(ADDR_TO_PHY(port_info->rx_desc_base), RDLAR(port)); -#if defined(CONFIG_CPU_SH7763) - outl(ADDR_TO_PHY(port_info->rx_desc_base), RDFAR(port)); - outl(ADDR_TO_PHY(cur_rx_desc), RDFXR(port)); - outl(RDFFR_RDLF, RDFFR(port)); + sh_eth_write(eth, ADDR_TO_PHY(port_info->rx_desc_base), RDLAR); +#if defined(SH_ETH_TYPE_GETHER) + sh_eth_write(eth, ADDR_TO_PHY(port_info->rx_desc_base), RDFAR); + sh_eth_write(eth, ADDR_TO_PHY(cur_rx_desc), RDFXR); + sh_eth_write(eth, RDFFR_RDLF, RDFFR); #endif return ret; @@ -348,8 +345,9 @@ static int sh_eth_phy_config(struct sh_eth_dev *eth) struct eth_device *dev = port_info->dev; struct phy_device *phydev; - phydev = phy_connect(miiphy_get_dev_by_name(dev->name), - port_info->phy_addr, dev, PHY_INTERFACE_MODE_MII); + phydev = phy_connect( + miiphy_get_dev_by_name(dev->name), + port_info->phy_addr, dev, CONFIG_SH_ETHER_PHY_MODE); port_info->phydev = phydev; phy_config(phydev); @@ -365,43 +363,39 @@ static int sh_eth_config(struct sh_eth_dev *eth, bd_t *bd) struct phy_device *phy; /* Configure e-dmac registers */ - outl((inl(EDMR(port)) & ~EMDR_DESC_R) | EDMR_EL, EDMR(port)); - outl(0, EESIPR(port)); - outl(0, TRSCER(port)); - outl(0, TFTR(port)); - outl((FIFO_SIZE_T | FIFO_SIZE_R), FDR(port)); - outl(RMCR_RST, RMCR(port)); -#ifndef CONFIG_CPU_SH7757 - outl(0, RPADIR(port)); + sh_eth_write(eth, (sh_eth_read(eth, EDMR) & ~EMDR_DESC_R) | EDMR_EL, + EDMR); + sh_eth_write(eth, 0, EESIPR); + sh_eth_write(eth, 0, TRSCER); + sh_eth_write(eth, 0, TFTR); + sh_eth_write(eth, (FIFO_SIZE_T | FIFO_SIZE_R), FDR); + sh_eth_write(eth, RMCR_RST, RMCR); +#if defined(SH_ETH_TYPE_GETHER) + sh_eth_write(eth, 0, RPADIR); #endif - outl((FIFO_F_D_RFF | FIFO_F_D_RFD), FCFTR(port)); + sh_eth_write(eth, (FIFO_F_D_RFF | FIFO_F_D_RFD), FCFTR); /* Configure e-mac registers */ -#if defined(CONFIG_CPU_SH7757) - outl(ECSIPR_BRCRXIP | ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | - ECSIPR_MPDIP | ECSIPR_ICDIP, ECSIPR(port)); -#else - outl(0, ECSIPR(port)); -#endif + sh_eth_write(eth, 0, ECSIPR); /* Set Mac address */ val = dev->enetaddr[0] << 24 | dev->enetaddr[1] << 16 | dev->enetaddr[2] << 8 | dev->enetaddr[3]; - outl(val, MAHR(port)); + sh_eth_write(eth, val, MAHR); val = dev->enetaddr[4] << 8 | dev->enetaddr[5]; - outl(val, MALR(port)); - - outl(RFLR_RFL_MIN, RFLR(port)); -#ifndef CONFIG_CPU_SH7757 - outl(0, PIPR(port)); + sh_eth_write(eth, val, MALR); + + sh_eth_write(eth, RFLR_RFL_MIN, RFLR); +#if defined(SH_ETH_TYPE_GETHER) + sh_eth_write(eth, 0, PIPR); + sh_eth_write(eth, APR_AP, APR); + sh_eth_write(eth, MPR_MP, MPR); + sh_eth_write(eth, TPAUSER_TPAUSE, TPAUSER); #endif - outl(APR_AP, APR(port)); - outl(MPR_MP, MPR(port)); -#ifdef CONFIG_CPU_SH7757 - outl(TPAUSER_UNLIMITED, TPAUSER(port)); -#else - outl(TPAUSER_TPAUSE, TPAUSER(port)); + +#if defined(CONFIG_CPU_SH7734) || defined(CONFIG_R8A7740) + sh_eth_write(eth, CONFIG_SH_ETHER_SH7734_MII, RMII_MII); #endif /* Configure phy */ ret = sh_eth_phy_config(eth); @@ -410,35 +404,47 @@ static int sh_eth_config(struct sh_eth_dev *eth, bd_t *bd) goto err_phy_cfg; } phy = port_info->phydev; - phy_startup(phy); + ret = phy_startup(phy); + if (ret) { + printf(SHETHER_NAME ": phy startup failure\n"); + return ret; + } + + val = 0; /* Set the transfer speed */ -#ifdef CONFIG_CPU_SH7763 if (phy->speed == 100) { printf(SHETHER_NAME ": 100Base/"); - outl(GECMR_100B, GECMR(port)); +#if defined(SH_ETH_TYPE_GETHER) + sh_eth_write(eth, GECMR_100B, GECMR); +#elif defined(CONFIG_CPU_SH7757) || defined(CONFIG_CPU_SH7752) + sh_eth_write(eth, 1, RTRATE); +#elif defined(CONFIG_CPU_SH7724) + val = ECMR_RTM; +#endif } else if (phy->speed == 10) { printf(SHETHER_NAME ": 10Base/"); - outl(GECMR_10B, GECMR(port)); - } +#if defined(SH_ETH_TYPE_GETHER) + sh_eth_write(eth, GECMR_10B, GECMR); +#elif defined(CONFIG_CPU_SH7757) || defined(CONFIG_CPU_SH7752) + sh_eth_write(eth, 0, RTRATE); #endif -#if defined(CONFIG_CPU_SH7757) - if (phy->speed == 100) { - printf("100Base/"); - outl(1, RTRATE(port)); - } else if (phy->speed == 10) { - printf("10Base/"); - outl(0, RTRATE(port)); + } +#if defined(SH_ETH_TYPE_GETHER) + else if (phy->speed == 1000) { + printf(SHETHER_NAME ": 1000Base/"); + sh_eth_write(eth, GECMR_1000B, GECMR); } #endif /* Check if full duplex mode is supported by the phy */ if (phy->duplex) { printf("Full\n"); - outl((ECMR_CHG_DM|ECMR_RE|ECMR_TE|ECMR_DM), ECMR(port)); + sh_eth_write(eth, val | (ECMR_CHG_DM|ECMR_RE|ECMR_TE|ECMR_DM), + ECMR); } else { printf("Half\n"); - outl((ECMR_CHG_DM|ECMR_RE|ECMR_TE), ECMR(port)); + sh_eth_write(eth, val | (ECMR_CHG_DM|ECMR_RE|ECMR_TE), ECMR); } return ret; @@ -453,12 +459,12 @@ static void sh_eth_start(struct sh_eth_dev *eth) * Enable the e-dmac receiver only. The transmitter will be enabled when * we have something to transmit */ - outl(EDRRR_R, EDRRR(eth->port)); + sh_eth_write(eth, EDRRR_R, EDRRR); } static void sh_eth_stop(struct sh_eth_dev *eth) { - outl(~EDRRR_R, EDRRR(eth->port)); + sh_eth_write(eth, ~EDRRR_R, EDRRR); } int sh_eth_init(struct eth_device *dev, bd_t *bd) @@ -562,9 +568,8 @@ static int sh_eth_bb_init(struct bb_miiphy_bus *bus) static int sh_eth_bb_mdio_active(struct bb_miiphy_bus *bus) { struct sh_eth_dev *eth = bus->priv; - int port = eth->port; - outl(inl(PIR(port)) | PIR_MMD, PIR(port)); + sh_eth_write(eth, sh_eth_read(eth, PIR) | PIR_MMD, PIR); return 0; } @@ -572,9 +577,8 @@ static int sh_eth_bb_mdio_active(struct bb_miiphy_bus *bus) static int sh_eth_bb_mdio_tristate(struct bb_miiphy_bus *bus) { struct sh_eth_dev *eth = bus->priv; - int port = eth->port; - outl(inl(PIR(port)) & ~PIR_MMD, PIR(port)); + sh_eth_write(eth, sh_eth_read(eth, PIR) & ~PIR_MMD, PIR); return 0; } @@ -582,12 +586,11 @@ static int sh_eth_bb_mdio_tristate(struct bb_miiphy_bus *bus) static int sh_eth_bb_set_mdio(struct bb_miiphy_bus *bus, int v) { struct sh_eth_dev *eth = bus->priv; - int port = eth->port; if (v) - outl(inl(PIR(port)) | PIR_MDO, PIR(port)); + sh_eth_write(eth, sh_eth_read(eth, PIR) | PIR_MDO, PIR); else - outl(inl(PIR(port)) & ~PIR_MDO, PIR(port)); + sh_eth_write(eth, sh_eth_read(eth, PIR) & ~PIR_MDO, PIR); return 0; } @@ -595,9 +598,8 @@ static int sh_eth_bb_set_mdio(struct bb_miiphy_bus *bus, int v) static int sh_eth_bb_get_mdio(struct bb_miiphy_bus *bus, int *v) { struct sh_eth_dev *eth = bus->priv; - int port = eth->port; - *v = (inl(PIR(port)) & PIR_MDI) >> 3; + *v = (sh_eth_read(eth, PIR) & PIR_MDI) >> 3; return 0; } @@ -605,12 +607,11 @@ static int sh_eth_bb_get_mdio(struct bb_miiphy_bus *bus, int *v) static int sh_eth_bb_set_mdc(struct bb_miiphy_bus *bus, int v) { struct sh_eth_dev *eth = bus->priv; - int port = eth->port; if (v) - outl(inl(PIR(port)) | PIR_MDC, PIR(port)); + sh_eth_write(eth, sh_eth_read(eth, PIR) | PIR_MDC, PIR); else - outl(inl(PIR(port)) & ~PIR_MDC, PIR(port)); + sh_eth_write(eth, sh_eth_read(eth, PIR) & ~PIR_MDC, PIR); return 0; }