[PATCH] sunxi:cedar: unify sun5i and sun4i

148 views
Skip to first unread message

wing...@gmail.com

unread,
Mar 25, 2013, 6:09:01 AM3/25/13
to d...@linux-sunxi.org, Alexsey Shestacov
From: Alexsey Shestacov <wing...@gmail.com>

unify cedarX driver

Note: cedar_avs.c STILL broken don't enable it in menuconfig
---
arch/arm/plat-sunxi/core.c | 6 +-
drivers/media/video/Kconfig | 22 +-
drivers/media/video/Makefile | 7 +-
drivers/media/video/sun4i/Kconfig | 18 -
drivers/media/video/sun4i/Makefile | 5 -
drivers/media/video/sun4i/cache-v7.S | 65 --
drivers/media/video/sun4i/readme | 48 --
drivers/media/video/sun4i/sun4i_avs.c | 427 ------------
drivers/media/video/sun4i/sun4i_cedar.c | 1113 ------------------------------
drivers/media/video/sun4i/sun4i_cedar.h | 133 ----
drivers/media/video/sun5i/Kconfig | 18 -
drivers/media/video/sun5i/Makefile | 4 -
drivers/media/video/sun5i/readme | 48 --
drivers/media/video/sun5i/sun5i_avs.c | 427 ------------
drivers/media/video/sun5i/sun5i_cedar.c | 1119 -------------------------------
drivers/media/video/sun5i/sun5i_cedar.h | 127 ----
drivers/media/video/sunxi/Kconfig | 18 +
drivers/media/video/sunxi/Makefile | 5 +
drivers/media/video/sunxi/cache-v7.S | 65 ++
drivers/media/video/sunxi/readme | 48 ++
drivers/media/video/sunxi/sunxi_avs.c | 426 ++++++++++++
drivers/media/video/sunxi/sunxi_cedar.c | 1113 ++++++++++++++++++++++++++++++
drivers/media/video/sunxi/sunxi_cedar.h | 133 ++++
23 files changed, 1818 insertions(+), 3577 deletions(-)
delete mode 100644 drivers/media/video/sun4i/Kconfig
delete mode 100644 drivers/media/video/sun4i/Makefile
delete mode 100644 drivers/media/video/sun4i/cache-v7.S
delete mode 100644 drivers/media/video/sun4i/readme
delete mode 100644 drivers/media/video/sun4i/sun4i_avs.c
delete mode 100644 drivers/media/video/sun4i/sun4i_cedar.c
delete mode 100644 drivers/media/video/sun4i/sun4i_cedar.h
delete mode 100644 drivers/media/video/sun5i/Kconfig
delete mode 100644 drivers/media/video/sun5i/Makefile
delete mode 100644 drivers/media/video/sun5i/readme
delete mode 100644 drivers/media/video/sun5i/sun5i_avs.c
delete mode 100644 drivers/media/video/sun5i/sun5i_cedar.c
delete mode 100644 drivers/media/video/sun5i/sun5i_cedar.h
create mode 100644 drivers/media/video/sunxi/Kconfig
create mode 100644 drivers/media/video/sunxi/Makefile
create mode 100644 drivers/media/video/sunxi/cache-v7.S
create mode 100644 drivers/media/video/sunxi/readme
create mode 100644 drivers/media/video/sunxi/sunxi_avs.c
create mode 100644 drivers/media/video/sunxi/sunxi_cedar.c
create mode 100644 drivers/media/video/sunxi/sunxi_cedar.h

diff --git a/arch/arm/plat-sunxi/core.c b/arch/arm/plat-sunxi/core.c
index 6dbed2a..b549d30 100644
--- a/arch/arm/plat-sunxi/core.c
+++ b/arch/arm/plat-sunxi/core.c
@@ -253,10 +253,8 @@ static int __init reserve_g2d_param(char *s)
early_param("sunxi_g2d_mem_reserve", reserve_g2d_param);
#endif

