Merge branch 'drm-radeon-testing' of ../drm-radeon-next into drm-core-next
[linux-2.6-block.git] / drivers / net / ethernet / stmicro / stmmac / dwmac1000_dma.c
CommitLineData
47dd7a54
GC
1/*******************************************************************************
2 This is the driver for the GMAC on-chip Ethernet controller for ST SoCs.
3 DWC Ether MAC 10/100/1000 Universal version 3.41a has been used for
4 developing this code.
5
56b106ae 6 This contains the functions to handle the dma.
21d437cc 7
47dd7a54
GC
8 Copyright (C) 2007-2009 STMicroelectronics Ltd
9
10 This program is free software; you can redistribute it and/or modify it
11 under the terms and conditions of the GNU General Public License,
12 version 2, as published by the Free Software Foundation.
13
14 This program is distributed in the hope it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 more details.
18
19 You should have received a copy of the GNU General Public License along with
20 this program; if not, write to the Free Software Foundation, Inc.,
21 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
22
23 The full GNU General Public License is included in this distribution in
24 the file called "COPYING".
25
26 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
27*******************************************************************************/
28
b7f080cf 29#include <asm/io.h>
21d437cc 30#include "dwmac1000.h"
aec7ff27 31#include "dwmac_dma.h"
47dd7a54 32
ad01b7d4 33static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx,
21d437cc 34 u32 dma_rx)
47dd7a54
GC
35{
36 u32 value = readl(ioaddr + DMA_BUS_MODE);
c629882a
GC
37 int limit;
38
47dd7a54
GC
39 /* DMA SW reset */
40 value |= DMA_BUS_MODE_SFT_RESET;
41 writel(value, ioaddr + DMA_BUS_MODE);
bbc17546 42 limit = 10;
c629882a
GC
43 while (limit--) {
44 if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET))
45 break;
bbc17546 46 mdelay(10);
c629882a
GC
47 }
48 if (limit < 0)
49 return -EBUSY;
47dd7a54
GC
50
51 value = /* DMA_BUS_MODE_FB | */ DMA_BUS_MODE_4PBL |
52 ((pbl << DMA_BUS_MODE_PBL_SHIFT) |
53 (pbl << DMA_BUS_MODE_RPBL_SHIFT));
54
55#ifdef CONFIG_STMMAC_DA
56 value |= DMA_BUS_MODE_DA; /* Rx has priority over tx */
57#endif
58 writel(value, ioaddr + DMA_BUS_MODE);
59
60 /* Mask interrupts by writing to CSR7 */
61 writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
62
63 /* The base address of the RX/TX descriptor lists must be written into
64 * DMA CSR3 and CSR4, respectively. */
65 writel(dma_tx, ioaddr + DMA_TX_BASE_ADDR);
66 writel(dma_rx, ioaddr + DMA_RCV_BASE_ADDR);
67
68 return 0;
69}
70
ad01b7d4 71static void dwmac1000_dma_operation_mode(void __iomem *ioaddr, int txmode,
47dd7a54
GC
72 int rxmode)
73{
74 u32 csr6 = readl(ioaddr + DMA_CONTROL);
75
76 if (txmode == SF_DMA_MODE) {
56b106ae 77 CHIP_DBG(KERN_DEBUG "GMAC: enable TX store and forward mode\n");
47dd7a54
GC
78 /* Transmit COE type 2 cannot be done in cut-through mode. */
79 csr6 |= DMA_CONTROL_TSF;
80 /* Operating on second frame increase the performance
81 * especially when transmit store-and-forward is used.*/
82 csr6 |= DMA_CONTROL_OSF;
83 } else {
56b106ae 84 CHIP_DBG(KERN_DEBUG "GMAC: disabling TX store and forward mode"
47dd7a54
GC
85 " (threshold = %d)\n", txmode);
86 csr6 &= ~DMA_CONTROL_TSF;
87 csr6 &= DMA_CONTROL_TC_TX_MASK;
af901ca1 88 /* Set the transmit threshold */
47dd7a54
GC
89 if (txmode <= 32)
90 csr6 |= DMA_CONTROL_TTC_32;
91 else if (txmode <= 64)
92 csr6 |= DMA_CONTROL_TTC_64;
93 else if (txmode <= 128)
94 csr6 |= DMA_CONTROL_TTC_128;
95 else if (txmode <= 192)
96 csr6 |= DMA_CONTROL_TTC_192;
97 else
98 csr6 |= DMA_CONTROL_TTC_256;
99 }
100
101 if (rxmode == SF_DMA_MODE) {
56b106ae 102 CHIP_DBG(KERN_DEBUG "GMAC: enable RX store and forward mode\n");
47dd7a54
GC
103 csr6 |= DMA_CONTROL_RSF;
104 } else {
56b106ae 105 CHIP_DBG(KERN_DEBUG "GMAC: disabling RX store and forward mode"
47dd7a54
GC
106 " (threshold = %d)\n", rxmode);
107 csr6 &= ~DMA_CONTROL_RSF;
108 csr6 &= DMA_CONTROL_TC_RX_MASK;
109 if (rxmode <= 32)
110 csr6 |= DMA_CONTROL_RTC_32;
111 else if (rxmode <= 64)
112 csr6 |= DMA_CONTROL_RTC_64;
113 else if (rxmode <= 96)
114 csr6 |= DMA_CONTROL_RTC_96;
115 else
116 csr6 |= DMA_CONTROL_RTC_128;
117 }
118
119 writel(csr6, ioaddr + DMA_CONTROL);
47dd7a54
GC
120}
121
ad01b7d4 122static void dwmac1000_dump_dma_regs(void __iomem *ioaddr)
47dd7a54
GC
123{
124 int i;
125 pr_info(" DMA registers\n");
126 for (i = 0; i < 22; i++) {
127 if ((i < 9) || (i > 17)) {
128 int offset = i * 4;
129 pr_err("\t Reg No. %d (offset 0x%x): 0x%08x\n", i,
130 (DMA_BUS_MODE + offset),
131 readl(ioaddr + DMA_BUS_MODE + offset));
132 }
133 }
47dd7a54
GC
134}
135
e7434821
GC
136static unsigned int dwmac1000_get_hw_feature(void __iomem *ioaddr)
137{
138 return readl(ioaddr + DMA_HW_FEATURE);
139}
140
cadb7924 141const struct stmmac_dma_ops dwmac1000_dma_ops = {
21d437cc
GC
142 .init = dwmac1000_dma_init,
143 .dump_regs = dwmac1000_dump_dma_regs,
144 .dma_mode = dwmac1000_dma_operation_mode,
aec7ff27
GC
145 .enable_dma_transmission = dwmac_enable_dma_transmission,
146 .enable_dma_irq = dwmac_enable_dma_irq,
147 .disable_dma_irq = dwmac_disable_dma_irq,
148 .start_tx = dwmac_dma_start_tx,
149 .stop_tx = dwmac_dma_stop_tx,
150 .start_rx = dwmac_dma_start_rx,
151 .stop_rx = dwmac_dma_stop_rx,
152 .dma_interrupt = dwmac_dma_interrupt,
e7434821 153 .get_hw_feature = dwmac1000_get_hw_feature,
db98a0b0 154};