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>
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
18 index 0000000..ef45e02
20 +++ b/arch/powerpc/platforms/52xx/bestcomm.c
23 + * arch/ppc/syslib/bestcomm/bestcomm.c
25 + * Driver for MPC52xx processor BestComm peripheral controller
27 + * Author: Dale Farnsworth <dfarnsworth@mvista.com>
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
36 + * 2005-08-14 Converted to platform driver by
37 + * Andrey Volkov <avolkov@varma-el.com>, Varma Electronics Oy
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>
52 +#include <asm/mpc52xx.h>
54 +#include "bestcomm.h"
56 +#define DRIVER_NAME "mpc52xx-sdma"
60 +static spinlock_t sdma_lock = SPIN_LOCK_UNLOCKED;
62 +#ifdef CONFIG_BESTCOMM_DEBUG
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++) {
83 + printk("\n** %02X:",i);
84 + printk(" %04X",sdma.io->tcr[i]);
86 + printk("\n** IPR dump:");
87 + for (i=0;i<32;i++) {
89 + printk("\n** %02X:",i);
90 + printk(" %02X",sdma.io->ipr[i]);
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);
105 +#ifdef CONFIG_BESTCOMM_DEBUG
106 +#define SDMA_DUMP_REGS() sdma_dump()
108 +#define SDMA_DUMP_REGS()
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.
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.
121 + * Area 2 is at the end of SRAM and is used for the remaining allocations.
122 + * Successive allocations return lower addresses.
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.
130 +static u8 *area1_end;
131 +static u8 *area2_begin;
133 +void *sdma_sram_alloc(int size, int alignment, u32 *dma_handle)
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;
147 + a = 0; /* out of memory */
149 + a = (u8 *)(((u32)area2_begin - size) & ~(alignment - 1));
150 + if (a >= area1_end)
153 + a = 0; /* out of memory */
155 + if(a && dma_handle)
156 + *dma_handle = sdma_sram_pa(a);
157 + spin_unlock(&sdma_lock);
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;
186 + spin_lock(&sdma_lock);
189 + for (i=0; i<SDMA_MAX_TASKS; i++, tdt++)
190 + if (tdt->start == 0)
192 + if (i == SDMA_MAX_TASKS)
195 + spin_unlock(&sdma_lock);
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;
206 + u32 *var_src, *var_dst;
210 + BUG_ON(head->magic != SDMA_TASK_MAGIC);
212 + tasknum = new_task_number();
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);
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));
235 +void sdma_set_initiator(int task, int initiator)
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))
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);
258 +struct sdma *sdma_alloc(int queue_size)
260 + struct sdma *s = kmalloc(sizeof(*s), GFP_KERNEL);
266 + memset(s, 0, sizeof(*s));
269 + cookie = kmalloc(sizeof(*cookie) * queue_size, GFP_KERNEL);
274 + s->cookie = cookie;
277 + s->num_bd = queue_size;
281 +void sdma_free(struct sdma *s)
288 +static int __devinit mpc52xx_sdma_probe(struct device *dev)
290 + struct platform_device *pdev = to_platform_device(dev);
294 + struct sdma_tdt *tdt;
295 + struct resource *mem_io, *mem_sram;
296 + u32 tdt_pa, var_pa, context_pa, fdt_pa;
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)
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");
308 + sdma.base_reg_addr = mem_io->start;
310 + sdma.io = ioremap_nocache(mem_io->start, sizeof(struct mpc52xx_sdma));
313 + printk(KERN_ERR DRIVER_NAME " - failed to map sdma regs\n");
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;
326 + sdma.base_sram_addr = mem_sram->start;
327 + sdma.sram = ioremap_nocache(mem_sram->start, sdma.sram_size);
329 + printk(KERN_ERR DRIVER_NAME " - failed to map sdma sram\n");
331 + goto map_sram_error;
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);
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;
359 + var_pa += (SDMA_MAX_VAR + SDMA_MAX_INC)*sizeof(u32);
360 + context_pa += SDMA_MAX_CONTEXT*sizeof(u32);
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");
374 + release_mem_region(mem_sram->start, sdma.sram_size);
378 + release_mem_region(mem_io->start, mem_io->end - mem_io->start + 1);
380 + printk(KERN_ERR "DMA: MPC52xx BestComm init FAILED !!!\n");
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 */
392 +/* .suspend = mpc52xx_sdma_suspend, TODO */
393 +/* .resume = mpc52xx_sdma_resume, TODO */
398 +mpc52xx_sdma_init(void)
400 + printk(KERN_INFO "DMA: MPC52xx BestComm driver\n");
401 + return driver_register(&mpc52xx_sdma_driver);
406 +mpc52xx_sdma_exit(void)
408 + driver_unregister(&mpc52xx_sdma_driver);
413 + subsys_initcall(mpc52xx_sdma_init);
415 + module_init(mpc52xx_sdma_init);
416 + module_exit(mpc52xx_sdma_exit);
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
432 index 0000000..14bf397
434 +++ b/arch/powerpc/platforms/52xx/bestcomm.h
437 + * arch/ppc/syslib/bestcomm/bestcomm.h
439 + * Driver for MPC52xx processor BestComm peripheral controller
441 + * Author: Dale Farnsworth <dfarnsworth@mvista.com>
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
450 + * 2005-08-14 Converted to platform driver by
451 + * Andrey Volkov <avolkov@varma-el.com>, Varma Electronics Oy
454 +#ifndef __BESTCOMM_BESTCOMM_H__
455 +#define __BESTCOMM_BESTCOMM_H__
457 +/* Buffer Descriptor definitions */
470 + unsigned long base_reg_addr;
471 + struct mpc52xx_sdma __iomem *io;
472 + unsigned long base_sram_addr;
473 + void __iomem *sram;
476 + struct sdma_tdt __iomem *tdt;
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)
499 + struct sdma_bd *bd;
500 + struct sdma_bd2 *bd2;
510 +#define SDMA_FLAGS_NONE 0x0000
511 +#define SDMA_FLAGS_ENABLE_TASK 0x0001
512 +#define SDMA_FLAGS_BD2 0x0002
514 +/* Task Descriptor Table Entry */
520 + u32 exec_status; /* used internally by SmartComm engine */
521 + u32 mvtp; /* used internally by SmartComm engine */
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
545 + #ifdef CONFIG_BESTCOMM_DEBUG
546 + #define DPRINTK(a,b...) printk(KERN_DEBUG "sdma: %s: " a, __FUNCTION__ , ## b)
548 + #define DPRINTK(a,b...)
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);
622 + if (sdma_queue_empty(s))
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));
632 + if (sdma_queue_empty(s))
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,
679 +#ifdef CONFIG_BESTCOMM_DEBUG
680 + BUG_ON(s->flags & SDMA_FLAGS_BD2);
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".
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);
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);
715 + *length = s->bd[s->outdex].status & SDMA_LEN_MASK;
716 + s->outdex = sdma_next_outdex(s);
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));
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));
743 + *length = s->bd2[s->outdex].status & SDMA_LEN_MASK;
744 + s->outdex = sdma_next_outdex(s);
748 +#define SDMA_TASK_MAGIC 0x4243544B /* 'BCTK' */
750 +/* the size fields are given in number of 32-bit words */
751 +struct sdma_task_header {
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, */
773 +#define SDMA_PRAGMA_BIT_RST_ERROR_NO 5 /* don't reset errors on */
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
911 index 0000000..8756856
913 +++ b/arch/powerpc/platforms/52xx/fec.c
916 + * arch/ppc/syslib/bestcomm/fec.c
918 + * Driver for MPC52xx processor BestComm FEC controller
920 + * Author: Dale Farnsworth <dfarnsworth@mvista.com>
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
929 + * 2005-08-14 Converted to platform driver by
930 + * Andrey Volkov <avolkov@varma-el.com>, Varma Electronics Oy
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>
942 +#include <asm/mpc52xx.h>
944 +#include "bestcomm.h"
948 + * Initialize FEC receive task.
949 + * Returns task number of FEC receive task.
950 + * Returns -1 on failure
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;
962 + tasknum = sdma_load_task(sdma_fec_rx_task);
968 + bd = (struct sdma_bd *)sdma_sram_alloc(sizeof(*bd) * s->num_bd,
969 + SDMA_BD_ALIGN, &bd_pa);
973 + sdma_disable_task(tasknum);
975 + s->tasknum = tasknum;
977 + s->flags = SDMA_FLAGS_NONE;
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]);
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);
1008 + * Return 2nd to last DRD
1009 + * This is an ugly hack, but at least it's only done once at initialization
1011 +static u32 *self_modified_drd(int tasknum)
1018 + num_descs = sdma_task_num_descs(tasknum);
1019 + desc = sdma_task_desc(tasknum) + num_descs - 1;
1021 + for (i=0; i<num_descs; i++, desc--)
1022 + if (sdma_desc_is_drd(*desc) && ++drd_count == 3)
1028 + * Initialize FEC transmit task.
1029 + * Returns task number of FEC transmit task.
1030 + * Returns -1 on failure
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;
1041 + if (tasknum < 0) {
1042 + tasknum = sdma_load_task(sdma_fec_tx_task);
1048 + bd = (struct sdma_bd *)sdma_sram_alloc(sizeof(*bd) * s->num_bd,
1049 + SDMA_BD_ALIGN, &bd_pa);
1053 + sdma_disable_task(tasknum);
1055 + s->tasknum = tasknum;
1057 + s->flags = SDMA_FLAGS_ENABLE_TASK;
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));
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);
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
1093 +++ b/arch/powerpc/platforms/52xx/fec.h
1096 + * arch/ppc/syslib/bestcomm/fec.h
1098 + * Driver for MPC52xx processor BestComm FEC controller
1100 + * Author: Dale Farnsworth <dfarnsworth@mvista.com>
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
1109 + * 2005-08-14 Converted to platform driver by
1110 + * Andrey Volkov <avolkov@varma-el.com>, Varma Electronics Oy
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 {
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 {
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
1170 +++ b/arch/powerpc/platforms/52xx/sdma_fec_rx_task.c
1173 + * sdma_fec_rx_task.c
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
1179 +#include <linux/types.h>
1182 + * The header consists of the following fields:
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];
1190 + * The size fields contain the number of 32-bit words.
1193 +uint32_t sdma_fec_rx_task[] = {
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] */
1234 + /* INC[0]-INC[6] */
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
1247 +++ b/arch/powerpc/platforms/52xx/sdma_fec_tx_task.c
1250 + * sdma_fec_tx_task.c
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
1256 +#include <linux/types.h>
1259 + * The header consists of the following fields:
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];
1267 + * The size fields contain the number of 32-bit words.
1270 +uint32_t sdma_fec_tx_task[] = {
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] */
1324 + /* INC[0]-INC[6] */