-#if defined CONFIG_VIDEO_DECODER_SUN4I || \
- defined CONFIG_VIDEO_DECODER_SUN4I_MODULE || \
- defined CONFIG_VIDEO_DECODER_SUN5I || \
- defined CONFIG_VIDEO_DECODER_SUN5I_MODULE
+#if defined CONFIG_VIDEO_DECODER_SUNXI || \
+ defined CONFIG_VIDEO_DECODER_SUNXI_MODULE
/* The VE block is used by:
*
* - the Cedar video engine, drivers/media/video/sun4i
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index c0c13ab..ace0ad0 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -1233,24 +1233,14 @@ if VIDEO_SUN3I_CEDAR
source "drivers/media/video/sun3i/Kconfig"
endif

-config VIDEO_SUN4I_CEDAR
- tristate "CEDAR driver for sun4i"
- depends on ARCH_SUN4I
+config VIDEO_SUNXI_CEDAR
+ tristate "CEDAR driver for sunxi"
+ depends on ARCH_SUN4I || ARCH_SUN5I
help
- CEDAR driver for sun4i
+ CEDAR driver for sunxi

-if VIDEO_SUN4I_CEDAR
-source "drivers/media/video/sun4i/Kconfig"
-endif
-
-config VIDEO_SUN5I_CEDAR
- tristate "CEDAR driver for sun5i"
- depends on ARCH_SUN5I
- help
- CEDAR driver for sun5i
-
-if VIDEO_SUN5I_CEDAR
-source "drivers/media/video/sun5i/Kconfig"
+if VIDEO_SUNXI_CEDAR
+source "drivers/media/video/sunxi/Kconfig"
endif

menuconfig VIDEO_CSI_SUN4I
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 1776050..0c9fdec 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -214,11 +214,8 @@ ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core
ccflags-y += -I$(srctree)/drivers/media/dvb/frontends
ccflags-y += -I$(srctree)/drivers/media/common/tuners

-ifdef CONFIG_VIDEO_SUN4I_CEDAR
- obj-$(CONFIG_VIDEO_SUN4I_CEDAR) += sun4i/
-endif
-ifdef CONFIG_VIDEO_SUN5I_CEDAR
- obj-$(CONFIG_VIDEO_SUN5I_CEDAR) += sun5i/
+ifdef CONFIG_VIDEO_SUNXI_CEDAR
+ obj-$(CONFIG_VIDEO_SUNXI_CEDAR) += sunxi/
endif

ifdef CONFIG_VIDEO_SUN3I_CEDAR
diff --git a/drivers/media/video/sun4i/Kconfig b/drivers/media/video/sun4i/Kconfig
deleted file mode 100644
index 3c83be5..0000000
--- a/drivers/media/video/sun4i/Kconfig
+++ /dev/null
@@ -1,18 +0,0 @@
-config VIDEO_DECODER_SUN4I
- tristate "sun4i video decoder support"
- depends on VIDEO_SUN4I_CEDAR
- default y
- ---help---
- This is the driver for sun4i video decoder, including h264/
- mpeg4/mpeg2/vc1/rmvb.
- To compile this driver as a module, choose M here: the
- module will be called cedar_dev.
-
-config VIDEO_AVS_COUNTER
- tristate "sun4i av-sync counter support"
- depends on VIDEO_SUN4I_CEDAR
- default n
- ---help---
- This is the driver for sun4i av-sync counter.
- To compile this driver as a module, choose M here: the
- module will be called avs_dev.
diff --git a/drivers/media/video/sun4i/Makefile b/drivers/media/video/sun4i/Makefile
deleted file mode 100644
index 1dc253b..0000000
--- a/drivers/media/video/sun4i/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-# AW16XX Audio Card Support
-obj-$(CONFIG_VIDEO_DECODER_SUN4I) += sun4i_cedar_mod.o
-obj-$(CONFIG_VIDEO_AVS_COUNTER) += sun4i_avs.o
-
-sun4i_cedar_mod-objs := sun4i_cedar.o cache-v7.o
diff --git a/drivers/media/video/sun4i/cache-v7.S b/drivers/media/video/sun4i/cache-v7.S
deleted file mode 100644
index 560ef5a..0000000
--- a/drivers/media/video/sun4i/cache-v7.S
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * drivers/media/video/sun4i/cache-v7.S
- *
- * (C) Copyright 2007-2012
- * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program 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 program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-
-#ifndef __ASSEMBLY__
-#define __ASSEMBLY__
-#endif
-#include <asm/assembler.h>
-/*
- c code declared as follows:
- int flush_clean_user_range(long start, long end);
-*/
- .macro dcache_line_size, reg, tmp
- mrc p15, 1, \tmp, c0, c0, 0 @ read CSIDR
- and \tmp, \tmp, #7 @ cache line size encoding
- mov \reg, #16 @ size offset
- mov \reg, \reg, lsl \tmp @ actual cache line size
- .endm
-
- .text
- .globl flush_clean_user_range
-flush_clean_user_range:
- dcache_line_size r2, r3
- sub r3, r2, #1
- bic r0, r0, r3
-1:
- USER( mcr p15, 0, r0, c7, c14, 1 ) @ clean and flush D line to the point of unification
- add r0, r0, r2
-2:
- cmp r0, r1
- blo 1b
- mov r0, #0
- dsb
- mov pc, lr
-
-/*
- * Fault handling for the cache operation above. If the virtual address in r0
- * isn't mapped, just try the next page.
- */
-9001:
- mov r0, r0, lsr #12
- mov r0, r0, lsl #12
- add r0, r0, #4096
- b 2b
-
-
diff --git a/drivers/media/video/sun4i/readme b/drivers/media/video/sun4i/readme
deleted file mode 100644
index a91b192..0000000
--- a/drivers/media/video/sun4i/readme
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * drivers/media/video/sun4i/readme
- *
- * (C) Copyright 2007-2012
- * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program 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 program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#------------------------------------------------------------
-# Cedar_dev : video engine driver
-#------------------------------------------------------------
-
-#------------------------------------------------------------
-#@version: cedar_vers0_08
-#@Author : Truby.Zong
-#@Date : 2011-4-06
-#@Description:
-# The second version of cedar video engine driver, which
-# add VD/DE SRAM prority and change file name.
-#-------------------------------------------------------------
-#
-#------------------------------------------------------------
-#@version: Vers0_01
-#@Author : Truby.Zong
-#@Date : 2011-3-18
-#@Description:
-# The first version of cedar video engine driver, which
-#handles the irq/clock/phy memory alloc of the cedar device,
-#and also the AV-SYNC counter (AVS_CNT1);
-# Please pay attention to the method to request/remap IO
-#resource and request/free irq, which are just handle once in
-#module init and module exit.
-#-------------------------------------------------------------
-
diff --git a/drivers/media/video/sun4i/sun4i_avs.c b/drivers/media/video/sun4i/sun4i_avs.c
deleted file mode 100644
index d8eff0e..0000000
--- a/drivers/media/video/sun4i/sun4i_avs.c
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
- * drivers/media/video/sun4i/sun4i_avs.c
- *
- * (C) Copyright 2007-2012
- * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program 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 program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * sun4i_avs.c
- * driver for av-sync counter
- * Author : Truby.Zong <truby....@chipsbank.com>
- */
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/ioctl.h>
-#include <linux/fs.h>
-#include <linux/device.h>
-#include <linux/err.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-#include <linux/smp_lock.h>
-#include <linux/preempt.h>
-#include <linux/cdev.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/clk.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <mach/hardware.h>
-#include <asm/system.h>
-#include <linux/rmap.h>
-#include <linux/wait.h>
-#include <linux/poll.h>
-#include <linux/spinlock.h>
-
-#include "sun4i_cedar.h"
-
-#define DRV_VERSION "0.01alpha"
-
-#ifndef AVSDEV_MAJOR
-#define AVSDEV_MAJOR (151)
-#endif
-#ifndef AVSDEV_MINOR
-#define AVSDEV_MINOR (0)
-#endif
-
-#undef _info
-#ifdef CEDAR_DEBUG
-# define _info(fmt, args...) printk( KERN_DEBUG "[avs]: " fmt, ## args)
-#else
-# define _info(fmt, args...)
-#endif
-
-int g_dev_major = AVSDEV_MAJOR;
-int g_dev_minor = AVSDEV_MINOR;
-module_param(g_dev_major, int, S_IRUGO);
-module_param(g_dev_minor, int, S_IRUGO);
-
-struct iomap_resource{
- struct resource *io_sram;
- struct resource *io_ccmu;
- struct resource *io_macc;
- struct resource *io_mpeg;
- struct resource *io_vc1;
- struct resource *io_memc;
-};
-struct iomap_resource iomap_res;
-
-struct iomap_para{
- volatile char* regs_sram;
- volatile char* regs_ccmu;
- volatile char* regs_macc;
- volatile char* regs_mpeg;
- volatile char* regs_vc1;
- volatile char* regs_memc;
-};
-
-struct avs_dev {
- struct cdev cdev; /* char device struct */
- struct device *dev; /* ptr to class device struct */
- struct class *class; /* class for auto create device node */
-
- struct semaphore sem; /* mutual exclusion semaphore */
- spinlock_t lock; /* spinlock to pretect ioctl access */
-
- struct iomap_para iomap_addrs; /* io remap addrs */
- struct iomap_resource iomap_res; /* io remap resources */
-};
-struct avs_dev *avs_devp;
-
-/*
- * ioremap and request iomem
- */
-static void avs_register_iomem(struct avs_dev *devp)
-{
- struct resource *res;
- char *addr;
-
- memset(&devp->iomap_res, 0, sizeof(struct iomap_resource));
- memset(&devp->iomap_addrs, 0, sizeof(struct iomap_para));
-
- /* request mem for ccmu */
- res = request_mem_region(CCMU_REGS_pBASE, 1024, "ccmu");
- if (res == NULL) {
- printk("Cannot reserve region for ccmu\n");
- goto err_out;
- }
- devp->iomap_res.io_ccmu = res;
-
- /* ioremap for ccmu */
- addr = ioremap(CCMU_REGS_pBASE, 4096);
- if (!addr){
- printk("cannot map region for ccmu");
- goto err_out;
- }
- devp->iomap_addrs.regs_ccmu = addr;
-
- return;
-
-err_out:
- if (devp->iomap_addrs.regs_ccmu)
- iounmap(devp->iomap_addrs.regs_ccmu);
-}
-
-/*
- * unmap/release iomem
- */
-static void avs_iomem_unregister(struct avs_dev *devp)
-{
- if (devp->iomap_res.io_ccmu) {
- release_resource(devp->iomap_res.io_ccmu);
- devp->iomap_res.io_ccmu = NULL;
- }
-
- /* iounmap */
- if (devp->iomap_addrs.regs_ccmu) {
- iounmap(devp->iomap_addrs.regs_ccmu);
- devp->iomap_addrs.regs_ccmu = NULL;
- }
-}
-
-/*
- * ioctl function
- * including : wait video engine done,
- * AVS Counter control,
- * Physical memory control,
- * module clock/freq control.
- */
-long avsdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
-{
- long ret;
- unsigned int v;
-
- spinlock_t *lock;
- struct avs_dev *devp;
-
- ret = 0;
- devp = filp->private_data;
- lock = &devp->lock;
-
- switch (cmd)
- {
- case IOCTL_GETVALUE_AVS2:
- spin_lock(lock);
-
- v = readl(devp->iomap_addrs.regs_ccmu + 0xc40);
-
- spin_unlock(lock);
- return v;
-
- case IOCTL_CONFIG_AVS2:
- spin_lock(lock);
-
- v = readl(devp->iomap_addrs.regs_ccmu + 0xc44);
- v = 239<<16 | (v&0xffff);
- writel(v, devp->iomap_addrs.regs_ccmu + 0xc44);
- v = readl(devp->iomap_addrs.regs_ccmu + 0xc38);
- v |= 1<<9 | 1<<1;
- writel(v, devp->iomap_addrs.regs_ccmu + 0xc38);
- writel(0, devp->iomap_addrs.regs_ccmu + 0xc40);
-
- spin_unlock(lock);
- break;
-
- case IOCTL_RESET_AVS2:
- spin_lock(lock);
-
- writel(0, devp->iomap_addrs.regs_ccmu + 0xc40);
-
- spin_unlock(lock);
- break;
-
- case IOCTL_PAUSE_AVS2:
- spin_lock(lock);
-
- v = readl(devp->iomap_addrs.regs_ccmu + 0xc38);
- v |= 1<<9;
- writel(v, devp->iomap_addrs.regs_ccmu + 0xc38);
-
- spin_unlock(lock);
- break;
-
- case IOCTL_START_AVS2:
- spin_lock(lock);
-
- v = readl(devp->iomap_addrs.regs_ccmu + 0xc38);
- v &= ~(1<<9);
- writel(v, devp->iomap_addrs.regs_ccmu + 0xc38);
-
- spin_unlock(lock);
- break;
-
- default:
- break;
- }
-
- return ret;
-}
-
-static int avsdev_open(struct inode *inode, struct file *filp)
-{
- struct avs_dev *devp;
- devp = container_of(inode->i_cdev, struct avs_dev, cdev);
- filp->private_data = devp;
-
- if (down_interruptible(&devp->sem)) {
- return -ERESTARTSYS;
- }
-
- // init other resource here
-
- up(&devp->sem);
-
- nonseekable_open(inode, filp);
- return 0;
-}
-
-static int avsdev_release(struct inode *inode, struct file *filp)
-{
- struct avs_dev *devp;
-
- devp = filp->private_data;
-
- if (down_interruptible(&devp->sem)) {
- return -ERESTARTSYS;
- }
-
- /* release other resource here */
-
- up(&devp->sem);
- return 0;
-}
-
-void avsdev_vma_open(struct vm_area_struct *vma)
-{
- printk(KERN_NOTICE "avsdev VMA open, virt %lx, phys %lx\n",
- vma->vm_start, vma->vm_pgoff << PAGE_SHIFT);
- return;
-}
-
-void avsdev_vma_close(struct vm_area_struct *vma)
-{
- printk(KERN_NOTICE "avsdev VMA close.\n");
- return;
-}
-
-static struct vm_operations_struct avsdev_remap_vm_ops = {
- .open = avsdev_vma_open,
- .close = avsdev_vma_close,
-};
-
-static int avsdev_mmap(struct file *filp, struct vm_area_struct *vma)
-{
- unsigned long temp_pfn;
- unsigned int VAddr;
- struct iomap_para addrs;
-
- unsigned int io_ram = 0;
- VAddr = vma->vm_pgoff << 12;
-
- addrs = avs_devp->iomap_addrs;
-
- if(VAddr == (unsigned int)addrs.regs_ccmu) {
- temp_pfn = CCMU_REGS_pBASE >> 12;
- io_ram = 1;
- } else {
- temp_pfn = (__pa(vma->vm_pgoff << 12))>>12;
- io_ram = 0;
- }
-
- if (io_ram == 0) {
- /* Set reserved and I/O flag for the area. */
- vma->vm_flags |= VM_RESERVED | VM_IO;
-
- /* Select uncached access. */
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-
- if (remap_pfn_range(vma, vma->vm_start, temp_pfn,
- vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
- return -EAGAIN;
- }
- } else {
- /* Set reserved and I/O flag for the area. */
- vma->vm_flags |= VM_RESERVED | VM_IO;
-
- /* Select uncached access. */
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-
- if (io_remap_pfn_range(vma, vma->vm_start, temp_pfn,
- vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
- return -EAGAIN;
- }
- }
-
- vma->vm_ops = &avsdev_remap_vm_ops;
- avsdev_vma_open(vma);
-
- return 0;
-}
-
-static struct file_operations avsdev_fops = {
- .owner = THIS_MODULE,
- .unlocked_ioctl = avsdev_ioctl,
- .mmap = avsdev_mmap,
- .open = avsdev_open,
- .release = avsdev_release,
- .llseek = no_llseek,
-};
-
-static int __init avsdev_init(void)
-{
- int ret;
- int devno;
- dev_t dev = 0;
-
- printk("[tt]----- avs_dev driver load... ----\n");
- if (g_dev_major) {
- dev = MKDEV(g_dev_major, g_dev_minor);
- ret = register_chrdev_region(dev, 1, "avs_dev");
- } else {
- ret = alloc_chrdev_region(&dev, g_dev_minor, 1, "avs_dev");
- g_dev_major = MAJOR(dev);
- g_dev_minor = MINOR(dev);
- }
-
- if (ret < 0) {
- printk(KERN_WARNING "avs_dev: can't get major %d\n", g_dev_major);
- return ret;
- }
-
- avs_devp = kmalloc(sizeof(struct avs_dev), GFP_KERNEL);
- if (avs_devp == NULL) {
- printk("malloc mem for avs device err\n");
- return -ENOMEM;
- }
- memset(avs_devp, 0, sizeof(struct avs_dev));
-
- init_MUTEX(&avs_devp->sem);
-
- /* request resources and ioremap */
- printk("[tt]----- register iomem ----\n");
- avs_register_iomem(avs_devp);
-
- /* init lock for protect ioctl access */
- spin_lock_init(&avs_devp->lock);
-
- devno = MKDEV(g_dev_major, g_dev_minor);
- cdev_init(&avs_devp->cdev, &avsdev_fops);
- avs_devp->cdev.owner = THIS_MODULE;
- avs_devp->cdev.ops = &avsdev_fops;
- ret = cdev_add(&avs_devp->cdev, devno, 1);
- if (ret) {
- printk(KERN_NOTICE "Err:%d add avsdev", ret);
- }
-
- avs_devp->class = class_create(THIS_MODULE, "avs_dev");
- avs_devp->dev = device_create(avs_devp->class, NULL, devno, NULL, "avs_dev");
-
- printk("[tt]--- avs_dev driver load ok!! -----\n");
- return 0;
-}
-module_init(avsdev_init);
-
-static void __exit avsdev_exit(void)
-{
- dev_t dev;
- dev = MKDEV(g_dev_major, g_dev_minor);
-
- /* Unregister iomem and iounmap */
- avs_iomem_unregister(avs_devp);
-
- if (avs_devp) {
- cdev_del(&avs_devp->cdev);
- device_destroy(avs_devp->class, dev);
- class_destroy(avs_devp->class);
- }
-
- unregister_chrdev_region(dev, 1);
-
- if (avs_devp) {
- kfree(avs_devp);
- }
-}
-module_exit(avsdev_exit);
-
-MODULE_AUTHOR("Soft-Allwinner");
-MODULE_DESCRIPTION("avs device driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/media/video/sun4i/sun4i_cedar.c b/drivers/media/video/sun4i/sun4i_cedar.c
deleted file mode 100644
index ab2b396..0000000
--- a/drivers/media/video/sun4i/sun4i_cedar.c
+++ /dev/null
@@ -1,1113 +0,0 @@
-/*
- * drivers\media\video\sun4i\sun4i_cedar.c
- * (C) Copyright 2007-2011
- * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
- * huangxin <huan...@allwinnertech.com>
- *
- * some simple description for this code
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- */
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/ioctl.h>
-#include <linux/fs.h>
-#include <linux/device.h>
-#include <linux/err.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-#include <linux/preempt.h>
-#include <linux/cdev.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/clk.h>
-#include <linux/rmap.h>
-#include <linux/wait.h>
-#include <linux/semaphore.h>
-#include <linux/poll.h>
-#include <linux/spinlock.h>
-#include <linux/sched.h>
-#include <linux/kthread.h>
-#include <linux/delay.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <mach/hardware.h>
-#include <asm/system.h>
-#include <asm/siginfo.h>
-#include <asm/signal.h>
-#include <mach/system.h>
-#include <mach/clock.h>
-#include "sun4i_cedar.h"
-
-#define DRV_VERSION "0.01alpha"
-
-#define CHIP_VERSION_F23
-
-#undef USE_CEDAR_ENGINE
-
-#ifndef CEDARDEV_MAJOR
-#define CEDARDEV_MAJOR (150)
-#endif
-#ifndef CEDARDEV_MINOR
-#define CEDARDEV_MINOR (0)
-#endif
-
-//#define CEDAR_DEBUG
-
-#define CONFIG_SW_SYSMEM_RESERVED_BASE 0x43000000
-#define CONFIG_SW_SYSMEM_RESERVED_SIZE 75776
-
-int g_dev_major = CEDARDEV_MAJOR;
-int g_dev_minor = CEDARDEV_MINOR;
-module_param(g_dev_major, int, S_IRUGO);//S_IRUGO represent that g_dev_major can be read,but canot be write
-module_param(g_dev_minor, int, S_IRUGO);
-
-#ifdef CHIP_VERSION_F23
-#define VE_IRQ_NO (53)
-#else
-#define VE_IRQ_NO (48)
-#endif
-
-struct clk *ve_moduleclk = NULL;
-struct clk *ve_pll4clk = NULL;
-struct clk *ahb_veclk = NULL;
-struct clk *dram_veclk = NULL;
-struct clk *avs_moduleclk = NULL;
-struct clk *hosc_clk = NULL;
-
-static unsigned long pll4clk_rate = 720000000;
-
-extern unsigned long ve_start;
-extern unsigned long ve_size;
-extern int flush_clean_user_range(long start, long end);
-struct iomap_para{
- volatile char* regs_macc;
- #ifdef CHIP_VERSION_F23
- volatile char* regs_avs;
- #else
- volatile char* regs_ccmu;
- #endif
-};
-
-static DECLARE_WAIT_QUEUE_HEAD(wait_ve);
-struct cedar_dev {
- struct cdev cdev; /* char device struct */
- struct device *dev; /* ptr to class device struct */
- struct class *class; /* class for auto create device node */
-
- struct semaphore sem; /* mutual exclusion semaphore */
-
- wait_queue_head_t wq; /* wait queue for poll ops */
-
- struct iomap_para iomap_addrs; /* io remap addrs */
-
- struct timer_list cedar_engine_timer;
- struct timer_list cedar_engine_timer_rel;
-
- u32 irq; /* cedar video engine irq number */
- u32 irq_flag; /* flag of video engine irq generated */
- u32 irq_value; /* value of video engine irq */
- u32 irq_has_enable;
- u32 ref_count;
-};
-struct cedar_dev *cedar_devp;
-
-u32 int_sta=0,int_value;
-
-/*
- * Video engine interrupt service routine
- * To wake up ve wait queue
- */
-static irqreturn_t VideoEngineInterupt(int irq, void *dev)
-{
- unsigned int ve_int_ctrl_reg;
- volatile int val;
- int modual_sel;
- struct iomap_para addrs = cedar_devp->iomap_addrs;
-
- modual_sel = readl(addrs.regs_macc + 0);
- modual_sel &= 0xf;
-
- /* estimate Which video format */
- switch (modual_sel)
- {
- case 0: //mpeg124
- ve_int_ctrl_reg = (unsigned int)(addrs.regs_macc + 0x100 + 0x14);
- break;
- case 1: //h264
- ve_int_ctrl_reg = (unsigned int)(addrs.regs_macc + 0x200 + 0x20);
- break;
- case 2: //vc1
- ve_int_ctrl_reg = (unsigned int)(addrs.regs_macc + 0x300 + 0x24);
- break;
- case 3: //rmvb
- ve_int_ctrl_reg = (unsigned int)(addrs.regs_macc + 0x400 + 0x14);
- break;
- case 0xa: //isp
- ve_int_ctrl_reg = (unsigned int)(addrs.regs_macc + 0xa00 + 0x08);
- break;
- case 0xb: //avc enc
- ve_int_ctrl_reg = (unsigned int)(addrs.regs_macc + 0xb00 + 0x14);
- break;
- default:
- ve_int_ctrl_reg = (unsigned int)(addrs.regs_macc + 0x100 + 0x14);
- printk("macc modual sel not defined!\n");
- break;
- }
-
- //disable interrupt
- if(modual_sel == 0) {
- val = readl(ve_int_ctrl_reg);
- writel(val & (~0x7c), ve_int_ctrl_reg);
- } else {
- val = readl(ve_int_ctrl_reg);
- writel(val & (~0xf), ve_int_ctrl_reg);
- }
-
- cedar_devp->irq_value = 1; //hx modify 2011-8-1 16:08:47
- cedar_devp->irq_flag = 1;
- //any interrupt will wake up wait queue
- wake_up_interruptible(&wait_ve); //ioctl
-
- return IRQ_HANDLED;
-}
-
-/*
- * poll operateion for wait for ve irq
- */
-unsigned int cedardev_poll(struct file *filp, struct poll_table_struct *wait)
-{
- int mask = 0;
- struct cedar_dev *devp = filp->private_data;
-
- poll_wait(filp, &devp->wq, wait);
- if (devp->irq_flag == 1) {
- devp->irq_flag = 0;
- mask |= POLLIN | POLLRDNORM;
- }
- return mask;
-}
-
-static int clk_status = 0;
-static LIST_HEAD(run_task_list);
-static LIST_HEAD(del_task_list);
-static spinlock_t cedar_spin_lock;
-#define CEDAR_RUN_LIST_NONULL -1
-#define CEDAR_NONBLOCK_TASK 0 //非阻塞
-#define CEDAR_BLOCK_TASK 1
-#define CLK_REL_TIME 10000 //10秒
-#define TIMER_CIRCLE 50 //50毫秒
-#define TASK_INIT 0x00
-#define TASK_TIMEOUT 0x55
-#define TASK_RELEASE 0xaa
-#define SIG_CEDAR 35
-
-int enable_cedar_hw_clk(void)
-{
- unsigned long flags;
- int res = -EFAULT;
-
- spin_lock_irqsave(&cedar_spin_lock, flags);
-
- if (clk_status == 1)
- goto out;
- clk_status = 1;
-
- if(0 != clk_enable(ahb_veclk)){
- printk("ahb_veclk failed; \n");
- goto out;
- }
- if(0 != clk_enable(ve_moduleclk)){
- printk("ve_moduleclk failed; \n");
- goto out3;
- }
- if(0 != clk_enable(dram_veclk)){
- printk("dram_veclk failed; \n");
- goto out2;
- }
- if(0 != clk_enable(avs_moduleclk)){
- printk("ve_moduleclk failed; \n");
- goto out1;
- }
- #ifdef CEDAR_DEBUG
- printk("%s,%d\n",__func__,__LINE__);
- #endif
- res = 0;
- goto out;
-
-out1:
- clk_disable(dram_veclk);
-out2:
- clk_disable(ve_moduleclk);
-out3:
- clk_disable(ahb_veclk);
-out:
- spin_unlock_irqrestore(&cedar_spin_lock, flags);
- return res;
-}
-
-int disable_cedar_hw_clk(void)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&cedar_spin_lock, flags);
-
- if (clk_status == 0)
- goto out;
- clk_status = 0;
-
- clk_disable(dram_veclk);
- clk_disable(ve_moduleclk);
- clk_disable(ahb_veclk);
- clk_disable(avs_moduleclk);
- #ifdef CEDAR_DEBUG
- printk("%s,%d\n",__func__,__LINE__);
- #endif
-out:
- spin_unlock_irqrestore(&cedar_spin_lock, flags);
- return 0;
-}
-
-void cedardev_insert_task(struct cedarv_engine_task* new_task)
-{
- struct cedarv_engine_task *task_entry;
- unsigned long flags;
-
- spin_lock_irqsave(&cedar_spin_lock, flags);
-
- if(list_empty(&run_task_list))
- new_task->is_first_task = 1;
-
- /*遍历run_task_list链表,如果插入的任务优先级比链表节点中的任务优先级高,并且当前插入任务不是第一个插入的任务。
- *那么就将优先级高的任务放于前面,队列中的任务采取从高到底的优先级队列排队。
- */
- list_for_each_entry(task_entry, &run_task_list, list) {
- if ((task_entry->is_first_task == 0) && (task_entry->running == 0) && (task_entry->t.task_prio < new_task->t.task_prio)) {
- break;
- }
- }
-
- list_add(&new_task->list, task_entry->list.prev);
-
- #ifdef CEDAR_DEBUG
- printk("%s,%d, TASK_ID:",__func__,__LINE__);
- list_for_each_entry(task_entry, &run_task_list, list) {
- printk("%d!", task_entry->t.ID);
- }
- printk("\n");
- #endif
- /*每次插入一个任务,就将当前的计时器时间重置为系统当前的jiffies*/
- mod_timer(&cedar_devp->cedar_engine_timer, jiffies + 0);
-
- spin_unlock_irqrestore(&cedar_spin_lock, flags);
-}
-
-int cedardev_del_task(int task_id)
-{
- struct cedarv_engine_task *task_entry;
- unsigned long flags;
-
- spin_lock_irqsave(&cedar_spin_lock, flags);
-
- /*遍历run_task_list链表
- *如果找到对应的id号,那么就将run_task_list链表中的任务移到del_task_list链表的表头。
- */
- list_for_each_entry(task_entry, &run_task_list, list) {
- if (task_entry->t.ID == task_id && task_entry->status != TASK_RELEASE) {
- task_entry->status = TASK_RELEASE;
-
- spin_unlock_irqrestore(&cedar_spin_lock, flags);
- mod_timer(&cedar_devp->cedar_engine_timer, jiffies + 0);
- return 0;
- }
- }
- spin_unlock_irqrestore(&cedar_spin_lock, flags);
-
- //找不到对应 ID
- return -1;
-}
-
-int cedardev_check_delay(int check_prio)
-{
- struct cedarv_engine_task *task_entry;
- int timeout_total = 0;
- unsigned long flags;
-
- /*获取总的等待时间*/
- spin_lock_irqsave(&cedar_spin_lock, flags);
- list_for_each_entry(task_entry, &run_task_list, list) {
- if ((task_entry->t.task_prio >= check_prio) || (task_entry->running == 1) || (task_entry->is_first_task == 1))
- timeout_total = timeout_total + task_entry->t.frametime;
- }
-
- spin_unlock_irqrestore(&cedar_spin_lock, flags);
-#ifdef CEDAR_DEBUG
- printk("%s,%d,%d\n", __func__, __LINE__, timeout_total);
-#endif
- return timeout_total;
-}
-
-static void cedar_engine_for_timer_rel(unsigned long arg)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&cedar_spin_lock, flags);
-
- if(list_empty(&run_task_list)){
- disable_cedar_hw_clk();
- } else {
- printk("Warring: cedar engine timeout for clk disable, but task left, something wrong?\n");
- mod_timer( &cedar_devp->cedar_engine_timer, jiffies + msecs_to_jiffies(TIMER_CIRCLE));
- }
-
- spin_unlock_irqrestore(&cedar_spin_lock, flags);
-}
-
-static void cedar_engine_for_events(unsigned long arg)
-{
- struct cedarv_engine_task *task_entry, *task_entry_tmp;
- struct siginfo info;
- unsigned long flags;
-
- spin_lock_irqsave(&cedar_spin_lock, flags);
-
- list_for_each_entry_safe(task_entry, task_entry_tmp, &run_task_list, list) {
- mod_timer(&cedar_devp->cedar_engine_timer_rel, jiffies + msecs_to_jiffies(CLK_REL_TIME));
- if (task_entry->status == TASK_RELEASE ||
- time_after(jiffies, task_entry->t.timeout)) {
- if (task_entry->status == TASK_INIT)
- task_entry->status = TASK_TIMEOUT;
- list_move(&task_entry->list, &del_task_list);
- }
- }
-
- list_for_each_entry_safe(task_entry, task_entry_tmp, &del_task_list, list) {
- info.si_signo = SIG_CEDAR;
- info.si_code = task_entry->t.ID;
- if (task_entry->status == TASK_TIMEOUT){//表示任务timeout删除
- info.si_errno = TASK_TIMEOUT;
- send_sig_info(SIG_CEDAR, &info, task_entry->task_handle);
- }else if(task_entry->status == TASK_RELEASE){//表示任务正常运行完毕删除
- info.si_errno = TASK_RELEASE;
- send_sig_info(SIG_CEDAR, &info, task_entry->task_handle);
- }
- list_del(&task_entry->list);
- kfree(task_entry);
- }
-
- /*激活链表中的task*/
- if(!list_empty(&run_task_list)){
- task_entry = list_entry(run_task_list.next, struct cedarv_engine_task, list);
- if(task_entry->running == 0){
- task_entry->running = 1;
- info.si_signo = SIG_CEDAR;
- info.si_code = task_entry->t.ID;
- info.si_errno = TASK_INIT; //任务已经启动
- send_sig_info(SIG_CEDAR, &info, task_entry->task_handle);
- }
-
- mod_timer( &cedar_devp->cedar_engine_timer, jiffies + msecs_to_jiffies(TIMER_CIRCLE));
- }
-
- spin_unlock_irqrestore(&cedar_spin_lock, flags);
-}
-
-#ifdef CHIP_VERSION_F23
-static unsigned int g_ctx_reg0;
-static void save_context(void)
-{
- g_ctx_reg0 = readl(0xf1c20e00);
-}
-
-static void restore_context(void)
-{
- writel(g_ctx_reg0, 0xf1c20e00);
-}
-#else
- #define save_context()
- #define restore_context()
-#endif
-
-#ifdef CHIP_VERSION_F23
-short VEPLLTable[][6] =
-{
- //set, actual, Nb, Kb, Mb, Pb
- { 60, 60, 5, 2, 2, 1},
- { 90, 90, 5, 2, 0, 2},
- {120, 120, 5, 2, 2, 0},
- {150, 150, 25, 0, 0, 2},
- {180, 180, 5, 2, 0, 1},
- {216, 216, 6, 2, 0, 1},
- {240, 240, 5, 3, 0, 1},
- {270, 270, 15, 2, 0, 2},
- {300, 300, 25, 0, 0, 1},
- {330, 336, 7, 1, 0, 0},
- {360, 360, 5, 2, 0, 0},
- {384, 384, 4, 3, 0, 0},
- {402, 400, 25, 1, 2, 0},
- {420, 416, 13, 3, 2, 0},
- {444, 448, 14, 3, 2, 0},
- {456, 456, 19, 0, 0, 0},
- {468, 468, 13, 2, 0, 1},
- {480, 480, 5, 3, 0, 0},
- {492, 496, 31, 1, 2, 0},
-};
-#endif
-
-/*
- * ioctl function
- * including : wait video engine done,
- * AVS Counter control,
- * Physical memory control,
- * module clock/freq control.
- * cedar engine
- */
-long cedardev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
-{
- long ret = 0;
- unsigned int v;
- int ve_timeout = 0;
- struct cedar_dev *devp;
-#ifdef USE_CEDAR_ENGINE
- int rel_taskid = 0;
- struct __cedarv_task task_ret;
- struct cedarv_engine_task *task_ptr = NULL;
-#endif
- unsigned long flags;
-
- devp = filp->private_data;
-
- switch (cmd)
- {
- case IOCTL_ENGINE_REQ:
- #ifdef USE_CEDAR_ENGINE
- if(copy_from_user(&task_ret, (void __user*)arg, sizeof(struct __cedarv_task))){
- printk("IOCTL_ENGINE_REQ copy_from_user fail\n");
- return -EFAULT;
- }
- spin_lock_irqsave(&cedar_spin_lock, flags);
- /*如果task为非阻塞状态,请求者可以立即返回*/
- if(!list_empty(&run_task_list) && ( task_ret.block_mode == CEDAR_NONBLOCK_TASK)){
- spin_unlock_irqrestore(&cedar_spin_lock, flags);
- return CEDAR_RUN_LIST_NONULL; //run_task_list里面有任务,返回-1
- }
- spin_unlock_irqrestore(&cedar_spin_lock, flags);
-
- /*如果task为阻塞状态,将task插入run_task_list链表中*/
- task_ptr = kmalloc(sizeof(struct cedarv_engine_task), GFP_KERNEL);
- if(!task_ptr){
- printk("get mem for IOCTL_ENGINE_REQ\n");
- return PTR_ERR(task_ptr);
- }
- task_ptr->task_handle = current;
- task_ptr->t.ID = task_ret.ID;
- task_ptr->t.timeout = jiffies + msecs_to_jiffies(1000*task_ret.timeout);//ms to jiffies
- task_ptr->t.frametime = task_ret.frametime;
- task_ptr->t.task_prio = task_ret.task_prio;
- task_ptr->running = 0;
- task_ptr->is_first_task = 0;
- task_ptr->status = TASK_INIT;
-
- cedardev_insert_task(task_ptr);
-
- enable_cedar_hw_clk();
-
- return task_ptr->is_first_task;//插入run_task_list链表中的任务是第一个任务,返回1,不是第一个任务返回0. hx modify 2011-7-28 16:59:16!!!
- #else
- enable_cedar_hw_clk();
- cedar_devp->ref_count++;
- break;
- #endif
- case IOCTL_ENGINE_REL:
- #ifdef USE_CEDAR_ENGINE
- rel_taskid = (int)arg;
- /*
- * 利用任务的id号进行任务的删除操作。返回值意义:找不到对应ID,返回-1;找到对应ID,返回0。
- */
- ret = cedardev_del_task(rel_taskid);
- #else
- disable_cedar_hw_clk();
- cedar_devp->ref_count--;
- #endif
- return ret;
- case IOCTL_ENGINE_CHECK_DELAY:
- {
- struct cedarv_engine_task_info task_info;
- /*从用户空间中获取要查询的任务优先级,通过任务优先级,统计需要等待的总时间total_time.
- * 在这个接口中,同时也给用户传递了当前任务的frametime(这样做可以减少接口,但是用户空间要多设置一个空的frametime值)
- *对于当前task的frametime,也可以用额外的接口获取,但是这样做,frametime和total_time就处于不同接口中。好处???
- */
- if(copy_from_user(&task_info, (void __user*)arg, sizeof(struct cedarv_engine_task_info))){
- printk("IOCTL_ENGINE_CHECK_DELAY copy_from_user fail\n");
- return -EFAULT;
- }
- task_info.total_time = cedardev_check_delay(task_info.task_prio);//task_info.task_prio是传递过来的优先级
- #ifdef CEDAR_DEBUG
- printk("%s,%d,%d\n", __func__, __LINE__, task_info.total_time);
- #endif
- task_info.frametime = 0;
- spin_lock_irqsave(&cedar_spin_lock, flags);
- if(!list_empty(&run_task_list)){
- /*获取run_task_list链表中的第一个任务,也就是当前运行的任务,通过当前运行的任务获取frametime时间*/
- struct cedarv_engine_task *task_entry;
- #ifdef CEDAR_DEBUG
- printk("%s,%d\n",__func__,__LINE__);
- #endif
- task_entry = list_entry(run_task_list.next, struct cedarv_engine_task, list);
- if(task_entry->running == 1)
- task_info.frametime = task_entry->t.frametime;
- #ifdef CEDAR_DEBUG
- printk("%s,%d,%d\n",__func__,__LINE__,task_info.frametime);
- #endif
- }
- spin_unlock_irqrestore(&cedar_spin_lock, flags);
- /*
- *将任务优先级,total_time,frametime拷贝到用户空间。任务优先级还是用户设置的值,total_time是需要等待的总时间,
- *frametime是当前任务的运行时间.其实当前任务的信息最好用另一个接口实现.减少耦合度和接口的拓展性.
- */
- if (copy_to_user((void *)arg, &task_info, sizeof(struct cedarv_engine_task_info))){
- printk("IOCTL_ENGINE_CHECK_DELAY copy_to_user fail\n");
- return -EFAULT;
- }
- }
- break;
- case IOCTL_WAIT_VE:
- //wait_event_interruptible(wait_ve, cedar_devp->irq_flag);
- ve_timeout = (int)arg;
- cedar_devp->irq_value = 0;
-
- spin_lock_irqsave(&cedar_spin_lock, flags);
- if(cedar_devp->irq_flag)
- cedar_devp->irq_value = 1;
- spin_unlock_irqrestore(&cedar_spin_lock, flags);
-
- wait_event_interruptible_timeout(wait_ve, cedar_devp->irq_flag, ve_timeout*HZ);
- //printk("%s,%d,ve_timeout:%d,cedar_devp->irq_value:%d\n", __func__, __LINE__, ve_timeout, cedar_devp->irq_value);
- cedar_devp->irq_flag = 0;
- /*返回1,表示中断返回,返回0,表示timeout返回*/
- return cedar_devp->irq_value;
-
- case IOCTL_ENABLE_VE:
- clk_enable(ve_moduleclk);
- break;
-
- case IOCTL_DISABLE_VE:
- clk_disable(ve_moduleclk);
- break;
-
- case IOCTL_RESET_VE:
- clk_disable(dram_veclk);
- clk_reset(ve_moduleclk, 1);
- clk_reset(ve_moduleclk, 0);
- clk_enable(dram_veclk);
- break;
-
- case IOCTL_SET_VE_FREQ:
- {
- int arg_rate = (int)arg;
- if(arg_rate >= 320){
- clk_set_rate(ve_moduleclk, pll4clk_rate/3);//ve_moduleclk rate is 320khz
- }else if((arg_rate >= 240) && (arg_rate < 320)){
- clk_set_rate(ve_moduleclk, pll4clk_rate/4);//ve_moduleclk rate is 240khz
- }else if((arg_rate >= 160) && (arg_rate < 240)){
- clk_set_rate(ve_moduleclk, pll4clk_rate/6);//ve_moduleclk rate is 160khz
- }else{
- printk("IOCTL_SET_VE_FREQ set ve freq error,%s,%d\n", __func__, __LINE__);
- }
- break;
- }
- case IOCTL_GETVALUE_AVS2:
- /* Return AVS1 counter value */
- return readl(cedar_devp->iomap_addrs.regs_avs + 0x88);
-
- case IOCTL_ADJUST_AVS2:
- {
- int arg_s = (int)arg;
- int temp;
- if(MAGIC_VER_A == sw_get_ic_ver()){
- save_context();
- v = readl(cedar_devp->iomap_addrs.regs_avs + 0x8c);
- temp = v & 0xffff0000;
- temp =temp + temp*arg_s/100;
- temp = temp > (244<<16) ? (244<<16) : temp;
- temp = temp < (234<<16) ? (234<<16) : temp;
- v = (temp & 0xffff0000) | (v&0x0000ffff);
- #ifdef CEDAR_DEBUG
- printk("Kernel AVS ADJUST Print: 0x%x\n", v);
- #endif
- writel(v, cedar_devp->iomap_addrs.regs_avs + 0x8c);
- restore_context();
- }else if(MAGIC_VER_B == sw_get_ic_ver() || MAGIC_VER_C == sw_get_ic_ver()){
- v = readl(cedar_devp->iomap_addrs.regs_avs + 0x8c);
- temp = v & 0xffff0000;
- temp =temp + temp*arg_s/100;
- temp = temp > (244<<16) ? (244<<16) : temp;
- temp = temp < (234<<16) ? (234<<16) : temp;
- v = (temp & 0xffff0000) | (v&0x0000ffff);
- #ifdef CEDAR_DEBUG
- printk("Kernel AVS ADJUST Print: 0x%x\n", v);
- #endif
- writel(v, cedar_devp->iomap_addrs.regs_avs + 0x8c);
- }else{
- printk("IOCTL_ADJUST_AVS2 error:%s,%d\n", __func__, __LINE__);
- return -EFAULT;
- }
- break;
- }
-
- case IOCTL_ADJUST_AVS2_ABS:
- {
- int arg_s = (int)arg;
- int v_dst;
-
- switch(arg_s){
- case -2:
- v_dst = 234;
- break;
- case -1:
- v_dst = 236;
- break;
- case 1:
- v_dst = 242;
- break;
- case 2:
- v_dst = 244;
- break;
- default:
- v_dst = 239;
- break;
- }
-
- if(MAGIC_VER_A == sw_get_ic_ver()){
- save_context();
- v = readl(cedar_devp->iomap_addrs.regs_avs + 0x8c);
- v = (v_dst<<16) | (v&0x0000ffff);
- writel(v, cedar_devp->iomap_addrs.regs_avs + 0x8c);
- restore_context();
- }else if(MAGIC_VER_B == sw_get_ic_ver() || MAGIC_VER_C == sw_get_ic_ver()){
- v = readl(cedar_devp->iomap_addrs.regs_avs + 0x8c);
- v = (v_dst<<16) | (v&0x0000ffff);
- writel(v, cedar_devp->iomap_addrs.regs_avs + 0x8c);
- }else{
- printk("IOCTL_ADJUST_AVS2 error:%s,%d\n", __func__, __LINE__);
- return -EFAULT;
- }
- break;
- }
-
- case IOCTL_CONFIG_AVS2:
- if(MAGIC_VER_A == sw_get_ic_ver()){
- save_context();
- /* Set AVS counter divisor */
- v = readl(cedar_devp->iomap_addrs.regs_avs + 0x8c);
- v = 239 << 16 | (v & 0xffff);
- writel(v, cedar_devp->iomap_addrs.regs_avs + 0x8c);
-
- /* Enable AVS_CNT1 and Pause it */
- v = readl(cedar_devp->iomap_addrs.regs_avs + 0x80);
- v |= 1 << 9 | 1 << 1;
- writel(v, cedar_devp->iomap_addrs.regs_avs + 0x80);
-
- /* Set AVS_CNT1 init value as zero */
- writel(0, cedar_devp->iomap_addrs.regs_avs + 0x88);
- restore_context();
- }else if(MAGIC_VER_B == sw_get_ic_ver() || MAGIC_VER_C == sw_get_ic_ver()){
- /* Set AVS counter divisor */
- v = readl(cedar_devp->iomap_addrs.regs_avs + 0x8c);
- v = 239 << 16 | (v & 0xffff);
- writel(v, cedar_devp->iomap_addrs.regs_avs + 0x8c);
-
- /* Enable AVS_CNT1 and Pause it */
- v = readl(cedar_devp->iomap_addrs.regs_avs + 0x80);
- v |= 1 << 9 | 1 << 1;
- writel(v, cedar_devp->iomap_addrs.regs_avs + 0x80);
-
- /* Set AVS_CNT1 init value as zero */
- writel(0, cedar_devp->iomap_addrs.regs_avs + 0x88);
- }else{
- printk("IOCTL_CONFIG_AVS2 error:%s,%d\n", __func__, __LINE__);
- return -EFAULT;
- }
- break;
-
- case IOCTL_RESET_AVS2:
- /* Set AVS_CNT1 init value as zero */
- if(MAGIC_VER_A == sw_get_ic_ver()){
- save_context();
- writel(0, cedar_devp->iomap_addrs.regs_avs + 0x88);
- restore_context();
- }else if(MAGIC_VER_B == sw_get_ic_ver() || MAGIC_VER_C == sw_get_ic_ver()){
- writel(0, cedar_devp->iomap_addrs.regs_avs + 0x88);
- }else{
- printk("IOCTL_RESET_AVS2 error:%s,%d\n", __func__, __LINE__);
- return -EFAULT;
- }
- break;
-
- case IOCTL_PAUSE_AVS2:
- /* Pause AVS_CNT1 */
- if(MAGIC_VER_A == sw_get_ic_ver()){
- save_context();
- v = readl(cedar_devp->iomap_addrs.regs_avs + 0x80);
- v |= 1 << 9;
- writel(v, cedar_devp->iomap_addrs.regs_avs + 0x80);
- restore_context();
- }else if(MAGIC_VER_B == sw_get_ic_ver() || MAGIC_VER_C == sw_get_ic_ver()){
- v = readl(cedar_devp->iomap_addrs.regs_avs + 0x80);
- v |= 1 << 9;
- writel(v, cedar_devp->iomap_addrs.regs_avs + 0x80);
- }else{
- printk("IOCTL_PAUSE_AVS2 get error:%s,%d\n", __func__, __LINE__);
- return -EFAULT;
- }
- break;
-
- case IOCTL_START_AVS2:
- /* Start AVS_CNT1 : do not pause */
- if(MAGIC_VER_A == sw_get_ic_ver()){
- save_context();
- v = readl(cedar_devp->iomap_addrs.regs_avs + 0x80);
- v &= ~(1 << 9);
- writel(v, cedar_devp->iomap_addrs.regs_avs + 0x80);
- restore_context();
- }else if(MAGIC_VER_B == sw_get_ic_ver() || MAGIC_VER_C == sw_get_ic_ver()){
- v = readl(cedar_devp->iomap_addrs.regs_avs + 0x80);
- v &= ~(1 << 9);
- writel(v, cedar_devp->iomap_addrs.regs_avs + 0x80);
- }else{
- printk("IOCTL_START_AVS2 error:%s,%d\n", __func__, __LINE__);
- return -EFAULT;
- }
- break;
-
- case IOCTL_GET_ENV_INFO:
- {
- struct cedarv_env_infomation env_info;
- env_info.phymem_start = (unsigned int)phys_to_virt(ve_start);
- env_info.phymem_total_size = ve_size;
- env_info.address_macc = (unsigned int)cedar_devp->iomap_addrs.regs_macc;
- if (copy_to_user((char *)arg, &env_info, sizeof(struct cedarv_env_infomation)))
- return -EFAULT;
- }
- break;
- case IOCTL_GET_IC_VER:
- {
- if(MAGIC_VER_A == sw_get_ic_ver()){
- return 0x0A10000A;
- }else if(MAGIC_VER_B == sw_get_ic_ver() || MAGIC_VER_C == sw_get_ic_ver()){
- return 0x0A10000B;
- }else{
- printk("IC_VER get error:%s,%d\n", __func__, __LINE__);
- return -EFAULT;
- }
- }
- case IOCTL_FLUSH_CACHE:
- {
- struct cedarv_cache_range cache_range;
- if(copy_from_user(&cache_range, (void __user*)arg, sizeof(struct cedarv_cache_range))){
- printk("IOCTL_FLUSH_CACHE copy_from_user fail\n");
- return -EFAULT;
- }
- flush_clean_user_range(cache_range.start, cache_range.end);
- }
- break;
- default:
- break;
- }
- return ret;
-}
-
-static int cedardev_open(struct inode *inode, struct file *filp)
-{
- struct cedar_dev *devp;
- devp = container_of(inode->i_cdev, struct cedar_dev, cdev);
- filp->private_data = devp;
- if (down_interruptible(&devp->sem)) {
- return -ERESTARTSYS;
- }
- /* init other resource here */
- devp->irq_flag = 0;
- up(&devp->sem);
- nonseekable_open(inode, filp);
- return 0;
-}
-
-static int cedardev_release(struct inode *inode, struct file *filp)
-{
- struct cedar_dev *devp;
-
- devp = filp->private_data;
- if (down_interruptible(&devp->sem)) {
- return -ERESTARTSYS;
- }
- /* release other resource here */
- devp->irq_flag = 1;
- up(&devp->sem);
- return 0;
-}
-
-void cedardev_vma_open(struct vm_area_struct *vma)
-{
-}
-
-void cedardev_vma_close(struct vm_area_struct *vma)
-{
-}
-
-static struct vm_operations_struct cedardev_remap_vm_ops = {
- .open = cedardev_vma_open,
- .close = cedardev_vma_close,
-};
-
-static int cedardev_mmap(struct file *filp, struct vm_area_struct *vma)
-{
- unsigned long temp_pfn;
- unsigned int VAddr;
- struct iomap_para addrs;
-
- unsigned int io_ram = 0;
- VAddr = vma->vm_pgoff << 12;
- addrs = cedar_devp->iomap_addrs;
-
- if (VAddr == (unsigned int)addrs.regs_macc) {
- temp_pfn = MACC_REGS_BASE >> 12;
- io_ram = 1;
- } else {
- temp_pfn = (__pa(vma->vm_pgoff << 12))>>12;
- io_ram = 0;
- }
-
- if (io_ram == 0) {
- /* Set reserved and I/O flag for the area. */
- vma->vm_flags |= VM_RESERVED | VM_IO;
-
- /* Select uncached access. */
- //vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-
- if (remap_pfn_range(vma, vma->vm_start, temp_pfn,
- vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
- return -EAGAIN;
- }
- } else {
- /* Set reserved and I/O flag for the area. */
- vma->vm_flags |= VM_RESERVED | VM_IO;
- /* Select uncached access. */
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-
- if (io_remap_pfn_range(vma, vma->vm_start, temp_pfn,
- vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
- return -EAGAIN;
- }
- }
-
- vma->vm_ops = &cedardev_remap_vm_ops;
- cedardev_vma_open(vma);
-
- return 0;
-}
-
-static int snd_sw_cedar_suspend(struct platform_device *pdev,pm_message_t state)
-{
- disable_cedar_hw_clk();
-
- return 0;
-}
-
-static int snd_sw_cedar_resume(struct platform_device *pdev)
-{
- if(cedar_devp->ref_count == 0){
- return 0;
- }
- enable_cedar_hw_clk();
-
- return 0;
-}
-
-static struct file_operations cedardev_fops = {
- .owner = THIS_MODULE,
- .mmap = cedardev_mmap,
- .poll = cedardev_poll,
- .open = cedardev_open,
- .release = cedardev_release,
- .llseek = no_llseek,
- .unlocked_ioctl = cedardev_ioctl,
-};
-
-/*data relating*/
-static struct platform_device sw_device_cedar = {
- .name = "sun4i-cedar",
-};
-
-/*method relating*/
-static struct platform_driver sw_cedar_driver = {
-#ifdef CONFIG_PM
- .suspend = snd_sw_cedar_suspend,
- .resume = snd_sw_cedar_resume,
-#endif
- .driver = {
- .name = "sun4i-cedar",
- },
-};
-
-static int __init cedardev_init(void)
-{
- int ret = 0;
- int err = 0;
- int devno;
- unsigned int val;
- dev_t dev = 0;
-
- if (ve_size == 0)
- return -ENODEV;
-
- printk("[cedar dev]: install start!!!\n");
- if((platform_device_register(&sw_device_cedar))<0)
- return err;
-
- if ((err = platform_driver_register(&sw_cedar_driver)) < 0)
- return err;
- /*register or alloc the device number.*/
- if (g_dev_major) {
- dev = MKDEV(g_dev_major, g_dev_minor);
- ret = register_chrdev_region(dev, 1, "cedar_dev");
- } else {
- ret = alloc_chrdev_region(&dev, g_dev_minor, 1, "cedar_dev");
- g_dev_major = MAJOR(dev);
- g_dev_minor = MINOR(dev);
- }
-
- if (ret < 0) {
- printk(KERN_WARNING "cedar_dev: can't get major %d\n", g_dev_major);
- return ret;
- }
- spin_lock_init(&cedar_spin_lock);
- cedar_devp = kmalloc(sizeof(struct cedar_dev), GFP_KERNEL);
- if (cedar_devp == NULL) {
- printk("malloc mem for cedar device err\n");
- return -ENOMEM;
- }
- memset(cedar_devp, 0, sizeof(struct cedar_dev));
- cedar_devp->irq = VE_IRQ_NO;
-
- sema_init(&cedar_devp->sem, 1);
- init_waitqueue_head(&cedar_devp->wq);
-
- memset(&cedar_devp->iomap_addrs, 0, sizeof(struct iomap_para));
-
- ret = request_irq(VE_IRQ_NO, VideoEngineInterupt, 0, "cedar_dev", NULL);
- if (ret < 0) {
- printk("request irq err\n");
- return -EINVAL;
- }
- /* map for macc io space */
- cedar_devp->iomap_addrs.regs_macc = ioremap(MACC_REGS_BASE, 4096);
- if (!cedar_devp->iomap_addrs.regs_macc){
- printk("cannot map region for macc");
- }
- cedar_devp->iomap_addrs.regs_avs = ioremap(AVS_REGS_BASE, 1024);
-
- //VE_SRAM mapping to AC320
- val = readl(0xf1c00000);
- val &= 0x80000000;
- writel(val,0xf1c00000);
- //remapping SRAM to MACC for codec test
- val = readl(0xf1c00000);
- val |= 0x7fffffff;
- writel(val,0xf1c00000);
-
- ve_pll4clk = clk_get(NULL,"ve_pll");
- pll4clk_rate = clk_get_rate(ve_pll4clk);
- /* getting ahb clk for ve!(macc) */
- ahb_veclk = clk_get(NULL,"ahb_ve");
- ve_moduleclk = clk_get(NULL,"ve");
- if(clk_set_parent(ve_moduleclk, ve_pll4clk)){
- printk("set parent of ve_moduleclk to ve_pll4clk failed!\n");
- return -EFAULT;
- }
- /*default the ve freq to 160M by lys 2011-12-23 15:25:34*/
- clk_set_rate(ve_moduleclk, pll4clk_rate/6);
- /*geting dram clk for ve!*/
- dram_veclk = clk_get(NULL, "sdram_ve");
- hosc_clk = clk_get(NULL,"hosc");
- avs_moduleclk = clk_get(NULL,"avs");
- if(clk_set_parent(avs_moduleclk, hosc_clk)){
- printk("set parent of avs_moduleclk to hosc_clk failed!\n");
- return -EFAULT;
- }
-
- /*for clk test*/
- #ifdef CEDAR_DEBUG
- printk("PLL4 CLK:0xf1c20018 is:%x\n", *(volatile int *)0xf1c20018);
- printk("AHB CLK:0xf1c20064 is:%x\n", *(volatile int *)0xf1c20064);
- printk("VE CLK:0xf1c2013c is:%x\n", *(volatile int *)0xf1c2013c);
- printk("SDRAM CLK:0xf1c20100 is:%x\n", *(volatile int *)0xf1c20100);
- printk("SRAM:0xf1c00000 is:%x\n", *(volatile int *)0xf1c00000);
- #endif
- /* Create char device */
- devno = MKDEV(g_dev_major, g_dev_minor);
- cdev_init(&cedar_devp->cdev, &cedardev_fops);
- cedar_devp->cdev.owner = THIS_MODULE;
- cedar_devp->cdev.ops = &cedardev_fops;
- ret = cdev_add(&cedar_devp->cdev, devno, 1);
- if (ret) {
- printk(KERN_NOTICE "Err:%d add cedardev", ret);
- }
- cedar_devp->class = class_create(THIS_MODULE, "cedar_dev");
- cedar_devp->dev = device_create(cedar_devp->class, NULL, devno, NULL, "cedar_dev");
- /*在cedar drv初始化的时候,初始化定时器并设置它的成员
- * 在有任务插入run_task_list的时候,启动定时器,并设置定时器的时钟为当前系统的jiffies,参考cedardev_insert_task
- */
- setup_timer(&cedar_devp->cedar_engine_timer, cedar_engine_for_events, (unsigned long)cedar_devp);
- setup_timer(&cedar_devp->cedar_engine_timer_rel, cedar_engine_for_timer_rel, (unsigned long)cedar_devp);
- printk("[cedar dev]: install end!!!\n");
- return 0;
-}
-module_init(cedardev_init);
-
-static void __exit cedardev_exit(void)
-{
- dev_t dev;
- dev = MKDEV(g_dev_major, g_dev_minor);
-
- free_irq(VE_IRQ_NO, NULL);
- iounmap(cedar_devp->iomap_addrs.regs_macc);
- iounmap(cedar_devp->iomap_addrs.regs_avs);
- /* Destroy char device */
- if(cedar_devp){
- cdev_del(&cedar_devp->cdev);
- device_destroy(cedar_devp->class, dev);
- class_destroy(cedar_devp->class);
- }
- clk_disable(dram_veclk);
- clk_put(dram_veclk);
-
- clk_disable(ve_moduleclk);
- clk_put(ve_moduleclk);
-
- clk_disable(ahb_veclk);
- clk_put(ahb_veclk);
-
- clk_put(ve_pll4clk);
-
- clk_disable(avs_moduleclk);
- clk_put(avs_moduleclk);
-
- unregister_chrdev_region(dev, 1);
- platform_driver_unregister(&sw_cedar_driver);
- if (cedar_devp) {
- kfree(cedar_devp);
- }
-}
-module_exit(cedardev_exit);
-
-MODULE_AUTHOR("Soft-Allwinner");
-MODULE_DESCRIPTION("User mode CEDAR device interface");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/media/video/sun4i/sun4i_cedar.h b/drivers/media/video/sun4i/sun4i_cedar.h
deleted file mode 100644
index c7296a2..0000000
--- a/drivers/media/video/sun4i/sun4i_cedar.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * drivers/media/video/sun4i/sun4i_cedar.h
- *
- * (C) Copyright 2007-2012
- * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program 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 program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
-**************************************************************************************************************
-* eLDK
-* the Easy Portable/Player Develop Kits
-* desktop system
-*
-* (c) Copyright 2009-2012, ,HUANGXIN China
-* All Rights Reserved
-*
-* File : sun4i_cedar.h
-* By : HUANGXIN
-* Func :
-* Version : v1.0
-* ============================================================================================================
-* 2011-5-25 9:57:05 HUANGXIN create this file, implements the fundemental interface;
-**************************************************************************************************************
-*/
-#ifndef _SUN4I_CEDAR_H_
-#define _SUN4I_CEDAR_H_
-
-enum IOCTL_CMD {
- IOCTL_UNKOWN = 0x100,
- IOCTL_GET_ENV_INFO,
- IOCTL_WAIT_VE,
- IOCTL_RESET_VE,
- IOCTL_ENABLE_VE,
- IOCTL_DISABLE_VE,
- IOCTL_SET_VE_FREQ,
-
- IOCTL_CONFIG_AVS2 = 0x200,
- IOCTL_GETVALUE_AVS2 ,
- IOCTL_PAUSE_AVS2 ,
- IOCTL_START_AVS2 ,
- IOCTL_RESET_AVS2 ,
- IOCTL_ADJUST_AVS2,
- IOCTL_ENGINE_REQ,
- IOCTL_ENGINE_REL,
- IOCTL_ENGINE_CHECK_DELAY,
- IOCTL_GET_IC_VER,
-
- IOCTL_ADJUST_AVS2_ABS,
- IOCTL_FLUSH_CACHE,
-};
-
-struct cedarv_env_infomation{
- unsigned int phymem_start;
- int phymem_total_size;
- unsigned int address_macc;
-};
-
-struct cedarv_cache_range{
- long start;
- long end;
-};
-
-struct __cedarv_task {
- int task_prio;
- int ID;
- unsigned long timeout;
- unsigned int frametime;
- unsigned int block_mode;
-};
-
-struct cedarv_engine_task {
- struct __cedarv_task t;
- struct list_head list;
- struct task_struct *task_handle;
- unsigned int status;
- unsigned int running;
- unsigned int is_first_task;
-};
-
-/*利用优先级task_prio查询当前运行task的frametime,和比优先级task_prio高的task可能运行的总时间total_time*/
-struct cedarv_engine_task_info {
- int task_prio;
- unsigned int frametime;
- unsigned int total_time;
-};
-
-/*--------------------------------------------------------------------------------*/
-#define REGS_pBASE (0x01C00000) // register base addr
-
-#define SRAM_REGS_pBASE (REGS_pBASE + 0x00000) // SRAM Controller
-#define CCMU_REGS_pBASE (REGS_pBASE + 0x20000) // clock manager unit
-#define MACC_REGS_pBASE (REGS_pBASE + 0x0E000) // media accelerate VE
-#define SS_REGS_pBASE (REGS_pBASE + 0x15000) // Security System
-#define SDRAM_REGS_pBASE (REGS_pBASE + 0x01000) // SDRAM Controller
-#define AVS_REGS_pBASE (REGS_pBASE + 0x20c00)
-
-#define SRAM_REGS_BASE SRAM_REGS_pBASE // SRAM Controller
-#define CCMU_REGS_BASE CCMU_REGS_pBASE // Clock Control manager unit OK
-#define MACC_REGS_BASE MACC_REGS_pBASE // Media ACCelerate
-#define SS_REGS_BASE SS_REGS_pBASE // Security System
-#define SDRAM_REGS_BASE SDRAM_REGS_pBASE //SDRAM Controller OK
-#define AVS_REGS_BASE AVS_REGS_pBASE
-
-#define MPEG_REGS_BASE (MACC_REGS_BASE + 0x100) // MPEG engine
-#define H264_REGS_BASE (MACC_REGS_BASE + 0x200) // H264 engine
-#define VC1_REGS_BASE (MACC_REGS_BASE + 0x300) // VC-1 engine
-
-#define SRAM_REGS_SIZE (4096) // 4K
-#define CCMU_REGS_SIZE (1024) // 1K
-#define MACC_REGS_SIZE (4096) // 4K
-#define SS_REGS_SIZE (4096) // 4K
-/*--------------------------------------------------------------------------------*/
-
-#define SRAM_REG_o_CFG (0x00)
-#define SRAM_REG_ADDR_CFG (SRAM_REGS_BASE + SRAM_REG_o_CFG) // SRAM MAP Cfg Reg 0
-/*--------------------------------------------------------------------------------*/
-
-#endif
diff --git a/drivers/media/video/sun5i/Kconfig b/drivers/media/video/sun5i/Kconfig
deleted file mode 100644
index 5d5dcd2..0000000
--- a/drivers/media/video/sun5i/Kconfig
+++ /dev/null
@@ -1,18 +0,0 @@
-config VIDEO_DECODER_SUN5I
- tristate "sun5i video decoder support"
- depends on VIDEO_SUN5I_CEDAR
- default y
- ---help---
- This is the driver for sun4i video decoder, including h264/
- mpeg4/mpeg2/vc1/rmvb.
- To compile this driver as a module, choose M here: the
- module will be called cedar_dev.
-
-config VIDEO_AVS_COUNTER
- tristate "sun5i av-sync counter support"
- depends on VIDEO_SUN5I_CEDAR
- default n
- ---help---
- This is the driver for sun4i av-sync counter.
- To compile this driver as a module, choose M here: the
- module will be called avs_dev.
diff --git a/drivers/media/video/sun5i/Makefile b/drivers/media/video/sun5i/Makefile
deleted file mode 100644
index e9c6ebc..0000000
--- a/drivers/media/video/sun5i/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-# AW16XX Audio Card Support
-obj-$(CONFIG_VIDEO_DECODER_SUN5I) += sun5i_cedar.o
-obj-$(CONFIG_VIDEO_AVS_COUNTER) += sun5i_avs.o
-
diff --git a/drivers/media/video/sun5i/readme b/drivers/media/video/sun5i/readme
deleted file mode 100644
index 1daf295..0000000
--- a/drivers/media/video/sun5i/readme
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * drivers/media/video/sun5i/readme
- *
- * (C) Copyright 2007-2012
- * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program 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 program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#------------------------------------------------------------
-# Cedar_dev : video engine driver
-#------------------------------------------------------------
-
-#------------------------------------------------------------
-#@version: cedar_vers0_08
-#@Author : Truby.Zong
-#@Date : 2011-4-06
-#@Description:
-# The second version of cedar video engine driver, which
-# add VD/DE SRAM prority and change file name.
-#-------------------------------------------------------------
-#
-#------------------------------------------------------------
-#@version: Vers0_01
-#@Author : Truby.Zong
-#@Date : 2011-3-18
-#@Description:
-# The first version of cedar video engine driver, which
-#handles the irq/clock/phy memory alloc of the cedar device,
-#and also the AV-SYNC counter (AVS_CNT1);
-# Please pay attention to the method to request/remap IO
-#resource and request/free irq, which are just handle once in
-#module init and module exit.
-#-------------------------------------------------------------
-
diff --git a/drivers/media/video/sun5i/sun5i_avs.c b/drivers/media/video/sun5i/sun5i_avs.c
deleted file mode 100644
index f3f3d33..0000000
--- a/drivers/media/video/sun5i/sun5i_avs.c
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
- * drivers/media/video/sun5i/sun5i_avs.c
- *
- * (C) Copyright 2007-2012
- * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program 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 program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * sun4i_avs.c
- * driver for av-sync counter
- * Author : Truby.Zong <truby....@chipsbank.com>
- */
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/ioctl.h>
-#include <linux/fs.h>
-#include <linux/device.h>
-#include <linux/err.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-#include <linux/smp_lock.h>
-#include <linux/preempt.h>
-#include <linux/cdev.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/clk.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <mach/hardware.h>
-#include <asm/system.h>
-#include <linux/rmap.h>
-#include <linux/wait.h>
-#include <linux/poll.h>
-#include <linux/spinlock.h>
-
-#include "sun5i_cedar.h"
-
-#define DRV_VERSION "0.01alpha"
-
-#ifndef AVSDEV_MAJOR
-#define AVSDEV_MAJOR (151)
-#endif
-#ifndef AVSDEV_MINOR
-#define AVSDEV_MINOR (0)
-#endif
-
-#undef _info
-#ifdef CEDAR_DEBUG
-# define _info(fmt, args...) printk( KERN_DEBUG "[avs]: " fmt, ## args)
-#else
-# define _info(fmt, args...)
-#endif
-
-int g_dev_major = AVSDEV_MAJOR;
-int g_dev_minor = AVSDEV_MINOR;
-module_param(g_dev_major, int, S_IRUGO);
-module_param(g_dev_minor, int, S_IRUGO);
-
-struct iomap_resource{
- struct resource *io_sram;
- struct resource *io_ccmu;
- struct resource *io_macc;
- struct resource *io_mpeg;
- struct resource *io_vc1;
- struct resource *io_memc;
-};
-struct iomap_resource iomap_res;
-
-struct iomap_para{
- volatile char* regs_sram;
- volatile char* regs_ccmu;
- volatile char* regs_macc;
- volatile char* regs_mpeg;
- volatile char* regs_vc1;
- volatile char* regs_memc;
-};
-
-struct avs_dev {
- struct cdev cdev; /* char device struct */
- struct device *dev; /* ptr to class device struct */
- struct class *class; /* class for auto create device node */
-
- struct semaphore sem; /* mutual exclusion semaphore */
- spinlock_t lock; /* spinlock to pretect ioctl access */
-
- struct iomap_para iomap_addrs; /* io remap addrs */
- struct iomap_resource iomap_res; /* io remap resources */
-};
-struct avs_dev *avs_devp;
-
-/*
- * ioremap and request iomem
- */
-static void avs_register_iomem(struct avs_dev *devp)
-{
- struct resource *res;
- char *addr;
-
- memset(&devp->iomap_res, 0, sizeof(struct iomap_resource));
- memset(&devp->iomap_addrs, 0, sizeof(struct iomap_para));
-
- /* request mem for ccmu */
- res = request_mem_region(CCMU_REGS_pBASE, 1024, "ccmu");
- if (res == NULL) {
- printk("Cannot reserve region for ccmu\n");
- goto err_out;
- }
- devp->iomap_res.io_ccmu = res;
-
- /* ioremap for ccmu */
- addr = ioremap(CCMU_REGS_pBASE, 4096);
- if (!addr){
- printk("cannot map region for ccmu");
- goto err_out;
- }
- devp->iomap_addrs.regs_ccmu = addr;
-
- return;
-
-err_out:
- if (devp->iomap_addrs.regs_ccmu)
- iounmap(devp->iomap_addrs.regs_ccmu);
-}
-
-/*
- * unmap/release iomem
- */
-static void avs_iomem_unregister(struct avs_dev *devp)
-{
- if (devp->iomap_res.io_ccmu) {
- release_resource(devp->iomap_res.io_ccmu);
- devp->iomap_res.io_ccmu = NULL;
- }
-
- /* iounmap */
- if (devp->iomap_addrs.regs_ccmu) {
- iounmap(devp->iomap_addrs.regs_ccmu);
- devp->iomap_addrs.regs_ccmu = NULL;
- }
-}
-
-/*
- * ioctl function
- * including : wait video engine done,
- * AVS Counter control,
- * Physical memory control,
- * module clock/freq control.
- */
-long avsdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
-{
- long ret;
- unsigned int v;
-
- spinlock_t *lock;
- struct avs_dev *devp;
-
- ret = 0;
- devp = filp->private_data;
- lock = &devp->lock;
-
- switch (cmd)
- {
- case IOCTL_GETVALUE_AVS2:
- spin_lock(lock);
-
- v = readl(devp->iomap_addrs.regs_ccmu + 0xc40);
-
- spin_unlock(lock);
- return v;
-
- case IOCTL_CONFIG_AVS2:
- spin_lock(lock);
-
- v = readl(devp->iomap_addrs.regs_ccmu + 0xc44);
- v = 239<<16 | (v&0xffff);
- writel(v, devp->iomap_addrs.regs_ccmu + 0xc44);
- v = readl(devp->iomap_addrs.regs_ccmu + 0xc38);
- v |= 1<<9 | 1<<1;
- writel(v, devp->iomap_addrs.regs_ccmu + 0xc38);
- writel(0, devp->iomap_addrs.regs_ccmu + 0xc40);
-
- spin_unlock(lock);
- break;
-
- case IOCTL_RESET_AVS2:
- spin_lock(lock);
-
- writel(0, devp->iomap_addrs.regs_ccmu + 0xc40);
-
- spin_unlock(lock);
- break;
-
- case IOCTL_PAUSE_AVS2:
- spin_lock(lock);
-
- v = readl(devp->iomap_addrs.regs_ccmu + 0xc38);
- v |= 1<<9;
- writel(v, devp->iomap_addrs.regs_ccmu + 0xc38);
-
- spin_unlock(lock);
- break;
-
- case IOCTL_START_AVS2:
- spin_lock(lock);
-
- v = readl(devp->iomap_addrs.regs_ccmu + 0xc38);
- v &= ~(1<<9);
- writel(v, devp->iomap_addrs.regs_ccmu + 0xc38);
-
- spin_unlock(lock);
- break;
-
- default:
- break;
- }
-
- return ret;
-}
-
-static int avsdev_open(struct inode *inode, struct file *filp)
-{
- struct avs_dev *devp;
- devp = container_of(inode->i_cdev, struct avs_dev, cdev);
- filp->private_data = devp;
-
- if (down_interruptible(&devp->sem)) {
- return -ERESTARTSYS;
- }
-
- // init other resource here
-
- up(&devp->sem);
-
- nonseekable_open(inode, filp);
- return 0;
-}
-
-static int avsdev_release(struct inode *inode, struct file *filp)
-{
- struct avs_dev *devp;
-
- devp = filp->private_data;
-
- if (down_interruptible(&devp->sem)) {
- return -ERESTARTSYS;
- }
-
- /* release other resource here */
-
- up(&devp->sem);
- return 0;
-}
-
-void avsdev_vma_open(struct vm_area_struct *vma)
-{
- printk(KERN_NOTICE "avsdev VMA open, virt %lx, phys %lx\n",
- vma->vm_start, vma->vm_pgoff << PAGE_SHIFT);
- return;
-}
-
-void avsdev_vma_close(struct vm_area_struct *vma)
-{
- printk(KERN_NOTICE "avsdev VMA close.\n");
- return;
-}
-
-static struct vm_operations_struct avsdev_remap_vm_ops = {
- .open = avsdev_vma_open,
- .close = avsdev_vma_close,
-};
-
-static int avsdev_mmap(struct file *filp, struct vm_area_struct *vma)
-{
- unsigned long temp_pfn;
- unsigned int VAddr;
- struct iomap_para addrs;
-
- unsigned int io_ram = 0;
- VAddr = vma->vm_pgoff << 12;
-
- addrs = avs_devp->iomap_addrs;
-
- if(VAddr == (unsigned int)addrs.regs_ccmu) {
- temp_pfn = CCMU_REGS_pBASE >> 12;
- io_ram = 1;
- } else {
- temp_pfn = (__pa(vma->vm_pgoff << 12))>>12;
- io_ram = 0;
- }
-
- if (io_ram == 0) {
- /* Set reserved and I/O flag for the area. */
- vma->vm_flags |= VM_RESERVED | VM_IO;
-
- /* Select uncached access. */
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-
- if (remap_pfn_range(vma, vma->vm_start, temp_pfn,
- vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
- return -EAGAIN;
- }
- } else {
- /* Set reserved and I/O flag for the area. */
- vma->vm_flags |= VM_RESERVED | VM_IO;
-
- /* Select uncached access. */
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-
- if (io_remap_pfn_range(vma, vma->vm_start, temp_pfn,
- vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
- return -EAGAIN;
- }
- }
-
- vma->vm_ops = &avsdev_remap_vm_ops;
- avsdev_vma_open(vma);
-
- return 0;
-}
-
-static struct file_operations avsdev_fops = {
- .owner = THIS_MODULE,
- .unlocked_ioctl = avsdev_ioctl,
- .mmap = avsdev_mmap,
- .open = avsdev_open,
- .release = avsdev_release,
- .llseek = no_llseek,
-};
-
-static int __init avsdev_init(void)
-{
- int ret;
- int devno;
- dev_t dev = 0;
-
- printk("[tt]----- avs_dev driver load... ----\n");
- if (g_dev_major) {
- dev = MKDEV(g_dev_major, g_dev_minor);
- ret = register_chrdev_region(dev, 1, "avs_dev");
- } else {
- ret = alloc_chrdev_region(&dev, g_dev_minor, 1, "avs_dev");
- g_dev_major = MAJOR(dev);
- g_dev_minor = MINOR(dev);
- }
-
- if (ret < 0) {
- printk(KERN_WARNING "avs_dev: can't get major %d\n", g_dev_major);
- return ret;
- }
-
- avs_devp = kmalloc(sizeof(struct avs_dev), GFP_KERNEL);
- if (avs_devp == NULL) {
- printk("malloc mem for avs device err\n");
- return -ENOMEM;
- }
- memset(avs_devp, 0, sizeof(struct avs_dev));
-
- init_MUTEX(&avs_devp->sem);
-
- /* request resources and ioremap */
- printk("[tt]----- register iomem ----\n");
- avs_register_iomem(avs_devp);
-
- /* init lock for protect ioctl access */
- spin_lock_init(&avs_devp->lock);
-
- devno = MKDEV(g_dev_major, g_dev_minor);
- cdev_init(&avs_devp->cdev, &avsdev_fops);
- avs_devp->cdev.owner = THIS_MODULE;
- avs_devp->cdev.ops = &avsdev_fops;
- ret = cdev_add(&avs_devp->cdev, devno, 1);
- if (ret) {
- printk(KERN_NOTICE "Err:%d add avsdev", ret);
- }
-
- avs_devp->class = class_create(THIS_MODULE, "avs_dev");
- avs_devp->dev = device_create(avs_devp->class, NULL, devno, NULL, "avs_dev");
-
- printk("[tt]--- avs_dev driver load ok!! -----\n");
- return 0;
-}
-module_init(avsdev_init);
-
-static void __exit avsdev_exit(void)
-{
- dev_t dev;
- dev = MKDEV(g_dev_major, g_dev_minor);
-
- /* Unregister iomem and iounmap */
- avs_iomem_unregister(avs_devp);
-
- if (avs_devp) {
- cdev_del(&avs_devp->cdev);
- device_destroy(avs_devp->class, dev);
- class_destroy(avs_devp->class);
- }
-
- unregister_chrdev_region(dev, 1);
-
- if (avs_devp) {
- kfree(avs_devp);
- }
-}
-module_exit(avsdev_exit);
-
-MODULE_AUTHOR("Soft-Allwinner");
-MODULE_DESCRIPTION("avs device driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/media/video/sun5i/sun5i_cedar.c b/drivers/media/video/sun5i/sun5i_cedar.c
deleted file mode 100644
index d3ffc4d..0000000
--- a/drivers/media/video/sun5i/sun5i_cedar.c
+++ /dev/null
@@ -1,1119 +0,0 @@
-/*
- * drivers\media\video\sun5i\sun5i_cedar.c
- * (C) Copyright 2007-2011
- * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
- * huangxin <huan...@allwinnertech.com>
- *
- * some simple description for this code
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- */
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/ioctl.h>
-#include <linux/fs.h>
-#include <linux/device.h>
-#include <linux/err.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-#include <linux/preempt.h>
-#include <linux/cdev.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/clk.h>
-#include <linux/rmap.h>
-#include <linux/wait.h>
-#include <linux/semaphore.h>
-#include <linux/poll.h>
-#include <linux/spinlock.h>
-#include <linux/sched.h>
-#include <linux/kthread.h>
-#include <linux/delay.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <mach/hardware.h>
-#include <asm/system.h>
-#include <asm/siginfo.h>
-#include <asm/signal.h>
-#include <mach/system.h>
-#include <mach/clock.h>
-#include "sun5i_cedar.h"
-
-#define DRV_VERSION "0.01alpha"
-
-#define CHIP_VERSION_F23
-
-#undef USE_CEDAR_ENGINE
-
-#ifndef CEDARDEV_MAJOR
-#define CEDARDEV_MAJOR (150)
-#endif
-#ifndef CEDARDEV_MINOR
-#define CEDARDEV_MINOR (0)
-#endif
-
-//#define CEDAR_DEBUG
-
-int g_dev_major = CEDARDEV_MAJOR;
-int g_dev_minor = CEDARDEV_MINOR;
-module_param(g_dev_major, int, S_IRUGO);//S_IRUGO represent that g_dev_major can be read,but canot be write
-module_param(g_dev_minor, int, S_IRUGO);
-
-#ifdef CHIP_VERSION_F23
-#define VE_IRQ_NO (53)
-#else
-#define VE_IRQ_NO (48)
-#endif
-
-struct clk *ve_moduleclk = NULL;
-struct clk *ve_pll4clk = NULL;
-struct clk *ahb_veclk = NULL;
-struct clk *dram_veclk = NULL;
-struct clk *avs_moduleclk = NULL;
-struct clk *hosc_clk = NULL;
-
-static unsigned long pll4clk_rate = 240000000;
-
-extern unsigned long ve_start;
-extern unsigned long ve_size;
-
-struct iomap_para{
- volatile char* regs_macc;
- #ifdef CHIP_VERSION_F23
- volatile char* regs_avs;
- #else
- volatile char* regs_ccmu;
- #endif
-};
-
-static DECLARE_WAIT_QUEUE_HEAD(wait_ve);
-struct cedar_dev {
- struct cdev cdev; /* char device struct */
- struct device *dev; /* ptr to class device struct */
- struct class *class; /* class for auto create device node */
-
- struct semaphore sem; /* mutual exclusion semaphore */
-
- wait_queue_head_t wq; /* wait queue for poll ops */
-
- struct iomap_para iomap_addrs; /* io remap addrs */
-
- struct timer_list cedar_engine_timer;
- struct timer_list cedar_engine_timer_rel;
-
- u32 irq; /* cedar video engine irq number */
- u32 irq_flag; /* flag of video engine irq generated */
- u32 irq_value; /* value of video engine irq */
- u32 irq_has_enable;
- u32 ref_count;
-};
-struct cedar_dev *cedar_devp;
-
-u32 int_sta=0,int_value;
-
-/*
- * Video engine interrupt service routine
- * To wake up ve wait queue
- */
-static irqreturn_t VideoEngineInterupt(int irq, void *dev)
-{
- unsigned int ve_int_ctrl_reg;
- volatile int val;
- int modual_sel;
- struct iomap_para addrs = cedar_devp->iomap_addrs;
-
- modual_sel = readl(addrs.regs_macc + 0);
- modual_sel &= 0xf;
-
- /* estimate Which video format */
- switch (modual_sel)
- {
- case 0: //mpeg124
- ve_int_ctrl_reg = (unsigned int)(addrs.regs_macc + 0x100 + 0x14);
- break;
- case 1: //h264
- ve_int_ctrl_reg = (unsigned int)(addrs.regs_macc + 0x200 + 0x20);
- break;
- case 2: //vc1
- ve_int_ctrl_reg = (unsigned int)(addrs.regs_macc + 0x300 + 0x24);
- break;
- case 3: //rmvb
- ve_int_ctrl_reg = (unsigned int)(addrs.regs_macc + 0x400 + 0x14);
- break;
- case 0xa: //isp
- ve_int_ctrl_reg = (unsigned int)(addrs.regs_macc + 0xa00 + 0x08);
- break;
- case 0xb: //avc enc
- ve_int_ctrl_reg = (unsigned int)(addrs.regs_macc + 0xb00 + 0x14);
- break;
- default:
- ve_int_ctrl_reg = (unsigned int)(addrs.regs_macc + 0x100 + 0x14);
- printk("macc modual sel not defined!\n");
- break;
- }
-
- //disable interrupt
- if(modual_sel == 0) {
- val = readl(ve_int_ctrl_reg);
- writel(val & (~0x7c), ve_int_ctrl_reg);
- } else {
- val = readl(ve_int_ctrl_reg);
- writel(val & (~0xf), ve_int_ctrl_reg);
- }
-
- cedar_devp->irq_value = 1; //hx modify 2011-8-1 16:08:47
- cedar_devp->irq_flag = 1;
- //any interrupt will wake up wait queue
- wake_up_interruptible(&wait_ve); //ioctl
-
- return IRQ_HANDLED;
-}
-
-/*
- * poll operateion for wait for ve irq
- */
-unsigned int cedardev_poll(struct file *filp, struct poll_table_struct *wait)
-{
- int mask = 0;
- struct cedar_dev *devp = filp->private_data;
-
- poll_wait(filp, &devp->wq, wait);
- if (devp->irq_flag == 1) {
- devp->irq_flag = 0;
- mask |= POLLIN | POLLRDNORM;
- }
- return mask;
-}
-
-static int clk_status = 0;
-static LIST_HEAD(run_task_list);
-static LIST_HEAD(del_task_list);
-static spinlock_t cedar_spin_lock;
-#define CEDAR_RUN_LIST_NONULL -1
-#define CEDAR_NONBLOCK_TASK 0 //非阻塞
-#define CEDAR_BLOCK_TASK 1
-#define CLK_REL_TIME 10000 //10秒
-#define TIMER_CIRCLE 50 //50毫秒
-#define TASK_INIT 0x00
-#define TASK_TIMEOUT 0x55
-#define TASK_RELEASE 0xaa
-#define SIG_CEDAR 35
-
-int enable_cedar_hw_clk(void)
-{
- unsigned long flags;
- int res = -EFAULT;
-
- spin_lock_irqsave(&cedar_spin_lock, flags);
-
- if (clk_status == 1)
- goto out;
- clk_status = 1;
-
- if(0 != clk_enable(ahb_veclk)){
- printk("ahb_veclk failed; \n");
- goto out;
- }
- if(0 != clk_enable(ve_moduleclk)){
- printk("ve_moduleclk failed; \n");
- goto out3;
- }
- if(0 != clk_enable(dram_veclk)){
- printk("dram_veclk failed; \n");
- goto out2;
- }
- if(0 != clk_enable(avs_moduleclk)){
- printk("ve_moduleclk failed; \n");
- goto out1;
- }
- #ifdef CEDAR_DEBUG
- printk("%s,%d\n",__func__,__LINE__);
- #endif
- res = 0;
- goto out;
-
-out1:
- clk_disable(dram_veclk);
-out2:
- clk_disable(ve_moduleclk);
-out3:
- clk_disable(ahb_veclk);
-out:
- spin_unlock_irqrestore(&cedar_spin_lock, flags);
- return res;
-}
-
-int disable_cedar_hw_clk(void)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&cedar_spin_lock, flags);
-
- if (clk_status == 0)
- goto out;
- clk_status = 0;
-
- clk_disable(dram_veclk);
- clk_disable(ve_moduleclk);
- clk_disable(ahb_veclk);
- clk_disable(avs_moduleclk);
- #ifdef CEDAR_DEBUG
- printk("%s,%d\n",__func__,__LINE__);
- #endif
-out:
- spin_unlock_irqrestore(&cedar_spin_lock, flags);
- return 0;
-}
-
-void cedardev_insert_task(struct cedarv_engine_task* new_task)
-{
- struct cedarv_engine_task *task_entry;
- unsigned long flags;
-
- spin_lock_irqsave(&cedar_spin_lock, flags);
-
- if(list_empty(&run_task_list))
- new_task->is_first_task = 1;
-
- /*遍历run_task_list链表,如果插入的任务优先级比链表节点中的任务优先级高,并且当前插入任务不是第一个插入的任务。
- *那么就将优先级高的任务放于前面,队列中的任务采取从高到底的优先级队列排队。
- */
- list_for_each_entry(task_entry, &run_task_list, list) {
- if ((task_entry->is_first_task == 0) && (task_entry->running == 0) && (task_entry->t.task_prio < new_task->t.task_prio)) {
- break;
- }
- }
-
- list_add(&new_task->list, task_entry->list.prev);
-
- #ifdef CEDAR_DEBUG
- printk("%s,%d, TASK_ID:",__func__,__LINE__);
- list_for_each_entry(task_entry, &run_task_list, list) {
- printk("%d!", task_entry->t.ID);
- }
- printk("\n");
- #endif
- /*每次插入一个任务,就将当前的计时器时间重置为系统当前的jiffies*/
- mod_timer(&cedar_devp->cedar_engine_timer, jiffies + 0);
-
- spin_unlock_irqrestore(&cedar_spin_lock, flags);
-}
-
-int cedardev_del_task(int task_id)
-{
- struct cedarv_engine_task *task_entry;
- unsigned long flags;
-
- spin_lock_irqsave(&cedar_spin_lock, flags);
-
- /*遍历run_task_list链表
- *如果找到对应的id号,那么就将run_task_list链表中的任务移到del_task_list链表的表头。
- */
- list_for_each_entry(task_entry, &run_task_list, list) {
- if (task_entry->t.ID == task_id && task_entry->status != TASK_RELEASE) {
- task_entry->status = TASK_RELEASE;
-
- spin_unlock_irqrestore(&cedar_spin_lock, flags);
- mod_timer(&cedar_devp->cedar_engine_timer, jiffies + 0);
- return 0;
- }
- }
- spin_unlock_irqrestore(&cedar_spin_lock, flags);
-
- //找不到对应 ID
- return -1;
-}
-
-int cedardev_check_delay(int check_prio)
-{
- struct cedarv_engine_task *task_entry;
- int timeout_total = 0;
- unsigned long flags;
-
- /*获取总的等待时间*/
- spin_lock_irqsave(&cedar_spin_lock, flags);
- list_for_each_entry(task_entry, &run_task_list, list) {
- if ((task_entry->t.task_prio >= check_prio) || (task_entry->running == 1) || (task_entry->is_first_task == 1))
- timeout_total = timeout_total + task_entry->t.frametime;
- }
-
- spin_unlock_irqrestore(&cedar_spin_lock, flags);
-#ifdef CEDAR_DEBUG
- printk("%s,%d,%d\n", __func__, __LINE__, timeout_total);
-#endif
- return timeout_total;
-}
-
-static void cedar_engine_for_timer_rel(unsigned long arg)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&cedar_spin_lock, flags);
-
- if(list_empty(&run_task_list)){
- disable_cedar_hw_clk();
- } else {
- printk("Warring: cedar engine timeout for clk disable, but task left, something wrong?\n");
- mod_timer( &cedar_devp->cedar_engine_timer, jiffies + msecs_to_jiffies(TIMER_CIRCLE));
- }
-
- spin_unlock_irqrestore(&cedar_spin_lock, flags);
-}
-
-static void cedar_engine_for_events(unsigned long arg)
-{
- struct cedarv_engine_task *task_entry, *task_entry_tmp;
- struct siginfo info;
- unsigned long flags;
-
- spin_lock_irqsave(&cedar_spin_lock, flags);
-
- list_for_each_entry_safe(task_entry, task_entry_tmp, &run_task_list, list) {
- mod_timer(&cedar_devp->cedar_engine_timer_rel, jiffies + msecs_to_jiffies(CLK_REL_TIME));
- if (task_entry->status == TASK_RELEASE ||
- time_after(jiffies, task_entry->t.timeout)) {
- if (task_entry->status == TASK_INIT)
- task_entry->status = TASK_TIMEOUT;
- list_move(&task_entry->list, &del_task_list);
- }
- }
-
- list_for_each_entry_safe(task_entry, task_entry_tmp, &del_task_list, list) {
- info.si_signo = SIG_CEDAR;
- info.si_code = task_entry->t.ID;
- if (task_entry->status == TASK_TIMEOUT){//表示任务timeout删除
- info.si_errno = TASK_TIMEOUT;
- send_sig_info(SIG_CEDAR, &info, task_entry->task_handle);
- }else if(task_entry->status == TASK_RELEASE){//表示任务正常运行完毕删除
- info.si_errno = TASK_RELEASE;
- send_sig_info(SIG_CEDAR, &info, task_entry->task_handle);
- }
- list_del(&task_entry->list);
- kfree(task_entry);
- }
-
- /*激活链表中的task*/
- if(!list_empty(&run_task_list)){
- task_entry = list_entry(run_task_list.next, struct cedarv_engine_task, list);
- if(task_entry->running == 0){
- task_entry->running = 1;
- info.si_signo = SIG_CEDAR;
- info.si_code = task_entry->t.ID;
- info.si_errno = TASK_INIT; //任务已经启动
- send_sig_info(SIG_CEDAR, &info, task_entry->task_handle);
- }
-
- mod_timer( &cedar_devp->cedar_engine_timer, jiffies + msecs_to_jiffies(TIMER_CIRCLE));
- }
-
- spin_unlock_irqrestore(&cedar_spin_lock, flags);
-}
-
-#ifdef CHIP_VERSION_F23
-static unsigned int g_ctx_reg0;
-static void save_context(void)
-{
- g_ctx_reg0 = readl(0xf1c20e00);
-}
-
-static void restore_context(void)
-{
- writel(g_ctx_reg0, 0xf1c20e00);
-}
-#else
- #define save_context()
- #define restore_context()
-#endif
-
-#ifdef CHIP_VERSION_F23
-short VEPLLTable[][6] =
-{
- //set, actual, Nb, Kb, Mb, Pb
- { 60, 60, 5, 2, 2, 1},
- { 90, 90, 5, 2, 0, 2},
- {120, 120, 5, 2, 2, 0},
- {150, 150, 25, 0, 0, 2},
- {180, 180, 5, 2, 0, 1},
- {216, 216, 6, 2, 0, 1},
- {240, 240, 5, 3, 0, 1},
- {270, 270, 15, 2, 0, 2},
- {300, 300, 25, 0, 0, 1},
- {330, 336, 7, 1, 0, 0},
- {360, 360, 5, 2, 0, 0},
- {384, 384, 4, 3, 0, 0},
- {402, 400, 25, 1, 2, 0},
- {420, 416, 13, 3, 2, 0},
- {444, 448, 14, 3, 2, 0},
- {456, 456, 19, 0, 0, 0},
- {468, 468, 13, 2, 0, 1},
- {480, 480, 5, 3, 0, 0},
- {492, 496, 31, 1, 2, 0},
-};
-#endif
-
-/*
- * ioctl function
- * including : wait video engine done,
- * AVS Counter control,
- * Physical memory control,
- * module clock/freq control.
- * cedar engine
- */
-long cedardev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
-{
- long ret = 0;
- unsigned int v;
- int ve_timeout = 0;
- struct cedar_dev *devp;
-#ifdef USE_CEDAR_ENGINE
- int rel_taskid = 0;
- struct __cedarv_task task_ret;
- struct cedarv_engine_task *task_ptr = NULL;
-#endif
- unsigned long flags;
- //unsigned int val;
- devp = filp->private_data;
-
- switch (cmd)
- {
- case IOCTL_ENGINE_REQ:
- #ifdef USE_CEDAR_ENGINE
- if(copy_from_user(&task_ret, (void __user*)arg, sizeof(struct __cedarv_task))){
- printk("IOCTL_ENGINE_REQ copy_from_user fail\n");
- return -EFAULT;
- }
- spin_lock_irqsave(&cedar_spin_lock, flags);
- /*如果task为非阻塞状态,请求者可以立即返回*/
- if(!list_empty(&run_task_list) && ( task_ret.block_mode == CEDAR_NONBLOCK_TASK)){
- spin_unlock_irqrestore(&cedar_spin_lock, flags);
- return CEDAR_RUN_LIST_NONULL; //run_task_list里面有任务,返回-1
- }
- spin_unlock_irqrestore(&cedar_spin_lock, flags);
-
- /*如果task为阻塞状态,将task插入run_task_list链表中*/
- task_ptr = kmalloc(sizeof(struct cedarv_engine_task), GFP_KERNEL);
- if(!task_ptr){
- printk("get mem for IOCTL_ENGINE_REQ\n");
- return PTR_ERR(task_ptr);
- }
- task_ptr->task_handle = current;
- task_ptr->t.ID = task_ret.ID;
- task_ptr->t.timeout = jiffies + msecs_to_jiffies(1000*task_ret.timeout);//ms to jiffies
- task_ptr->t.frametime = task_ret.frametime;
- task_ptr->t.task_prio = task_ret.task_prio;
- task_ptr->running = 0;
- task_ptr->is_first_task = 0;
- task_ptr->status = TASK_INIT;
-
- cedardev_insert_task(task_ptr);
-
- enable_cedar_hw_clk();
-
- return task_ptr->is_first_task;//插入run_task_list链表中的任务是第一个任务,返回1,不是第一个任务返回0. hx modify 2011-7-28 16:59:16!!!
- #else
- enable_cedar_hw_clk();
- cedar_devp->ref_count++;
- break;
- #endif
- case IOCTL_ENGINE_REL:
- #ifdef USE_CEDAR_ENGINE
- rel_taskid = (int)arg;
- /*
- * 利用任务的id号进行任务的删除操作。返回值意义:找不到对应ID,返回-1;找到对应ID,返回0。
- */
- ret = cedardev_del_task(rel_taskid);
- #else
- disable_cedar_hw_clk();
- cedar_devp->ref_count--;
- #endif
- return ret;
- case IOCTL_ENGINE_CHECK_DELAY:
- {
- struct cedarv_engine_task_info task_info;
- /*从用户空间中获取要查询的任务优先级,通过任务优先级,统计需要等待的总时间total_time.
- * 在这个接口中,同时也给用户传递了当前任务的frametime(这样做可以减少接口,但是用户空间要多设置一个空的frametime值)
- *对于当前task的frametime,也可以用额外的接口获取,但是这样做,frametime和total_time就处于不同接口中。好处???
- */
- if(copy_from_user(&task_info, (void __user*)arg, sizeof(struct cedarv_engine_task_info))){
- printk("IOCTL_ENGINE_CHECK_DELAY copy_from_user fail\n");
- return -EFAULT;
- }
- task_info.total_time = cedardev_check_delay(task_info.task_prio);//task_info.task_prio是传递过来的优先级
- #ifdef CEDAR_DEBUG
- printk("%s,%d,%d\n", __func__, __LINE__, task_info.total_time);
- #endif
- task_info.frametime = 0;
- spin_lock_irqsave(&cedar_spin_lock, flags);
- if(!list_empty(&run_task_list)){
- /*获取run_task_list链表中的第一个任务,也就是当前运行的任务,通过当前运行的任务获取frametime时间*/
- struct cedarv_engine_task *task_entry;
- #ifdef CEDAR_DEBUG
- printk("%s,%d\n",__func__,__LINE__);
- #endif
- task_entry = list_entry(run_task_list.next, struct cedarv_engine_task, list);
- if(task_entry->running == 1)
- task_info.frametime = task_entry->t.frametime;
- #ifdef CEDAR_DEBUG
- printk("%s,%d,%d\n",__func__,__LINE__,task_info.frametime);
- #endif
- }
- spin_unlock_irqrestore(&cedar_spin_lock, flags);
- /*
- *将任务优先级,total_time,frametime拷贝到用户空间。任务优先级还是用户设置的值,total_time是需要等待的总时间,
- *frametime是当前任务的运行时间.其实当前任务的信息最好用另一个接口实现.减少耦合度和接口的拓展性.
- */
- if (copy_to_user((void *)arg, &task_info, sizeof(struct cedarv_engine_task_info))){
- printk("IOCTL_ENGINE_CHECK_DELAY copy_to_user fail\n");
- return -EFAULT;
- }
- }
- break;
- case IOCTL_WAIT_VE:
- //wait_event_interruptible(wait_ve, cedar_devp->irq_flag);
- ve_timeout = (int)arg;
- cedar_devp->irq_value = 0;
-
- spin_lock_irqsave(&cedar_spin_lock, flags);
- if(cedar_devp->irq_flag)
- cedar_devp->irq_value = 1;
- spin_unlock_irqrestore(&cedar_spin_lock, flags);
-
- wait_event_interruptible_timeout(wait_ve, cedar_devp->irq_flag, ve_timeout*HZ);
- //printk("%s,%d,ve_timeout:%d,cedar_devp->irq_value:%d\n", __func__, __LINE__, ve_timeout, cedar_devp->irq_value);
- cedar_devp->irq_flag = 0;
- /*返回1,表示中断返回,返回0,表示timeout返回*/
- return cedar_devp->irq_value;
-
- case IOCTL_ENABLE_VE:
- clk_enable(ve_moduleclk);
- break;
-
- case IOCTL_DISABLE_VE:
- clk_disable(ve_moduleclk);
- break;
-
- case IOCTL_RESET_VE:
- clk_disable(dram_veclk);
- clk_reset(ve_moduleclk, 1);
- clk_reset(ve_moduleclk, 0);
- /*********for fpga*********/
-// val = readl(0xf1c2013c);
-// val &= ~0x00000001;
-// writel(val,0xf1c2013c);
-// val |= 0x00000001;
-// writel(val,0xf1c2013c);
- /*********for fpga*********/
- clk_enable(dram_veclk);
- break;
-
- case IOCTL_SET_VE_FREQ:
- {
-// int arg_rate = (int)arg;
-// if(arg_rate >= 320){
-// clk_set_rate(ve_moduleclk, pll4clk_rate/3);//ve_moduleclk rate is 320khz
-// }else if((arg_rate >= 240) && (arg_rate < 320)){
-// clk_set_rate(ve_moduleclk, pll4clk_rate/4);//ve_moduleclk rate is 240khz
-// }else if((arg_rate >= 160) && (arg_rate < 240)){
-// clk_set_rate(ve_moduleclk, pll4clk_rate/6);//ve_moduleclk rate is 160khz
-// }else{
-// printk("IOCTL_SET_VE_FREQ set ve freq error,%s,%d\n", __func__, __LINE__);
-// }
- break;
- }
- case IOCTL_GETVALUE_AVS2:
- /* Return AVS1 counter value */
- return readl(cedar_devp->iomap_addrs.regs_avs + 0x88);
-
- case IOCTL_ADJUST_AVS2:
- {
- int arg_s = (int)arg;
- int temp;
- if(MAGIC_VER_A == sw_get_ic_ver()){
- save_context();
- v = readl(cedar_devp->iomap_addrs.regs_avs + 0x8c);
- temp = v & 0xffff0000;
- temp =temp + temp*arg_s/100;
- temp = temp > (244<<16) ? (244<<16) : temp;
- temp = temp < (234<<16) ? (234<<16) : temp;
- v = (temp & 0xffff0000) | (v&0x0000ffff);
- #ifdef CEDAR_DEBUG
- printk("Kernel AVS ADJUST Print: 0x%x\n", v);
- #endif
- writel(v, cedar_devp->iomap_addrs.regs_avs + 0x8c);
- restore_context();
- }else if(MAGIC_VER_B == sw_get_ic_ver()){
- v = readl(cedar_devp->iomap_addrs.regs_avs + 0x8c);
- temp = v & 0xffff0000;
- temp =temp + temp*arg_s/100;
- temp = temp > (244<<16) ? (244<<16) : temp;
- temp = temp < (234<<16) ? (234<<16) : temp;
- v = (temp & 0xffff0000) | (v&0x0000ffff);
- #ifdef CEDAR_DEBUG
- printk("Kernel AVS ADJUST Print: 0x%x\n", v);
- #endif
- writel(v, cedar_devp->iomap_addrs.regs_avs + 0x8c);
- }else{
- printk("IOCTL_ADJUST_AVS2 error:%s,%d\n", __func__, __LINE__);
- return -EFAULT;
- }
- break;
- }
-
- case IOCTL_ADJUST_AVS2_ABS:
- {
- int arg_s = (int)arg;
- int v_dst;
-
- switch(arg_s){
- case -2:
- v_dst = 234;
- break;
- case -1:
- v_dst = 236;
- break;
- case 1:
- v_dst = 242;
- break;
- case 2:
- v_dst = 244;
- break;
- default:
- v_dst = 239;
- break;
- }
-
- if(MAGIC_VER_A == sw_get_ic_ver()){
- save_context();
- v = readl(cedar_devp->iomap_addrs.regs_avs + 0x8c);
- v = (v_dst<<16) | (v&0x0000ffff);
- writel(v, cedar_devp->iomap_addrs.regs_avs + 0x8c);
- restore_context();
- }else if(MAGIC_VER_B == sw_get_ic_ver()){
- v = readl(cedar_devp->iomap_addrs.regs_avs + 0x8c);
- v = (v_dst<<16) | (v&0x0000ffff);
- writel(v, cedar_devp->iomap_addrs.regs_avs + 0x8c);
- }else{
- printk("IOCTL_ADJUST_AVS2 error:%s,%d\n", __func__, __LINE__);
- return -EFAULT;
- }
- break;
- }
-
- case IOCTL_CONFIG_AVS2:
- if(MAGIC_VER_A == sw_get_ic_ver()){
- save_context();
- /* Set AVS counter divisor */
- v = readl(cedar_devp->iomap_addrs.regs_avs + 0x8c);
- v = 239 << 16 | (v & 0xffff);
- writel(v, cedar_devp->iomap_addrs.regs_avs + 0x8c);
-
- /* Enable AVS_CNT1 and Pause it */
- v = readl(cedar_devp->iomap_addrs.regs_avs + 0x80);
- v |= 1 << 9 | 1 << 1;
- writel(v, cedar_devp->iomap_addrs.regs_avs + 0x80);
-
- /* Set AVS_CNT1 init value as zero */
- writel(0, cedar_devp->iomap_addrs.regs_avs + 0x88);
- restore_context();
- }else if(MAGIC_VER_B == sw_get_ic_ver()){
- /* Set AVS counter divisor */
- v = readl(cedar_devp->iomap_addrs.regs_avs + 0x8c);
- v = 239 << 16 | (v & 0xffff);
- writel(v, cedar_devp->iomap_addrs.regs_avs + 0x8c);
-
- /* Enable AVS_CNT1 and Pause it */
- v = readl(cedar_devp->iomap_addrs.regs_avs + 0x80);
- v |= 1 << 9 | 1 << 1;
- writel(v, cedar_devp->iomap_addrs.regs_avs + 0x80);
-
- /* Set AVS_CNT1 init value as zero */
- writel(0, cedar_devp->iomap_addrs.regs_avs + 0x88);
- }else{
- printk("IOCTL_CONFIG_AVS2 error:%s,%d\n", __func__, __LINE__);
- return -EFAULT;
- }
- break;
-
- case IOCTL_RESET_AVS2:
- /* Set AVS_CNT1 init value as zero */
- if(MAGIC_VER_A == sw_get_ic_ver()){
- save_context();
- writel(0, cedar_devp->iomap_addrs.regs_avs + 0x88);
- restore_context();
- }else if(MAGIC_VER_B == sw_get_ic_ver()){
- writel(0, cedar_devp->iomap_addrs.regs_avs + 0x88);
- }else{
- printk("IOCTL_RESET_AVS2 error:%s,%d\n", __func__, __LINE__);
- return -EFAULT;
- }
- break;
-
- case IOCTL_PAUSE_AVS2:
- /* Pause AVS_CNT1 */
- if(MAGIC_VER_A == sw_get_ic_ver()){
- save_context();
- v = readl(cedar_devp->iomap_addrs.regs_avs + 0x80);
- v |= 1 << 9;
- writel(v, cedar_devp->iomap_addrs.regs_avs + 0x80);
- restore_context();
- }else if(MAGIC_VER_B == sw_get_ic_ver()){
- v = readl(cedar_devp->iomap_addrs.regs_avs + 0x80);
- v |= 1 << 9;
- writel(v, cedar_devp->iomap_addrs.regs_avs + 0x80);
- }else{
- printk("IOCTL_PAUSE_AVS2 get error:%s,%d\n", __func__, __LINE__);
- return -EFAULT;
- }
- break;
-
- case IOCTL_START_AVS2:
- /* Start AVS_CNT1 : do not pause */
- if(MAGIC_VER_A == sw_get_ic_ver()){
- save_context();
- v = readl(cedar_devp->iomap_addrs.regs_avs + 0x80);
- v &= ~(1 << 9);
- writel(v, cedar_devp->iomap_addrs.regs_avs + 0x80);
- restore_context();
- }else if(MAGIC_VER_B == sw_get_ic_ver()){
- v = readl(cedar_devp->iomap_addrs.regs_avs + 0x80);
- v &= ~(1 << 9);
- writel(v, cedar_devp->iomap_addrs.regs_avs + 0x80);
- }else{
- printk("IOCTL_START_AVS2 error:%s,%d\n", __func__, __LINE__);
- return -EFAULT;
- }
- break;
-
- case IOCTL_GET_ENV_INFO:
- {
- struct cedarv_env_infomation env_info;
- env_info.phymem_start = (unsigned int)phys_to_virt(ve_start);
- env_info.phymem_total_size = ve_size;
- env_info.address_macc = (unsigned int)cedar_devp->iomap_addrs.regs_macc;
- if (copy_to_user((char *)arg, &env_info, sizeof(struct cedarv_env_infomation)))
- return -EFAULT;
- }
- break;
- case IOCTL_GET_IC_VER:
- {
- if(MAGIC_VER_A == sw_get_ic_ver()){
- return 0x0A10000A;
- }else if(MAGIC_VER_B == sw_get_ic_ver()){
- return 0x0A10000B;
- }else{
- printk("IC_VER get error:%s,%d\n", __func__, __LINE__);
- return -EFAULT;
- }
- }
- default:
- break;
- }
- return ret;
-}
-
-static int cedardev_open(struct inode *inode, struct file *filp)
-{
- struct cedar_dev *devp;
- devp = container_of(inode->i_cdev, struct cedar_dev, cdev);
- filp->private_data = devp;
- if (down_interruptible(&devp->sem)) {
- return -ERESTARTSYS;
- }
- /* init other resource here */
- devp->irq_flag = 0;
- up(&devp->sem);
- nonseekable_open(inode, filp);
- return 0;
-}
-
-static int cedardev_release(struct inode *inode, struct file *filp)
-{
- struct cedar_dev *devp;
-
- devp = filp->private_data;
- if (down_interruptible(&devp->sem)) {
- return -ERESTARTSYS;
- }
- /* release other resource here */
- devp->irq_flag = 1;
- up(&devp->sem);
- return 0;
-}
-
-void cedardev_vma_open(struct vm_area_struct *vma)
-{
-}
-
-void cedardev_vma_close(struct vm_area_struct *vma)
-{
-}
-
-static struct vm_operations_struct cedardev_remap_vm_ops = {
- .open = cedardev_vma_open,
- .close = cedardev_vma_close,
-};
-
-static int cedardev_mmap(struct file *filp, struct vm_area_struct *vma)
-{
- unsigned long temp_pfn;
- unsigned int VAddr;
- struct iomap_para addrs;
-
- unsigned int io_ram = 0;
- VAddr = vma->vm_pgoff << 12;
- addrs = cedar_devp->iomap_addrs;
-
- if (VAddr == (unsigned int)addrs.regs_macc) {
- temp_pfn = MACC_REGS_BASE >> 12;
- io_ram = 1;
- } else {
- temp_pfn = (__pa(vma->vm_pgoff << 12))>>12;
- io_ram = 0;
- }
-
- if (io_ram == 0) {
- /* Set reserved and I/O flag for the area. */
- vma->vm_flags |= VM_RESERVED | VM_IO;
-
- /* Select uncached access. */
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-
- if (remap_pfn_range(vma, vma->vm_start, temp_pfn,
- vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
- return -EAGAIN;
- }
- } else {
- /* Set reserved and I/O flag for the area. */
- vma->vm_flags |= VM_RESERVED | VM_IO;
- /* Select uncached access. */
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-
- if (io_remap_pfn_range(vma, vma->vm_start, temp_pfn,
- vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
- return -EAGAIN;
- }
- }
-
- vma->vm_ops = &cedardev_remap_vm_ops;
- cedardev_vma_open(vma);
-
- return 0;
-}
-
-static int snd_sw_cedar_suspend(struct platform_device *pdev,pm_message_t state)
-{
- disable_cedar_hw_clk();
-
- return 0;
-}
-
-static int snd_sw_cedar_resume(struct platform_device *pdev)
-{
- if(cedar_devp->ref_count == 0){
- return 0;
- }
- enable_cedar_hw_clk();
-
- return 0;
-}
-
-static struct file_operations cedardev_fops = {
- .owner = THIS_MODULE,
- .mmap = cedardev_mmap,
- .poll = cedardev_poll,
- .open = cedardev_open,
- .release = cedardev_release,
- .llseek = no_llseek,
- .unlocked_ioctl = cedardev_ioctl,
-};
-
-/*data relating*/
-static struct platform_device sw_device_cedar = {
- .name = "sun4i-cedar",
-};
-
-/*method relating*/
-static struct platform_driver sw_cedar_driver = {
-#ifdef CONFIG_PM
- .suspend = snd_sw_cedar_suspend,
- .resume = snd_sw_cedar_resume,
-#endif
- .driver = {
- .name = "sun4i-cedar",
- },
-};
-
-static int __init cedardev_init(void)
-{
- int ret = 0;
- int err = 0;
- int devno;
- unsigned int val;
- dev_t dev = 0;
-
- if (ve_size == 0)
- return -ENODEV;
-
- printk("[cedar dev]: install start!!!\n");
- if((platform_device_register(&sw_device_cedar))<0)
- return err;
-
- if ((err = platform_driver_register(&sw_cedar_driver)) < 0)
- return err;
- /*register or alloc the device number.*/
- if (g_dev_major) {
- dev = MKDEV(g_dev_major, g_dev_minor);
- ret = register_chrdev_region(dev, 1, "cedar_dev");
- } else {
- ret = alloc_chrdev_region(&dev, g_dev_minor, 1, "cedar_dev");
- g_dev_major = MAJOR(dev);
- g_dev_minor = MINOR(dev);
- }
-
- if (ret < 0) {
- printk(KERN_WARNING "cedar_dev: can't get major %d\n", g_dev_major);
- return ret;
- }
- spin_lock_init(&cedar_spin_lock);
- cedar_devp = kmalloc(sizeof(struct cedar_dev), GFP_KERNEL);
- if (cedar_devp == NULL) {
- printk("malloc mem for cedar device err\n");
- return -ENOMEM;
- }
- memset(cedar_devp, 0, sizeof(struct cedar_dev));
- cedar_devp->irq = VE_IRQ_NO;
-
- sema_init(&cedar_devp->sem, 1);
- init_waitqueue_head(&cedar_devp->wq);
-
- memset(&cedar_devp->iomap_addrs, 0, sizeof(struct iomap_para));
-
- ret = request_irq(VE_IRQ_NO, VideoEngineInterupt, 0, "cedar_dev", NULL);
- if (ret < 0) {
- printk("request irq err\n");
- return -EINVAL;
- }
- /* map for macc io space */
- cedar_devp->iomap_addrs.regs_macc = ioremap(MACC_REGS_BASE, 4096);
- if (!cedar_devp->iomap_addrs.regs_macc){
- printk("cannot map region for macc");
- }
- cedar_devp->iomap_addrs.regs_avs = ioremap(AVS_REGS_BASE, 1024);
-
- //VE_SRAM mapping to AC320
- val = readl(0xf1c00000);
- val &= 0x80000000;
- writel(val,0xf1c00000);
- //remapping SRAM to MACC for codec test
- val = readl(0xf1c00000);
- val |= 0x7fffffff;
- writel(val,0xf1c00000);
- /*********for fpga*********/
-// val = readl(0xf1c2013c);
-// val |= 0x00000001;
-// writel(val,0xf1c2013c);
- /*********for fpga*********/
- ve_pll4clk = clk_get(NULL,"ve_pll");
- pll4clk_rate = clk_get_rate(ve_pll4clk);
- /* getting ahb clk for ve!(macc) */
- ahb_veclk = clk_get(NULL,"ahb_ve");
- ve_moduleclk = clk_get(NULL,"ve");
- if(clk_set_parent(ve_moduleclk, ve_pll4clk)){
- printk("set parent of ve_moduleclk to ve_pll4clk failed!\n");
- return -EFAULT;
- }
- clk_set_rate(ve_moduleclk, pll4clk_rate/2);
- // //macc PLL
-// val = readl(0xf1c20018);
-// val &= 0x7ffc0000;
-// val |= 1<<31;
-// val |= (0x0)<<16; //Pb
-// val |= (0x3)<<8; //Nb
-// val |= (0x3)<<4; //Kb
-// val |= (0x0)<<0; //Mb
-// writel(val,0xf1c20018);
- /*geting dram clk for ve!*/
- dram_veclk = clk_get(NULL, "sdram_ve");
- hosc_clk = clk_get(NULL,"hosc");
- avs_moduleclk = clk_get(NULL,"avs");
- if(clk_set_parent(avs_moduleclk, hosc_clk)){
- printk("set parent of avs_moduleclk to hosc_clk failed!\n");
- return -EFAULT;
- }
-
- /*for clk test*/
- #ifdef CEDAR_DEBUG
- printk("PLL4 CLK:0xf1c20018 is:%x\n", *(volatile int *)0xf1c20018);
- printk("AHB CLK:0xf1c20064 is:%x\n", *(volatile int *)0xf1c20064);
- printk("VE CLK:0xf1c2013c is:%x\n", *(volatile int *)0xf1c2013c);
- printk("SDRAM CLK:0xf1c20100 is:%x\n", *(volatile int *)0xf1c20100);
- printk("SRAM:0xf1c00000 is:%x\n", *(volatile int *)0xf1c00000);
- #endif
- /* Create char device */
- devno = MKDEV(g_dev_major, g_dev_minor);
- cdev_init(&cedar_devp->cdev, &cedardev_fops);
- cedar_devp->cdev.owner = THIS_MODULE;
- cedar_devp->cdev.ops = &cedardev_fops;
- ret = cdev_add(&cedar_devp->cdev, devno, 1);
- if (ret) {
- printk(KERN_NOTICE "Err:%d add cedardev", ret);
- }
- cedar_devp->class = class_create(THIS_MODULE, "cedar_dev");
- cedar_devp->dev = device_create(cedar_devp->class, NULL, devno, NULL, "cedar_dev");
- /*在cedar drv初始化的时候,初始化定时器并设置它的成员
- * 在有任务插入run_task_list的时候,启动定时器,并设置定时器的时钟为当前系统的jiffies,参考cedardev_insert_task
- */
- setup_timer(&cedar_devp->cedar_engine_timer, cedar_engine_for_events, (unsigned long)cedar_devp);
- setup_timer(&cedar_devp->cedar_engine_timer_rel, cedar_engine_for_timer_rel, (unsigned long)cedar_devp);
- printk("[cedar dev]: install end!!!\n");
- return 0;
-}
-module_init(cedardev_init);
-
-static void __exit cedardev_exit(void)
-{
- dev_t dev;
- dev = MKDEV(g_dev_major, g_dev_minor);
-
- free_irq(VE_IRQ_NO, NULL);
- iounmap(cedar_devp->iomap_addrs.regs_macc);
- iounmap(cedar_devp->iomap_addrs.regs_avs);
- /* Destroy char device */
- if(cedar_devp){
- cdev_del(&cedar_devp->cdev);
- device_destroy(cedar_devp->class, dev);
- class_destroy(cedar_devp->class);
- }
- clk_disable(dram_veclk);
- clk_put(dram_veclk);
-
- clk_disable(ve_moduleclk);
- clk_put(ve_moduleclk);
-
- clk_disable(ahb_veclk);
- clk_put(ahb_veclk);
-
- clk_put(ve_pll4clk);
-
- clk_disable(avs_moduleclk);
- clk_put(avs_moduleclk);
-
- unregister_chrdev_region(dev, 1);
- platform_driver_unregister(&sw_cedar_driver);
- if (cedar_devp) {
- kfree(cedar_devp);
- }
-}
-module_exit(cedardev_exit);
-
-MODULE_AUTHOR("Soft-Allwinner");
-MODULE_DESCRIPTION("User mode CEDAR device interface");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/media/video/sun5i/sun5i_cedar.h b/drivers/media/video/sun5i/sun5i_cedar.h
deleted file mode 100644
index 3427297..0000000
--- a/drivers/media/video/sun5i/sun5i_cedar.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * drivers/media/video/sun5i/sun5i_cedar.h
- *
- * (C) Copyright 2007-2012
- * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program 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 program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
-**************************************************************************************************************
-* eLDK
-* the Easy Portable/Player Develop Kits
-* desktop system
-*
-* (c) Copyright 2009-2012, ,HUANGXIN China
-* All Rights Reserved
-*
-* File : sun4i_cedar.h
-* By : HUANGXIN
-* Func :
-* Version : v1.0
-* ============================================================================================================
-* 2011-5-25 9:57:05 HUANGXIN create this file, implements the fundemental interface;
-**************************************************************************************************************
-*/
-#ifndef _SUN4I_CEDAR_H_
-#define _SUN4I_CEDAR_H_
-
-enum IOCTL_CMD {
- IOCTL_UNKOWN = 0x100,
- IOCTL_GET_ENV_INFO,
- IOCTL_WAIT_VE,
- IOCTL_RESET_VE,
- IOCTL_ENABLE_VE,
- IOCTL_DISABLE_VE,
- IOCTL_SET_VE_FREQ,
-
- IOCTL_CONFIG_AVS2 = 0x200,
- IOCTL_GETVALUE_AVS2 ,
- IOCTL_PAUSE_AVS2 ,
- IOCTL_START_AVS2 ,
- IOCTL_RESET_AVS2 ,
- IOCTL_ADJUST_AVS2,
- IOCTL_ENGINE_REQ,
- IOCTL_ENGINE_REL,
- IOCTL_ENGINE_CHECK_DELAY,
- IOCTL_GET_IC_VER,
-
- IOCTL_ADJUST_AVS2_ABS,
-};
-
-struct cedarv_env_infomation{
- unsigned int phymem_start;
- int phymem_total_size;
- unsigned int address_macc;
-};
-
-struct __cedarv_task {
- int task_prio;
- int ID;
- unsigned long timeout;
- unsigned int frametime;
- unsigned int block_mode;
-};
-
-struct cedarv_engine_task {
- struct __cedarv_task t;
- struct list_head list;
- struct task_struct *task_handle;
- unsigned int status;
- unsigned int running;
- unsigned int is_first_task;
-};
-
-/*利用优先级task_prio查询当前运行task的frametime,和比优先级task_prio高的task可能运行的总时间total_time*/
-struct cedarv_engine_task_info {
- int task_prio;
- unsigned int frametime;
- unsigned int total_time;
-};
-
-/*--------------------------------------------------------------------------------*/
-#define REGS_pBASE (0x01C00000) // register base addr
-
-#define SRAM_REGS_pBASE (REGS_pBASE + 0x00000) // SRAM Controller
-#define CCMU_REGS_pBASE (REGS_pBASE + 0x20000) // clock manager unit
-#define MACC_REGS_pBASE (REGS_pBASE + 0x0E000) // media accelerate VE
-#define SS_REGS_pBASE (REGS_pBASE + 0x15000) // Security System
-#define SDRAM_REGS_pBASE (REGS_pBASE + 0x01000) // SDRAM Controller
-#define AVS_REGS_pBASE (REGS_pBASE + 0x20c00)
-
-#define SRAM_REGS_BASE SRAM_REGS_pBASE // SRAM Controller
-#define CCMU_REGS_BASE CCMU_REGS_pBASE // Clock Control manager unit OK
-#define MACC_REGS_BASE MACC_REGS_pBASE // Media ACCelerate
-#define SS_REGS_BASE SS_REGS_pBASE // Security System
-#define SDRAM_REGS_BASE SDRAM_REGS_pBASE //SDRAM Controller OK
-#define AVS_REGS_BASE AVS_REGS_pBASE
-
-#define MPEG_REGS_BASE (MACC_REGS_BASE + 0x100) // MPEG engine
-#define H264_REGS_BASE (MACC_REGS_BASE + 0x200) // H264 engine
-#define VC1_REGS_BASE (MACC_REGS_BASE + 0x300) // VC-1 engine
-
-#define SRAM_REGS_SIZE (4096) // 4K
-#define CCMU_REGS_SIZE (1024) // 1K
-#define MACC_REGS_SIZE (4096) // 4K
-#define SS_REGS_SIZE (4096) // 4K
-/*--------------------------------------------------------------------------------*/
-
-#define SRAM_REG_o_CFG (0x00)
-#define SRAM_REG_ADDR_CFG (SRAM_REGS_BASE + SRAM_REG_o_CFG) // SRAM MAP Cfg Reg 0
-/*--------------------------------------------------------------------------------*/
-
-#endif
diff --git a/drivers/media/video/sunxi/Kconfig b/drivers/media/video/sunxi/Kconfig
new file mode 100644
index 0000000..50bd199
--- /dev/null
+++ b/drivers/media/video/sunxi/Kconfig
@@ -0,0 +1,18 @@
+config VIDEO_DECODER_SUNXI
+ tristate "sunxi video decoder support"
+ depends on VIDEO_SUNXI_CEDAR
+ default y
+ ---help---
+ This is the driver for sunxi video decoder, including h264/
+ mpeg4/mpeg2/vc1/rmvb.
+ To compile this driver as a module, choose M here: the
+ module will be called cedar_dev.
+
+config VIDEO_AVS_COUNTER
+ tristate "sunxi av-sync counter support"
+ depends on VIDEO_SUNXI_CEDAR
+ default n
+ ---help---
+ This is the driver for sunxi av-sync counter.
+ To compile this driver as a module, choose M here: the
+ module will be called avs_dev.
diff --git a/drivers/media/video/sunxi/Makefile b/drivers/media/video/sunxi/Makefile
new file mode 100644
index 0000000..378790a
--- /dev/null
+++ b/drivers/media/video/sunxi/Makefile
@@ -0,0 +1,5 @@
+# AW16XX Audio Card Support
+obj-$(CONFIG_VIDEO_DECODER_SUNXI) += sunxi_cedar_mod.o
+obj-$(CONFIG_VIDEO_AVS_COUNTER) += sunxi_avs.o
+
+sunxi_cedar_mod-objs := sunxi_cedar.o cache-v7.o
diff --git a/drivers/media/video/sunxi/cache-v7.S b/drivers/media/video/sunxi/cache-v7.S
new file mode 100644
index 0000000..a2279db
--- /dev/null
+++ b/drivers/media/video/sunxi/cache-v7.S
@@ -0,0 +1,65 @@
+/*
+ * drivers/media/video/sunxi/cache-v7.S
+ *
+ * (C) Copyright 2007-2012
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program 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 program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+
+#ifndef __ASSEMBLY__
+#define __ASSEMBLY__
+#endif
+#include <asm/assembler.h>
+/*
+ c code declared as follows:
+ int flush_clean_user_range(long start, long end);
+*/
+ .macro dcache_line_size, reg, tmp
+ mrc p15, 1, \tmp, c0, c0, 0 @ read CSIDR
+ and \tmp, \tmp, #7 @ cache line size encoding
+ mov \reg, #16 @ size offset
+ mov \reg, \reg, lsl \tmp @ actual cache line size
+ .endm
+
+ .text
+ .globl flush_clean_user_range
+flush_clean_user_range:
+ dcache_line_size r2, r3
+ sub r3, r2, #1
+ bic r0, r0, r3
+1:
+ USER( mcr p15, 0, r0, c7, c14, 1 ) @ clean and flush D line to the point of unification
+ add r0, r0, r2
+2:
+ cmp r0, r1
+ blo 1b
+ mov r0, #0
+ dsb
+ mov pc, lr
+
+/*
+ * Fault handling for the cache operation above. If the virtual address in r0
+ * isn't mapped, just try the next page.
+ */
+9001:
+ mov r0, r0, lsr #12
+ mov r0, r0, lsl #12
+ add r0, r0, #4096
+ b 2b
+
+
diff --git a/drivers/media/video/sunxi/readme b/drivers/media/video/sunxi/readme
new file mode 100644
index 0000000..a91b192
--- /dev/null
+++ b/drivers/media/video/sunxi/readme
@@ -0,0 +1,48 @@
+/*
+ * drivers/media/video/sun4i/readme
+ *
+ * (C) Copyright 2007-2012
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program 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 program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#------------------------------------------------------------
+# Cedar_dev : video engine driver
+#------------------------------------------------------------
+
+#------------------------------------------------------------
+#@version: cedar_vers0_08
+#@Author : Truby.Zong
+#@Date : 2011-4-06
+#@Description:
+# The second version of cedar video engine driver, which
+# add VD/DE SRAM prority and change file name.
+#-------------------------------------------------------------
+#
+#------------------------------------------------------------
+#@version: Vers0_01
+#@Author : Truby.Zong
+#@Date : 2011-3-18
+#@Description:
+# The first version of cedar video engine driver, which
+#handles the irq/clock/phy memory alloc of the cedar device,
+#and also the AV-SYNC counter (AVS_CNT1);
+# Please pay attention to the method to request/remap IO
+#resource and request/free irq, which are just handle once in
+#module init and module exit.
+#-------------------------------------------------------------
+
diff --git a/drivers/media/video/sunxi/sunxi_avs.c b/drivers/media/video/sunxi/sunxi_avs.c
new file mode 100644
index 0000000..5923c3b
--- /dev/null
+++ b/drivers/media/video/sunxi/sunxi_avs.c
@@ -0,0 +1,426 @@
+/*
+ * drivers/media/video/sunxi/sunxi_avs.c
+ *
+ * (C) Copyright 2007-2012
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program 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 program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * sunxi_avs.c
+ * driver for av-sync counter
+ * Author : Truby.Zong <truby....@chipsbank.com>
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/ioctl.h>
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/preempt.h>
+#include <linux/cdev.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/clk.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <mach/hardware.h>
+#include <asm/system.h>
+#include <linux/rmap.h>
+#include <linux/wait.h>
+#include <linux/poll.h>
+#include <linux/spinlock.h>
+
+#include "sunxi_cedar.h"
+
+#define DRV_VERSION "0.01alpha"
+
+#ifndef AVSDEV_MAJOR
+#define AVSDEV_MAJOR (151)
+#endif
+#ifndef AVSDEV_MINOR
+#define AVSDEV_MINOR (0)
+#endif
+
+#undef _info
+#ifdef CEDAR_DEBUG
+# define _info(fmt, args...) printk( KERN_DEBUG "[avs]: " fmt, ## args)
+#else
+# define _info(fmt, args...)
+#endif
+
+int g_dev_major = AVSDEV_MAJOR;
+int g_dev_minor = AVSDEV_MINOR;
+module_param(g_dev_major, int, S_IRUGO);
+module_param(g_dev_minor, int, S_IRUGO);
+
+struct iomap_resource{
+ struct resource *io_sram;
+ struct resource *io_ccmu;
+ struct resource *io_macc;
+ struct resource *io_mpeg;
+ struct resource *io_vc1;
+ struct resource *io_memc;
+};
+struct iomap_resource iomap_res;
+
+struct iomap_para{
+ volatile char* regs_sram;
+ volatile char* regs_ccmu;
+ volatile char* regs_macc;
+ volatile char* regs_mpeg;
+ volatile char* regs_vc1;
+ volatile char* regs_memc;
+};
+
+struct avs_dev {
+ struct cdev cdev; /* char device struct */
+ struct device *dev; /* ptr to class device struct */
+ struct class *class; /* class for auto create device node */
+
+ struct semaphore sem; /* mutual exclusion semaphore */
+ spinlock_t lock; /* spinlock to pretect ioctl access */
+
+ struct iomap_para iomap_addrs; /* io remap addrs */
+ struct iomap_resource iomap_res; /* io remap resources */
+};
+struct avs_dev *avs_devp;
+
+/*
+ * ioremap and request iomem
+ */
+static void avs_register_iomem(struct avs_dev *devp)
+{
+ struct resource *res;
+ char *addr;
+
+ memset(&devp->iomap_res, 0, sizeof(struct iomap_resource));
+ memset(&devp->iomap_addrs, 0, sizeof(struct iomap_para));
+
+ /* request mem for ccmu */
+ res = request_mem_region(CCMU_REGS_pBASE, 1024, "ccmu");
+ if (res == NULL) {
+ printk("Cannot reserve region for ccmu\n");
+ goto err_out;
+ }
+ devp->iomap_res.io_ccmu = res;
+
+ /* ioremap for ccmu */
+ addr = ioremap(CCMU_REGS_pBASE, 4096);
+ if (!addr){
+ printk("cannot map region for ccmu");
+ goto err_out;
+ }
+ devp->iomap_addrs.regs_ccmu = addr;
+
+ return;
+
+err_out:
+ if (devp->iomap_addrs.regs_ccmu)
+ iounmap(devp->iomap_addrs.regs_ccmu);
+}
+
+/*
+ * unmap/release iomem
+ */
+static void avs_iomem_unregister(struct avs_dev *devp)
+{
+ if (devp->iomap_res.io_ccmu) {
+ release_resource(devp->iomap_res.io_ccmu);
+ devp->iomap_res.io_ccmu = NULL;
+ }
+
+ /* iounmap */
+ if (devp->iomap_addrs.regs_ccmu) {
+ iounmap(devp->iomap_addrs.regs_ccmu);
+ devp->iomap_addrs.regs_ccmu = NULL;
+ }
+}
+
+/*
+ * ioctl function
+ * including : wait video engine done,
+ * AVS Counter control,
+ * Physical memory control,
+ * module clock/freq control.
+ */
+long avsdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ long ret;
+ unsigned int v;
+
+ spinlock_t *lock;
+ struct avs_dev *devp;
+
+ ret = 0;
+ devp = filp->private_data;
+ lock = &devp->lock;
+
+ switch (cmd)
+ {
+ case IOCTL_GETVALUE_AVS2:
+ spin_lock(lock);
+
+ v = readl(devp->iomap_addrs.regs_ccmu + 0xc40);
+
+ spin_unlock(lock);
+ return v;
+
+ case IOCTL_CONFIG_AVS2:
+ spin_lock(lock);
+
+ v = readl(devp->iomap_addrs.regs_ccmu + 0xc44);
+ v = 239<<16 | (v&0xffff);
+ writel(v, devp->iomap_addrs.regs_ccmu + 0xc44);
+ v = readl(devp->iomap_addrs.regs_ccmu + 0xc38);
+ v |= 1<<9 | 1<<1;
+ writel(v, devp->iomap_addrs.regs_ccmu + 0xc38);
+ writel(0, devp->iomap_addrs.regs_ccmu + 0xc40);
+
+ spin_unlock(lock);
+ break;
+
+ case IOCTL_RESET_AVS2:
+ spin_lock(lock);
+
+ writel(0, devp->iomap_addrs.regs_ccmu + 0xc40);
+
+ spin_unlock(lock);
+ break;
+
+ case IOCTL_PAUSE_AVS2:
+ spin_lock(lock);
+
+ v = readl(devp->iomap_addrs.regs_ccmu + 0xc38);
+ v |= 1<<9;
+ writel(v, devp->iomap_addrs.regs_ccmu + 0xc38);
+
+ spin_unlock(lock);
+ break;
+
+ case IOCTL_START_AVS2:
+ spin_lock(lock);
+
+ v = readl(devp->iomap_addrs.regs_ccmu + 0xc38);
+ v &= ~(1<<9);
+ writel(v, devp->iomap_addrs.regs_ccmu + 0xc38);
+
+ spin_unlock(lock);
+ break;
+
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+static int avsdev_open(struct inode *inode, struct file *filp)
+{
+ struct avs_dev *devp;
+ devp = container_of(inode->i_cdev, struct avs_dev, cdev);
+ filp->private_data = devp;
+
+ if (down_interruptible(&devp->sem)) {
+ return -ERESTARTSYS;
+ }
+
+ // init other resource here
+
+ up(&devp->sem);
+
+ nonseekable_open(inode, filp);
+ return 0;
+}
+
+static int avsdev_release(struct inode *inode, struct file *filp)
+{
+ struct avs_dev *devp;
+
+ devp = filp->private_data;
+
+ if (down_interruptible(&devp->sem)) {
+ return -ERESTARTSYS;
+ }
+
+ /* release other resource here */
+
+ up(&devp->sem);
+ return 0;
+}
+
+void avsdev_vma_open(struct vm_area_struct *vma)
+{
+ printk(KERN_NOTICE "avsdev VMA open, virt %lx, phys %lx\n",
+ vma->vm_start, vma->vm_pgoff << PAGE_SHIFT);
+ return;
+}
+
+void avsdev_vma_close(struct vm_area_struct *vma)
+{
+ printk(KERN_NOTICE "avsdev VMA close.\n");
+ return;
+}
+
+static struct vm_operations_struct avsdev_remap_vm_ops = {
+ .open = avsdev_vma_open,
+ .close = avsdev_vma_close,
+};
+
+static int avsdev_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ unsigned long temp_pfn;
+ unsigned int VAddr;
+ struct iomap_para addrs;
+
+ unsigned int io_ram = 0;
+ VAddr = vma->vm_pgoff << 12;
+
+ addrs = avs_devp->iomap_addrs;
+
+ if(VAddr == (unsigned int)addrs.regs_ccmu) {
+ temp_pfn = CCMU_REGS_pBASE >> 12;
+ io_ram = 1;
+ } else {
+ temp_pfn = (__pa(vma->vm_pgoff << 12))>>12;
+ io_ram = 0;
+ }
+
+ if (io_ram == 0) {
+ /* Set reserved and I/O flag for the area. */
+ vma->vm_flags |= VM_RESERVED | VM_IO;
+
+ /* Select uncached access. */
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+ if (remap_pfn_range(vma, vma->vm_start, temp_pfn,
+ vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
+ return -EAGAIN;
+ }
+ } else {
+ /* Set reserved and I/O flag for the area. */
+ vma->vm_flags |= VM_RESERVED | VM_IO;
+
+ /* Select uncached access. */
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+ if (io_remap_pfn_range(vma, vma->vm_start, temp_pfn,
+ vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
+ return -EAGAIN;
+ }
+ }
+
+ vma->vm_ops = &avsdev_remap_vm_ops;
+ avsdev_vma_open(vma);
+
+ return 0;
+}
+
+static struct file_operations avsdev_fops = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = avsdev_ioctl,
+ .mmap = avsdev_mmap,
+ .open = avsdev_open,
+ .release = avsdev_release,
+ .llseek = no_llseek,
+};
+
+static int __init avsdev_init(void)
+{
+ int ret;
+ int devno;
+ dev_t dev = 0;
+
+ printk("[tt]----- avs_dev driver load... ----\n");
+ if (g_dev_major) {
+ dev = MKDEV(g_dev_major, g_dev_minor);
+ ret = register_chrdev_region(dev, 1, "avs_dev");
+ } else {
+ ret = alloc_chrdev_region(&dev, g_dev_minor, 1, "avs_dev");
+ g_dev_major = MAJOR(dev);
+ g_dev_minor = MINOR(dev);
+ }
+
+ if (ret < 0) {
+ printk(KERN_WARNING "avs_dev: can't get major %d\n", g_dev_major);
+ return ret;
+ }
+
+ avs_devp = kmalloc(sizeof(struct avs_dev), GFP_KERNEL);
+ if (avs_devp == NULL) {
+ printk("malloc mem for avs device err\n");
+ return -ENOMEM;
+ }
+ memset(avs_devp, 0, sizeof(struct avs_dev));
+
+ sema_init(&avs_devp->sem,1);
+
+ /* request resources and ioremap */
+ printk("[tt]----- register iomem ----\n");
+ avs_register_iomem(avs_devp);
+
+ /* init lock for protect ioctl access */
+ spin_lock_init(&avs_devp->lock);
+
+ devno = MKDEV(g_dev_major, g_dev_minor);
+ cdev_init(&avs_devp->cdev, &avsdev_fops);
+ avs_devp->cdev.owner = THIS_MODULE;
+ avs_devp->cdev.ops = &avsdev_fops;
+ ret = cdev_add(&avs_devp->cdev, devno, 1);
+ if (ret) {
+ printk(KERN_NOTICE "Err:%d add avsdev", ret);
+ }
+
+ avs_devp->class = class_create(THIS_MODULE, "avs_dev");
+ avs_devp->dev = device_create(avs_devp->class, NULL, devno, NULL, "avs_dev");
+
+ printk("[tt]--- avs_dev driver load ok!! -----\n");
+ return 0;
+}
+module_init(avsdev_init);
+
+static void __exit avsdev_exit(void)
+{
+ dev_t dev;
+ dev = MKDEV(g_dev_major, g_dev_minor);
+
+ /* Unregister iomem and iounmap */
+ avs_iomem_unregister(avs_devp);
+
+ if (avs_devp) {
+ cdev_del(&avs_devp->cdev);
+ device_destroy(avs_devp->class, dev);
+ class_destroy(avs_devp->class);
+ }
+
+ unregister_chrdev_region(dev, 1);
+
+ if (avs_devp) {
+ kfree(avs_devp);
+ }
+}
+module_exit(avsdev_exit);
+
+MODULE_AUTHOR("Soft-Allwinner");
+MODULE_DESCRIPTION("avs device driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/media/video/sunxi/sunxi_cedar.c b/drivers/media/video/sunxi/sunxi_cedar.c
new file mode 100644
index 0000000..8036757
--- /dev/null
+++ b/drivers/media/video/sunxi/sunxi_cedar.c
@@ -0,0 +1,1113 @@
+/*
+ * drivers\media\video\sunxi\sunxi_cedar.c
+ * (C) Copyright 2007-2011
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * huangxin <huan...@allwinnertech.com>
+ *
+ * some simple description for this code
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/ioctl.h>
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/preempt.h>
+#include <linux/cdev.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/clk.h>
+#include <linux/rmap.h>
+#include <linux/wait.h>
+#include <linux/semaphore.h>
+#include <linux/poll.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+#include <linux/kthread.h>
+#include <linux/delay.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <mach/hardware.h>
+#include <asm/system.h>
+#include <asm/siginfo.h>
+#include <asm/signal.h>
+#include <mach/system.h>
+#include <mach/clock.h>
+#include "sunxi_cedar.h"
+
+#define DRV_VERSION "0.01alpha"
+
+#define CHIP_VERSION_F23
+
+#undef USE_CEDAR_ENGINE
+
+#ifndef CEDARDEV_MAJOR
+#define CEDARDEV_MAJOR (150)
+#endif
+#ifndef CEDARDEV_MINOR
+#define CEDARDEV_MINOR (0)
+#endif
+
+//#define CEDAR_DEBUG
+
+#define CONFIG_SW_SYSMEM_RESERVED_BASE 0x43000000
+#define CONFIG_SW_SYSMEM_RESERVED_SIZE 75776
+
+int g_dev_major = CEDARDEV_MAJOR;
+int g_dev_minor = CEDARDEV_MINOR;
+module_param(g_dev_major, int, S_IRUGO);//S_IRUGO represent that g_dev_major can be read,but canot be write
+module_param(g_dev_minor, int, S_IRUGO);
+
+#ifdef CHIP_VERSION_F23
+#define VE_IRQ_NO (53)
+#else
+#define VE_IRQ_NO (48)
+#endif
+
+struct clk *ve_moduleclk = NULL;
+struct clk *ve_pll4clk = NULL;
+struct clk *ahb_veclk = NULL;
+struct clk *dram_veclk = NULL;
+struct clk *avs_moduleclk = NULL;
+struct clk *hosc_clk = NULL;
+
+static unsigned long pll4clk_rate = 720000000;
+
+extern unsigned long ve_start;
+extern unsigned long ve_size;
+extern int flush_clean_user_range(long start, long end);
+struct iomap_para{
+ volatile char* regs_macc;
+ #ifdef CHIP_VERSION_F23
+ volatile char* regs_avs;
+ #else
+ volatile char* regs_ccmu;
+ #endif
+};
+
+static DECLARE_WAIT_QUEUE_HEAD(wait_ve);
+struct cedar_dev {
+ struct cdev cdev; /* char device struct */
+ struct device *dev; /* ptr to class device struct */
+ struct class *class; /* class for auto create device node */
+
+ struct semaphore sem; /* mutual exclusion semaphore */
+
+ wait_queue_head_t wq; /* wait queue for poll ops */
+
+ struct iomap_para iomap_addrs; /* io remap addrs */
+
+ struct timer_list cedar_engine_timer;
+ struct timer_list cedar_engine_timer_rel;
+
+ u32 irq; /* cedar video engine irq number */
+ u32 irq_flag; /* flag of video engine irq generated */
+ u32 irq_value; /* value of video engine irq */
+ u32 irq_has_enable;
+ u32 ref_count;
+};
+struct cedar_dev *cedar_devp;
+
+u32 int_sta=0,int_value;
+
+/*
+ * Video engine interrupt service routine
+ * To wake up ve wait queue
+ */
+static irqreturn_t VideoEngineInterupt(int irq, void *dev)
+{
+ unsigned int ve_int_ctrl_reg;
+ volatile int val;
+ int modual_sel;
+ struct iomap_para addrs = cedar_devp->iomap_addrs;
+
+ modual_sel = readl(addrs.regs_macc + 0);
+ modual_sel &= 0xf;
+
+ /* estimate Which video format */
+ switch (modual_sel)
+ {
+ case 0: //mpeg124
+ ve_int_ctrl_reg = (unsigned int)(addrs.regs_macc + 0x100 + 0x14);
+ break;
+ case 1: //h264
+ ve_int_ctrl_reg = (unsigned int)(addrs.regs_macc + 0x200 + 0x20);
+ break;
+ case 2: //vc1
+ ve_int_ctrl_reg = (unsigned int)(addrs.regs_macc + 0x300 + 0x24);
+ break;
+ case 3: //rmvb
+ ve_int_ctrl_reg = (unsigned int)(addrs.regs_macc + 0x400 + 0x14);
+ break;
+ case 0xa: //isp
+ ve_int_ctrl_reg = (unsigned int)(addrs.regs_macc + 0xa00 + 0x08);
+ break;
+ case 0xb: //avc enc
+ ve_int_ctrl_reg = (unsigned int)(addrs.regs_macc + 0xb00 + 0x14);
+ break;
+ default:
+ ve_int_ctrl_reg = (unsigned int)(addrs.regs_macc + 0x100 + 0x14);
+ printk("macc modual sel not defined!\n");
+ break;
+ }
+
+ //disable interrupt
+ if(modual_sel == 0) {
+ val = readl(ve_int_ctrl_reg);
+ writel(val & (~0x7c), ve_int_ctrl_reg);
+ } else {
+ val = readl(ve_int_ctrl_reg);
+ writel(val & (~0xf), ve_int_ctrl_reg);
+ }
+
+ cedar_devp->irq_value = 1; //hx modify 2011-8-1 16:08:47
+ cedar_devp->irq_flag = 1;
+ //any interrupt will wake up wait queue
+ wake_up_interruptible(&wait_ve); //ioctl
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * poll operateion for wait for ve irq
+ */
+unsigned int cedardev_poll(struct file *filp, struct poll_table_struct *wait)
+{
+ int mask = 0;
+ struct cedar_dev *devp = filp->private_data;
+
+ poll_wait(filp, &devp->wq, wait);
+ if (devp->irq_flag == 1) {
+ devp->irq_flag = 0;
+ mask |= POLLIN | POLLRDNORM;
+ }
+ return mask;
+}
+
+static int clk_status = 0;
+static LIST_HEAD(run_task_list);
+static LIST_HEAD(del_task_list);
+static spinlock_t cedar_spin_lock;
+#define CEDAR_RUN_LIST_NONULL -1
+#define CEDAR_NONBLOCK_TASK 0 //非阻塞
+#define CEDAR_BLOCK_TASK 1
+#define CLK_REL_TIME 10000 //10秒
+#define TIMER_CIRCLE 50 //50毫秒
+#define TASK_INIT 0x00
+#define TASK_TIMEOUT 0x55
+#define TASK_RELEASE 0xaa
+#define SIG_CEDAR 35
+
+int enable_cedar_hw_clk(void)
+{
+ unsigned long flags;
+ int res = -EFAULT;
+
+ spin_lock_irqsave(&cedar_spin_lock, flags);
+
+ if (clk_status == 1)
+ goto out;
+ clk_status = 1;
+
+ if(0 != clk_enable(ahb_veclk)){
+ printk("ahb_veclk failed; \n");
+ goto out;
+ }
+ if(0 != clk_enable(ve_moduleclk)){
+ printk("ve_moduleclk failed; \n");
+ goto out3;
+ }
+ if(0 != clk_enable(dram_veclk)){
+ printk("dram_veclk failed; \n");
+ goto out2;
+ }
+ if(0 != clk_enable(avs_moduleclk)){
+ printk("ve_moduleclk failed; \n");
+ goto out1;
+ }
+ #ifdef CEDAR_DEBUG
+ printk("%s,%d\n",__func__,__LINE__);
+ #endif
+ res = 0;
+ goto out;
+
+out1:
+ clk_disable(dram_veclk);
+out2:
+ clk_disable(ve_moduleclk);
+out3:
+ clk_disable(ahb_veclk);
+out:
+ spin_unlock_irqrestore(&cedar_spin_lock, flags);
+ return res;
+}
+
+int disable_cedar_hw_clk(void)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&cedar_spin_lock, flags);
+
+ if (clk_status == 0)
+ goto out;
+ clk_status = 0;
+
+ clk_disable(dram_veclk);
+ clk_disable(ve_moduleclk);
+ clk_disable(ahb_veclk);
+ clk_disable(avs_moduleclk);
+ #ifdef CEDAR_DEBUG
+ printk("%s,%d\n",__func__,__LINE__);
+ #endif
+out:
+ spin_unlock_irqrestore(&cedar_spin_lock, flags);
+ return 0;
+}
+
+void cedardev_insert_task(struct cedarv_engine_task* new_task)
+{
+ struct cedarv_engine_task *task_entry;
+ unsigned long flags;
+
+ spin_lock_irqsave(&cedar_spin_lock, flags);
+
+ if(list_empty(&run_task_list))
+ new_task->is_first_task = 1;
+
+ /*遍历run_task_list链表,如果插入的任务优先级比链表节点中的任务优先级高,并且当前插入任务不是第一个插入的任务。
+ *那么就将优先级高的任务放于前面,队列中的任务采取从高到底的优先级队列排队。
+ */
+ list_for_each_entry(task_entry, &run_task_list, list) {
+ if ((task_entry->is_first_task == 0) && (task_entry->running == 0) && (task_entry->t.task_prio < new_task->t.task_prio)) {
+ break;
+ }
+ }
+
+ list_add(&new_task->list, task_entry->list.prev);
+
+ #ifdef CEDAR_DEBUG
+ printk("%s,%d, TASK_ID:",__func__,__LINE__);
+ list_for_each_entry(task_entry, &run_task_list, list) {
+ printk("%d!", task_entry->t.ID);
+ }
+ printk("\n");
+ #endif
+ /*每次插入一个任务,就将当前的计时器时间重置为系统当前的jiffies*/
+ mod_timer(&cedar_devp->cedar_engine_timer, jiffies + 0);
+
+ spin_unlock_irqrestore(&cedar_spin_lock, flags);
+}
+
+int cedardev_del_task(int task_id)
+{
+ struct cedarv_engine_task *task_entry;
+ unsigned long flags;
+
+ spin_lock_irqsave(&cedar_spin_lock, flags);
+
+ /*遍历run_task_list链表
+ *如果找到对应的id号,那么就将run_task_list链表中的任务移到del_task_list链表的表头。
+ */
+ list_for_each_entry(task_entry, &run_task_list, list) {
+ if (task_entry->t.ID == task_id && task_entry->status != TASK_RELEASE) {
+ task_entry->status = TASK_RELEASE;
+
+ spin_unlock_irqrestore(&cedar_spin_lock, flags);
+ mod_timer(&cedar_devp->cedar_engine_timer, jiffies + 0);
+ return 0;
+ }
+ }
+ spin_unlock_irqrestore(&cedar_spin_lock, flags);
+
+ //找不到对应 ID
+ return -1;
+}
+
+int cedardev_check_delay(int check_prio)
+{
+ struct cedarv_engine_task *task_entry;
+ int timeout_total = 0;
+ unsigned long flags;
+
+ /*获取总的等待时间*/
+ spin_lock_irqsave(&cedar_spin_lock, flags);
+ list_for_each_entry(task_entry, &run_task_list, list) {
+ if ((task_entry->t.task_prio >= check_prio) || (task_entry->running == 1) || (task_entry->is_first_task == 1))
+ timeout_total = timeout_total + task_entry->t.frametime;
+ }
+
+ spin_unlock_irqrestore(&cedar_spin_lock, flags);
+#ifdef CEDAR_DEBUG
+ printk("%s,%d,%d\n", __func__, __LINE__, timeout_total);
+#endif
+ return timeout_total;
+}
+
+static void cedar_engine_for_timer_rel(unsigned long arg)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&cedar_spin_lock, flags);
+
+ if(list_empty(&run_task_list)){
+ disable_cedar_hw_clk();
+ } else {
+ printk("Warring: cedar engine timeout for clk disable, but task left, something wrong?\n");
+ mod_timer( &cedar_devp->cedar_engine_timer, jiffies + msecs_to_jiffies(TIMER_CIRCLE));
+ }
+
+ spin_unlock_irqrestore(&cedar_spin_lock, flags);
+}
+
+static void cedar_engine_for_events(unsigned long arg)
+{
+ struct cedarv_engine_task *task_entry, *task_entry_tmp;
+ struct siginfo info;
+ unsigned long flags;
+
+ spin_lock_irqsave(&cedar_spin_lock, flags);
+
+ list_for_each_entry_safe(task_entry, task_entry_tmp, &run_task_list, list) {
+ mod_timer(&cedar_devp->cedar_engine_timer_rel, jiffies + msecs_to_jiffies(CLK_REL_TIME));
+ if (task_entry->status == TASK_RELEASE ||
+ time_after(jiffies, task_entry->t.timeout)) {
+ if (task_entry->status == TASK_INIT)
+ task_entry->status = TASK_TIMEOUT;
+ list_move(&task_entry->list, &del_task_list);
+ }
+ }
+
+ list_for_each_entry_safe(task_entry, task_entry_tmp, &del_task_list, list) {
+ info.si_signo = SIG_CEDAR;
+ info.si_code = task_entry->t.ID;
+ if (task_entry->status == TASK_TIMEOUT){//表示任务timeout删除
+ info.si_errno = TASK_TIMEOUT;
+ send_sig_info(SIG_CEDAR, &info, task_entry->task_handle);
+ }else if(task_entry->status == TASK_RELEASE){//表示任务正常运行完毕删除
+ info.si_errno = TASK_RELEASE;
+ send_sig_info(SIG_CEDAR, &info, task_entry->task_handle);
+ }
+ list_del(&task_entry->list);
+ kfree(task_entry);
+ }
+
+ /*激活链表中的task*/
+ if(!list_empty(&run_task_list)){
+ task_entry = list_entry(run_task_list.next, struct cedarv_engine_task, list);
+ if(task_entry->running == 0){
+ task_entry->running = 1;
+ info.si_signo = SIG_CEDAR;
+ info.si_code = task_entry->t.ID;
+ info.si_errno = TASK_INIT; //任务已经启动
+ send_sig_info(SIG_CEDAR, &info, task_entry->task_handle);
+ }
+
+ mod_timer( &cedar_devp->cedar_engine_timer, jiffies + msecs_to_jiffies(TIMER_CIRCLE));
+ }
+
+ spin_unlock_irqrestore(&cedar_spin_lock, flags);
+}
+
+#ifdef CHIP_VERSION_F23
+static unsigned int g_ctx_reg0;
+static void save_context(void)
+{
+ g_ctx_reg0 = readl(0xf1c20e00);
+}
+
+static void restore_context(void)
+{
+ writel(g_ctx_reg0, 0xf1c20e00);
+}
+#else
+ #define save_context()
+ #define restore_context()
+#endif
+
+#ifdef CHIP_VERSION_F23
+short VEPLLTable[][6] =
+{
+ //set, actual, Nb, Kb, Mb, Pb
+ { 60, 60, 5, 2, 2, 1},
+ { 90, 90, 5, 2, 0, 2},
+ {120, 120, 5, 2, 2, 0},
+ {150, 150, 25, 0, 0, 2},
+ {180, 180, 5, 2, 0, 1},
+ {216, 216, 6, 2, 0, 1},
+ {240, 240, 5, 3, 0, 1},
+ {270, 270, 15, 2, 0, 2},
+ {300, 300, 25, 0, 0, 1},
+ {330, 336, 7, 1, 0, 0},
+ {360, 360, 5, 2, 0, 0},
+ {384, 384, 4, 3, 0, 0},
+ {402, 400, 25, 1, 2, 0},
+ {420, 416, 13, 3, 2, 0},
+ {444, 448, 14, 3, 2, 0},
+ {456, 456, 19, 0, 0, 0},
+ {468, 468, 13, 2, 0, 1},
+ {480, 480, 5, 3, 0, 0},
+ {492, 496, 31, 1, 2, 0},
+};
+#endif
+
+/*
+ * ioctl function
+ * including : wait video engine done,
+ * AVS Counter control,
+ * Physical memory control,
+ * module clock/freq control.
+ * cedar engine
+ */
+long cedardev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ long ret = 0;
+ unsigned int v;
+ int ve_timeout = 0;
+ struct cedar_dev *devp;
+#ifdef USE_CEDAR_ENGINE
+ int rel_taskid = 0;
+ struct __cedarv_task task_ret;
+ struct cedarv_engine_task *task_ptr = NULL;
+#endif
+ unsigned long flags;
+
+ devp = filp->private_data;
+
+ switch (cmd)
+ {
+ case IOCTL_ENGINE_REQ:
+ #ifdef USE_CEDAR_ENGINE
+ if(copy_from_user(&task_ret, (void __user*)arg, sizeof(struct __cedarv_task))){
+ printk("IOCTL_ENGINE_REQ copy_from_user fail\n");
+ return -EFAULT;
+ }
+ spin_lock_irqsave(&cedar_spin_lock, flags);
+ /*如果task为非阻塞状态,请求者可以立即返回*/
+ if(!list_empty(&run_task_list) && ( task_ret.block_mode == CEDAR_NONBLOCK_TASK)){
+ spin_unlock_irqrestore(&cedar_spin_lock, flags);
+ return CEDAR_RUN_LIST_NONULL; //run_task_list里面有任务,返回-1
+ }
+ spin_unlock_irqrestore(&cedar_spin_lock, flags);
+
+ /*如果task为阻塞状态,将task插入run_task_list链表中*/
+ task_ptr = kmalloc(sizeof(struct cedarv_engine_task), GFP_KERNEL);
+ if(!task_ptr){
+ printk("get mem for IOCTL_ENGINE_REQ\n");
+ return PTR_ERR(task_ptr);
+ }
+ task_ptr->task_handle = current;
+ task_ptr->t.ID = task_ret.ID;
+ task_ptr->t.timeout = jiffies + msecs_to_jiffies(1000*task_ret.timeout);//ms to jiffies
+ task_ptr->t.frametime = task_ret.frametime;
+ task_ptr->t.task_prio = task_ret.task_prio;
+ task_ptr->running = 0;
+ task_ptr->is_first_task = 0;
+ task_ptr->status = TASK_INIT;
+
+ cedardev_insert_task(task_ptr);
+
+ enable_cedar_hw_clk();
+
+ return task_ptr->is_first_task;//插入run_task_list链表中的任务是第一个任务,返回1,不是第一个任务返回0. hx modify 2011-7-28 16:59:16!!!
+ #else
+ enable_cedar_hw_clk();
+ cedar_devp->ref_count++;
+ break;
+ #endif
+ case IOCTL_ENGINE_REL:
+ #ifdef USE_CEDAR_ENGINE
+ rel_taskid = (int)arg;
+ /*
+ * 利用任务的id号进行任务的删除操作。返回值意义:找不到对应ID,返回-1;找到对应ID,返回0。
+ */
+ ret = cedardev_del_task(rel_taskid);
+ #else
+ disable_cedar_hw_clk();
+ cedar_devp->ref_count--;
+ #endif
+ return ret;
+ case IOCTL_ENGINE_CHECK_DELAY:
+ {
+ struct cedarv_engine_task_info task_info;
+ /*从用户空间中获取要查询的任务优先级,通过任务优先级,统计需要等待的总时间total_time.
+ * 在这个接口中,同时也给用户传递了当前任务的frametime(这样做可以减少接口,但是用户空间要多设置一个空的frametime值)
+ *对于当前task的frametime,也可以用额外的接口获取,但是这样做,frametime和total_time就处于不同接口中。好处???
+ */
+ if(copy_from_user(&task_info, (void __user*)arg, sizeof(struct cedarv_engine_task_info))){
+ printk("IOCTL_ENGINE_CHECK_DELAY copy_from_user fail\n");
+ return -EFAULT;
+ }
+ task_info.total_time = cedardev_check_delay(task_info.task_prio);//task_info.task_prio是传递过来的优先级
+ #ifdef CEDAR_DEBUG
+ printk("%s,%d,%d\n", __func__, __LINE__, task_info.total_time);
+ #endif
+ task_info.frametime = 0;
+ spin_lock_irqsave(&cedar_spin_lock, flags);
+ if(!list_empty(&run_task_list)){
+ /*获取run_task_list链表中的第一个任务,也就是当前运行的任务,通过当前运行的任务获取frametime时间*/
+ struct cedarv_engine_task *task_entry;
+ #ifdef CEDAR_DEBUG
+ printk("%s,%d\n",__func__,__LINE__);
+ #endif
+ task_entry = list_entry(run_task_list.next, struct cedarv_engine_task, list);
+ if(task_entry->running == 1)
+ task_info.frametime = task_entry->t.frametime;
+ #ifdef CEDAR_DEBUG
+ printk("%s,%d,%d\n",__func__,__LINE__,task_info.frametime);
+ #endif
+ }
+ spin_unlock_irqrestore(&cedar_spin_lock, flags);
+ /*
+ *将任务优先级,total_time,frametime拷贝到用户空间。任务优先级还是用户设置的值,total_time是需要等待的总时间,
+ *frametime是当前任务的运行时间.其实当前任务的信息最好用另一个接口实现.减少耦合度和接口的拓展性.
+ */
+ if (copy_to_user((void *)arg, &task_info, sizeof(struct cedarv_engine_task_info))){
+ printk("IOCTL_ENGINE_CHECK_DELAY copy_to_user fail\n");
+ return -EFAULT;
+ }
+ }
+ break;
+ case IOCTL_WAIT_VE:
+ //wait_event_interruptible(wait_ve, cedar_devp->irq_flag);
+ ve_timeout = (int)arg;
+ cedar_devp->irq_value = 0;
+
+ spin_lock_irqsave(&cedar_spin_lock, flags);
+ if(cedar_devp->irq_flag)
+ cedar_devp->irq_value = 1;
+ spin_unlock_irqrestore(&cedar_spin_lock, flags);
+
+ wait_event_interruptible_timeout(wait_ve, cedar_devp->irq_flag, ve_timeout*HZ);
+ //printk("%s,%d,ve_timeout:%d,cedar_devp->irq_value:%d\n", __func__, __LINE__, ve_timeout, cedar_devp->irq_value);
+ cedar_devp->irq_flag = 0;
+ /*返回1,表示中断返回,返回0,表示timeout返回*/
+ return cedar_devp->irq_value;
+
+ case IOCTL_ENABLE_VE:
+ clk_enable(ve_moduleclk);
+ break;
+
+ case IOCTL_DISABLE_VE:
+ clk_disable(ve_moduleclk);
+ break;
+
+ case IOCTL_RESET_VE:
+ clk_disable(dram_veclk);
+ clk_reset(ve_moduleclk, 1);
+ clk_reset(ve_moduleclk, 0);
+ clk_enable(dram_veclk);
+ break;
+
+ case IOCTL_SET_VE_FREQ:
+ {
+ int arg_rate = (int)arg;
+ if(arg_rate >= 320){
+ clk_set_rate(ve_moduleclk, pll4clk_rate/3);//ve_moduleclk rate is 320khz
+ }else if((arg_rate >= 240) && (arg_rate < 320)){
+ clk_set_rate(ve_moduleclk, pll4clk_rate/4);//ve_moduleclk rate is 240khz
+ }else if((arg_rate >= 160) && (arg_rate < 240)){
+ clk_set_rate(ve_moduleclk, pll4clk_rate/6);//ve_moduleclk rate is 160khz
+ }else{
+ printk("IOCTL_SET_VE_FREQ set ve freq error,%s,%d\n", __func__, __LINE__);
+ }
+ break;
+ }
+ case IOCTL_GETVALUE_AVS2:
+ /* Return AVS1 counter value */
+ return readl(cedar_devp->iomap_addrs.regs_avs + 0x88);
+
+ case IOCTL_ADJUST_AVS2:
+ {
+ int arg_s = (int)arg;
+ int temp;
+ if(MAGIC_VER_A == sw_get_ic_ver()){
+ save_context();
+ v = readl(cedar_devp->iomap_addrs.regs_avs + 0x8c);
+ temp = v & 0xffff0000;
+ temp =temp + temp*arg_s/100;
+ temp = temp > (244<<16) ? (244<<16) : temp;
+ temp = temp < (234<<16) ? (234<<16) : temp;
+ v = (temp & 0xffff0000) | (v&0x0000ffff);
+ #ifdef CEDAR_DEBUG
+ printk("Kernel AVS ADJUST Print: 0x%x\n", v);
+ #endif
+ writel(v, cedar_devp->iomap_addrs.regs_avs + 0x8c);
+ restore_context();
+ }else if(MAGIC_VER_B == sw_get_ic_ver() || MAGIC_VER_C == sw_get_ic_ver()){
+ v = readl(cedar_devp->iomap_addrs.regs_avs + 0x8c);
+ temp = v & 0xffff0000;
+ temp =temp + temp*arg_s/100;
+ temp = temp > (244<<16) ? (244<<16) : temp;
+ temp = temp < (234<<16) ? (234<<16) : temp;
+ v = (temp & 0xffff0000) | (v&0x0000ffff);
+ #ifdef CEDAR_DEBUG
+ printk("Kernel AVS ADJUST Print: 0x%x\n", v);
+ #endif
+ writel(v, cedar_devp->iomap_addrs.regs_avs + 0x8c);
+ }else{
+ printk("IOCTL_ADJUST_AVS2 error:%s,%d\n", __func__, __LINE__);
+ return -EFAULT;
+ }
+ break;
+ }
+
+ case IOCTL_ADJUST_AVS2_ABS:
+ {
+ int arg_s = (int)arg;
+ int v_dst;
+
+ switch(arg_s){
+ case -2:
+ v_dst = 234;
+ break;
+ case -1:
+ v_dst = 236;
+ break;
+ case 1:
+ v_dst = 242;
+ break;
+ case 2:
+ v_dst = 244;
+ break;
+ default:
+ v_dst = 239;
+ break;
+ }
+
+ if(MAGIC_VER_A == sw_get_ic_ver()){
+ save_context();
+ v = readl(cedar_devp->iomap_addrs.regs_avs + 0x8c);
+ v = (v_dst<<16) | (v&0x0000ffff);
+ writel(v, cedar_devp->iomap_addrs.regs_avs + 0x8c);
+ restore_context();
+ }else if(MAGIC_VER_B == sw_get_ic_ver() || MAGIC_VER_C == sw_get_ic_ver()){
+ v = readl(cedar_devp->iomap_addrs.regs_avs + 0x8c);
+ v = (v_dst<<16) | (v&0x0000ffff);
+ writel(v, cedar_devp->iomap_addrs.regs_avs + 0x8c);
+ }else{
+ printk("IOCTL_ADJUST_AVS2 error:%s,%d\n", __func__, __LINE__);
+ return -EFAULT;
+ }
+ break;
+ }
+
+ case IOCTL_CONFIG_AVS2:
+ if(MAGIC_VER_A == sw_get_ic_ver()){
+ save_context();
+ /* Set AVS counter divisor */
+ v = readl(cedar_devp->iomap_addrs.regs_avs + 0x8c);
+ v = 239 << 16 | (v & 0xffff);
+ writel(v, cedar_devp->iomap_addrs.regs_avs + 0x8c);
+
+ /* Enable AVS_CNT1 and Pause it */
+ v = readl(cedar_devp->iomap_addrs.regs_avs + 0x80);
+ v |= 1 << 9 | 1 << 1;
+ writel(v, cedar_devp->iomap_addrs.regs_avs + 0x80);
+
+ /* Set AVS_CNT1 init value as zero */
+ writel(0, cedar_devp->iomap_addrs.regs_avs + 0x88);
+ restore_context();
+ }else if(MAGIC_VER_B == sw_get_ic_ver() || MAGIC_VER_C == sw_get_ic_ver()){
+ /* Set AVS counter divisor */
+ v = readl(cedar_devp->iomap_addrs.regs_avs + 0x8c);
+ v = 239 << 16 | (v & 0xffff);
+ writel(v, cedar_devp->iomap_addrs.regs_avs + 0x8c);
+
+ /* Enable AVS_CNT1 and Pause it */
+ v = readl(cedar_devp->iomap_addrs.regs_avs + 0x80);
+ v |= 1 << 9 | 1 << 1;
+ writel(v, cedar_devp->iomap_addrs.regs_avs + 0x80);
+
+ /* Set AVS_CNT1 init value as zero */
+ writel(0, cedar_devp->iomap_addrs.regs_avs + 0x88);
+ }else{
+ printk("IOCTL_CONFIG_AVS2 error:%s,%d\n", __func__, __LINE__);
+ return -EFAULT;
+ }
+ break;
+
+ case IOCTL_RESET_AVS2:
+ /* Set AVS_CNT1 init value as zero */
+ if(MAGIC_VER_A == sw_get_ic_ver()){
+ save_context();
+ writel(0, cedar_devp->iomap_addrs.regs_avs + 0x88);
+ restore_context();
+ }else if(MAGIC_VER_B == sw_get_ic_ver() || MAGIC_VER_C == sw_get_ic_ver()){
+ writel(0, cedar_devp->iomap_addrs.regs_avs + 0x88);
+ }else{
+ printk("IOCTL_RESET_AVS2 error:%s,%d\n", __func__, __LINE__);
+ return -EFAULT;
+ }
+ break;
+
+ case IOCTL_PAUSE_AVS2:
+ /* Pause AVS_CNT1 */
+ if(MAGIC_VER_A == sw_get_ic_ver()){
+ save_context();
+ v = readl(cedar_devp->iomap_addrs.regs_avs + 0x80);
+ v |= 1 << 9;
+ writel(v, cedar_devp->iomap_addrs.regs_avs + 0x80);
+ restore_context();
+ }else if(MAGIC_VER_B == sw_get_ic_ver() || MAGIC_VER_C == sw_get_ic_ver()){
+ v = readl(cedar_devp->iomap_addrs.regs_avs + 0x80);
+ v |= 1 << 9;
+ writel(v, cedar_devp->iomap_addrs.regs_avs + 0x80);
+ }else{
+ printk("IOCTL_PAUSE_AVS2 get error:%s,%d\n", __func__, __LINE__);
+ return -EFAULT;
+ }
+ break;
+
+ case IOCTL_START_AVS2:
+ /* Start AVS_CNT1 : do not pause */
+ if(MAGIC_VER_A == sw_get_ic_ver()){
+ save_context();
+ v = readl(cedar_devp->iomap_addrs.regs_avs + 0x80);
+ v &= ~(1 << 9);
+ writel(v, cedar_devp->iomap_addrs.regs_avs + 0x80);
+ restore_context();
+ }else if(MAGIC_VER_B == sw_get_ic_ver() || MAGIC_VER_C == sw_get_ic_ver()){
+ v = readl(cedar_devp->iomap_addrs.regs_avs + 0x80);
+ v &= ~(1 << 9);
+ writel(v, cedar_devp->iomap_addrs.regs_avs + 0x80);
+ }else{
+ printk("IOCTL_START_AVS2 error:%s,%d\n", __func__, __LINE__);
+ return -EFAULT;
+ }
+ break;
+
+ case IOCTL_GET_ENV_INFO:
+ {
+ struct cedarv_env_infomation env_info;
+ env_info.phymem_start = (unsigned int)phys_to_virt(ve_start);
+ env_info.phymem_total_size = ve_size;
+ env_info.address_macc = (unsigned int)cedar_devp->iomap_addrs.regs_macc;
+ if (copy_to_user((char *)arg, &env_info, sizeof(struct cedarv_env_infomation)))
+ return -EFAULT;
+ }
+ break;
+ case IOCTL_GET_IC_VER:
+ {
+ if(MAGIC_VER_A == sw_get_ic_ver()){
+ return 0x0A10000A;
+ }else if(MAGIC_VER_B == sw_get_ic_ver() || MAGIC_VER_C == sw_get_ic_ver()){
+ return 0x0A10000B;
+ }else{
+ printk("IC_VER get error:%s,%d\n", __func__, __LINE__);
+ return -EFAULT;
+ }
+ }
+ case IOCTL_FLUSH_CACHE:
+ {
+ struct cedarv_cache_range cache_range;
+ if(copy_from_user(&cache_range, (void __user*)arg, sizeof(struct cedarv_cache_range))){
+ printk("IOCTL_FLUSH_CACHE copy_from_user fail\n");
+ return -EFAULT;
+ }
+ flush_clean_user_range(cache_range.start, cache_range.end);
+ }
+ break;
+ default:
+ break;
+ }
+ return ret;
+}
+
+static int cedardev_open(struct inode *inode, struct file *filp)
+{
+ struct cedar_dev *devp;
+ devp = container_of(inode->i_cdev, struct cedar_dev, cdev);
+ filp->private_data = devp;
+ if (down_interruptible(&devp->sem)) {
+ return -ERESTARTSYS;
+ }
+ /* init other resource here */
+ devp->irq_flag = 0;
+ up(&devp->sem);
+ nonseekable_open(inode, filp);
+ return 0;
+}
+
+static int cedardev_release(struct inode *inode, struct file *filp)
+{
+ struct cedar_dev *devp;
+
+ devp = filp->private_data;
+ if (down_interruptible(&devp->sem)) {
+ return -ERESTARTSYS;
+ }
+ /* release other resource here */
+ devp->irq_flag = 1;
+ up(&devp->sem);
+ return 0;
+}
+
+void cedardev_vma_open(struct vm_area_struct *vma)
+{
+}
+
+void cedardev_vma_close(struct vm_area_struct *vma)
+{
+}
+
+static struct vm_operations_struct cedardev_remap_vm_ops = {
+ .open = cedardev_vma_open,
+ .close = cedardev_vma_close,
+};
+
+static int cedardev_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ unsigned long temp_pfn;
+ unsigned int VAddr;
+ struct iomap_para addrs;
+
+ unsigned int io_ram = 0;
+ VAddr = vma->vm_pgoff << 12;
+ addrs = cedar_devp->iomap_addrs;
+
+ if (VAddr == (unsigned int)addrs.regs_macc) {
+ temp_pfn = MACC_REGS_BASE >> 12;
+ io_ram = 1;
+ } else {
+ temp_pfn = (__pa(vma->vm_pgoff << 12))>>12;
+ io_ram = 0;
+ }
+
+ if (io_ram == 0) {
+ /* Set reserved and I/O flag for the area. */
+ vma->vm_flags |= VM_RESERVED | VM_IO;
+
+ /* Select uncached access. */
+ //vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+ if (remap_pfn_range(vma, vma->vm_start, temp_pfn,
+ vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
+ return -EAGAIN;
+ }
+ } else {
+ /* Set reserved and I/O flag for the area. */
+ vma->vm_flags |= VM_RESERVED | VM_IO;
+ /* Select uncached access. */
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+ if (io_remap_pfn_range(vma, vma->vm_start, temp_pfn,
+ vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
+ return -EAGAIN;
+ }
+ }
+
+ vma->vm_ops = &cedardev_remap_vm_ops;
+ cedardev_vma_open(vma);
+
+ return 0;
+}
+
+static int snd_sw_cedar_suspend(struct platform_device *pdev,pm_message_t state)
+{
+ disable_cedar_hw_clk();
+
+ return 0;
+}
+
+static int snd_sw_cedar_resume(struct platform_device *pdev)
+{
+ if(cedar_devp->ref_count == 0){
+ return 0;
+ }
+ enable_cedar_hw_clk();
+
+ return 0;
+}
+
+static struct file_operations cedardev_fops = {
+ .owner = THIS_MODULE,
+ .mmap = cedardev_mmap,
+ .poll = cedardev_poll,
+ .open = cedardev_open,
+ .release = cedardev_release,
+ .llseek = no_llseek,
+ .unlocked_ioctl = cedardev_ioctl,
+};
+
+/*data relating*/
+static struct platform_device sw_device_cedar = {
+ .name = "sun4i-cedar",
+};
+
+/*method relating*/
+static struct platform_driver sw_cedar_driver = {
+#ifdef CONFIG_PM
+ .suspend = snd_sw_cedar_suspend,
+ .resume = snd_sw_cedar_resume,
+#endif
+ .driver = {
+ .name = "sun4i-cedar",
+ },
+};
+
+static int __init cedardev_init(void)
+{
+ int ret = 0;
+ int err = 0;
+ int devno;
+ unsigned int val;
+ dev_t dev = 0;
+
+ if (ve_size == 0)
+ return -ENODEV;
+
+ printk("[cedar dev]: install start!!!\n");
+ if((platform_device_register(&sw_device_cedar))<0)
+ return err;
+
+ if ((err = platform_driver_register(&sw_cedar_driver)) < 0)
+ return err;
+ /*register or alloc the device number.*/
+ if (g_dev_major) {
+ dev = MKDEV(g_dev_major, g_dev_minor);
+ ret = register_chrdev_region(dev, 1, "cedar_dev");
+ } else {
+ ret = alloc_chrdev_region(&dev, g_dev_minor, 1, "cedar_dev");
+ g_dev_major = MAJOR(dev);
+ g_dev_minor = MINOR(dev);
+ }
+
+ if (ret < 0) {
+ printk(KERN_WARNING "cedar_dev: can't get major %d\n", g_dev_major);
+ return ret;
+ }
+ spin_lock_init(&cedar_spin_lock);
+ cedar_devp = kmalloc(sizeof(struct cedar_dev), GFP_KERNEL);
+ if (cedar_devp == NULL) {
+ printk("malloc mem for cedar device err\n");
+ return -ENOMEM;
+ }
+ memset(cedar_devp, 0, sizeof(struct cedar_dev));
+ cedar_devp->irq = VE_IRQ_NO;
+
+ sema_init(&cedar_devp->sem, 1);
+ init_waitqueue_head(&cedar_devp->wq);
+
+ memset(&cedar_devp->iomap_addrs, 0, sizeof(struct iomap_para));
+
+ ret = request_irq(VE_IRQ_NO, VideoEngineInterupt, 0, "cedar_dev", NULL);
+ if (ret < 0) {
+ printk("request irq err\n");
+ return -EINVAL;
+ }
+ /* map for macc io space */
+ cedar_devp->iomap_addrs.regs_macc = ioremap(MACC_REGS_BASE, 4096);
+ if (!cedar_devp->iomap_addrs.regs_macc){
+ printk("cannot map region for macc");
+ }
+ cedar_devp->iomap_addrs.regs_avs = ioremap(AVS_REGS_BASE, 1024);
+
+ //VE_SRAM mapping to AC320
+ val = readl(0xf1c00000);
+ val &= 0x80000000;
+ writel(val,0xf1c00000);
+ //remapping SRAM to MACC for codec test
+ val = readl(0xf1c00000);
+ val |= 0x7fffffff;
+ writel(val,0xf1c00000);
+
+ ve_pll4clk = clk_get(NULL,"ve_pll");
+ pll4clk_rate = clk_get_rate(ve_pll4clk);
+ /* getting ahb clk for ve!(macc) */
+ ahb_veclk = clk_get(NULL,"ahb_ve");
+ ve_moduleclk = clk_get(NULL,"ve");
+ if(clk_set_parent(ve_moduleclk, ve_pll4clk)){
+ printk("set parent of ve_moduleclk to ve_pll4clk failed!\n");
+ return -EFAULT;
+ }
+ /*default the ve freq to 160M by lys 2011-12-23 15:25:34*/
+ clk_set_rate(ve_moduleclk, pll4clk_rate/6);
+ /*geting dram clk for ve!*/
+ dram_veclk = clk_get(NULL, "sdram_ve");
+ hosc_clk = clk_get(NULL,"hosc");
+ avs_moduleclk = clk_get(NULL,"avs");
+ if(clk_set_parent(avs_moduleclk, hosc_clk)){
+ printk("set parent of avs_moduleclk to hosc_clk failed!\n");
+ return -EFAULT;
+ }
+
+ /*for clk test*/
+ #ifdef CEDAR_DEBUG
+ printk("PLL4 CLK:0xf1c20018 is:%x\n", *(volatile int *)0xf1c20018);
+ printk("AHB CLK:0xf1c20064 is:%x\n", *(volatile int *)0xf1c20064);
+ printk("VE CLK:0xf1c2013c is:%x\n", *(volatile int *)0xf1c2013c);
+ printk("SDRAM CLK:0xf1c20100 is:%x\n", *(volatile int *)0xf1c20100);
+ printk("SRAM:0xf1c00000 is:%x\n", *(volatile int *)0xf1c00000);
+ #endif
+ /* Create char device */
+ devno = MKDEV(g_dev_major, g_dev_minor);
+ cdev_init(&cedar_devp->cdev, &cedardev_fops);
+ cedar_devp->cdev.owner = THIS_MODULE;
+ cedar_devp->cdev.ops = &cedardev_fops;
+ ret = cdev_add(&cedar_devp->cdev, devno, 1);
+ if (ret) {
+ printk(KERN_NOTICE "Err:%d add cedardev", ret);
+ }
+ cedar_devp->class = class_create(THIS_MODULE, "cedar_dev");
+ cedar_devp->dev = device_create(cedar_devp->class, NULL, devno, NULL, "cedar_dev");
+ /*在cedar drv初始化的时候,初始化定时器并设置它的成员
+ * 在有任务插入run_task_list的时候,启动定时器,并设置定时器的时钟为当前系统的jiffies,参考cedardev_insert_task
+ */
+ setup_timer(&cedar_devp->cedar_engine_timer, cedar_engine_for_events, (unsigned long)cedar_devp);
+ setup_timer(&cedar_devp->cedar_engine_timer_rel, cedar_engine_for_timer_rel, (unsigned long)cedar_devp);
+ printk("[cedar dev]: install end!!!\n");
+ return 0;
+}
+module_init(cedardev_init);
+
+static void __exit cedardev_exit(void)
+{
+ dev_t dev;
+ dev = MKDEV(g_dev_major, g_dev_minor);
+
+ free_irq(VE_IRQ_NO, NULL);
+ iounmap(cedar_devp->iomap_addrs.regs_macc);
+ iounmap(cedar_devp->iomap_addrs.regs_avs);
+ /* Destroy char device */
+ if(cedar_devp){
+ cdev_del(&cedar_devp->cdev);
+ device_destroy(cedar_devp->class, dev);
+ class_destroy(cedar_devp->class);
+ }
+ clk_disable(dram_veclk);
+ clk_put(dram_veclk);
+
+ clk_disable(ve_moduleclk);
+ clk_put(ve_moduleclk);
+
+ clk_disable(ahb_veclk);
+ clk_put(ahb_veclk);
+
+ clk_put(ve_pll4clk);
+
+ clk_disable(avs_moduleclk);
+ clk_put(avs_moduleclk);
+
+ unregister_chrdev_region(dev, 1);
+ platform_driver_unregister(&sw_cedar_driver);
+ if (cedar_devp) {
+ kfree(cedar_devp);
+ }
+}
+module_exit(cedardev_exit);
+
+MODULE_AUTHOR("Soft-Allwinner");
+MODULE_DESCRIPTION("User mode CEDAR device interface");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/media/video/sunxi/sunxi_cedar.h b/drivers/media/video/sunxi/sunxi_cedar.h
new file mode 100644
index 0000000..294db94
--- /dev/null
+++ b/drivers/media/video/sunxi/sunxi_cedar.h
@@ -0,0 +1,133 @@
+/*
+ * drivers/media/video/sunxi/sunxi_cedar.h
+ *
+ * (C) Copyright 2007-2012
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program 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 program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+**************************************************************************************************************
+* eLDK
+* the Easy Portable/Player Develop Kits
+* desktop system
+*
+* (c) Copyright 2009-2012, ,HUANGXIN China
+* All Rights Reserved
+*
+* File : sunxi_cedar.h
+* By : HUANGXIN
+* Func :
+* Version : v1.0
+* ============================================================================================================
+* 2011-5-25 9:57:05 HUANGXIN create this file, implements the fundemental interface;
+**************************************************************************************************************
+*/
+#ifndef _SUNXI_CEDAR_H_
+#define _SUNXI_CEDAR_H_
+
+enum IOCTL_CMD {
+ IOCTL_UNKOWN = 0x100,
+ IOCTL_GET_ENV_INFO,
+ IOCTL_WAIT_VE,
+ IOCTL_RESET_VE,
+ IOCTL_ENABLE_VE,
+ IOCTL_DISABLE_VE,
+ IOCTL_SET_VE_FREQ,
+
+ IOCTL_CONFIG_AVS2 = 0x200,
+ IOCTL_GETVALUE_AVS2 ,
+ IOCTL_PAUSE_AVS2 ,
+ IOCTL_START_AVS2 ,
+ IOCTL_RESET_AVS2 ,
+ IOCTL_ADJUST_AVS2,
+ IOCTL_ENGINE_REQ,
+ IOCTL_ENGINE_REL,
+ IOCTL_ENGINE_CHECK_DELAY,
+ IOCTL_GET_IC_VER,
+
+ IOCTL_ADJUST_AVS2_ABS,
+ IOCTL_FLUSH_CACHE,
+};
+
+struct cedarv_env_infomation{
+ unsigned int phymem_start;
+ int phymem_total_size;
+ unsigned int address_macc;
+};
+
+struct cedarv_cache_range{
+ long start;
+ long end;
+};
+
+struct __cedarv_task {
+ int task_prio;
+ int ID;
+ unsigned long timeout;
+ unsigned int frametime;
+ unsigned int block_mode;
+};
+
+struct cedarv_engine_task {
+ struct __cedarv_task t;
+ struct list_head list;
+ struct task_struct *task_handle;
+ unsigned int status;
+ unsigned int running;
+ unsigned int is_first_task;
+};
+
+/*利用优先级task_prio查询当前运行task的frametime,和比优先级task_prio高的task可能运行的总时间total_time*/
+struct cedarv_engine_task_info {
+ int task_prio;
+ unsigned int frametime;
+ unsigned int total_time;
+};
+
+/*--------------------------------------------------------------------------------*/
+#define REGS_pBASE (0x01C00000) // register base addr
+
+#define SRAM_REGS_pBASE (REGS_pBASE + 0x00000) // SRAM Controller
+#define CCMU_REGS_pBASE (REGS_pBASE + 0x20000) // clock manager unit
+#define MACC_REGS_pBASE (REGS_pBASE + 0x0E000) // media accelerate VE
+#define SS_REGS_pBASE (REGS_pBASE + 0x15000) // Security System
+#define SDRAM_REGS_pBASE (REGS_pBASE + 0x01000) // SDRAM Controller
+#define AVS_REGS_pBASE (REGS_pBASE + 0x20c00)
+
+#define SRAM_REGS_BASE SRAM_REGS_pBASE // SRAM Controller
+#define CCMU_REGS_BASE CCMU_REGS_pBASE // Clock Control manager unit OK
+#define MACC_REGS_BASE MACC_REGS_pBASE // Media ACCelerate
+#define SS_REGS_BASE SS_REGS_pBASE // Security System
+#define SDRAM_REGS_BASE SDRAM_REGS_pBASE //SDRAM Controller OK
+#define AVS_REGS_BASE AVS_REGS_pBASE
+
+#define MPEG_REGS_BASE (MACC_REGS_BASE + 0x100) // MPEG engine
+#define H264_REGS_BASE (MACC_REGS_BASE + 0x200) // H264 engine
+#define VC1_REGS_BASE (MACC_REGS_BASE + 0x300) // VC-1 engine
+
+#define SRAM_REGS_SIZE (4096) // 4K
+#define CCMU_REGS_SIZE (1024) // 1K
+#define MACC_REGS_SIZE (4096) // 4K
+#define SS_REGS_SIZE (4096) // 4K
+/*--------------------------------------------------------------------------------*/
+
+#define SRAM_REG_o_CFG (0x00)
+#define SRAM_REG_ADDR_CFG (SRAM_REGS_BASE + SRAM_REG_o_CFG) // SRAM MAP Cfg Reg 0
+/*--------------------------------------------------------------------------------*/
+
+#endif
--
1.7.10.4

