Skip to content

Commit

Permalink
TI Davinci EMAC : Abstract Buffer address translation logic.
Browse files Browse the repository at this point in the history
When programming the DMA engine, the next pointers must be
programmed with physical address as seen from the DMA master
address space. This address may be different from physical
address of the buffer RAM area. This patch abstracts the
buffer address translation logic.

Signed-off-by: Sriramakrishnan <srk@ti.com>
Acked-by: Chaithrika U S <chaithrika@ti.com>
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
  • Loading branch information
Sriramakrishnan authored and Kevin Hilman committed Feb 4, 2010
1 parent 01a9af3 commit ad021ae
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 17 deletions.
41 changes: 24 additions & 17 deletions drivers/net/davinci_emac.c
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,7 @@ struct emac_priv {
void __iomem *ctrl_base;
void __iomem *emac_ctrl_ram;
u32 ctrl_ram_size;
u32 hw_ram_addr;
struct emac_txch *txch[EMAC_DEF_MAX_TX_CH];
struct emac_rxch *rxch[EMAC_DEF_MAX_RX_CH];
u32 link; /* 1=link on, 0=link off */
Expand Down Expand Up @@ -497,11 +498,9 @@ static struct clk *emac_clk;
static unsigned long emac_bus_frequency;
static unsigned long mdio_max_freq;

/* EMAC internal utility function */
static inline u32 emac_virt_to_phys(void __iomem *addr)
{
return (u32 __force) io_v2p(addr);
}
#define emac_virt_to_phys(addr, priv) \
(((u32 __force)(addr) - (u32 __force)(priv->emac_ctrl_ram)) \
+ priv->hw_ram_addr)

/* Cache macros - Packet buffers would be from skb pool which is cached */
#define EMAC_VIRT_NOCACHE(addr) (addr)
Expand Down Expand Up @@ -1309,7 +1308,7 @@ static int emac_tx_bdproc(struct emac_priv *priv, u32 ch, u32 budget)
curr_bd = txch->active_queue_head;
if (NULL == curr_bd) {
emac_write(EMAC_TXCP(ch),
emac_virt_to_phys(txch->last_hw_bdprocessed));
emac_virt_to_phys(txch->last_hw_bdprocessed, priv));
txch->no_active_pkts++;
spin_unlock_irqrestore(&priv->tx_lock, flags);
return 0;
Expand All @@ -1319,7 +1318,7 @@ static int emac_tx_bdproc(struct emac_priv *priv, u32 ch, u32 budget)
while ((curr_bd) &&
((frame_status & EMAC_CPPI_OWNERSHIP_BIT) == 0) &&
(pkts_processed < budget)) {
emac_write(EMAC_TXCP(ch), emac_virt_to_phys(curr_bd));
emac_write(EMAC_TXCP(ch), emac_virt_to_phys(curr_bd, priv));
txch->active_queue_head = curr_bd->next;
if (frame_status & EMAC_CPPI_EOQ_BIT) {
if (curr_bd->next) { /* misqueued packet */
Expand Down Expand Up @@ -1406,7 +1405,7 @@ static int emac_send(struct emac_priv *priv, struct emac_netpktobj *pkt, u32 ch)
txch->active_queue_tail = curr_bd;
if (1 != txch->queue_active) {
emac_write(EMAC_TXHDP(ch),
emac_virt_to_phys(curr_bd));
emac_virt_to_phys(curr_bd, priv));
txch->queue_active = 1;
}
++txch->queue_reinit;
Expand All @@ -1418,10 +1417,11 @@ static int emac_send(struct emac_priv *priv, struct emac_netpktobj *pkt, u32 ch)
tail_bd->next = curr_bd;
txch->active_queue_tail = curr_bd;
tail_bd = EMAC_VIRT_NOCACHE(tail_bd);
tail_bd->h_next = (int)emac_virt_to_phys(curr_bd);
tail_bd->h_next = (int)emac_virt_to_phys(curr_bd, priv);
frame_status = tail_bd->mode;
if (frame_status & EMAC_CPPI_EOQ_BIT) {
emac_write(EMAC_TXHDP(ch), emac_virt_to_phys(curr_bd));
emac_write(EMAC_TXHDP(ch),
emac_virt_to_phys(curr_bd, priv));
frame_status &= ~(EMAC_CPPI_EOQ_BIT);
tail_bd->mode = frame_status;
++txch->end_of_queue_add;
Expand Down Expand Up @@ -1611,7 +1611,8 @@ static int emac_init_rxch(struct emac_priv *priv, u32 ch, char *param)
}

/* populate the hardware descriptor */
curr_bd->h_next = emac_virt_to_phys(rxch->active_queue_head);
curr_bd->h_next = emac_virt_to_phys(rxch->active_queue_head,
priv);
/* FIXME buff_ptr = dma_map_single(... data_ptr ...) */
curr_bd->buff_ptr = virt_to_phys(curr_bd->data_ptr);
curr_bd->off_b_len = rxch->buf_size;
Expand Down Expand Up @@ -1886,7 +1887,7 @@ static void emac_addbd_to_rx_queue(struct emac_priv *priv, u32 ch,
rxch->active_queue_tail = curr_bd;
if (0 != rxch->queue_active) {
emac_write(EMAC_RXHDP(ch),
emac_virt_to_phys(rxch->active_queue_head));
emac_virt_to_phys(rxch->active_queue_head, priv));
rxch->queue_active = 1;
}
} else {
Expand All @@ -1897,11 +1898,11 @@ static void emac_addbd_to_rx_queue(struct emac_priv *priv, u32 ch,
rxch->active_queue_tail = curr_bd;
tail_bd->next = curr_bd;
tail_bd = EMAC_VIRT_NOCACHE(tail_bd);
tail_bd->h_next = emac_virt_to_phys(curr_bd);
tail_bd->h_next = emac_virt_to_phys(curr_bd, priv);
frame_status = tail_bd->mode;
if (frame_status & EMAC_CPPI_EOQ_BIT) {
emac_write(EMAC_RXHDP(ch),
emac_virt_to_phys(curr_bd));
emac_virt_to_phys(curr_bd, priv));
frame_status &= ~(EMAC_CPPI_EOQ_BIT);
tail_bd->mode = frame_status;
++rxch->end_of_queue_add;
Expand Down Expand Up @@ -1994,7 +1995,7 @@ static int emac_rx_bdproc(struct emac_priv *priv, u32 ch, u32 budget)
curr_pkt->num_bufs = 1;
curr_pkt->pkt_length =
(frame_status & EMAC_RX_BD_PKT_LENGTH_MASK);
emac_write(EMAC_RXCP(ch), emac_virt_to_phys(curr_bd));
emac_write(EMAC_RXCP(ch), emac_virt_to_phys(curr_bd, priv));
++rxch->processed_bd;
last_bd = curr_bd;
curr_bd = last_bd->next;
Expand All @@ -2005,7 +2006,7 @@ static int emac_rx_bdproc(struct emac_priv *priv, u32 ch, u32 budget)
if (curr_bd) {
++rxch->mis_queued_packets;
emac_write(EMAC_RXHDP(ch),
emac_virt_to_phys(curr_bd));
emac_virt_to_phys(curr_bd, priv));
} else {
++rxch->end_of_queue;
rxch->queue_active = 0;
Expand Down Expand Up @@ -2106,7 +2107,7 @@ static int emac_hw_enable(struct emac_priv *priv)
emac_write(EMAC_RXINTMASKSET, BIT(ch));
rxch->queue_active = 1;
emac_write(EMAC_RXHDP(ch),
emac_virt_to_phys(rxch->active_queue_head));
emac_virt_to_phys(rxch->active_queue_head, priv));
}

/* Enable MII */
Expand Down Expand Up @@ -2702,6 +2703,12 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev)
priv->ctrl_ram_size = pdata->ctrl_ram_size;
priv->emac_ctrl_ram = priv->remap_addr + pdata->ctrl_ram_offset;

if (pdata->hw_ram_addr)
priv->hw_ram_addr = pdata->hw_ram_addr;
else
priv->hw_ram_addr = (u32 __force)res->start +
pdata->ctrl_ram_offset;

res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!res) {
dev_err(emac_dev, "DaVinci EMAC: Error getting irq res\n");
Expand Down
1 change: 1 addition & 0 deletions include/linux/davinci_emac.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ struct emac_platform_data {
u32 ctrl_reg_offset;
u32 ctrl_mod_reg_offset;
u32 ctrl_ram_offset;
u32 hw_ram_addr;
u32 mdio_reg_offset;
u32 ctrl_ram_size;
u32 phy_mask;
Expand Down

0 comments on commit ad021ae

Please sign in to comment.