libattr: remove libattr because it is clashing with udev/attr and is not used by...
[openembedded.git] / recipes / linux / linux-efika-2.6.20 / 0021-POWERPC-Copy-bestcomm-support-files-into-arch-powerpc.txt
blob958ca7f20b291366e661d2dd25a559c5e7b5de35
1 From 50ea8834d3b4c79ddaa8f1df88d285ebe8e71cd4 Mon Sep 17 00:00:00 2001
2 From: Grant Likely <grant.likely@secretlab.ca>
3 Date: Mon, 4 Dec 2006 22:19:21 -0700
4 Subject: [PATCH] [POWERPC] Copy bestcomm support files into arch/powerpc
6 Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
7 ---
8  arch/powerpc/platforms/52xx/bestcomm.c         |  408 ++++++++++++++++++++
9  arch/powerpc/platforms/52xx/bestcomm.h         |  473 ++++++++++++++++++++++++
10  arch/powerpc/platforms/52xx/fec.c              |  174 +++++++++
11  arch/powerpc/platforms/52xx/fec.h              |   71 ++++
12  arch/powerpc/platforms/52xx/sdma_fec_rx_task.c |   71 ++++
13  arch/powerpc/platforms/52xx/sdma_fec_tx_task.c |   84 +++++
14  6 files changed, 1281 insertions(+), 0 deletions(-)
16 diff --git a/arch/powerpc/platforms/52xx/bestcomm.c b/arch/powerpc/platforms/52xx/bestcomm.c
17 new file mode 100644
18 index 0000000..ef45e02
19 --- /dev/null
20 +++ b/arch/powerpc/platforms/52xx/bestcomm.c
21 @@ -0,0 +1,408 @@
22 +/*
23 + * arch/ppc/syslib/bestcomm/bestcomm.c
24 + *
25 + * Driver for MPC52xx processor BestComm peripheral controller
26 + *
27 + * Author: Dale Farnsworth <dfarnsworth@mvista.com>
28 + *
29 + * 2003-2004 (c) MontaVista, Software, Inc.  This file is licensed under
30 + * the terms of the GNU General Public License version 2.  This program
31 + * is licensed "as is" without any warranty of any kind, whether express
32 + * or implied.
33 + *
34 + * HISTORY:
35 + *
36 + * 2005-08-14  Converted to platform driver by 
37 + *             Andrey Volkov <avolkov@varma-el.com>, Varma Electronics Oy
38 + */
40 +#include <linux/config.h>
41 +#include <linux/version.h>
42 +#include <linux/module.h>
43 +#include <linux/kernel.h>
44 +#include <linux/errno.h>
45 +#include <linux/slab.h>
46 +#include <linux/spinlock.h>
47 +#include <linux/string.h>
48 +#include <linux/device.h>
50 +#include <asm/bug.h>
51 +#include <asm/io.h>
52 +#include <asm/mpc52xx.h>
54 +#include "bestcomm.h"
56 +#define DRIVER_NAME            "mpc52xx-sdma"
58 +struct sdma_io sdma;
60 +static spinlock_t sdma_lock = SPIN_LOCK_UNLOCKED;
62 +#ifdef CONFIG_BESTCOMM_DEBUG
63 +void sdma_dump(void)
65 +       int i;
66 +       printk("** SDMA registers: pa = %08x, va = %08x\n", sdma.base_reg_addr, sdma.io);
67 +       printk("**  taskBar = %08x\n", sdma.io->taskBar);
68 +       printk("**  currentPointer = %08x\n", sdma.io->currentPointer);
69 +       printk("**  endPointer = %08x\n", sdma.io->endPointer);
70 +       printk("**  variablePointer = %08x\n", sdma.io->variablePointer);
72 +       printk("**  IntVect1 = %08x\n", sdma.io->IntVect1);
73 +       printk("**  IntVect2 = %08x\n", sdma.io->IntVect2);
74 +       printk("**  PtdCntrl = %08x\n", sdma.io->PtdCntrl);
76 +       printk("**  IntPend = %08x\n", sdma.io->IntPend);
77 +       printk("**  IntMask = %08x\n", sdma.io->IntMask);
79 +       printk("**  TCR dump:");        
81 +       for (i=0;i<16;i++)  {
82 +               if(i%8 == 0)
83 +                       printk("\n**   %02X:",i);
84 +               printk(" %04X",sdma.io->tcr[i]);
85 +       }
86 +       printk("\n**  IPR dump:");      
87 +       for (i=0;i<32;i++)  {
88 +               if(i%16 == 0)
89 +                       printk("\n**   %02X:",i);
90 +               printk(" %02X",sdma.io->ipr[i]);
91 +       }
92 +       printk("\n**  cReqSelect = %08x\n", sdma.io->cReqSelect);
93 +       printk("**  task_size0 = %08x\n", sdma.io->task_size0);
94 +       printk("**  task_size1 = %08x\n", sdma.io->task_size1);
95 +       printk("**  MDEDebug = %08x\n", sdma.io->MDEDebug);
96 +       printk("**  ADSDebug = %08x\n", sdma.io->ADSDebug);
97 +       printk("**  Value1 = %08x\n", sdma.io->Value1);
98 +       printk("**  Value2 = %08x\n", sdma.io->Value2);
99 +       printk("**  Control = %08x\n", sdma.io->Control);
100 +       printk("**  Status = %08x\n", sdma.io->Status);
101 +       printk("**  PTDDebug = %08x\n", sdma.io->PTDDebug);
103 +#endif
105 +#ifdef CONFIG_BESTCOMM_DEBUG
106 +#define SDMA_DUMP_REGS()       sdma_dump()
107 +#else
108 +#define SDMA_DUMP_REGS()
109 +#endif
112 + * Use a very simple SRAM allocator.
113 + * There is no mechanism for freeing space.
114 + * In an attempt to minimize internal fragmentation, the SRAM is
115 + * divided into two areas.
116 + *
117 + * Area 1 is at the beginning of SRAM
118 + * and is used for allocations requiring alignments of 16 bytes or less.
119 + * Successive allocations return higher addresses.
120 + *
121 + * Area 2 is at the end of SRAM and is used for the remaining allocations.
122 + * Successive allocations return lower addresses.
123 + *
124 + * I've considered adding routines to support the freeing of SRAM allocations,
125 + * but the SRAM is so small (16K) that fragmentation can quickly cause the
126 + * SRAM to be unusable.  If you can come up with a slick way to free SRAM
127 + * memory without the fragmentation problem, please do so.
128 + */
130 +static u8 *area1_end;
131 +static u8 *area2_begin;
133 +void *sdma_sram_alloc(int size, int alignment, u32 *dma_handle)
135 +       u8 *a;
137 +       spin_lock(&sdma_lock);
139 +       /* alignment must be a power of 2 */
140 +       BUG_ON(alignment & (alignment - 1));
142 +       if (alignment < 16) {
143 +               a = (u8 *)(((u32)area1_end + (alignment-1)) & ~(alignment-1));
144 +               if (a + size <= area2_begin)
145 +                       area1_end = a + size;
146 +               else
147 +                       a = 0;                          /* out of memory */
148 +       } else {
149 +               a = (u8 *)(((u32)area2_begin - size) & ~(alignment - 1));
150 +               if (a >= area1_end)
151 +                       area2_begin = a;
152 +               else
153 +                       a = 0;                          /* out of memory */
154 +       }
155 +       if(a && dma_handle)
156 +               *dma_handle = sdma_sram_pa(a);
157 +       spin_unlock(&sdma_lock);
158 +       return (void *)a;
161 +/* this will need to be updated if Freescale changes their task code FDT */
162 +static u32 fdt_ops[] = {
163 +       0xa0045670,     /* FDT[48] */
164 +       0x80045670,     /* FDT[49] */
165 +       0x21800000,     /* FDT[50] */
166 +       0x21e00000,     /* FDT[51] */
167 +       0x21500000,     /* FDT[52] */
168 +       0x21400000,     /* FDT[53] */
169 +       0x21500000,     /* FDT[54] */
170 +       0x20400000,     /* FDT[55] */
171 +       0x20500000,     /* FDT[56] */
172 +       0x20800000,     /* FDT[57] */
173 +       0x20a00000,     /* FDT[58] */
174 +       0xc0170000,     /* FDT[59] */
175 +       0xc0145670,     /* FDT[60] */
176 +       0xc0345670,     /* FDT[61] */
177 +       0xa0076540,     /* FDT[62] */
178 +       0xa0000760,     /* FDT[63] */
181 +static int new_task_number(void)
183 +       struct sdma_tdt *tdt;
184 +       int i;
186 +       spin_lock(&sdma_lock);
188 +       tdt = sdma.tdt;
189 +       for (i=0; i<SDMA_MAX_TASKS; i++, tdt++)
190 +               if (tdt->start == 0)
191 +                       break;
192 +       if (i == SDMA_MAX_TASKS)
193 +               i = -1;
195 +       spin_unlock(&sdma_lock);
197 +       return i;
200 +int sdma_load_task(u32 *task_image)
202 +       struct sdma_task_header *head = (struct sdma_task_header *)task_image;
203 +       struct sdma_tdt *tdt;
204 +       int tasknum;
205 +       u32 *desc;
206 +       u32 *var_src, *var_dst;
207 +       u32 *inc_src;
208 +       void *start;
210 +       BUG_ON(head->magic != SDMA_TASK_MAGIC);
212 +       tasknum = new_task_number();
213 +       if (tasknum < 0)
214 +               return -ENOMEM;
216 +       desc = (u32 *)(head + 1);
217 +       var_src = desc + head->desc_size;
218 +       inc_src = var_src + head->var_size;
220 +       tdt = &sdma.tdt[tasknum];
222 +       start = sdma_sram_alloc(head->desc_size * sizeof(u32), 4, &tdt->start);
223 +       if (!start)
224 +               return -ENOMEM;
225 +       tdt->stop = tdt->start + (head->desc_size - 1)*sizeof(u32);
226 +       var_dst = sdma_sram_va(tdt->var);
228 +       memcpy(start, desc, head->desc_size * sizeof(u32));
229 +       memcpy(&var_dst[head->first_var], var_src, head->var_size * sizeof(u32));
230 +       memcpy(&var_dst[SDMA_MAX_VAR], inc_src, head->inc_size * sizeof(u32));
232 +       return tasknum;
235 +void sdma_set_initiator(int task, int initiator)
237 +       int i;
238 +       int num_descs;
239 +       u32 *desc;
240 +       int next_drd_has_initiator;
242 +       sdma_set_tcr_initiator(task, initiator);
244 +       desc = sdma_task_desc(task);
245 +       next_drd_has_initiator = 1;
246 +       num_descs = sdma_task_num_descs(task);
248 +       for (i=0; i<num_descs; i++, desc++) {
249 +               if (!sdma_desc_is_drd(*desc))
250 +                       continue;
251 +               if (next_drd_has_initiator)
252 +                       if (sdma_desc_initiator(*desc) != SDMA_INITIATOR_ALWAYS)
253 +                               sdma_set_desc_initiator(desc, initiator);
254 +               next_drd_has_initiator = !sdma_drd_is_extended(*desc);
255 +       }
258 +struct sdma *sdma_alloc(int queue_size)
260 +       struct sdma *s = kmalloc(sizeof(*s), GFP_KERNEL);
261 +       void **cookie;
263 +       if (!s)
264 +               return NULL;
266 +       memset(s, 0, sizeof(*s));
268 +       if (queue_size) {
269 +               cookie = kmalloc(sizeof(*cookie) * queue_size, GFP_KERNEL);
270 +               if (!cookie) {
271 +                       kfree(s);
272 +                       return NULL;
273 +               }
274 +               s->cookie = cookie;
275 +       }
277 +       s->num_bd = queue_size;
278 +       return s;
281 +void sdma_free(struct sdma *s)
283 +       if (s->cookie)
284 +               kfree(s->cookie);
285 +       kfree(s);
288 +static int __devinit mpc52xx_sdma_probe(struct device *dev)
290 +       struct platform_device *pdev = to_platform_device(dev);
291 +       int task;
292 +       u32 *context;
293 +       u32 *fdt;
294 +       struct sdma_tdt *tdt;
295 +       struct resource *mem_io, *mem_sram;
296 +       u32 tdt_pa, var_pa, context_pa, fdt_pa; 
297 +       int ret = -ENODEV;
299 +       mem_io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
300 +       mem_sram = platform_get_resource(pdev, IORESOURCE_MEM, 1);
301 +       if (!mem_io || !mem_sram)
302 +               goto out;
304 +       if (!request_mem_region(mem_io->start, mem_io->end - mem_io->start + 1, DRIVER_NAME)) {
305 +               printk(KERN_ERR DRIVER_NAME " - resource unavailable\n");
306 +               goto out;
307 +       }
308 +       sdma.base_reg_addr = mem_io->start;
310 +       sdma.io = ioremap_nocache(mem_io->start, sizeof(struct mpc52xx_sdma));
312 +       if (!sdma.io ) {
313 +               printk(KERN_ERR DRIVER_NAME " - failed to map sdma regs\n");
314 +               ret = -ENOMEM;
315 +               goto map_io_error;
316 +       }
318 +       SDMA_DUMP_REGS();
320 +       sdma.sram_size = mem_sram->end - mem_sram->start + 1;
321 +       if (!request_mem_region(mem_sram->start, sdma.sram_size, DRIVER_NAME)) {
322 +               printk(KERN_ERR DRIVER_NAME " - resource unavailable\n");
323 +               goto req_sram_error;
324 +       }
326 +       sdma.base_sram_addr = mem_sram->start;
327 +       sdma.sram = ioremap_nocache(mem_sram->start, sdma.sram_size);
328 +       if (!sdma.sram ) {
329 +               printk(KERN_ERR DRIVER_NAME " - failed to map sdma sram\n");
330 +               ret = -ENOMEM;
331 +               goto map_sram_error;
332 +       }
334 +       area1_end = sdma.sram;
335 +       area2_begin = area1_end + sdma.sram_size;
337 +       memset(area1_end, 0, sdma.sram_size);
339 +       /* allocate space for task descriptors, contexts, and var tables */
340 +       sdma.tdt = sdma_sram_alloc(sizeof(struct sdma_tdt) * SDMA_MAX_TASKS, 4, &tdt_pa);
342 +       context = sdma_sram_alloc(SDMA_CONTEXT_SIZE * SDMA_MAX_TASKS,
343 +                                                         SDMA_CONTEXT_ALIGN, &context_pa);
344 +       sdma.var = sdma_sram_alloc( (SDMA_VAR_SIZE + SDMA_INC_SIZE) * SDMA_MAX_TASKS, 
345 +                                                               SDMA_VAR_ALIGN, &var_pa);
346 +       fdt = sdma_sram_alloc(SDMA_FDT_SIZE, SDMA_FDT_ALIGN, &fdt_pa);
347 +       memcpy(&fdt[48], fdt_ops, sizeof(fdt_ops));
349 +       out_be32(&sdma.io->taskBar, tdt_pa);
351 +       tdt = sdma.tdt;
352 +       for (task=0; task < SDMA_MAX_TASKS; task++) {
353 +               out_be16(&sdma.io->tcr[task], 0);
354 +               out_8(&sdma.io->ipr[task], 0);
356 +               tdt->context = context_pa;
357 +               tdt->var = var_pa;
358 +               tdt->fdt = fdt_pa;
359 +               var_pa += (SDMA_MAX_VAR + SDMA_MAX_INC)*sizeof(u32);
360 +               context_pa += SDMA_MAX_CONTEXT*sizeof(u32);
361 +               tdt++;
362 +       }
364 +       out_8(&sdma.io->ipr[SDMA_INITIATOR_ALWAYS], SDMA_IPR_ALWAYS);
366 +       /* Disable COMM Bus Prefetch, apparently it's not reliable yet */
367 +       out_be16(&sdma.io->PtdCntrl, in_be16(&sdma.io->PtdCntrl) | 1);
369 +       printk(KERN_INFO "MPC52xx BestComm inited\n");
371 +       return 0;
373 +map_sram_error:
374 +       release_mem_region(mem_sram->start, sdma.sram_size);
375 +req_sram_error:
376 +       iounmap(sdma.io);
377 +map_io_error:
378 +       release_mem_region(mem_io->start, mem_io->end - mem_io->start + 1);
379 +out:
380 +       printk(KERN_ERR "DMA: MPC52xx BestComm init FAILED !!!\n");
381 +       return ret;
385 +static struct device_driver mpc52xx_sdma_driver = {
386 +       .owner    = THIS_MODULE,
387 +       .name     = DRIVER_NAME,
388 +       .bus      = &platform_bus_type,
389 +       .probe    = mpc52xx_sdma_probe,
390 +/*     .remove   = mpc52xx_sdma_remove,        TODO */
391 +#ifdef CONFIG_PM
392 +/*     .suspend        = mpc52xx_sdma_suspend, TODO */
393 +/*     .resume         = mpc52xx_sdma_resume,  TODO */
394 +#endif
397 +static int __init
398 +mpc52xx_sdma_init(void)
400 +       printk(KERN_INFO "DMA: MPC52xx BestComm driver\n");
401 +       return driver_register(&mpc52xx_sdma_driver);
404 +#ifdef MODULE
405 +static void __exit
406 +mpc52xx_sdma_exit(void)
408 +       driver_unregister(&mpc52xx_sdma_driver);
410 +#endif
412 +#ifndef MODULE
413 + subsys_initcall(mpc52xx_sdma_init);
414 +#else
415 + module_init(mpc52xx_sdma_init);
416 + module_exit(mpc52xx_sdma_exit);
417 +#endif
420 +MODULE_DESCRIPTION("Freescale MPC52xx BestComm DMA");
421 +MODULE_LICENSE("GPL");
423 +EXPORT_SYMBOL(sdma_sram_alloc);
424 +EXPORT_SYMBOL(sdma_load_task);
425 +EXPORT_SYMBOL(sdma_set_initiator);
426 +EXPORT_SYMBOL(sdma_free);
427 +EXPORT_SYMBOL(sdma);
430 diff --git a/arch/powerpc/platforms/52xx/bestcomm.h b/arch/powerpc/platforms/52xx/bestcomm.h
431 new file mode 100644
432 index 0000000..14bf397
433 --- /dev/null
434 +++ b/arch/powerpc/platforms/52xx/bestcomm.h
435 @@ -0,0 +1,473 @@
437 + * arch/ppc/syslib/bestcomm/bestcomm.h
438 + *
439 + * Driver for MPC52xx processor BestComm peripheral controller
440 + *
441 + * Author: Dale Farnsworth <dfarnsworth@mvista.com>
442 + *
443 + * 2003-2004 (c) MontaVista, Software, Inc.  This file is licensed under
444 + * the terms of the GNU General Public License version 2.  This program
445 + * is licensed "as is" without any warranty of any kind, whether express
446 + * or implied.
447 + *
448 + * HISTORY:
449 + *
450 + * 2005-08-14  Converted to platform driver by 
451 + *             Andrey Volkov <avolkov@varma-el.com>, Varma Electronics Oy
452 + */
454 +#ifndef __BESTCOMM_BESTCOMM_H__
455 +#define __BESTCOMM_BESTCOMM_H__
457 +/* Buffer Descriptor definitions */
458 +struct sdma_bd {
459 +       u32 status;
460 +       void *data;
463 +struct sdma_bd2 {
464 +       u32 status;
465 +       void *data1;
466 +       void *data2;
469 +struct sdma_io {
470 +       unsigned long                   base_reg_addr;
471 +       struct mpc52xx_sdma __iomem     *io;
472 +       unsigned long                   base_sram_addr;
473 +       void __iomem                    *sram;
474 +       size_t                          sram_size;
476 +       struct sdma_tdt __iomem         *tdt;
477 +       u32 __iomem                     *var;
479 +extern struct sdma_io sdma;
481 +#define        sdma_sram_pa(virt)      (((unsigned long)(((void __iomem *)(virt))-sdma.sram))+sdma.base_sram_addr)
482 +#define        sdma_sram_va(pa)        ((void __iomem *)((((unsigned long)(pa))-sdma.base_sram_addr)+((unsigned long)sdma.sram)))
484 +#define        sdma_io_pa(virt)        (((unsigned long)(((void __iomem *)(virt))-((void __iomem *)sdma.io)))+sdma.base_reg_addr)
485 +#define        sdma_io_va(pa)  ((void __iomem *)((((unsigned long)(pa))-sdma.base_reg_addr)+((unsigned long)sdma.io)))
487 +#define SDMA_LEN_BITS          26
488 +#define SDMA_LEN_MASK          ((1 << SDMA_LEN_BITS) - 1)
490 +#define SDMA_BD_READY          0x40000000UL
492 +#define SDMA_FEC_TX_BD_TFD     0x08000000UL    /* transmit frame done */
493 +#define SDMA_FEC_TX_BD_INT     0x04000000UL    /* Interrupt */
494 +#define SDMA_FEC_TX_BD_TFD_INIT        (SDMA_BD_READY | SDMA_FEC_TX_BD_TFD | \
495 +                                                       SDMA_FEC_TX_BD_INT)
497 +struct sdma {
498 +       union {
499 +               struct sdma_bd *bd;
500 +               struct sdma_bd2 *bd2;
501 +       };
502 +       void **cookie;
503 +       u16 index;
504 +       u16 outdex;
505 +       u16 num_bd;
506 +       s16 tasknum;
507 +       u32 flags;
510 +#define SDMA_FLAGS_NONE                0x0000
511 +#define SDMA_FLAGS_ENABLE_TASK 0x0001
512 +#define SDMA_FLAGS_BD2         0x0002
514 +/* Task Descriptor Table Entry */
515 +struct sdma_tdt {
516 +       u32 start;
517 +       u32 stop;
518 +       u32 var;
519 +       u32 fdt;
520 +       u32 exec_status; /* used internally by SmartComm engine */
521 +       u32 mvtp;                /* used internally by SmartComm engine */
522 +       u32 context;
523 +       u32 litbase;
526 +//extern struct sdma_tdt *sdma_tdt;
528 +#define SDMA_MAX_TASKS         16
529 +#define SDMA_MAX_VAR           24
530 +#define SDMA_MAX_INC           8
531 +#define SDMA_MAX_FDT           64
532 +#define SDMA_MAX_CONTEXT       20
533 +#define SDMA_CONTEXT_SIZE      SDMA_MAX_CONTEXT * sizeof(u32)
534 +#define SDMA_CONTEXT_ALIGN     0x100
535 +#define SDMA_VAR_SIZE          SDMA_MAX_VAR * sizeof(u32)
536 +#define SDMA_VAR_ALIGN         0x80
537 +#define SDMA_INC_SIZE          SDMA_MAX_INC * sizeof(u32)
538 +#define SDMA_FDT_SIZE          SDMA_MAX_FDT * sizeof(u32)
539 +#define SDMA_FDT_ALIGN         0x100
540 +#define SDMA_BD_ALIGN          0x10
542 +#define TASK_ENABLE            0x8000
544 +#ifndef DPRINK
545 +       #ifdef CONFIG_BESTCOMM_DEBUG
546 +       #define DPRINTK(a,b...) printk(KERN_DEBUG "sdma: %s: " a, __FUNCTION__ , ## b)
547 +       #else
548 +       #define DPRINTK(a,b...)
549 +       #endif
550 +#endif
552 +static inline void sdma_enable_task(int task)
554 +       DPRINTK("***DMA enable task (%d): tdt = %08x\n",task, sdma.tdt);
555 +       DPRINTK("***tdt->start   = %08x\n",sdma.tdt[task].start);
556 +       DPRINTK("***tdt->stop    = %08x\n",sdma.tdt[task].stop);
557 +       DPRINTK("***tdt->var     = %08x\n",sdma.tdt[task].var);
558 +       DPRINTK("***tdt->fdt     = %08x\n",sdma.tdt[task].fdt);
559 +       DPRINTK("***tdt->status  = %08x\n",sdma.tdt[task].exec_status);
560 +       DPRINTK("***tdt->mvtp    = %08x\n",sdma.tdt[task].mvtp);
561 +       DPRINTK("***tdt->context = %08x\n",sdma.tdt[task].context);
562 +       DPRINTK("***tdt->litbase = %08x\n",sdma.tdt[task].litbase);
563 +       DPRINTK("***--------------\n");
565 +       u16 reg = in_be16(&sdma.io->tcr[task]);
566 +       DPRINTK("***enable task: &sdma.io->tcr=%08x, reg = %04x\n", &sdma.io->tcr, reg);
567 +       out_be16(&sdma.io->tcr[task],  reg | TASK_ENABLE);
570 +static inline void sdma_disable_task(int task)
572 +       u16 reg = in_be16(&sdma.io->tcr[task]);
573 +       DPRINTK("***disable task(%d): reg = %04x\n", task, reg);
574 +       out_be16(&sdma.io->tcr[task], reg & ~TASK_ENABLE);
577 +static inline int sdma_irq(struct sdma *s)
579 +       return MPC52xx_SDMA_IRQ_BASE + s->tasknum;
582 +static inline void sdma_enable(struct sdma *s)
584 +       sdma_enable_task(s->tasknum);
587 +static inline void sdma_disable(struct sdma *s)
589 +       sdma_disable_task(s->tasknum);
592 +static inline int sdma_queue_empty(struct sdma *s)
594 +       return s->index == s->outdex;
597 +static inline void sdma_clear_irq(struct sdma *s)
599 +       out_be32(&sdma.io->IntPend, 1 << s->tasknum);
602 +static inline int sdma_next_index(struct sdma *s)
604 +       return ((s->index + 1) == s->num_bd) ? 0 : s->index + 1;
607 +static inline int sdma_next_outdex(struct sdma *s)
609 +       return ((s->outdex + 1) == s->num_bd) ? 0 : s->outdex + 1;
612 +static inline int sdma_queue_full(struct sdma *s)
614 +       return s->outdex == sdma_next_index(s);
617 +static inline int sdma_buffer_done(struct sdma *s)
619 +#ifdef CONFIG_BESTCOMM_DEBUG
620 +       BUG_ON(s->flags & SDMA_FLAGS_BD2);
621 +#endif
622 +       if (sdma_queue_empty(s))
623 +               return 0;
624 +       return (s->bd[s->outdex].status & SDMA_BD_READY) == 0;
627 +static inline int sdma_buffer2_done(struct sdma *s)
629 +#ifdef CONFIG_BESTCOMM_DEBUG
630 +       BUG_ON(!(s->flags & SDMA_FLAGS_BD2));
631 +#endif
632 +       if (sdma_queue_empty(s))
633 +               return 0;
635 +       return (s->bd2[s->outdex].status & SDMA_BD_READY) == 0;
638 +static inline u32 *sdma_task_desc(int task)
640 +       return sdma_sram_va(sdma.tdt[task].start);
643 +static inline u32 sdma_task_num_descs(int task)
645 +       return (sdma.tdt[task].stop - sdma.tdt[task].start)/sizeof(u32) + 1;
648 +static inline u32 *sdma_task_var(int task)
650 +       return sdma_sram_va(sdma.tdt[task].var);
653 +static inline u32 *sdma_task_inc(int task)
655 +       return &sdma_task_var(task)[SDMA_MAX_VAR];
658 +static inline void sdma_set_tcr_initiator(int task, int initiator) {
659 +       u16 *tcr = &sdma.io->tcr[task];
660 +       out_be16(tcr, (in_be16(tcr) & ~0x1f00) | (initiator << 8));
663 +#define SDMA_DRD_INITIATOR_SHIFT       21
665 +static inline int sdma_desc_initiator(u32 desc)
667 +       return (desc >> SDMA_DRD_INITIATOR_SHIFT) & 0x1f;
670 +static inline void sdma_set_desc_initiator(u32 *desc, int initiator)
672 +       *desc = (*desc & ~(0x1f << SDMA_DRD_INITIATOR_SHIFT)) |
673 +                       ((initiator << SDMA_DRD_INITIATOR_SHIFT) & 0x1f);
676 +static inline void sdma_submit_buffer(struct sdma *s, void *cookie, void *data,
677 +                                                               int length)
679 +#ifdef CONFIG_BESTCOMM_DEBUG
680 +       BUG_ON(s->flags & SDMA_FLAGS_BD2);
681 +#endif
682 +       s->cookie[s->index] = cookie;
683 +       s->bd[s->index].data = data;
684 +       s->bd[s->index].status = SDMA_BD_READY | length;
685 +       s->index = sdma_next_index(s);
686 +       if (s->flags & SDMA_FLAGS_ENABLE_TASK)
687 +               sdma_enable_task(s->tasknum);
691 + * Special submit_buffer function to submit last buffer of a frame to
692 + * the FEC tx task.  tfd means "transmit frame done".
693 + */
694 +static inline void sdma_fec_tfd_submit_buffer(struct sdma *s, void *cookie,
695 +                                                       void *data, int length)
697 +#ifdef CONFIG_BESTCOMM_DEBUG
698 +       BUG_ON(s->flags & SDMA_FLAGS_BD2);
699 +#endif
700 +       s->cookie[s->index] = cookie;
701 +       s->bd[s->index].data = data;
702 +       s->bd[s->index].status = SDMA_FEC_TX_BD_TFD_INIT | length;
703 +       s->index = sdma_next_index(s);
704 +       sdma_enable_task(s->tasknum);
707 +static inline void *sdma_retrieve_buffer(struct sdma *s, int *length)
709 +       void *cookie = s->cookie[s->outdex];
711 +#ifdef CONFIG_BESTCOMM_DEBUG
712 +       BUG_ON(s->flags & SDMA_FLAGS_BD2);
713 +#endif
714 +       if (length)
715 +               *length = s->bd[s->outdex].status & SDMA_LEN_MASK;
716 +       s->outdex = sdma_next_outdex(s);
717 +       return cookie;
720 +static inline void sdma_submit_buffer2(struct sdma *s, void *cookie,
721 +                                       void *data1, void *data2, int length)
723 +#ifdef CONFIG_BESTCOMM_DEBUG
724 +       BUG_ON(!(s->flags & SDMA_FLAGS_BD2));
725 +#endif
726 +       s->cookie[s->index] = cookie;
727 +       s->bd2[s->index].data1 = data1;
728 +       s->bd2[s->index].data2 = data2;
729 +       s->bd2[s->index].status = SDMA_BD_READY | length;
730 +       s->index = sdma_next_index(s);
731 +       if (s->flags & SDMA_FLAGS_ENABLE_TASK)
732 +               sdma_enable_task(s->tasknum);
735 +static inline void *sdma_retrieve_buffer2(struct sdma *s, int *length)
737 +       void *cookie = s->cookie[s->outdex];
739 +#ifdef CONFIG_BESTCOMM_DEBUG
740 +       BUG_ON(!(s->flags & SDMA_FLAGS_BD2));
741 +#endif
742 +       if (length)
743 +               *length = s->bd2[s->outdex].status & SDMA_LEN_MASK;
744 +       s->outdex = sdma_next_outdex(s);
745 +       return cookie;
748 +#define SDMA_TASK_MAGIC                0x4243544B      /* 'BCTK' */
750 +/* the size fields are given in number of 32-bit words */
751 +struct sdma_task_header {
752 +       u32     magic;
753 +       u8      desc_size;
754 +       u8      var_size;
755 +       u8      inc_size;
756 +       u8      first_var;
757 +       u8      reserved[8];
760 +#define SDMA_DESC_NOP          0x000001f8
761 +#define SDMA_LCD_MASK          0x80000000
762 +#define SDMA_DRD_EXTENDED      0x40000000
764 +#define sdma_drd_is_extended(desc) ((desc) & SDMA_DRD_EXTENDED)
766 +static inline int sdma_desc_is_drd(u32 desc) {
767 +       return !(desc & SDMA_LCD_MASK) && desc != SDMA_DESC_NOP;
770 +#define SDMA_PRAGMA_BIT_RSV            7       /* reserved pragma bit */
771 +#define SDMA_PRAGMA_BIT_PRECISE_INC    6       /* increment 0=when possible, */
772 +                                               /*      1=iter end */
773 +#define SDMA_PRAGMA_BIT_RST_ERROR_NO   5       /* don't reset errors on */
774 +                                               /* task enable */
775 +#define SDMA_PRAGMA_BIT_PACK           4       /* pack data enable */
776 +#define SDMA_PRAGMA_BIT_INTEGER                3       /* data alignment */
777 +                                               /* 0=frac(msb), 1=int(lsb) */
778 +#define SDMA_PRAGMA_BIT_SPECREAD       2       /* XLB speculative read */
779 +#define SDMA_PRAGMA_BIT_CW             1       /* write line buffer enable */
780 +#define SDMA_PRAGMA_BIT_RL             0       /* read line buffer enable */
782 +#define SDMA_STD_PRAGMA                ((0 << SDMA_PRAGMA_BIT_RSV)             | \
783 +                                (0 << SDMA_PRAGMA_BIT_PRECISE_INC)     | \
784 +                                (0 << SDMA_PRAGMA_BIT_RST_ERROR_NO)    | \
785 +                                (0 << SDMA_PRAGMA_BIT_PACK)            | \
786 +                                (0 << SDMA_PRAGMA_BIT_INTEGER)         | \
787 +                                (1 << SDMA_PRAGMA_BIT_SPECREAD)        | \
788 +                                (1 << SDMA_PRAGMA_BIT_CW)              | \
789 +                                (1 << SDMA_PRAGMA_BIT_RL))
791 +#define SDMA_PCI_PRAGMA                ((0 << SDMA_PRAGMA_BIT_RSV)             | \
792 +                                (0 << SDMA_PRAGMA_BIT_PRECISE_INC)     | \
793 +                                (0 << SDMA_PRAGMA_BIT_RST_ERROR_NO)    | \
794 +                                (0 << SDMA_PRAGMA_BIT_PACK)            | \
795 +                                (1 << SDMA_PRAGMA_BIT_INTEGER)         | \
796 +                                (1 << SDMA_PRAGMA_BIT_SPECREAD)        | \
797 +                                (1 << SDMA_PRAGMA_BIT_CW)              | \
798 +                                (1 << SDMA_PRAGMA_BIT_RL))
800 +#define SDMA_ATA_PRAGMA                SDMA_STD_PRAGMA
801 +#define SDMA_CRC16_DP_0_PRAGMA SDMA_STD_PRAGMA
802 +#define SDMA_CRC16_DP_1_PRAGMA SDMA_STD_PRAGMA
803 +#define SDMA_FEC_RX_BD_PRAGMA  SDMA_STD_PRAGMA
804 +#define SDMA_FEC_TX_BD_PRAGMA  SDMA_STD_PRAGMA
805 +#define SDMA_GEN_DP_0_PRAGMA   SDMA_STD_PRAGMA
806 +#define SDMA_GEN_DP_1_PRAGMA   SDMA_STD_PRAGMA
807 +#define SDMA_GEN_DP_2_PRAGMA   SDMA_STD_PRAGMA
808 +#define SDMA_GEN_DP_3_PRAGMA   SDMA_STD_PRAGMA
809 +#define SDMA_GEN_DP_BD_0_PRAGMA        SDMA_STD_PRAGMA
810 +#define SDMA_GEN_DP_BD_1_PRAGMA        SDMA_STD_PRAGMA
811 +#define SDMA_GEN_RX_BD_PRAGMA  SDMA_STD_PRAGMA
812 +#define SDMA_GEN_TX_BD_PRAGMA  SDMA_STD_PRAGMA
813 +#define SDMA_GEN_LPC_PRAGMA    SDMA_STD_PRAGMA
814 +#define SDMA_PCI_RX_PRAGMA     SDMA_PCI_PRAGMA
815 +#define SDMA_PCI_TX_PRAGMA     SDMA_PCI_PRAGMA
817 +static inline void sdma_set_task_pragma(int task, int pragma)
819 +       u32 *fdt = &sdma.tdt[task].fdt;
820 +       *fdt = (*fdt & ~0xff) | pragma;
823 +static inline void sdma_set_task_auto_start(int task, int next_task)
825 +       u16 *tcr = &sdma.io->tcr[task];
826 +       out_be16(tcr, (in_be16(tcr) & ~0xff) | 0x00c0 | next_task);
829 +#define SDMA_INITIATOR_ALWAYS   0
830 +#define SDMA_INITIATOR_SCTMR_0  1
831 +#define SDMA_INITIATOR_SCTMR_1  2
832 +#define SDMA_INITIATOR_FEC_RX   3
833 +#define SDMA_INITIATOR_FEC_TX   4
834 +#define SDMA_INITIATOR_ATA_RX   5
835 +#define SDMA_INITIATOR_ATA_TX   6
836 +#define SDMA_INITIATOR_SCPCI_RX         7
837 +#define SDMA_INITIATOR_SCPCI_TX         8
838 +#define SDMA_INITIATOR_PSC3_RX  9
839 +#define SDMA_INITIATOR_PSC3_TX 10
840 +#define SDMA_INITIATOR_PSC2_RX 11
841 +#define SDMA_INITIATOR_PSC2_TX 12
842 +#define SDMA_INITIATOR_PSC1_RX 13
843 +#define SDMA_INITIATOR_PSC1_TX 14
844 +#define SDMA_INITIATOR_SCTMR_2 15
845 +#define SDMA_INITIATOR_SCLPC   16
846 +#define SDMA_INITIATOR_PSC5_RX 17
847 +#define SDMA_INITIATOR_PSC5_TX 18
848 +#define SDMA_INITIATOR_PSC4_RX 19
849 +#define SDMA_INITIATOR_PSC4_TX 20
850 +#define SDMA_INITIATOR_I2C2_RX 21
851 +#define SDMA_INITIATOR_I2C2_TX 22
852 +#define SDMA_INITIATOR_I2C1_RX 23
853 +#define SDMA_INITIATOR_I2C1_TX 24
854 +#define SDMA_INITIATOR_PSC6_RX 25
855 +#define SDMA_INITIATOR_PSC6_TX 26
856 +#define SDMA_INITIATOR_IRDA_RX 25
857 +#define SDMA_INITIATOR_IRDA_TX 26
858 +#define SDMA_INITIATOR_SCTMR_3 27
859 +#define SDMA_INITIATOR_SCTMR_4 28
860 +#define SDMA_INITIATOR_SCTMR_5 29
861 +#define SDMA_INITIATOR_SCTMR_6 30
862 +#define SDMA_INITIATOR_SCTMR_7 31
864 +#define SDMA_IPR_ALWAYS        7
865 +#define SDMA_IPR_SCTMR_0       2
866 +#define SDMA_IPR_SCTMR_1       2
867 +#define SDMA_IPR_FEC_RX        6
868 +#define SDMA_IPR_FEC_TX        5
869 +#define SDMA_IPR_ATA_RX        4
870 +#define SDMA_IPR_ATA_TX        3
871 +#define SDMA_IPR_SCPCI_RX      2
872 +#define SDMA_IPR_SCPCI_TX      2
873 +#define SDMA_IPR_PSC3_RX       2
874 +#define SDMA_IPR_PSC3_TX       2
875 +#define SDMA_IPR_PSC2_RX       2
876 +#define SDMA_IPR_PSC2_TX       2
877 +#define SDMA_IPR_PSC1_RX       2
878 +#define SDMA_IPR_PSC1_TX       2
879 +#define SDMA_IPR_SCTMR_2       2
880 +#define SDMA_IPR_SCLPC         2
881 +#define SDMA_IPR_PSC5_RX       2
882 +#define SDMA_IPR_PSC5_TX       2
883 +#define SDMA_IPR_PSC4_RX       2
884 +#define SDMA_IPR_PSC4_TX       2
885 +#define SDMA_IPR_I2C2_RX       2
886 +#define SDMA_IPR_I2C2_TX       2
887 +#define SDMA_IPR_I2C1_RX       2
888 +#define SDMA_IPR_I2C1_TX       2
889 +#define SDMA_IPR_PSC6_RX       2
890 +#define SDMA_IPR_PSC6_TX       2
891 +#define SDMA_IPR_IRDA_RX       2
892 +#define SDMA_IPR_IRDA_TX       2
893 +#define SDMA_IPR_SCTMR_3       2
894 +#define SDMA_IPR_SCTMR_4       2
895 +#define SDMA_IPR_SCTMR_5       2
896 +#define SDMA_IPR_SCTMR_6       2
897 +#define SDMA_IPR_SCTMR_7       2
899 +extern struct sdma *sdma_alloc(int request_queue_size);
900 +extern void sdma_free(struct sdma *sdma_struct);
901 +extern int sdma_load_task(u32 *task_image);
902 +extern void *sdma_sram_alloc(int size, int alignment, u32 *dma_handle);
903 +extern void sdma_init_bd(struct sdma *s);
904 +extern void sdma_init_bd2(struct sdma *s);
906 +#define FIELD_OFFSET(s,f) ((unsigned long)(&(((struct s*)0)->f)))
908 +#endif  /* __BESTCOMM_BESTCOMM_H__ */
909 diff --git a/arch/powerpc/platforms/52xx/fec.c b/arch/powerpc/platforms/52xx/fec.c
910 new file mode 100644
911 index 0000000..8756856
912 --- /dev/null
913 +++ b/arch/powerpc/platforms/52xx/fec.c
914 @@ -0,0 +1,174 @@
916 + * arch/ppc/syslib/bestcomm/fec.c
917 + *
918 + * Driver for MPC52xx processor BestComm FEC controller
919 + *
920 + * Author: Dale Farnsworth <dfarnsworth@mvista.com>
921 + *
922 + * 2003-2004 (c) MontaVista, Software, Inc.  This file is licensed under
923 + * the terms of the GNU General Public License version 2.  This program
924 + * is licensed "as is" without any warranty of any kind, whether express
925 + * or implied.
926 + *
927 + * HISTORY:
928 + *
929 + * 2005-08-14  Converted to platform driver by 
930 + *             Andrey Volkov <avolkov@varma-el.com>, Varma Electronics Oy
931 + */
933 +#include <linux/config.h>
934 +#include <linux/version.h>
935 +#include <linux/module.h>
936 +#include <linux/kernel.h>
937 +#include <linux/string.h>
938 +#include <linux/types.h>
939 +#include <asm/errno.h>                           
940 +#include <asm/io.h>
942 +#include <asm/mpc52xx.h>
944 +#include "bestcomm.h"
945 +#include "fec.h"
948 + * Initialize FEC receive task.
949 + * Returns task number of FEC receive task.
950 + * Returns -1 on failure
951 + */
952 +int sdma_fec_rx_init(struct sdma *s, phys_addr_t fifo, int maxbufsize)
954 +       struct sdma_fec_rx_var *var;
955 +       struct sdma_fec_rx_inc *inc;
957 +       static int tasknum = -1;
958 +       static struct sdma_bd *bd = 0;
959 +       static u32 bd_pa;
961 +       if (tasknum < 0) {
962 +               tasknum = sdma_load_task(sdma_fec_rx_task);
963 +               if (tasknum < 0)
964 +                       return tasknum;
965 +       }
967 +       if (!bd) 
968 +               bd = (struct sdma_bd *)sdma_sram_alloc(sizeof(*bd) * s->num_bd,
969 +                                                               SDMA_BD_ALIGN, &bd_pa);
970 +       if (!bd)
971 +               return -ENOMEM;
973 +       sdma_disable_task(tasknum);
975 +       s->tasknum = tasknum;
976 +       s->bd = bd;
977 +       s->flags = SDMA_FLAGS_NONE;
978 +       s->index = 0;
979 +       s->outdex = 0;
980 +       memset(bd, 0, sizeof(*bd) * s->num_bd);
982 +       var = (struct sdma_fec_rx_var *)sdma_task_var(tasknum);
983 +       var->enable                     = sdma_io_pa(&sdma.io->tcr[tasknum]);
984 +       var->fifo                       = fifo;
985 +       var->bd_base            = bd_pa;
986 +       var->bd_last            = bd_pa + (s->num_bd - 1)*sizeof(struct sdma_bd);
987 +       var->bd_start           = bd_pa;
988 +       var->buffer_size        = maxbufsize;
990 +       /* These are constants, they should have been in the image file */
991 +       inc = (struct sdma_fec_rx_inc *)sdma_task_inc(tasknum);
992 +       inc->incr_bytes         = -(s16)sizeof(u32);
993 +       inc->incr_dst           = sizeof(u32);
994 +       inc->incr_dst_ma        = sizeof(u8);
996 +       sdma_set_task_pragma(tasknum, SDMA_FEC_RX_BD_PRAGMA);
997 +       sdma_set_task_auto_start(tasknum, tasknum);
999 +       /* clear pending interrupt bits */
1000 +       out_be32(&sdma.io->IntPend, 1<<tasknum);
1002 +       out_8(&sdma.io->ipr[SDMA_INITIATOR_FEC_RX], SDMA_IPR_FEC_RX);
1004 +       return tasknum;
1008 + * Return 2nd to last DRD
1009 + * This is an ugly hack, but at least it's only done once at initialization
1010 + */
1011 +static u32 *self_modified_drd(int tasknum)
1013 +       u32 *desc;
1014 +       int num_descs;
1015 +       int drd_count;
1016 +       int i;
1018 +       num_descs = sdma_task_num_descs(tasknum);
1019 +       desc = sdma_task_desc(tasknum) + num_descs - 1;
1020 +       drd_count = 0;
1021 +       for (i=0; i<num_descs; i++, desc--)
1022 +               if (sdma_desc_is_drd(*desc) && ++drd_count == 3)
1023 +                       break;
1024 +       return desc;
1028 + * Initialize FEC transmit task.
1029 + * Returns task number of FEC transmit task.
1030 + * Returns -1 on failure
1031 + */
1032 +int sdma_fec_tx_init(struct sdma *s, phys_addr_t fifo)
1034 +       struct sdma_fec_tx_var *var;
1035 +       struct sdma_fec_tx_inc *inc;
1037 +       static int tasknum = -1;
1038 +       static struct sdma_bd *bd = 0;
1039 +       static u32 bd_pa;
1041 +       if (tasknum < 0) {
1042 +               tasknum = sdma_load_task(sdma_fec_tx_task);
1043 +               if (tasknum < 0)
1044 +                       return tasknum;
1045 +       }
1047 +       if (!bd)  
1048 +               bd = (struct sdma_bd *)sdma_sram_alloc(sizeof(*bd) * s->num_bd,
1049 +                                                               SDMA_BD_ALIGN, &bd_pa);
1050 +       if (!bd)
1051 +               return -ENOMEM;
1053 +       sdma_disable_task(tasknum);
1055 +       s->tasknum = tasknum;
1056 +       s->bd = bd;
1057 +       s->flags = SDMA_FLAGS_ENABLE_TASK;
1058 +       s->index = 0;
1059 +       s->outdex = 0;
1060 +       memset(bd, 0, sizeof(*bd) * s->num_bd);
1062 +       var = (struct sdma_fec_tx_var *)sdma_task_var(tasknum);
1063 +       var->DRD                = sdma_sram_pa(self_modified_drd(tasknum));
1064 +       var->fifo               = fifo;
1065 +       var->enable             = sdma_io_pa(&sdma.io->tcr[tasknum]);
1066 +       var->bd_base    = bd_pa;
1067 +       var->bd_last    = bd_pa + (s->num_bd - 1)*sizeof(struct sdma_bd);
1068 +       var->bd_start   = bd_pa;
1070 +       /* These are constants, they should have been in the image file */
1071 +       inc = (struct sdma_fec_tx_inc *)sdma_task_inc(tasknum);
1072 +       inc->incr_bytes         = -(s16)sizeof(u32);
1073 +       inc->incr_src           = sizeof(u32);
1074 +       inc->incr_src_ma        = sizeof(u8);
1076 +       sdma_set_task_pragma(tasknum, SDMA_FEC_TX_BD_PRAGMA);
1077 +       sdma_set_task_auto_start(tasknum, tasknum);
1079 +       /* clear pending interrupt bits */
1080 +       out_be32(&sdma.io->IntPend, 1<<tasknum);
1082 +       out_8(&sdma.io->ipr[SDMA_INITIATOR_FEC_TX], SDMA_IPR_FEC_TX);
1084 +       return tasknum;
1087 +EXPORT_SYMBOL(sdma_fec_rx_init);
1088 +EXPORT_SYMBOL(sdma_fec_tx_init);
1089 diff --git a/arch/powerpc/platforms/52xx/fec.h b/arch/powerpc/platforms/52xx/fec.h
1090 new file mode 100644
1091 index 0000000..e3abc0f
1092 --- /dev/null
1093 +++ b/arch/powerpc/platforms/52xx/fec.h
1094 @@ -0,0 +1,71 @@
1096 + * arch/ppc/syslib/bestcomm/fec.h
1097 + *
1098 + * Driver for MPC52xx processor BestComm FEC controller
1099 + *
1100 + * Author: Dale Farnsworth <dfarnsworth@mvista.com>
1101 + *
1102 + * 2003-2004 (c) MontaVista, Software, Inc.  This file is licensed under
1103 + * the terms of the GNU General Public License version 2.  This program
1104 + * is licensed "as is" without any warranty of any kind, whether express
1105 + * or implied.
1106 + *
1107 + * HISTORY:
1108 + *
1109 + * 2005-08-14  Converted to platform driver by 
1110 + *             Andrey Volkov <avolkov@varma-el.com>, Varma Electronics Oy
1111 + */
1113 +#ifndef __BESTCOMM_FEC_H__
1114 +#define __BESTCOMM_FEC_H__
1117 +/* rx task vars that need to be set before enabling the task */
1118 +struct sdma_fec_rx_var {
1119 +       u32 enable;             /* (u16*) address of task's control register */
1120 +       u32 fifo;               /* (u32*) address of fec's fifo */
1121 +       u32 bd_base;            /* (struct sdma_bd*) beginning of ring buffer */
1122 +       u32 bd_last;            /* (struct sdma_bd*) end of ring buffer */
1123 +       u32 bd_start;           /* (struct sdma_bd*) current bd */
1124 +       u32 buffer_size;        /* size of receive buffer */
1127 +/* rx task incs that need to be set before enabling the task */
1128 +struct sdma_fec_rx_inc {
1129 +       u16 pad0;
1130 +       s16 incr_bytes;
1131 +       u16 pad1;
1132 +       s16 incr_dst;
1133 +       u16 pad2;
1134 +       s16 incr_dst_ma;
1137 +/* tx task vars that need to be set before enabling the task */
1138 +struct sdma_fec_tx_var {
1139 +       u32 DRD;                /* (u32*) address of self-modified DRD */
1140 +       u32 fifo;               /* (u32*) address of fec's fifo */
1141 +       u32 enable;             /* (u16*) address of task's control register */
1142 +       u32 bd_base;            /* (struct sdma_bd*) beginning of ring buffer */
1143 +       u32 bd_last;            /* (struct sdma_bd*) end of ring buffer */
1144 +       u32 bd_start;           /* (struct sdma_bd*) current bd */
1145 +       u32 buffer_size;        /* set by uCode for each packet */
1148 +/* tx task incs that need to be set before enabling the task */
1149 +struct sdma_fec_tx_inc {
1150 +       u16 pad0;
1151 +       s16 incr_bytes;
1152 +       u16 pad1;
1153 +       s16 incr_src;
1154 +       u16 pad2;
1155 +       s16 incr_src_ma;
1158 +extern int sdma_fec_rx_init(struct sdma *s, phys_addr_t fifo, int maxbufsize);
1159 +extern int sdma_fec_tx_init(struct sdma *s, phys_addr_t fifo);
1161 +extern u32 sdma_fec_rx_task[];
1162 +extern u32 sdma_fec_tx_task[];
1165 +#endif  /* __BESTCOMM_FEC_H__ */
1166 diff --git a/arch/powerpc/platforms/52xx/sdma_fec_rx_task.c b/arch/powerpc/platforms/52xx/sdma_fec_rx_task.c
1167 new file mode 100644
1168 index 0000000..511b036
1169 --- /dev/null
1170 +++ b/arch/powerpc/platforms/52xx/sdma_fec_rx_task.c
1171 @@ -0,0 +1,71 @@
1173 + * sdma_fec_rx_task.c
1174 + *
1175 + * Automatically created based on BestCommAPI-2.2/code_dma/image_rtos1/dma_image.hex
1176 + * on Tue Mar 22 11:19:38 2005 GMT
1177 + */
1179 +#include <linux/types.h>
1182 + * The header consists of the following fields:
1183 + *     uint32_t        magic;
1184 + *     uint8_t         desc_size;
1185 + *     uint8_t         var_size;
1186 + *     uint8_t         inc_size;
1187 + *     uint8_t         first_var;
1188 + *     uint8_t         reserved[8];
1189 + *
1190 + * The size fields contain the number of 32-bit words.
1193 +uint32_t sdma_fec_rx_task[] = {
1194 +       /* header */
1195 +       0x4243544b,
1196 +       0x18060709,
1197 +       0x00000000,
1198 +       0x00000000,
1200 +       /* Task descriptors */
1201 +       0x808220e3, /* LCD: idx0 = var1, idx1 = var4; idx1 <= var3; idx0 += inc4, idx1 += inc3 */
1202 +       0x10601010, /*   DRD1A: var4 = var2; FN=0 MORE init=3 WS=0 RS=0 */
1203 +       0xb8800264, /*   LCD: idx2 = *idx1, idx3 = var0; idx2 < var9; idx2 += inc4, idx3 += inc4 */
1204 +       0x10001308, /*     DRD1A: var4 = idx1; FN=0 MORE init=0 WS=0 RS=0 */
1205 +       0x60140002, /*     DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */
1206 +       0x0cccfcca, /*     DRD2B1: *idx3 = EU3(); EU3(*idx3,var10)  */
1207 +       0x80004000, /*   LCDEXT: idx2 = 0x00000000; ; */
1208 +       0xb8c58029, /*   LCD: idx3 = *(idx1 + var00000015); idx3 once var0; idx3 += inc5 */
1209 +       0x60000002, /*     DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=0 RS=0 */
1210 +       0x088cf8cc, /*     DRD2B1: idx2 = EU3(); EU3(idx3,var12)  */
1211 +       0x991982f2, /*   LCD: idx2 = idx2, idx3 = idx3; idx2 > var11; idx2 += inc6, idx3 += inc2 */
1212 +       0x006acf80, /*     DRD1A: *idx3 = *idx0; FN=0 init=3 WS=1 RS=1 */
1213 +       0x80004000, /*   LCDEXT: idx2 = 0x00000000; ; */
1214 +       0x9999802d, /*   LCD: idx3 = idx3; idx3 once var0; idx3 += inc5 */
1215 +       0x70000002, /*     DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */
1216 +       0x034cfc4e, /*     DRD2B1: var13 = EU3(); EU3(*idx1,var14)  */
1217 +       0x00008868, /*     DRD1A: idx2 = var13; FN=0 init=0 WS=0 RS=0 */
1218 +       0x99198341, /*   LCD: idx2 = idx2, idx3 = idx3; idx2 > var13; idx2 += inc0, idx3 += inc1 */
1219 +       0x007ecf80, /*     DRD1A: *idx3 = *idx0; FN=0 init=3 WS=3 RS=3 */
1220 +       0x99198272, /*   LCD: idx2 = idx2, idx3 = idx3; idx2 > var9; idx2 += inc6, idx3 += inc2 */
1221 +       0x046acf80, /*     DRD1A: *idx3 = *idx0; FN=0 INT init=3 WS=1 RS=1 */
1222 +       0x9819002d, /*   LCD: idx2 = idx0; idx2 once var0; idx2 += inc5 */
1223 +       0x0060c790, /*     DRD1A: *idx1 = *idx2; FN=0 init=3 WS=0 RS=0 */
1224 +       0x000001f8, /*   NOP */
1226 +       /* VAR[9]-VAR[14] */
1227 +       0x40000000,
1228 +       0x7fff7fff,
1229 +       0x00000000,
1230 +       0x00000003,
1231 +       0x40000008,
1232 +       0x43ffffff,
1234 +       /* INC[0]-INC[6] */
1235 +       0x40000000,
1236 +       0xe0000000,
1237 +       0xe0000000,
1238 +       0xa0000008,
1239 +       0x20000000,
1240 +       0x00000000,
1241 +       0x4000ffff,
1243 diff --git a/arch/powerpc/platforms/52xx/sdma_fec_tx_task.c b/arch/powerpc/platforms/52xx/sdma_fec_tx_task.c
1244 new file mode 100644
1245 index 0000000..d8d7fd3
1246 --- /dev/null
1247 +++ b/arch/powerpc/platforms/52xx/sdma_fec_tx_task.c
1248 @@ -0,0 +1,84 @@
1250 + * sdma_fec_tx_task.c
1251 + *
1252 + * Automatically created based on BestCommAPI-2.2/code_dma/image_rtos1/dma_image.hex
1253 + * on Tue Mar 22 11:19:29 2005 GMT
1254 + */
1256 +#include <linux/types.h>
1259 + * The header consists of the following fields:
1260 + *     uint32_t        magic;
1261 + *     uint8_t         desc_size;
1262 + *     uint8_t         var_size;
1263 + *     uint8_t         inc_size;
1264 + *     uint8_t         first_var;
1265 + *     uint8_t         reserved[8];
1266 + *
1267 + * The size fields contain the number of 32-bit words.
1270 +uint32_t sdma_fec_tx_task[] = {
1271 +       /* header */
1272 +       0x4243544b,
1273 +       0x2407070d,
1274 +       0x00000000,
1275 +       0x00000000,
1277 +       /* Task descriptors */
1278 +       0x8018001b, /* LCD: idx0 = var0; idx0 <= var0; idx0 += inc3 */
1279 +       0x60000005, /*   DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 EXT init=0 WS=0 RS=0 */
1280 +       0x01ccfc0d, /*   DRD2B1: var7 = EU3(); EU3(*idx0,var13)  */
1281 +       0x8082a123, /* LCD: idx0 = var1, idx1 = var5; idx1 <= var4; idx0 += inc4, idx1 += inc3 */
1282 +       0x10801418, /*   DRD1A: var5 = var3; FN=0 MORE init=4 WS=0 RS=0 */
1283 +       0xf88103a4, /*   LCDEXT: idx2 = *idx1, idx3 = var2; idx2 < var14; idx2 += inc4, idx3 += inc4 */
1284 +       0x801a6024, /*   LCD: idx4 = var0; ; idx4 += inc4 */
1285 +       0x10001708, /*     DRD1A: var5 = idx1; FN=0 MORE init=0 WS=0 RS=0 */
1286 +       0x60140002, /*     DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */
1287 +       0x0cccfccf, /*     DRD2B1: *idx3 = EU3(); EU3(*idx3,var15)  */
1288 +       0x991a002c, /*   LCD: idx2 = idx2, idx3 = idx4; idx2 once var0; idx2 += inc5, idx3 += inc4 */
1289 +       0x70000002, /*     DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */
1290 +       0x024cfc4d, /*     DRD2B1: var9 = EU3(); EU3(*idx1,var13)  */
1291 +       0x60000003, /*     DRD2A: EU0=0 EU1=0 EU2=0 EU3=3 EXT init=0 WS=0 RS=0 */
1292 +       0x0cccf247, /*     DRD2B1: *idx3 = EU3(); EU3(var9,var7)  */
1293 +       0x80004000, /*   LCDEXT: idx2 = 0x00000000; ; */
1294 +       0xb8c80029, /*   LCD: idx3 = *(idx1 + var0000001a); idx3 once var0; idx3 += inc5 */
1295 +       0x70000002, /*     DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */
1296 +       0x088cf8d1, /*     DRD2B1: idx2 = EU3(); EU3(idx3,var17)  */
1297 +       0x00002f10, /*     DRD1A: var11 = idx2; FN=0 init=0 WS=0 RS=0 */
1298 +       0x99198432, /*   LCD: idx2 = idx2, idx3 = idx3; idx2 > var16; idx2 += inc6, idx3 += inc2 */
1299 +       0x008ac398, /*     DRD1A: *idx0 = *idx3; FN=0 init=4 WS=1 RS=1 */
1300 +       0x80004000, /*   LCDEXT: idx2 = 0x00000000; ; */
1301 +       0x9999802d, /*   LCD: idx3 = idx3; idx3 once var0; idx3 += inc5 */
1302 +       0x70000002, /*     DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */
1303 +       0x048cfc53, /*     DRD2B1: var18 = EU3(); EU3(*idx1,var19)  */
1304 +       0x60000008, /*     DRD2A: EU0=0 EU1=0 EU2=0 EU3=8 EXT init=0 WS=0 RS=0 */
1305 +       0x088cf48b, /*     DRD2B1: idx2 = EU3(); EU3(var18,var11)  */
1306 +       0x99198481, /*   LCD: idx2 = idx2, idx3 = idx3; idx2 > var18; idx2 += inc0, idx3 += inc1 */
1307 +       0x009ec398, /*     DRD1A: *idx0 = *idx3; FN=0 init=4 WS=3 RS=3 */
1308 +       0x991983b2, /*   LCD: idx2 = idx2, idx3 = idx3; idx2 > var14; idx2 += inc6, idx3 += inc2 */
1309 +       0x088ac398, /*     DRD1A: *idx0 = *idx3; FN=0 TFD init=4 WS=1 RS=1 */
1310 +       0x9919002d, /*   LCD: idx2 = idx2; idx2 once var0; idx2 += inc5 */
1311 +       0x60000005, /*     DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 EXT init=0 WS=0 RS=0 */
1312 +       0x0c4cf88e, /*     DRD2B1: *idx1 = EU3(); EU3(idx2,var14)  */
1313 +       0x000001f8, /*   NOP */
1315 +       /* VAR[13]-VAR[19] */
1316 +       0x0c000000,
1317 +       0x40000000,
1318 +       0x7fff7fff,
1319 +       0x00000000,
1320 +       0x00000003,
1321 +       0x40000004,
1322 +       0x43ffffff,
1324 +       /* INC[0]-INC[6] */
1325 +       0x40000000,
1326 +       0xe0000000,
1327 +       0xe0000000,
1328 +       0xa0000008,
1329 +       0x20000000,
1330 +       0x00000000,
1331 +       0x4000ffff,
1333 -- 
1334 1.4.4.2