alex allss

unread,
Mar 29, 2013, 12:45:52 PM3/29/13
to d...@linux-sunxi.org
Please comment.

2013/3/25 <wing...@gmail.com>:

Oliver Schinagl

unread,
Mar 30, 2013, 11:22:56 AM3/30/13
to linux...@googlegroups.com
I assume this is mearly the deletion of sun5i and renaming of sun4i so I
guess it should be okay
> -#define CEDAR_NONBLOCK_TASK 0 //������
> -#define CEDAR_BLOCK_TASK 1
> -#define CLK_REL_TIME 10000 //10��
> -#define TIMER_CIRCLE 50 //50����
> - /*����run_task_list���?��������������ȼ�������ڵ��е��������ȼ��ߣ����ҵ�ǰ���������ǵ�һ�����������
> - *��ô�ͽ����ȼ��ߵ��������ǰ�棬�����е������ȡ�Ӹߵ��׵����ȼ������Ŷӡ�
> - */
> - list_for_each_entry(task_entry, &run_task_list, list) {
> - if ((task_entry->is_first_task == 0) && (task_entry->running == 0) && (task_entry->t.task_prio < new_task->t.task_prio)) {
> - break;
> - }
> - }
> -
> - list_add(&new_task->list, task_entry->list.prev);
> -
> - #ifdef CEDAR_DEBUG
> - printk("%s,%d, TASK_ID:",__func__,__LINE__);
> - list_for_each_entry(task_entry, &run_task_list, list) {
> - printk("%d!", task_entry->t.ID);
> - }
> - printk("\n");
> - #endif
> - /*ÿ�β���һ�����񣬾ͽ���ǰ�ļ�ʱ��ʱ������Ϊϵͳ��ǰ��jiffies*/
> - mod_timer(&cedar_devp->cedar_engine_timer, jiffies + 0);
> -
> - spin_unlock_irqrestore(&cedar_spin_lock, flags);
> -}
> -
> -int cedardev_del_task(int task_id)
> -{
> - struct cedarv_engine_task *task_entry;
> - unsigned long flags;
> -
> - spin_lock_irqsave(&cedar_spin_lock, flags);
> -
> - /*����run_task_list����
> - *����ҵ���Ӧ��id�ţ���ô�ͽ�run_task_list�����е������Ƶ�del_task_list����ı�ͷ��
> - */
> - list_for_each_entry(task_entry, &run_task_list, list) {
> - if (task_entry->t.ID == task_id && task_entry->status != TASK_RELEASE) {
> - task_entry->status = TASK_RELEASE;
> -
> - spin_unlock_irqrestore(&cedar_spin_lock, flags);
> - mod_timer(&cedar_devp->cedar_engine_timer, jiffies + 0);
> - return 0;
> - }
> - }
> - spin_unlock_irqrestore(&cedar_spin_lock, flags);
> -
> - //�Ҳ�����Ӧ ID
> - return -1;
> -}
> -
> -int cedardev_check_delay(int check_prio)
> -{
> - struct cedarv_engine_task *task_entry;
> - int timeout_total = 0;
> - unsigned long flags;
> -
> - /*��ȡ�ܵĵȴ�ʱ��*/
> - if (task_entry->status == TASK_TIMEOUT){//��ʾ����timeoutɾ��
> - info.si_errno = TASK_TIMEOUT;
> - send_sig_info(SIG_CEDAR, &info, task_entry->task_handle);
> - }else if(task_entry->status == TASK_RELEASE){//��ʾ�������������ɾ��
> - info.si_errno = TASK_RELEASE;
> - send_sig_info(SIG_CEDAR, &info, task_entry->task_handle);
> - }
> - list_del(&task_entry->list);
> - kfree(task_entry);
> - }
> -
> - /*���������е�task*/
> - if(!list_empty(&run_task_list)){
> - task_entry = list_entry(run_task_list.next, struct cedarv_engine_task, list);
> - if(task_entry->running == 0){
> - task_entry->running = 1;
> - info.si_signo = SIG_CEDAR;
> - info.si_code = task_entry->t.ID;
> - info.si_errno = TASK_INIT; //�����Ѿ�����
> - /*���taskΪ������״̬�������߿�����������*/
> - if(!list_empty(&run_task_list) && ( task_ret.block_mode == CEDAR_NONBLOCK_TASK)){
> - spin_unlock_irqrestore(&cedar_spin_lock, flags);
> - return CEDAR_RUN_LIST_NONULL; //run_task_list���������񣬷���-1
> - }
> - spin_unlock_irqrestore(&cedar_spin_lock, flags);
> -
> - /*���taskΪ����״̬����task����run_task_list������*/
> - task_ptr = kmalloc(sizeof(struct cedarv_engine_task), GFP_KERNEL);
> - if(!task_ptr){
> - printk("get mem for IOCTL_ENGINE_REQ\n");
> - return PTR_ERR(task_ptr);
> - }
> - task_ptr->task_handle = current;
> - task_ptr->t.ID = task_ret.ID;
> - task_ptr->t.timeout = jiffies + msecs_to_jiffies(1000*task_ret.timeout);//ms to jiffies
> - task_ptr->t.frametime = task_ret.frametime;
> - task_ptr->t.task_prio = task_ret.task_prio;
> - task_ptr->running = 0;
> - task_ptr->is_first_task = 0;
> - task_ptr->status = TASK_INIT;
> -
> - cedardev_insert_task(task_ptr);
> -
> - enable_cedar_hw_clk();
> -
> - return task_ptr->is_first_task;//����run_task_list�����е������ǵ�һ�����񣬷���1�����ǵ�һ�����񷵻�0. hx modify 2011-7-28 16:59:16������
> - #else
> - enable_cedar_hw_clk();
> - cedar_devp->ref_count++;
> - break;
> - #endif
> - case IOCTL_ENGINE_REL:
> - #ifdef USE_CEDAR_ENGINE
> - rel_taskid = (int)arg;
> - /*
> - * ���������id�Ž��������ɾ�����������ֵ���壺�Ҳ�����ӦID������-1;�ҵ���ӦID������0��
> - */
> - ret = cedardev_del_task(rel_taskid);
> - #else
> - disable_cedar_hw_clk();
> - cedar_devp->ref_count--;
> - #endif
> - return ret;
> - case IOCTL_ENGINE_CHECK_DELAY:
> - {
> - struct cedarv_engine_task_info task_info;
> - /*���û��ռ��л�ȡҪ��ѯ���������ȼ���ͨ���������ȼ���ͳ����Ҫ�ȴ����ʱ��total_time.
> - * ������ӿ��У�ͬʱҲ���û������˵�ǰ�����frametime�����������Լ��ٽӿڣ������û��ռ�Ҫ������һ���յ�frametimeֵ��
> - *���ڵ�ǰtask��frametime��Ҳ�����ö���Ľӿڻ�ȡ��������������frametime��total_time�ʹ��ڲ�ͬ�ӿ��С��ô�������
> - */
> - if(copy_from_user(&task_info, (void __user*)arg, sizeof(struct cedarv_engine_task_info))){
> - printk("IOCTL_ENGINE_CHECK_DELAY copy_from_user fail\n");
> - return -EFAULT;
> - }
> - task_info.total_time = cedardev_check_delay(task_info.task_prio);//task_info.task_prio�Ǵ��ݹ��������ȼ�
> - #ifdef CEDAR_DEBUG
> - printk("%s,%d,%d\n", __func__, __LINE__, task_info.total_time);
> - #endif
> - task_info.frametime = 0;
> - spin_lock_irqsave(&cedar_spin_lock, flags);
> - if(!list_empty(&run_task_list)){
> - /*��ȡrun_task_list�����еĵ�һ������Ҳ���ǵ�ǰ���е�����ͨ��ǰ���е������ȡframetimeʱ��*/
> - struct cedarv_engine_task *task_entry;
> - #ifdef CEDAR_DEBUG
> - printk("%s,%d\n",__func__,__LINE__);
> - #endif
> - task_entry = list_entry(run_task_list.next, struct cedarv_engine_task, list);
> - if(task_entry->running == 1)
> - task_info.frametime = task_entry->t.frametime;
> - #ifdef CEDAR_DEBUG
> - printk("%s,%d,%d\n",__func__,__LINE__,task_info.frametime);
> - #endif
> - }
> - spin_unlock_irqrestore(&cedar_spin_lock, flags);
> - /*
> - *���������ȼ���total_time,frametime�������û��ռ䡣�������ȼ������û����õ�ֵ��total_time����Ҫ�ȴ����ʱ�䣬
> - *frametime�ǵ�ǰ���������ʱ��.��ʵ��ǰ�������Ϣ�������һ���ӿ�ʵ��.������϶Ⱥͽӿڵ���չ��.
> - */
> - if (copy_to_user((void *)arg, &task_info, sizeof(struct cedarv_engine_task_info))){
> - printk("IOCTL_ENGINE_CHECK_DELAY copy_to_user fail\n");
> - return -EFAULT;
> - }
> - }
> - break;
> - case IOCTL_WAIT_VE:
> - //wait_event_interruptible(wait_ve, cedar_devp->irq_flag);
> - ve_timeout = (int)arg;
> - cedar_devp->irq_value = 0;
> -
> - spin_lock_irqsave(&cedar_spin_lock, flags);
> - if(cedar_devp->irq_flag)
> - cedar_devp->irq_value = 1;
> - spin_unlock_irqrestore(&cedar_spin_lock, flags);
> -
> - wait_event_interruptible_timeout(wait_ve, cedar_devp->irq_flag, ve_timeout*HZ);
> - //printk("%s,%d,ve_timeout:%d,cedar_devp->irq_value:%d\n", __func__, __LINE__, ve_timeout, cedar_devp->irq_value);
> - cedar_devp->irq_flag = 0;
> - /*����1����ʾ�жϷ��أ�����0����ʾtimeout����*/
> - /*��cedar drv��ʼ����ʱ�򣬳�ʼ����ʱ����������ij�Ա
> - * �����������run_task_list��ʱ��������ʱ���������ö�ʱ����ʱ��Ϊ��ǰϵͳ��jiffies���ο�cedardev_insert_task
> -/*�������ȼ�task_prio��ѯ��ǰ����task��frametime���ͱ����ȼ�task_prio�ߵ�task�������е���ʱ��total_time*/
> -#define CEDAR_NONBLOCK_TASK 0 //������
> -#define CEDAR_BLOCK_TASK 1
> -#define CLK_REL_TIME 10000 //10��
> -#define TIMER_CIRCLE 50 //50����
> - /*����run_task_list���?��������������ȼ�������ڵ��е��������ȼ��ߣ����ҵ�ǰ���������ǵ�һ�����������
> - *��ô�ͽ����ȼ��ߵ��������ǰ�棬�����е������ȡ�Ӹߵ��׵����ȼ������Ŷӡ�
> - */
> - list_for_each_entry(task_entry, &run_task_list, list) {
> - if ((task_entry->is_first_task == 0) && (task_entry->running == 0) && (task_entry->t.task_prio < new_task->t.task_prio)) {
> - break;
> - }
> - }
> -
> - list_add(&new_task->list, task_entry->list.prev);
> -
> - #ifdef CEDAR_DEBUG
> - printk("%s,%d, TASK_ID:",__func__,__LINE__);
> - list_for_each_entry(task_entry, &run_task_list, list) {
> - printk("%d!", task_entry->t.ID);
> - }
> - printk("\n");
> - #endif
> - /*ÿ�β���һ�����񣬾ͽ���ǰ�ļ�ʱ��ʱ������Ϊϵͳ��ǰ��jiffies*/
> - mod_timer(&cedar_devp->cedar_engine_timer, jiffies + 0);
> -
> - spin_unlock_irqrestore(&cedar_spin_lock, flags);
> -}
> -
> -int cedardev_del_task(int task_id)
> -{
> - struct cedarv_engine_task *task_entry;
> - unsigned long flags;
> -
> - spin_lock_irqsave(&cedar_spin_lock, flags);
> -
> - /*����run_task_list����
> - *����ҵ���Ӧ��id�ţ���ô�ͽ�run_task_list�����е������Ƶ�del_task_list����ı�ͷ��
> - */
> - list_for_each_entry(task_entry, &run_task_list, list) {
> - if (task_entry->t.ID == task_id && task_entry->status != TASK_RELEASE) {
> - task_entry->status = TASK_RELEASE;
> -
> - spin_unlock_irqrestore(&cedar_spin_lock, flags);
> - mod_timer(&cedar_devp->cedar_engine_timer, jiffies + 0);
> - return 0;
> - }
> - }
> - spin_unlock_irqrestore(&cedar_spin_lock, flags);
> -
> - //�Ҳ�����Ӧ ID
> - return -1;
> -}
> -
> -int cedardev_check_delay(int check_prio)
> -{
> - struct cedarv_engine_task *task_entry;
> - int timeout_total = 0;
> - unsigned long flags;
> -
> - /*��ȡ�ܵĵȴ�ʱ��*/
> - if (task_entry->status == TASK_TIMEOUT){//��ʾ����timeoutɾ��
> - info.si_errno = TASK_TIMEOUT;
> - send_sig_info(SIG_CEDAR, &info, task_entry->task_handle);
> - }else if(task_entry->status == TASK_RELEASE){//��ʾ�������������ɾ��
> - info.si_errno = TASK_RELEASE;
> - send_sig_info(SIG_CEDAR, &info, task_entry->task_handle);
> - }
> - list_del(&task_entry->list);
> - kfree(task_entry);
> - }
> -
> - /*���������е�task*/
> - if(!list_empty(&run_task_list)){
> - task_entry = list_entry(run_task_list.next, struct cedarv_engine_task, list);
> - if(task_entry->running == 0){
> - task_entry->running = 1;
> - info.si_signo = SIG_CEDAR;
> - info.si_code = task_entry->t.ID;
> - info.si_errno = TASK_INIT; //�����Ѿ�����
> - /*���taskΪ������״̬�������߿�����������*/
> - if(!list_empty(&run_task_list) && ( task_ret.block_mode == CEDAR_NONBLOCK_TASK)){
> - spin_unlock_irqrestore(&cedar_spin_lock, flags);
> - return CEDAR_RUN_LIST_NONULL; //run_task_list���������񣬷���-1
> - }
> - spin_unlock_irqrestore(&cedar_spin_lock, flags);
> -
> - /*���taskΪ����״̬����task����run_task_list������*/
> - task_ptr = kmalloc(sizeof(struct cedarv_engine_task), GFP_KERNEL);
> - if(!task_ptr){
> - printk("get mem for IOCTL_ENGINE_REQ\n");
> - return PTR_ERR(task_ptr);
> - }
> - task_ptr->task_handle = current;
> - task_ptr->t.ID = task_ret.ID;
> - task_ptr->t.timeout = jiffies + msecs_to_jiffies(1000*task_ret.timeout);//ms to jiffies
> - task_ptr->t.frametime = task_ret.frametime;
> - task_ptr->t.task_prio = task_ret.task_prio;
> - task_ptr->running = 0;
> - task_ptr->is_first_task = 0;
> - task_ptr->status = TASK_INIT;
> -
> - cedardev_insert_task(task_ptr);
> -
> - enable_cedar_hw_clk();
> -
> - return task_ptr->is_first_task;//����run_task_list�����е������ǵ�һ�����񣬷���1�����ǵ�һ�����񷵻�0. hx modify 2011-7-28 16:59:16������
> - #else
> - enable_cedar_hw_clk();
> - cedar_devp->ref_count++;
> - break;
> - #endif
> - case IOCTL_ENGINE_REL:
> - #ifdef USE_CEDAR_ENGINE
> - rel_taskid = (int)arg;
> - /*
> - * ���������id�Ž��������ɾ�����������ֵ���壺�Ҳ�����ӦID������-1;�ҵ���ӦID������0��
> - */
> - ret = cedardev_del_task(rel_taskid);
> - #else
> - disable_cedar_hw_clk();
> - cedar_devp->ref_count--;
> - #endif
> - return ret;
> - case IOCTL_ENGINE_CHECK_DELAY:
> - {
> - struct cedarv_engine_task_info task_info;
> - /*���û��ռ��л�ȡҪ��ѯ���������ȼ���ͨ���������ȼ���ͳ����Ҫ�ȴ����ʱ��total_time.
> - * ������ӿ��У�ͬʱҲ���û������˵�ǰ�����frametime�����������Լ��ٽӿڣ������û��ռ�Ҫ������һ���յ�frametimeֵ��
> - *���ڵ�ǰtask��frametime��Ҳ�����ö���Ľӿڻ�ȡ��������������frametime��total_time�ʹ��ڲ�ͬ�ӿ��С��ô�������
> - */
> - if(copy_from_user(&task_info, (void __user*)arg, sizeof(struct cedarv_engine_task_info))){
> - printk("IOCTL_ENGINE_CHECK_DELAY copy_from_user fail\n");
> - return -EFAULT;
> - }
> - task_info.total_time = cedardev_check_delay(task_info.task_prio);//task_info.task_prio�Ǵ��ݹ��������ȼ�
> - #ifdef CEDAR_DEBUG
> - printk("%s,%d,%d\n", __func__, __LINE__, task_info.total_time);
> - #endif
> - task_info.frametime = 0;
> - spin_lock_irqsave(&cedar_spin_lock, flags);
> - if(!list_empty(&run_task_list)){
> - /*��ȡrun_task_list�����еĵ�һ������Ҳ���ǵ�ǰ���е�����ͨ��ǰ���е������ȡframetimeʱ��*/
> - struct cedarv_engine_task *task_entry;
> - #ifdef CEDAR_DEBUG
> - printk("%s,%d\n",__func__,__LINE__);
> - #endif
> - task_entry = list_entry(run_task_list.next, struct cedarv_engine_task, list);
> - if(task_entry->running == 1)
> - task_info.frametime = task_entry->t.frametime;
> - #ifdef CEDAR_DEBUG
> - printk("%s,%d,%d\n",__func__,__LINE__,task_info.frametime);
> - #endif
> - }
> - spin_unlock_irqrestore(&cedar_spin_lock, flags);
> - /*
> - *���������ȼ���total_time,frametime�������û��ռ䡣�������ȼ������û����õ�ֵ��total_time����Ҫ�ȴ����ʱ�䣬
> - *frametime�ǵ�ǰ���������ʱ��.��ʵ��ǰ�������Ϣ�������һ���ӿ�ʵ��.������϶Ⱥͽӿڵ���չ��.
> - */
> - if (copy_to_user((void *)arg, &task_info, sizeof(struct cedarv_engine_task_info))){
> - printk("IOCTL_ENGINE_CHECK_DELAY copy_to_user fail\n");
> - return -EFAULT;
> - }
> - }
> - break;
> - case IOCTL_WAIT_VE:
> - //wait_event_interruptible(wait_ve, cedar_devp->irq_flag);
> - ve_timeout = (int)arg;
> - cedar_devp->irq_value = 0;
> -
> - spin_lock_irqsave(&cedar_spin_lock, flags);
> - if(cedar_devp->irq_flag)
> - cedar_devp->irq_value = 1;
> - spin_unlock_irqrestore(&cedar_spin_lock, flags);
> -
> - wait_event_interruptible_timeout(wait_ve, cedar_devp->irq_flag, ve_timeout*HZ);
> - //printk("%s,%d,ve_timeout:%d,cedar_devp->irq_value:%d\n", __func__, __LINE__, ve_timeout, cedar_devp->irq_value);
> - cedar_devp->irq_flag = 0;
> - /*����1����ʾ�жϷ��أ�����0����ʾtimeout����*/
> - /*��cedar drv��ʼ����ʱ�򣬳�ʼ����ʱ����������ij�Ա
> - * �����������run_task_list��ʱ��������ʱ���������ö�ʱ����ʱ��Ϊ��ǰϵͳ��jiffies���ο�cedardev_insert_task
> -/*�������ȼ�task_prio��ѯ��ǰ����task��frametime���ͱ����ȼ�task_prio�ߵ�task�������е���ʱ��total_time*/
> +#define CEDAR_NONBLOCK_TASK 0 //������
> +#define CEDAR_BLOCK_TASK 1
> +#define CLK_REL_TIME 10000 //10��
> +#define TIMER_CIRCLE 50 //50����
> + /*����run_task_list���?��������������ȼ�������ڵ��е��������ȼ��ߣ����ҵ�ǰ���������ǵ�һ�����������
> + *��ô�ͽ����ȼ��ߵ��������ǰ�棬�����е������ȡ�Ӹߵ��׵����ȼ������Ŷӡ�
> + */
> + list_for_each_entry(task_entry, &run_task_list, list) {
> + if ((task_entry->is_first_task == 0) && (task_entry->running == 0) && (task_entry->t.task_prio < new_task->t.task_prio)) {
> + break;
> + }
> + }
> +
> + list_add(&new_task->list, task_entry->list.prev);
> +
> + #ifdef CEDAR_DEBUG
> + printk("%s,%d, TASK_ID:",__func__,__LINE__);
> + list_for_each_entry(task_entry, &run_task_list, list) {
> + printk("%d!", task_entry->t.ID);
> + }
> + printk("\n");
> + #endif
> + /*ÿ�β���һ�����񣬾ͽ���ǰ�ļ�ʱ��ʱ������Ϊϵͳ��ǰ��jiffies*/
> + mod_timer(&cedar_devp->cedar_engine_timer, jiffies + 0);
> +
> + spin_unlock_irqrestore(&cedar_spin_lock, flags);
> +}
> +
> +int cedardev_del_task(int task_id)
> +{
> + struct cedarv_engine_task *task_entry;
> + unsigned long flags;
> +
> + spin_lock_irqsave(&cedar_spin_lock, flags);
> +
> + /*����run_task_list����
> + *����ҵ���Ӧ��id�ţ���ô�ͽ�run_task_list�����е������Ƶ�del_task_list����ı�ͷ��
> + */
> + list_for_each_entry(task_entry, &run_task_list, list) {
> + if (task_entry->t.ID == task_id && task_entry->status != TASK_RELEASE) {
> + task_entry->status = TASK_RELEASE;
> +
> + spin_unlock_irqrestore(&cedar_spin_lock, flags);
> + mod_timer(&cedar_devp->cedar_engine_timer, jiffies + 0);
> + return 0;
> + }
> + }
> + spin_unlock_irqrestore(&cedar_spin_lock, flags);
> +
> + //�Ҳ�����Ӧ ID
> + return -1;
> +}
> +
> +int cedardev_check_delay(int check_prio)
> +{
> + struct cedarv_engine_task *task_entry;
> + int timeout_total = 0;
> + unsigned long flags;
> +
> + /*��ȡ�ܵĵȴ�ʱ��*/
> + if (task_entry->status == TASK_TIMEOUT){//��ʾ����timeoutɾ��
> + info.si_errno = TASK_TIMEOUT;
> + send_sig_info(SIG_CEDAR, &info, task_entry->task_handle);
> + }else if(task_entry->status == TASK_RELEASE){//��ʾ�������������ɾ��
> + info.si_errno = TASK_RELEASE;
> + send_sig_info(SIG_CEDAR, &info, task_entry->task_handle);
> + }
> + list_del(&task_entry->list);
> + kfree(task_entry);
> + }
> +
> + /*���������е�task*/
> + if(!list_empty(&run_task_list)){
> + task_entry = list_entry(run_task_list.next, struct cedarv_engine_task, list);
> + if(task_entry->running == 0){
> + task_entry->running = 1;
> + info.si_signo = SIG_CEDAR;
> + info.si_code = task_entry->t.ID;
> + info.si_errno = TASK_INIT; //�����Ѿ�����
> + /*���taskΪ������״̬�������߿�����������*/
> + if(!list_empty(&run_task_list) && ( task_ret.block_mode == CEDAR_NONBLOCK_TASK)){
> + spin_unlock_irqrestore(&cedar_spin_lock, flags);
> + return CEDAR_RUN_LIST_NONULL; //run_task_list���������񣬷���-1
> + }
> + spin_unlock_irqrestore(&cedar_spin_lock, flags);
> +
> + /*���taskΪ����״̬����task����run_task_list������*/
> + task_ptr = kmalloc(sizeof(struct cedarv_engine_task), GFP_KERNEL);
> + if(!task_ptr){
> + printk("get mem for IOCTL_ENGINE_REQ\n");
> + return PTR_ERR(task_ptr);
> + }
> + task_ptr->task_handle = current;
> + task_ptr->t.ID = task_ret.ID;
> + task_ptr->t.timeout = jiffies + msecs_to_jiffies(1000*task_ret.timeout);//ms to jiffies
> + task_ptr->t.frametime = task_ret.frametime;
> + task_ptr->t.task_prio = task_ret.task_prio;
> + task_ptr->running = 0;
> + task_ptr->is_first_task = 0;
> + task_ptr->status = TASK_INIT;
> +
> + cedardev_insert_task(task_ptr);
> +
> + enable_cedar_hw_clk();
> +
> + return task_ptr->is_first_task;//����run_task_list�����е������ǵ�һ�����񣬷���1�����ǵ�һ�����񷵻�0. hx modify 2011-7-28 16:59:16������
> + #else
> + enable_cedar_hw_clk();
> + cedar_devp->ref_count++;
> + break;
> + #endif
> + case IOCTL_ENGINE_REL:
> + #ifdef USE_CEDAR_ENGINE
> + rel_taskid = (int)arg;
> + /*
> + * ���������id�Ž��������ɾ�����������ֵ���壺�Ҳ�����ӦID������-1;�ҵ���ӦID������0��
> + */
> + ret = cedardev_del_task(rel_taskid);
> + #else
> + disable_cedar_hw_clk();
> + cedar_devp->ref_count--;
> + #endif
> + return ret;
> + case IOCTL_ENGINE_CHECK_DELAY:
> + {
> + struct cedarv_engine_task_info task_info;
> + /*���û��ռ��л�ȡҪ��ѯ���������ȼ���ͨ���������ȼ���ͳ����Ҫ�ȴ����ʱ��total_time.
> + * ������ӿ��У�ͬʱҲ���û������˵�ǰ�����frametime�����������Լ��ٽӿڣ������û��ռ�Ҫ������һ���յ�frametimeֵ��
> + *���ڵ�ǰtask��frametime��Ҳ�����ö���Ľӿڻ�ȡ��������������frametime��total_time�ʹ��ڲ�ͬ�ӿ��С��ô�������
> + */
> + if(copy_from_user(&task_info, (void __user*)arg, sizeof(struct cedarv_engine_task_info))){
> + printk("IOCTL_ENGINE_CHECK_DELAY copy_from_user fail\n");
> + return -EFAULT;
> + }
> + task_info.total_time = cedardev_check_delay(task_info.task_prio);//task_info.task_prio�Ǵ��ݹ��������ȼ�
> + #ifdef CEDAR_DEBUG
> + printk("%s,%d,%d\n", __func__, __LINE__, task_info.total_time);
> + #endif
> + task_info.frametime = 0;
> + spin_lock_irqsave(&cedar_spin_lock, flags);
> + if(!list_empty(&run_task_list)){
> + /*��ȡrun_task_list�����еĵ�һ������Ҳ���ǵ�ǰ���е�����ͨ��ǰ���е������ȡframetimeʱ��*/
> + struct cedarv_engine_task *task_entry;
> + #ifdef CEDAR_DEBUG
> + printk("%s,%d\n",__func__,__LINE__);
> + #endif
> + task_entry = list_entry(run_task_list.next, struct cedarv_engine_task, list);
> + if(task_entry->running == 1)
> + task_info.frametime = task_entry->t.frametime;
> + #ifdef CEDAR_DEBUG
> + printk("%s,%d,%d\n",__func__,__LINE__,task_info.frametime);
> + #endif
> + }
> + spin_unlock_irqrestore(&cedar_spin_lock, flags);
> + /*
> + *���������ȼ���total_time,frametime�������û��ռ䡣�������ȼ������û����õ�ֵ��total_time����Ҫ�ȴ����ʱ�䣬
> + *frametime�ǵ�ǰ���������ʱ��.��ʵ��ǰ�������Ϣ�������һ���ӿ�ʵ��.������϶Ⱥͽӿڵ���չ��.
> + */
> + if (copy_to_user((void *)arg, &task_info, sizeof(struct cedarv_engine_task_info))){
> + printk("IOCTL_ENGINE_CHECK_DELAY copy_to_user fail\n");
> + return -EFAULT;
> + }
> + }
> + break;
> + case IOCTL_WAIT_VE:
> + //wait_event_interruptible(wait_ve, cedar_devp->irq_flag);
> + ve_timeout = (int)arg;
> + cedar_devp->irq_value = 0;
> +
> + spin_lock_irqsave(&cedar_spin_lock, flags);
> + if(cedar_devp->irq_flag)
> + cedar_devp->irq_value = 1;
> + spin_unlock_irqrestore(&cedar_spin_lock, flags);
> +
> + wait_event_interruptible_timeout(wait_ve, cedar_devp->irq_flag, ve_timeout*HZ);
> + //printk("%s,%d,ve_timeout:%d,cedar_devp->irq_value:%d\n", __func__, __LINE__, ve_timeout, cedar_devp->irq_value);
> + cedar_devp->irq_flag = 0;
> + /*����1����ʾ�жϷ��أ�����0����ʾtimeout����*/
> + /*��cedar drv��ʼ����ʱ�򣬳�ʼ����ʱ����������ij�Ա
> + * �����������run_task_list��ʱ��������ʱ���������ö�ʱ����ʱ��Ϊ��ǰϵͳ��jiffies���ο�cedardev_insert_task
> +/*�������ȼ�task_prio��ѯ��ǰ����task��frametime���ͱ����ȼ�task_prio�ߵ�task�������е���ʱ��total_time*/
Reply all
Reply to author
Forward
0 new messages