From mboxrd@z Thu Jan 1 00:00:00 1970 From: Vipin Kumar Date: Wed, 23 Jan 2013 10:59:21 +0530 Subject: [U-Boot] [PATCH 1/2] drivers/net/designware, do an explicit memory access instead of implicit, re-written assignments to use readl() and writel(), all of this as preperation for making the driver able to work in a cached environment (I$D$ support). In-Reply-To: <1358863821-31956-2-git-send-email-frank.dols@synopsys.com> References: <1358863821-31956-1-git-send-email-frank.dols@synopsys.com> <1358863821-31956-2-git-send-email-frank.dols@synopsys.com> Message-ID: <50FF7531.7030609@st.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Provide a short patch title and a longer description in the patch itself. that would be much more readable On 1/22/2013 7:40 PM, Frank Dols wrote: > Signed-off-by: Frank Dols > --- > drivers/net/designware.c | 108 +++++++++++++++++++++++++++------------------- > drivers/net/designware.h | 4 +- > 2 files changed, 66 insertions(+), 46 deletions(-) > > diff --git a/drivers/net/designware.c b/drivers/net/designware.c > index bf21a08..2f235d5 100644 > --- a/drivers/net/designware.c > +++ b/drivers/net/designware.c > @@ -44,29 +44,36 @@ static void tx_descs_init(struct eth_device *dev) > struct dmamacdescr *desc_p; > u32 idx; > > + txbuffs = (char *) ((((unsigned long) txbuffs) + > + CONFIG_SYS_CACHELINE_SIZE)& > + (~(CONFIG_SYS_CACHELINE_SIZE - 1))); > + > for (idx = 0; idx< CONFIG_TX_DESCR_NUM; idx++) { > desc_p =&desc_table_p[idx]; > - desc_p->dmamac_addr =&txbuffs[idx * CONFIG_ETH_BUFSIZE]; > - desc_p->dmamac_next =&desc_table_p[idx + 1]; > + > + writel((ulong)&txbuffs[(idx * CONFIG_ETH_BUFSIZE)], > + &desc_p->dmamac_addr); > + writel((ulong)&desc_table_p[idx + 1],&desc_p->dmamac_next); > My first feeling is that the descriptors are allocated as Normal Cachabale memory and it would not help to access them using readl/writel Should the desciptors be allocated as non-cachable memory. If yes then how to do that in u-boot I suppose the rest of the code would be better reviewed if we know about this Vipin > #if defined(CONFIG_DW_ALTDESCRIPTOR) > - desc_p->txrx_status&= ~(DESC_TXSTS_TXINT | DESC_TXSTS_TXLAST | > - DESC_TXSTS_TXFIRST | DESC_TXSTS_TXCRCDIS | \ > - DESC_TXSTS_TXCHECKINSCTRL | \ > - DESC_TXSTS_TXRINGEND | DESC_TXSTS_TXPADDIS); > - > - desc_p->txrx_status |= DESC_TXSTS_TXCHAIN; > - desc_p->dmamac_cntl = 0; > - desc_p->txrx_status&= ~(DESC_TXSTS_MSK | DESC_TXSTS_OWNBYDMA); > + writel(readl(&desc_p->txrx_status)& ~(DESC_TXSTS_TXINT | > + DESC_TXSTS_TXLAST | DESC_TXSTS_TXFIRST | > + DESC_TXSTS_TXCRCDIS | DESC_TXSTS_TXCHECKINSCTRL | > + DESC_TXSTS_TXRINGEND | DESC_TXSTS_TXPADDIS), > + &desc_p->txrx_status); > + writel(readl(&desc_p->txrx_status) | DESC_TXSTS_TXCHAIN, > + &desc_p->txrx_status); > + writel(0,&desc_p->dmamac_cntl); > + writel(readl(&desc_p->txrx_status)& ~(DESC_TXSTS_MSK | > + DESC_TXSTS_OWNBYDMA),&desc_p->txrx_status); > #else > - desc_p->dmamac_cntl = DESC_TXCTRL_TXCHAIN; > - desc_p->txrx_status = 0; > + writel(DESC_TXCTRL_TXCHAIN,&desc_p->dmamac_cntl); > + writel(0,&desc_p->txrx_status); > #endif > } > > /* Correcting the last pointer of the chain */ > - desc_p->dmamac_next =&desc_table_p[0]; > - > + writel((ulong)&desc_table_p[0],&desc_p->dmamac_next); > writel((ulong)&desc_table_p[0],&dma_p->txdesclistaddr); > } > > @@ -79,21 +86,23 @@ static void rx_descs_init(struct eth_device *dev) > struct dmamacdescr *desc_p; > u32 idx; > > + rxbuffs = (char *) ((((unsigned long) rxbuffs) + > + CONFIG_SYS_CACHELINE_SIZE)& > + (~(CONFIG_SYS_CACHELINE_SIZE - 1))); > + > for (idx = 0; idx< CONFIG_RX_DESCR_NUM; idx++) { > desc_p =&desc_table_p[idx]; > - desc_p->dmamac_addr =&rxbuffs[idx * CONFIG_ETH_BUFSIZE]; > - desc_p->dmamac_next =&desc_table_p[idx + 1]; > > - desc_p->dmamac_cntl = > - (MAC_MAX_FRAME_SZ& DESC_RXCTRL_SIZE1MASK) | \ > - DESC_RXCTRL_RXCHAIN; > - > - desc_p->txrx_status = DESC_RXSTS_OWNBYDMA; > + writel((ulong)&rxbuffs[idx * CONFIG_ETH_BUFSIZE], > + &desc_p->dmamac_addr); > + writel((ulong)&desc_table_p[idx + 1],&desc_p->dmamac_next); > + writel((MAC_MAX_FRAME_SZ& DESC_RXCTRL_SIZE1MASK) | > + DESC_RXCTRL_RXCHAIN,&desc_p->dmamac_cntl); > + writel(DESC_RXSTS_OWNBYDMA,&desc_p->txrx_status); > } > > /* Correcting the last pointer of the chain */ > - desc_p->dmamac_next =&desc_table_p[0]; > - > + writel((ulong)&desc_table_p[0],&desc_p->dmamac_next); > writel((ulong)&desc_table_p[0],&dma_p->rxdesclistaddr); > } > > @@ -134,7 +143,7 @@ static int dw_write_hwaddr(struct eth_device *dev) > u32 macid_lo, macid_hi; > u8 *mac_id =&dev->enetaddr[0]; > > - macid_lo = mac_id[0] + (mac_id[1]<< 8) + \ > + macid_lo = mac_id[0] + (mac_id[1]<< 8) + > (mac_id[2]<< 16) + (mac_id[3]<< 24); > macid_hi = mac_id[4] + (mac_id[5]<< 8); > > @@ -198,7 +207,6 @@ static int dw_eth_init(struct eth_device *dev, bd_t *bis) > */ > writel(readl(&dma_p->opmode) | RXSTART,&dma_p->opmode); > writel(readl(&dma_p->opmode) | TXSTART,&dma_p->opmode); > - > writel(readl(&mac_p->conf) | RXENABLE | TXENABLE,&mac_p->conf); > > return 0; > @@ -212,26 +220,27 @@ static int dw_eth_send(struct eth_device *dev, void *packet, int length) > struct dmamacdescr *desc_p =&priv->tx_mac_descrtable[desc_num]; > > /* Check if the descriptor is owned by CPU */ > - if (desc_p->txrx_status& DESC_TXSTS_OWNBYDMA) { > + if (readl(&desc_p->txrx_status)& DESC_TXSTS_OWNBYDMA) { > printf("CPU not owner of tx frame\n"); > return -1; > } > > - memcpy((void *)desc_p->dmamac_addr, packet, length); > + memcpy((void *)readl(&desc_p->dmamac_addr), packet, length); > > #if defined(CONFIG_DW_ALTDESCRIPTOR) > - desc_p->txrx_status |= DESC_TXSTS_TXFIRST | DESC_TXSTS_TXLAST; > - desc_p->dmamac_cntl |= (length<< DESC_TXCTRL_SIZE1SHFT)& \ > - DESC_TXCTRL_SIZE1MASK; > - > - desc_p->txrx_status&= ~(DESC_TXSTS_MSK); > - desc_p->txrx_status |= DESC_TXSTS_OWNBYDMA; > + writel(readl(&desc_p->txrx_status) | DESC_TXSTS_TXFIRST | > + DESC_TXSTS_TXLAST,&desc_p->txrx_status); > + writel(readl(&desc_p->dmamac_cntl) | (length<< DESC_TXCTRL_SIZE1SHFT) > + & DESC_TXCTRL_SIZE1MASK,&desc_p->dmamac_cntl); > + writel(readl(&desc_p->txrx_status)& ~(DESC_TXSTS_MSK), > + &desc_p->txrx_status); > + writel(readl(&desc_p->txrx_status) | DESC_TXSTS_OWNBYDMA, > + &desc_p->txrx_status); > #else > - desc_p->dmamac_cntl |= ((length<< DESC_TXCTRL_SIZE1SHFT)& \ > - DESC_TXCTRL_SIZE1MASK) | DESC_TXCTRL_TXLAST | \ > - DESC_TXCTRL_TXFIRST; > - > - desc_p->txrx_status = DESC_TXSTS_OWNBYDMA; > + writel(readl(&desc_p->dmamac_cntl) | ((length<< DESC_TXCTRL_SIZE1SHFT) > + & DESC_TXCTRL_SIZE1MASK) | DESC_TXCTRL_TXLAST | > + DESC_TXCTRL_TXFIRST,&desc_p->dmamac_cntl); > + writel(DESC_TXSTS_OWNBYDMA,&desc_p->txrx_status); > #endif > > /* Test the wrap-around condition. */ > @@ -240,6 +249,8 @@ static int dw_eth_send(struct eth_device *dev, void *packet, int length) > > priv->tx_currdescnum = desc_num; > > + wmb(); /* write memory barrier */ > + > /* Start the transmission */ > writel(POLL_DATA,&dma_p->txpolldemand); > > @@ -252,22 +263,28 @@ static int dw_eth_recv(struct eth_device *dev) > u32 desc_num = priv->rx_currdescnum; > struct dmamacdescr *desc_p =&priv->rx_mac_descrtable[desc_num]; > > - u32 status = desc_p->txrx_status; > + u32 status; > int length = 0; > + int timeout = 30; > + > + do { > + status = readl(&desc_p->txrx_status); > + } while ((status& DESC_RXSTS_OWNBYDMA)&& (timeout--> 0)); > > /* Check if the owner is the CPU */ > if (!(status& DESC_RXSTS_OWNBYDMA)) { > > - length = (status& DESC_RXSTS_FRMLENMSK)>> \ > + length = (status& DESC_RXSTS_FRMLENMSK)>> > DESC_RXSTS_FRMLENSHFT; > > - NetReceive(desc_p->dmamac_addr, length); > + NetReceive(readl(&desc_p->dmamac_addr), length); > > /* > * Make the current descriptor valid again and go to > * the next one > */ > - desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA; > + writel(readl(&desc_p->txrx_status) | DESC_RXSTS_OWNBYDMA, > + &desc_p->txrx_status); > > /* Test the wrap-around condition. */ > if (++desc_num>= CONFIG_RX_DESCR_NUM) > @@ -295,12 +312,13 @@ static int eth_mdio_read(struct eth_device *dev, u8 addr, u8 reg, u16 *val) > u32 miiaddr; > int timeout = CONFIG_MDIO_TIMEOUT; > > - miiaddr = ((addr<< MIIADDRSHIFT)& MII_ADDRMSK) | \ > + miiaddr = ((addr<< MIIADDRSHIFT)& MII_ADDRMSK) | > ((reg<< MIIREGSHIFT)& MII_REGMSK); > > writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY,&mac_p->miiaddr); > > start = get_timer(0); > + > while (get_timer(start)< timeout) { > if (!(readl(&mac_p->miiaddr)& MII_BUSY)) { > *val = readl(&mac_p->miidata); > @@ -324,7 +342,7 @@ static int eth_mdio_write(struct eth_device *dev, u8 addr, u8 reg, u16 val) > u16 value; > > writel(val,&mac_p->miidata); > - miiaddr = ((addr<< MIIADDRSHIFT)& MII_ADDRMSK) | \ > + miiaddr = ((addr<< MIIADDRSHIFT)& MII_ADDRMSK) | > ((reg<< MIIREGSHIFT)& MII_REGMSK) | MII_WRITE; > > writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY,&mac_p->miiaddr); > @@ -469,6 +487,7 @@ static int configure_phy(struct eth_device *dev) > #if defined(CONFIG_DW_AUTONEG) > timeout = CONFIG_AUTONEG_TIMEOUT; > start = get_timer(0); > + > puts("Waiting for PHY auto negotiation to complete"); > while (get_timer(start)< timeout) { > eth_mdio_read(dev, phy_addr, MII_BMSR,&bmsr); > @@ -570,5 +589,6 @@ int designware_initialize(u32 id, ulong base_addr, u32 phy_addr, u32 interface) > #if defined(CONFIG_MII) > miiphy_register(dev->name, dw_mii_read, dw_mii_write); > #endif > + > return 1; > } > diff --git a/drivers/net/designware.h b/drivers/net/designware.h > index d668f8f..2eeb52f 100644 > --- a/drivers/net/designware.h > +++ b/drivers/net/designware.h > @@ -246,8 +246,8 @@ struct dw_eth_dev { > struct dmamacdescr tx_mac_descrtable[CONFIG_TX_DESCR_NUM]; > struct dmamacdescr rx_mac_descrtable[CONFIG_RX_DESCR_NUM]; > > - char txbuffs[TX_TOTAL_BUFSIZE]; > - char rxbuffs[RX_TOTAL_BUFSIZE]; > + char txbuffs[TX_TOTAL_BUFSIZE + CONFIG_SYS_CACHELINE_SIZE]; > + char rxbuffs[RX_TOTAL_BUFSIZE + CONFIG_SYS_CACHELINE_SIZE]; > > struct eth_mac_regs *mac_regs_p; > struct eth_dma_regs *dma_regs_p;