summaryrefslogtreecommitdiff
path: root/Source/DirectFB/gfxdrivers/davinci/kernel-module
diff options
context:
space:
mode:
Diffstat (limited to 'Source/DirectFB/gfxdrivers/davinci/kernel-module')
-rwxr-xr-xSource/DirectFB/gfxdrivers/davinci/kernel-module/Makefile34
-rwxr-xr-xSource/DirectFB/gfxdrivers/davinci/kernel-module/c64x/Makefile2
-rwxr-xr-xSource/DirectFB/gfxdrivers/davinci/kernel-module/c64x/c64x.c507
-rwxr-xr-xSource/DirectFB/gfxdrivers/davinci/kernel-module/include/linux/c64x.h281
4 files changed, 824 insertions, 0 deletions
diff --git a/Source/DirectFB/gfxdrivers/davinci/kernel-module/Makefile b/Source/DirectFB/gfxdrivers/davinci/kernel-module/Makefile
new file mode 100755
index 0000000..cb2965a
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/davinci/kernel-module/Makefile
@@ -0,0 +1,34 @@
+KERNEL_VERSION = $(shell uname -r)
+KERNEL_MODLIB = /lib/modules/$(KERNEL_VERSION)
+KERNEL_BUILD = $(KERNEL_MODLIB)/build
+KERNEL_SOURCE = $(KERNEL_MODLIB)/source
+
+SUB=c64x
+
+export CONFIG_DAVINCI_C64X=m
+
+ifeq ($(shell test -e $(KERNEL_BUILD)/include/linux/autoconf.h && echo yes),yes)
+ AUTOCONF_H = -include $(KERNEL_BUILD)/include/linux/autoconf.h
+endif
+
+ifeq ($(shell test -e $(KERNEL_BUILD)/include/linux/config.h && echo yes),yes)
+ CPPFLAGS += -DHAVE_LINUX_CONFIG_H
+endif
+
+CPPFLAGS += -DMODULE
+
+.PHONY: all install clean
+
+it all:
+ $(MAKE) -C $(KERNEL_BUILD) \
+ KCPPFLAGS="$(CPPFLAGS) -I$(shell pwd)/include -I$(KERNEL_BUILD)/include" \
+ SUBDIRS=$(shell pwd)/$(SUB) ARCH=arm CROSS_COMPILE=arm-v4t-linux-gnueabi- modules
+
+install: all
+
+clean:
+ $(RM) -r $(SUB)/.tmp_versions $(SUB)/Module.symvers
+ find $(SUB) -name *.o -o -name *.ko -o -name .*.cmd -o -name *.mod.* | xargs rm -f
+
+so: it
+ find $(SUB) -name "*.ko" | xargs strip -x -R .comment -R .note
diff --git a/Source/DirectFB/gfxdrivers/davinci/kernel-module/c64x/Makefile b/Source/DirectFB/gfxdrivers/davinci/kernel-module/c64x/Makefile
new file mode 100755
index 0000000..8d211a5
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/davinci/kernel-module/c64x/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_DAVINCI_C64X) += c64x.o
+
diff --git a/Source/DirectFB/gfxdrivers/davinci/kernel-module/c64x/c64x.c b/Source/DirectFB/gfxdrivers/davinci/kernel-module/c64x/c64x.c
new file mode 100755
index 0000000..bbbbfe9
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/davinci/kernel-module/c64x/c64x.c
@@ -0,0 +1,507 @@
+/*
+ TI Davinci driver - C64X+ DSP Kernel Module
+
+ (c) Copyright 2007 Telio AG
+
+ Written by Olaf Dreesen <dreesen@qarx.de>.
+
+ All rights reserved.
+
+ This module is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/fcntl.h>
+#include <linux/firmware.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/page-flags.h>
+#include <linux/poll.h>
+#include <linux/proc_fs.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+
+#include <asm/cacheflush.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#include <linux/c64x.h>
+
+#define C64X_IRQ
+
+MODULE_LICENSE("GPL v2");
+//MODULE_LICENSE("Propietary");
+MODULE_AUTHOR("Olaf Dreesen <dreesen@qarx.de>");
+MODULE_DESCRIPTION("A little c64+ handling module.");
+
+#define C_MOD_MAJOR 400
+#define C_MOD_NUM_DEV 1
+#define C_MOD_NAME "c64x"
+#define F_NAME "c64x_drv.bin"
+
+#define CODE_BASE 0x00800000
+
+/* DDR2:
+ *
+ * transfer buffer
+ */
+#define R_BASE DAVINCI_C64X_MEM
+#define R_LEN 0x02000000
+
+/* L2RAM:
+ *
+ * 0x00800000 - 0x0080FFFF C64x+
+ * 0x11800000 - 0x1180FFFF ARM
+ */
+#define D_BASE 0x11800000
+#define D_LEN 0x00010000
+
+/* L1DRAM:
+ *
+ * 0x00F04000 - 0x00F0FFFF C64x+
+ * 0x11F04000 - 0x11F0FFFF ARM
+ *
+ * Queue controls @ 0x00F04000 (4096 Bytes)
+ */
+#define Q_BASE 0x11F04000
+#define Q_LEN 0x00001000
+
+#define HQueueDSP (l1dram[0x00>>2])
+#define HQueueARM (l1dram[0x04>>2])
+#define LQueueDSP (l1dram[0x08>>2])
+#define LQueueARM (l1dram[0x0C>>2])
+#define DSPidle (l1dram[0x10>>2])
+
+/* IO Register needed:
+ *
+ * 0x01C40008 DSPBOOTADDR DSP Boot Address
+ * 0x01C40010 INTGEN Interrupt Generator
+ * 0x01C40038 CHP_SHRTSW DSP Power
+ * 0x01C4169C MDCFG39 DSP Module config
+ * 0x01C41A9C MDCTL39 DSP Module control
+ */
+#define IO_BASE 0x01c40000
+#define IO_LEN 0x00010000
+
+#define DSPBOOTADDR (mmr[0x0008>>2])
+#define INTGEN (mmr[0x0010>>2])
+#define CHP_SHRTSW (mmr[0x0038>>2])
+#define MDCFG39 (mmr[0x169C>>2])
+#define MDCTL39 (mmr[0x1A9C>>2])
+
+MODULE_FIRMWARE(F_NAME);
+
+static dev_t dev_major;
+static struct cdev*dev_cdev;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
+static struct class*dev_class;
+#else
+static struct class_simple*dev_class;
+#endif
+
+static volatile unsigned int*mmr=0;
+static unsigned char*l2ram=0;
+static volatile unsigned int*l1dram=0;
+static volatile void*dram=0;
+static volatile c64xTaskControl*c64xctl=0;
+static volatile c64xTask*queue_l=0;
+
+#ifdef C64X_IRQ
+static int dev_irq=46;
+static DECLARE_WAIT_QUEUE_HEAD( wait_irq );
+
+/* IRQ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 21)
+static irqreturn_t dev_irq_handler(int irq,void*dev_id) {
+#else
+static irqreturn_t dev_irq_handler(int irq,void*dev_id,struct pt_regs*regs) {
+#endif
+ wake_up_all( &wait_irq );
+ return IRQ_HANDLED;
+}
+#endif
+
+static u32 opencnt=0;
+
+/* char-dev */
+static int dev_open(struct inode*inode,struct file*filp) {
+ if (opencnt++==0) {
+ DSPidle=0;
+ MDCTL39=0x00000103; /* Go! Go, go Go! */
+ while(DSPidle==0);
+ }
+ return 0;
+}
+static int dev_release(struct inode*inode,struct file*filp) {
+ if (--opencnt==0) {
+ MDCTL39=0x00000000; /* local reset */
+ }
+ return 0;
+}
+
+static ssize_t dev_write(struct file*filp,const char __user*buffer,size_t len,loff_t*off) {
+ long ret=0;
+ unsigned long offset=*off;
+ if (offset<D_LEN) {
+ if ((offset+len)>=D_LEN) { len=D_LEN-offset; }
+// printk(KERN_INFO "c64x+ : read got offset %08lx %08lx\n",offset,(long)len);
+ ret=len;
+ *off+=len;
+ }
+ return ret;
+}
+static ssize_t dev_read(struct file*filp,char __user*buffer,size_t len,loff_t*off) {
+ long ret=0;
+ unsigned long offset=*off;
+ if (offset<D_LEN) {
+ if ((offset+len)>=D_LEN) { len=D_LEN-offset; }
+// printk(KERN_INFO "c64x+ : read got offset %08lx %08lx\n",offset,(long)len);
+ ret=len;
+ ret-=copy_to_user(buffer,(l2ram+offset),len);
+ *off+=len;
+ }
+ return ret;
+}
+
+static int dev_mmap(struct file * file, struct vm_area_struct * vma) {
+ size_t size=vma->vm_end-vma->vm_start;
+ if (vma->vm_pgoff) {
+ if (size!=R_LEN) return -EINVAL;
+#if defined(pgprot_writecombine)
+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+#else
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+#endif
+ if (remap_pfn_range(vma,
+ vma->vm_start,
+ R_BASE>>PAGE_SHIFT,
+ size,
+ vma->vm_page_prot))
+ return -EAGAIN;
+ }
+ else {
+ if (size!=Q_LEN) return -EINVAL;
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ if (remap_pfn_range(vma,
+ vma->vm_start,
+ Q_BASE>>PAGE_SHIFT,
+ size,
+ vma->vm_page_prot))
+ return -EAGAIN;
+ }
+ return 0;
+}
+
+static void
+c64x_dump( const char *condition )
+{
+ static const char *state_names[] = { "DONE", "ERROR", "TODO", "RUNNING" };
+
+ uint32_t ql_dsp = c64xctl->QL_dsp;
+ uint32_t ql_arm = c64xctl->QL_arm;
+ uint32_t tl_dsp = queue_l[ql_dsp & C64X_QUEUE_MASK].c64x_function;
+ uint32_t tl_arm = queue_l[ql_arm & C64X_QUEUE_MASK].c64x_function;
+ int dl;
+
+ dl = ql_arm - ql_dsp;
+ if (dl < 0)
+ dl += C64X_QUEUE_LENGTH;
+
+ printk( "C64X+ Queue: %s\n"
+ " [DSP %d / %d (%s), ARM %d / %d (%s)] <- %d pending\n",
+ condition,
+ ql_dsp, (tl_dsp >> 2) & 0x3fff, state_names[tl_dsp & 3],
+ ql_arm, (tl_arm >> 2) & 0x3fff, state_names[tl_arm & 3],
+ dl );
+}
+
+static int
+c64x_wait_low( void )
+{
+ int ret;
+ int num = 0;
+ /* Keep reference values for comparison. */
+ u32 idle = c64xctl->idlecounter;
+ u32 dsp = c64xctl->QL_dsp;
+
+ /* Wait for equal pointers... */
+ while (dsp != c64xctl->QL_arm) {
+ /* ...each time for a 1/50 second... */
+ ret = wait_event_interruptible_timeout( wait_irq, c64xctl->QL_dsp == c64xctl->QL_arm, HZ/50 );
+ if (ret < 0)
+ return ret;
+
+ /* ...if after that 1/50 second still the same command is running... */
+ if (!ret && c64xctl->QL_dsp == dsp) {
+ /* ...and almost one second elapsed in total, or the DSP felt idle... */
+ if (++num > 42 || c64xctl->idlecounter != idle) {
+ /* ...timeout! */
+ printk( KERN_ERR "c64x+ : timeout waiting for idle queue\n" );
+ c64x_dump( "TIMEOUT!!!" );
+ return -ETIMEDOUT;
+ }
+ }
+ else {
+ /* Different command running, reset total elapsed time. */
+ num = 0;
+ }
+
+ /* Update reference values. */
+ idle = c64xctl->idlecounter;
+ dsp = c64xctl->QL_dsp;
+ }
+
+ return 0;
+}
+
+static int dev_ioctl(struct inode *i, struct file *f, unsigned int cmd, unsigned long arg) {
+ switch (cmd) {
+ case C64X_IOCTL_RESET:
+ MDCTL39=0x00000000; /* local reset */
+ mdelay(10);
+ DSPidle=0;
+ MDCTL39=0x00000103;
+ break;
+ case C64X_IOCTL_WAIT_LOW:
+ return c64x_wait_low();
+ default:
+ printk(KERN_INFO "c64x+ : unknown ioctl : cmd=%08x\n",cmd);
+ return -EAGAIN;
+ break;
+ }
+ return 0;
+}
+static struct file_operations dev_file_ops={
+ .owner = THIS_MODULE,
+ .open = dev_open,
+ .release = dev_release,
+ .read = dev_read,
+ .write = dev_write,
+ .mmap = dev_mmap,
+ .ioctl = dev_ioctl,
+};
+
+/* INIT */
+static __initdata struct device dev_device = {
+ .bus_id = "c64x0",
+};
+static int __init dev_init(void) {
+ int ret=-EIO;
+ u8 *at;
+ const struct firmware*fw = NULL;
+
+ printk(KERN_INFO "c64x+ : module load\n");
+
+ if ((dram=ioremap(R_BASE,R_LEN))==0) {
+ printk(KERN_ERR "c64x+ : module couldn't get memory\n");
+ goto err0;
+ }
+ printk(KERN_INFO "c64x+ : module got memory @ %p\n",dram);
+ queue_l = dram + 0x01e00000;
+
+ /* get the 'device' memory */
+ if ((mmr=ioremap(IO_BASE,IO_LEN))==0) {
+ printk(KERN_ERR "c64x+ : module couldn't get IO-MMR\n");
+ goto err0;
+ }
+ printk(KERN_INFO "c64x+ : DSP bootaddr: %08x\n",DSPBOOTADDR);
+ printk(KERN_INFO "c64x+ : got mmr %p %08x %08x\n",mmr,MDCTL39,MDCFG39);
+
+ printk(KERN_INFO "c64x+ : switch state: %08x\n",CHP_SHRTSW);
+
+ MDCTL39=0x00000000; /* local reset */
+ mdelay(10);
+ DSPBOOTADDR=CODE_BASE; /* set DSP base address */
+
+// printk(KERN_INFO "c64x+ : check0: %p %08x %08x\n",mmr,MDCTL39,MDCFG39);
+
+ /* get the 'device' memory */
+ if ((l1dram=ioremap(Q_BASE,Q_LEN))==0) {
+ printk(KERN_ERR "c64x+ : module couldn't get L1 dsp-memory\n");
+ goto err1;
+ }
+ printk(KERN_INFO "c64x+ : module got L1D @ %p\n",l1dram);
+ c64xctl = (volatile void*)l1dram;
+
+ if ((l2ram=ioremap(D_BASE,D_LEN))==0) {
+ printk(KERN_ERR "c64x+ : module couldn't get L2 dsp-memory\n");
+ goto err2;
+ }
+ printk(KERN_INFO "c64x+ : module got L2 @ %p\n",l2ram);
+
+ /* request firmware */
+ device_initialize(&dev_device);
+ ret=device_add(&dev_device);
+ if (ret) {
+ printk(KERN_ERR "c64x+ : device_add failed\n");
+ goto err3;
+ }
+ printk(KERN_INFO "c64x+ : module requesting firmware '%s'\n",F_NAME);
+ ret=request_firmware(&fw,F_NAME,&dev_device);
+ printk(KERN_INFO "c64x+ : module got fw %p\n",fw);
+ if (ret) {
+ printk(KERN_ERR "c64x+ : no firmware upload (timeout or file not found?)\n");
+ device_del(&dev_device);
+ goto err3;
+ }
+ printk(KERN_INFO "c64x+ : firmware upload %p %zd\n",fw->data,fw->size);
+ if (fw->size>32767) {
+ printk(KERN_ERR "c64x+ : firmware too big! 32767 is maximum (for now)\n");
+ release_firmware(fw);
+ device_del(&dev_device);
+ goto err3;
+ }
+ if (memcmp(fw->data+8,"C64x+DV",8)) {
+ printk(KERN_ERR "c64x+ : firmware signature missing\n");
+ release_firmware(fw);
+ device_del(&dev_device);
+ goto err3;
+ }
+ at = fw->data + fw->size;
+ while ((ulong)--at > (ulong)fw->data) {
+ if (*at == '@')
+ break;
+ }
+ if (at == fw->data) {
+ printk(KERN_ERR "c64x+ : firmware tag missing\n");
+ release_firmware(fw);
+ device_del(&dev_device);
+ goto err3;
+ }
+ printk(KERN_NOTICE "c64x+ : got firmware of length %d at %p with tag '%*s' of length %d at %p+1\n",
+ fw->size, fw->data,
+ (int)((ulong)(fw->data + fw->size) - (ulong)at - 1), at + 1,
+ (int)((ulong)(fw->data + fw->size) - (ulong)at - 1), at );
+ /* move firmware into the hardware buffer here. */
+ memcpy(l2ram,fw->data,fw->size);
+ release_firmware(fw);
+ device_del(&dev_device);
+
+#if 0
+ /* release DSP */
+ printk(KERN_INFO "c64x+ : check1: %p %08x %08x\n",mmr,MDCTL39,MDCFG39);
+ MDCTL39=0x00000103; /* Hopefully run... */
+ printk(KERN_INFO "c64x+ : check2: %p %08x %08x\n",mmr,MDCTL39,MDCFG39);
+ printk(KERN_INFO "c64x+ : check3: %08x\n",DSPBOOTADDR);
+#endif
+
+ /* register char-dev */
+ dev_major=MKDEV(C_MOD_MAJOR,0);
+ ret=register_chrdev_region(dev_major,C_MOD_NUM_DEV,C_MOD_NAME);
+ if (ret) {
+ printk(KERN_ERR "c64x+ : can't get chrdev %d\n",C_MOD_MAJOR);
+ goto err3;
+ }
+
+ /* allocate cdev */
+ dev_cdev=cdev_alloc();
+ dev_cdev->ops=&dev_file_ops;
+ /* cdev_init(&dev_data.cdev,&dev_file_ops); */
+ ret=cdev_add(dev_cdev,dev_major,1);
+ if (ret) {
+ printk(KERN_ERR "c64x+ : can't allocate cdev\n");
+ goto err4;
+ }
+
+#ifdef C64X_IRQ
+ /* allocate interrupt slot */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 21)
+ ret=request_irq(dev_irq,dev_irq_handler,IRQF_DISABLED,C_MOD_NAME,NULL);
+#else
+ ret=request_irq(dev_irq,dev_irq_handler,SA_INTERRUPT ,C_MOD_NAME,NULL);
+#endif
+ if (ret) {
+ printk(KERN_ERR "c64x+ : can't get IRQ %d\n",dev_irq);
+ goto err5;
+ }
+#endif
+
+ /* tell sysfs/udev */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
+ dev_class=class_create(THIS_MODULE,C_MOD_NAME);
+#else
+ dev_class=class_simple_create(THIS_MODULE,C_MOD_NAME);
+#endif
+ if (IS_ERR(dev_class)) {
+ ret=PTR_ERR(dev_class);
+ printk(KERN_ERR "c64x+ : can't allocate class\n");
+ goto err6;
+ }
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
+ class_device_create(dev_class,NULL,dev_major,NULL,C_MOD_NAME"%d",0);
+#else
+ class_simple_device_add(dev_class,dev_major,NULL,C_MOD_NAME"%d",0);
+#endif
+
+ printk(KERN_INFO "c64x+ : module load finished\n");
+ return 0;
+ /* error out */
+err6:
+#ifdef C64X_IRQ
+ free_irq(dev_irq,0);
+err5:
+#endif
+ cdev_del(dev_cdev);
+err4:
+ unregister_chrdev_region(dev_major,1);
+err3:
+ iounmap(l2ram);
+err2:
+ iounmap((void*)l1dram);
+err1:
+ iounmap((void*)mmr);
+err0:
+ if (dram)
+ iounmap((void*)dram);
+ return ret;
+}
+module_init(dev_init);
+
+/* EXIT */
+static void __exit dev_exit(void) {
+ /* Put the DSP into Reset */
+ MDCTL39=0x00000000;
+ /* release the DSP memory */
+ iounmap((void*)mmr);
+ iounmap((void*)l1dram);
+ iounmap(l2ram);
+ /* release all the other resources */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
+ class_device_destroy(dev_class,dev_major);
+ class_destroy(dev_class);
+#else
+ class_simple_device_remove(dev_major);
+ class_simple_destroy(dev_class);
+#endif
+#ifdef C64X_IRQ
+ free_irq(dev_irq,0);
+#endif
+ cdev_del(dev_cdev);
+ unregister_chrdev_region(dev_major,C_MOD_NUM_DEV);
+}
+module_exit(dev_exit);
+
diff --git a/Source/DirectFB/gfxdrivers/davinci/kernel-module/include/linux/c64x.h b/Source/DirectFB/gfxdrivers/davinci/kernel-module/include/linux/c64x.h
new file mode 100755
index 0000000..6117404
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/davinci/kernel-module/include/linux/c64x.h
@@ -0,0 +1,281 @@
+/*
+ TI Davinci driver - C64X+ DSP Firmware Interface
+
+ (c) Copyright 2008 directfb.org
+ (c) Copyright 2007 Telio AG
+
+ Written by Olaf Dreesen <olaf@directfb.org> and
+ Denis Oliver Kropp <dok@directfb.org>.
+
+ All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __C64X_H__
+#define __C64X_H__
+
+#ifndef __KERNEL__
+#include <stdint.h>
+#endif
+
+
+#ifndef DAVINCI_C64X_MEM
+#define DAVINCI_C64X_MEM 0x8e000000
+#endif
+
+
+typedef volatile struct {
+ uint32_t c64x_function;
+ uint32_t c64x_arg[7];
+} c64xTask;
+
+
+#define c64x_return c64x_arg[0]
+#define c64x_errno c64x_arg[1]
+
+#define c64x_flags c64x_function
+
+typedef enum {
+ C64X_STATE_DONE = 0,
+ C64X_STATE_ERROR = 1,
+ C64X_STATE_TODO = 2,
+ C64X_STATE_RUNNING = 3
+} C64XTaskState;
+
+typedef enum {
+ C64X_FLAG_RUN = 1,
+ C64X_FLAG_TODO = 2,
+ C64X_FLAG_INTERRUPT = 0x80000000
+} C64XTaskFlags;
+
+#define C64X_TASK_STATE(task) ((task)->c64x_flags & 3)
+
+typedef volatile struct {
+ uint32_t QH_dsp;
+ uint32_t QH_arm;
+ uint32_t QL_dsp;
+ uint32_t QL_arm;
+ uint32_t idlecounter;
+} c64xTaskControl;
+
+#define C64X_QUEUE_LENGTH 0x4000
+#define C64X_QUEUE_MASK 0x3fff
+
+
+typedef enum {
+ C64X_BLEND_SRC_INVSRC = 2, /* old school fader on all channels including alpha on itself */
+ C64X_BLEND_ONE_INVSRC = 1, /* SrcOver using premultiplied alpha channel */
+ C64X_BLEND_ONE_INVSRC_PREMULT_SRC = 0, /* SrcOver doing premultiplication of source S[rgb] with S[a] */
+ C64X_BLEND_ONE_INVSRC_PREMULT_ALPHA = 3, /* SrcOver with Alpha using premultiplied alpha channel,
+ but doing premultiplication of S[rgb] with Alpha */
+} C64XBlendSubFunction;
+
+typedef enum {
+ C64X_FLUSH_WRITE_BACK,
+ C64X_FLUSH_WB_INVALIDATE,
+ C64X_FLUSH_INVALIDATE
+} C64XFlushFunction;
+
+#define C64X_IOCTL_RESET _IO( 'c', 0 )
+#define C64X_IOCTL_WAIT_LOW _IO( 'c', 1 )
+
+
+/* function macro */
+#define _C64XFUNC(val) (((val)&0x3fff)<<2)
+
+
+#define C64X_NOP _C64XFUNC(0)
+
+/*
+void c64x_dither_argb(u32*dst_rgb, u8*dst_alpha, u32 dst_pitch, u32*src, u32 src_pitch, u32 width, u32 height);
+*/
+#define C64X_DITHER_ARGB _C64XFUNC(1)
+
+/*
+void c64x_fill_16(u16*dst, u32 pitch, u32 width, u32 height, u16 val);
+void c64x_fill_32(u32*dst, u32 pitch, u32 width, u32 height, u32 val);
+*/
+#define C64X_FILL_16 _C64XFUNC(2)
+#define C64X_FILL_32 _C64XFUNC(3)
+
+/*
+void c64x_copy_16(u16*dst, u32 dst_pitch, u16*src, u32 src_pitch, u32 width, u32 height);
+void c64x_copy_32(u32*dst, u32 dst_pitch, u32*src, u32 src_pitch, u32 width, u32 height);
+*/
+#define C64X_COPY_16 _C64XFUNC(4)
+#define C64X_COPY_32 _C64XFUNC(5)
+
+/*
+void c64x_blend_32(u32*dst, u32 dst_pitch, u32*src, u32 src_pitch, u32 width, u32 height, u8 alpha);
+*/
+//#define C64X_BLEND_16 _C64XFUNC(6)
+#define C64X_BLEND_32 _C64XFUNC(7)
+
+/*
+void c64x_copy_keyed_16(u16*dst, u32 pitches, u16*src, u32 width, u32 height, u16 key, u16 mask);
+void c64x_copy_keyed_32(u32*dst, u32 pitches, u32*src, u32 width, u32 height, u32 key, u32 mask);
+*/
+#define C64X_COPY_KEYED_16 _C64XFUNC(8)
+#define C64X_COPY_KEYED_32 _C64XFUNC(9)
+
+/*
+void c64x_stretch_32(u32 *dst, u32 *src, u32 pitches, u32 dsize, u32 ssize, u32 clip2, u32 clip1);
+*/
+#define C64X_STRETCH_32_up _C64XFUNC(10)
+#define C64X_STRETCH_32_down _C64XFUNC(11)
+
+
+/*
+void c64x_wb_inv_range(u32 *start, u32 len, C64XFlushFunction func);
+*/
+#define C64X_WB_INV_RANGE _C64XFUNC(14)
+
+
+/*
+void c64x_write_back_all(void);
+*/
+#define C64X_WRITE_BACK_ALL _C64XFUNC(15)
+
+
+
+/*
+void c64x_load_block(s32*blockwords, u32 num_words, u32 cbp);
+*/
+#define C64X_LOAD_BLOCK _C64XFUNC(48)
+
+/*
+void c64x_put_idct_uyvy_16x16(u16*dst, u32 pitch, u32 flags);
+*/
+#define C64X_PUT_IDCT_UYVY_16x16 _C64XFUNC(49)
+
+/*
+void c64x_put_mc_uyvy_16x16(u16*dst, u32 pitch, u32 flags);
+*/
+#define C64X_PUT_MC_UYVY_16x16 _C64XFUNC(50)
+
+/*
+void c64x_put_sum_uyvy_16x16(u16*dst, u32 pitch, u32 flags);
+*/
+#define C64X_PUT_SUM_UYVY_16x16 _C64XFUNC(51)
+
+/*
+void c64x_dva_begin_frame(u32 pitch, u16 *current, u16 *past, u16 *future, u32 flags);
+*/
+#define C64X_DVA_BEGIN_FRAME _C64XFUNC(52)
+
+/*
+void c64x_dva_motion(DVAMacroBlock *macroblock);
+*/
+#define C64X_DVA_MOTION_BLOCK _C64XFUNC(53)
+
+/*
+void c64x_dva_idct(u16* dst, u32 pitch, u16* src);
+*/
+#define C64X_DVA_IDCT _C64XFUNC(59)
+
+
+
+/*
+ * INTERNAL - for testing
+ */
+#define C64X_FETCH_BUFFER_PITCH 32
+#define C64X_TEMP_BUFFER_PITCH 32
+#define C64X_MC_BUFFER_PITCH 16
+#define C64X_IDCT_BUFFER_PITCH 32
+
+#define C64X_FETCH_BUFFER_Y(n) (0xf05840 + ((n) << 10))
+#define C64X_FETCH_BUFFER_U(n) (C64X_FETCH_BUFFER_Y(n) + 18*C64X_FETCH_BUFFER_PITCH)
+#define C64X_FETCH_BUFFER_V(n) (C64X_FETCH_BUFFER_U(n) + 16)
+
+#define C64X_FETCH_BUFFER0_Y C64X_FETCH_BUFFER_Y(0)
+#define C64X_FETCH_BUFFER0_U C64X_FETCH_BUFFER_U(0)
+#define C64X_FETCH_BUFFER0_V C64X_FETCH_BUFFER_V(0)
+
+#define C64X_FETCH_BUFFER1_Y C64X_FETCH_BUFFER_Y(1)
+#define C64X_FETCH_BUFFER1_U C64X_FETCH_BUFFER_U(1)
+#define C64X_FETCH_BUFFER1_V C64X_FETCH_BUFFER_V(1)
+
+#define C64X_TEMP_BUFFER_Y 0xf06040
+#define C64X_TEMP_BUFFER_U (C64X_TEMP_BUFFER_Y + 16*C64X_TEMP_BUFFER_PITCH)
+#define C64X_TEMP_BUFFER_V (C64X_TEMP_BUFFER_U + 8)
+
+#define C64X_MC_BUFFER_Y 0xf06440
+#define C64X_MC_BUFFER_U (C64X_MC_BUFFER_Y + 16*C64X_MC_BUFFER_PITCH)
+#define C64X_MC_BUFFER_V (C64X_MC_BUFFER_U + 8)
+
+#define C64X_MC_BUFFER_Y_ (C64X_MC_BUFFER_Y + C64X_MC_BUFFER_PITCH)
+#define C64X_MC_BUFFER_U_ (C64X_MC_BUFFER_U + C64X_MC_BUFFER_PITCH)
+#define C64X_MC_BUFFER_V_ (C64X_MC_BUFFER_V + C64X_MC_BUFFER_PITCH)
+
+#define C64X_IDCT_BUFFER_Y 0xf06a40
+#define C64X_IDCT_BUFFER_U (C64X_IDCT_BUFFER_Y + 16*C64X_IDCT_BUFFER_PITCH)
+#define C64X_IDCT_BUFFER_V (C64X_IDCT_BUFFER_U + 8)
+
+
+/* OBSOLETE
+void c64x_dezigzag(u16*dst, u16*src);
+*/
+#define C64X_DEZIGZAG _C64XFUNC(16)
+
+/* OBSOLETE
+void c64x_dealternate(u16*dst, u16*src);
+*/
+#define C64X_DEALTERNATE _C64XFUNC(17)
+
+/*
+void c64x_put_uyvy_16x16(u16*dst, u32 pitch, u8*src, u32 flags);
+*/
+#define C64X_PUT_UYVY_16x16 _C64XFUNC(18)
+
+/*
+void c64x_fetch_uyvy(u8 *dst, u8 *src, u32 spitch, u32 height);
+*/
+#define C64X_FETCH_UYVY _C64XFUNC(19)
+
+/*
+void mc_put_o_8 (u8*dst, u32 dstride, u8*ref_src, u8*ignored, u32 rstride, u32 height);
+void mc_put_x_8 (u8*dst, u32 dstride, u8*ref_src, u8*ignored, u32 rstride, u32 height);
+void mc_put_y_8 (u8*dst, u32 dstride, u8*ref_src, u8*ignored, u32 rstride, u32 height);
+void mc_put_xy_8 (u8*dst, u32 dstride, u8*ref_src, u8*ignored, u32 rstride, u32 height);
+*/
+#define C64X_MC_PUT_8(avgX,avgY) _C64XFUNC(32+(avgX)+(avgY)+(avgY))
+
+/*
+void mc_put_o_16 (u8*dst, u32 dstride, u8*ref_src, u8*ignored, u32 rstride, u32 height);
+void mc_put_x_16 (u8*dst, u32 dstride, u8*ref_src, u8*ignored, u32 rstride, u32 height);
+void mc_put_y_16 (u8*dst, u32 dstride, u8*ref_src, u8*ignored, u32 rstride, u32 height);
+void mc_put_xy_16(u8*dst, u32 dstride, u8*ref_src, u8*ignored, u32 rstride, u32 height);
+*/
+#define C64X_MC_PUT_16(avgX,avgY) _C64XFUNC(36+(avgX)+(avgY)+(avgY))
+
+/*
+void mc_avg_o_8 (u8*dst, u32 dstride, u8*ref_src, u8*ref_dst, u32 rstride, u32 height);
+void mc_avg_x_8 (u8*dst, u32 dstride, u8*ref_src, u8*ref_dst, u32 rstride, u32 height);
+void mc_avg_y_8 (u8*dst, u32 dstride, u8*ref_src, u8*ref_dst, u32 rstride, u32 height);
+void mc_avg_xy_8 (u8*dst, u32 dstride, u8*ref_src, u8*ref_dst, u32 rstride, u32 height);
+*/
+#define C64X_MC_AVG_8(avgX,avgY) _C64XFUNC(40+(avgX)+(avgY)+(avgY))
+
+/*
+void mc_avg_o_16 (u8*dst, u32 dstride, u8*ref_src, u8*ref_dst, u32 rstride, u32 height);
+void mc_avg_x_16 (u8*dst, u32 dstride, u8*ref_src, u8*ref_dst, u32 rstride, u32 height);
+void mc_avg_y_16 (u8*dst, u32 dstride, u8*ref_src, u8*ref_dst, u32 rstride, u32 height);
+void mc_avg_xy_16(u8*dst, u32 dstride, u8*ref_src, u8*ref_dst, u32 rstride, u32 height);
+*/
+#define C64X_MC_AVG_16(avgX,avgY) _C64XFUNC(44+(avgX)+(avgY)+(avgY))
+
+
+#endif