drm/amdgpu: Update gc golden setting for vega family
[sfrench/cifs-2.6.git] / arch / mips / bcm63xx / dev-enet.c
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
7  */
8
9 #include <linux/init.h>
10 #include <linux/kernel.h>
11 #include <linux/platform_device.h>
12 #include <linux/export.h>
13 #include <bcm63xx_dev_enet.h>
14 #include <bcm63xx_io.h>
15 #include <bcm63xx_regs.h>
16
17 static const unsigned long bcm6348_regs_enetdmac[] = {
18         [ENETDMAC_CHANCFG]      = ENETDMAC_CHANCFG_REG,
19         [ENETDMAC_IR]           = ENETDMAC_IR_REG,
20         [ENETDMAC_IRMASK]       = ENETDMAC_IRMASK_REG,
21         [ENETDMAC_MAXBURST]     = ENETDMAC_MAXBURST_REG,
22 };
23
24 static const unsigned long bcm6345_regs_enetdmac[] = {
25         [ENETDMAC_CHANCFG]      = ENETDMA_6345_CHANCFG_REG,
26         [ENETDMAC_IR]           = ENETDMA_6345_IR_REG,
27         [ENETDMAC_IRMASK]       = ENETDMA_6345_IRMASK_REG,
28         [ENETDMAC_MAXBURST]     = ENETDMA_6345_MAXBURST_REG,
29         [ENETDMAC_BUFALLOC]     = ENETDMA_6345_BUFALLOC_REG,
30         [ENETDMAC_RSTART]       = ENETDMA_6345_RSTART_REG,
31         [ENETDMAC_FC]           = ENETDMA_6345_FC_REG,
32         [ENETDMAC_LEN]          = ENETDMA_6345_LEN_REG,
33 };
34
35 const unsigned long *bcm63xx_regs_enetdmac;
36 EXPORT_SYMBOL(bcm63xx_regs_enetdmac);
37
38 static __init void bcm63xx_enetdmac_regs_init(void)
39 {
40         if (BCMCPU_IS_6345())
41                 bcm63xx_regs_enetdmac = bcm6345_regs_enetdmac;
42         else
43                 bcm63xx_regs_enetdmac = bcm6348_regs_enetdmac;
44 }
45
46 static struct resource shared_res[] = {
47         {
48                 .start          = -1, /* filled at runtime */
49                 .end            = -1, /* filled at runtime */
50                 .flags          = IORESOURCE_MEM,
51         },
52         {
53                 .start          = -1, /* filled at runtime */
54                 .end            = -1, /* filled at runtime */
55                 .flags          = IORESOURCE_MEM,
56         },
57         {
58                 .start          = -1, /* filled at runtime */
59                 .end            = -1, /* filled at runtime */
60                 .flags          = IORESOURCE_MEM,
61         },
62 };
63
64 static struct platform_device bcm63xx_enet_shared_device = {
65         .name           = "bcm63xx_enet_shared",
66         .id             = 0,
67         .num_resources  = ARRAY_SIZE(shared_res),
68         .resource       = shared_res,
69 };
70
71 static int shared_device_registered;
72
73 static struct resource enet0_res[] = {
74         {
75                 .start          = -1, /* filled at runtime */
76                 .end            = -1, /* filled at runtime */
77                 .flags          = IORESOURCE_MEM,
78         },
79         {
80                 .start          = -1, /* filled at runtime */
81                 .flags          = IORESOURCE_IRQ,
82         },
83         {
84                 .start          = -1, /* filled at runtime */
85                 .flags          = IORESOURCE_IRQ,
86         },
87         {
88                 .start          = -1, /* filled at runtime */
89                 .flags          = IORESOURCE_IRQ,
90         },
91 };
92
93 static struct bcm63xx_enet_platform_data enet0_pd;
94
95 static struct platform_device bcm63xx_enet0_device = {
96         .name           = "bcm63xx_enet",
97         .id             = 0,
98         .num_resources  = ARRAY_SIZE(enet0_res),
99         .resource       = enet0_res,
100         .dev            = {
101                 .platform_data = &enet0_pd,
102         },
103 };
104
105 static struct resource enet1_res[] = {
106         {
107                 .start          = -1, /* filled at runtime */
108                 .end            = -1, /* filled at runtime */
109                 .flags          = IORESOURCE_MEM,
110         },
111         {
112                 .start          = -1, /* filled at runtime */
113                 .flags          = IORESOURCE_IRQ,
114         },
115         {
116                 .start          = -1, /* filled at runtime */
117                 .flags          = IORESOURCE_IRQ,
118         },
119         {
120                 .start          = -1, /* filled at runtime */
121                 .flags          = IORESOURCE_IRQ,
122         },
123 };
124
125 static struct bcm63xx_enet_platform_data enet1_pd;
126
127 static struct platform_device bcm63xx_enet1_device = {
128         .name           = "bcm63xx_enet",
129         .id             = 1,
130         .num_resources  = ARRAY_SIZE(enet1_res),
131         .resource       = enet1_res,
132         .dev            = {
133                 .platform_data = &enet1_pd,
134         },
135 };
136
137 static struct resource enetsw_res[] = {
138         {
139                 /* start & end filled at runtime */
140                 .flags          = IORESOURCE_MEM,
141         },
142         {
143                 /* start filled at runtime */
144                 .flags          = IORESOURCE_IRQ,
145         },
146         {
147                 /* start filled at runtime */
148                 .flags          = IORESOURCE_IRQ,
149         },
150 };
151
152 static struct bcm63xx_enetsw_platform_data enetsw_pd;
153
154 static struct platform_device bcm63xx_enetsw_device = {
155         .name           = "bcm63xx_enetsw",
156         .num_resources  = ARRAY_SIZE(enetsw_res),
157         .resource       = enetsw_res,
158         .dev            = {
159                 .platform_data = &enetsw_pd,
160         },
161 };
162
163 static int __init register_shared(void)
164 {
165         int ret, chan_count;
166
167         if (shared_device_registered)
168                 return 0;
169
170         bcm63xx_enetdmac_regs_init();
171
172         shared_res[0].start = bcm63xx_regset_address(RSET_ENETDMA);
173         shared_res[0].end = shared_res[0].start;
174         if (BCMCPU_IS_6345())
175                 shared_res[0].end += (RSET_6345_ENETDMA_SIZE) - 1;
176         else
177                 shared_res[0].end += (RSET_ENETDMA_SIZE)  - 1;
178
179         if (BCMCPU_IS_6328() || BCMCPU_IS_6362() || BCMCPU_IS_6368())
180                 chan_count = 32;
181         else if (BCMCPU_IS_6345())
182                 chan_count = 8;
183         else
184                 chan_count = 16;
185
186         shared_res[1].start = bcm63xx_regset_address(RSET_ENETDMAC);
187         shared_res[1].end = shared_res[1].start;
188         shared_res[1].end += RSET_ENETDMAC_SIZE(chan_count)  - 1;
189
190         shared_res[2].start = bcm63xx_regset_address(RSET_ENETDMAS);
191         shared_res[2].end = shared_res[2].start;
192         shared_res[2].end += RSET_ENETDMAS_SIZE(chan_count)  - 1;
193
194         ret = platform_device_register(&bcm63xx_enet_shared_device);
195         if (ret)
196                 return ret;
197         shared_device_registered = 1;
198
199         return 0;
200 }
201
202 int __init bcm63xx_enet_register(int unit,
203                                  const struct bcm63xx_enet_platform_data *pd)
204 {
205         struct platform_device *pdev;
206         struct bcm63xx_enet_platform_data *dpd;
207         int ret;
208
209         if (unit > 1)
210                 return -ENODEV;
211
212         if (unit == 1 && (BCMCPU_IS_6338() || BCMCPU_IS_6345()))
213                 return -ENODEV;
214
215         ret = register_shared();
216         if (ret)
217                 return ret;
218
219         if (unit == 0) {
220                 enet0_res[0].start = bcm63xx_regset_address(RSET_ENET0);
221                 enet0_res[0].end = enet0_res[0].start;
222                 enet0_res[0].end += RSET_ENET_SIZE - 1;
223                 enet0_res[1].start = bcm63xx_get_irq_number(IRQ_ENET0);
224                 enet0_res[2].start = bcm63xx_get_irq_number(IRQ_ENET0_RXDMA);
225                 enet0_res[3].start = bcm63xx_get_irq_number(IRQ_ENET0_TXDMA);
226                 pdev = &bcm63xx_enet0_device;
227         } else {
228                 enet1_res[0].start = bcm63xx_regset_address(RSET_ENET1);
229                 enet1_res[0].end = enet1_res[0].start;
230                 enet1_res[0].end += RSET_ENET_SIZE - 1;
231                 enet1_res[1].start = bcm63xx_get_irq_number(IRQ_ENET1);
232                 enet1_res[2].start = bcm63xx_get_irq_number(IRQ_ENET1_RXDMA);
233                 enet1_res[3].start = bcm63xx_get_irq_number(IRQ_ENET1_TXDMA);
234                 pdev = &bcm63xx_enet1_device;
235         }
236
237         /* copy given platform data */
238         dpd = pdev->dev.platform_data;
239         memcpy(dpd, pd, sizeof(*pd));
240
241         /* adjust them in case internal phy is used */
242         if (dpd->use_internal_phy) {
243
244                 /* internal phy only exists for enet0 */
245                 if (unit == 1)
246                         return -ENODEV;
247
248                 dpd->phy_id = 1;
249                 dpd->has_phy_interrupt = 1;
250                 dpd->phy_interrupt = bcm63xx_get_irq_number(IRQ_ENET_PHY);
251         }
252
253         dpd->dma_chan_en_mask = ENETDMAC_CHANCFG_EN_MASK;
254         dpd->dma_chan_int_mask = ENETDMAC_IR_PKTDONE_MASK;
255         if (BCMCPU_IS_6345()) {
256                 dpd->dma_chan_en_mask |= ENETDMAC_CHANCFG_CHAINING_MASK;
257                 dpd->dma_chan_en_mask |= ENETDMAC_CHANCFG_WRAP_EN_MASK;
258                 dpd->dma_chan_en_mask |= ENETDMAC_CHANCFG_FLOWC_EN_MASK;
259                 dpd->dma_chan_int_mask |= ENETDMA_IR_BUFDONE_MASK;
260                 dpd->dma_chan_int_mask |= ENETDMA_IR_NOTOWNER_MASK;
261                 dpd->dma_chan_width = ENETDMA_6345_CHAN_WIDTH;
262                 dpd->dma_desc_shift = ENETDMA_6345_DESC_SHIFT;
263         } else {
264                 dpd->dma_has_sram = true;
265                 dpd->dma_chan_width = ENETDMA_CHAN_WIDTH;
266         }
267
268         if (unit == 0) {
269                 dpd->rx_chan = 0;
270                 dpd->tx_chan = 1;
271         } else {
272                 dpd->rx_chan = 2;
273                 dpd->tx_chan = 3;
274         }
275
276         ret = platform_device_register(pdev);
277         if (ret)
278                 return ret;
279         return 0;
280 }
281
282 int __init
283 bcm63xx_enetsw_register(const struct bcm63xx_enetsw_platform_data *pd)
284 {
285         int ret;
286
287         if (!BCMCPU_IS_6328() && !BCMCPU_IS_6362() && !BCMCPU_IS_6368())
288                 return -ENODEV;
289
290         ret = register_shared();
291         if (ret)
292                 return ret;
293
294         enetsw_res[0].start = bcm63xx_regset_address(RSET_ENETSW);
295         enetsw_res[0].end = enetsw_res[0].start;
296         enetsw_res[0].end += RSET_ENETSW_SIZE - 1;
297         enetsw_res[1].start = bcm63xx_get_irq_number(IRQ_ENETSW_RXDMA0);
298         enetsw_res[2].start = bcm63xx_get_irq_number(IRQ_ENETSW_TXDMA0);
299         if (!enetsw_res[2].start)
300                 enetsw_res[2].start = -1;
301
302         memcpy(bcm63xx_enetsw_device.dev.platform_data, pd, sizeof(*pd));
303
304         if (BCMCPU_IS_6328())
305                 enetsw_pd.num_ports = ENETSW_PORTS_6328;
306         else if (BCMCPU_IS_6362() || BCMCPU_IS_6368())
307                 enetsw_pd.num_ports = ENETSW_PORTS_6368;
308
309         enetsw_pd.dma_has_sram = true;
310         enetsw_pd.dma_chan_width = ENETDMA_CHAN_WIDTH;
311         enetsw_pd.dma_chan_en_mask = ENETDMAC_CHANCFG_EN_MASK;
312         enetsw_pd.dma_chan_int_mask = ENETDMAC_IR_PKTDONE_MASK;
313
314         ret = platform_device_register(&bcm63xx_enetsw_device);
315         if (ret)
316                 return ret;
317
318         return 0;
319 }