summaryrefslogtreecommitdiff
path: root/kernel_drivers
diff options
context:
space:
mode:
authorSteven J. Hill <sjhill@realitydiluted.com>2013-03-08 15:38:53 -0600
committerWladimir J. van der Laan <laanwj@gmail.com>2013-03-09 20:08:51 +0100
commite5d036ada615a2cf144786befef9dda1e6319dd3 (patch)
tree7a36e666c4cfb40d5e3035191a19605a9a2a7225 /kernel_drivers
parentf7c50ab7bb5c90f097e780d65be4ff3cae994b68 (diff)
kernel_drivers: v2: Add in Ingenic JZ4770 support.
Add in Ingenic JZ4770 SoC support. This driver works on the GCW0 platform and gets some 3D rendering working. It should be noted the version of this driver is 'v2.5.3.2.2.p3' and the latest Ingenic driver is 'v2.5.3.2.5.b7' for the GCW0. The v2 codebase will need to be upgraded to this version. Signed-off-by: Steven J. Hill <sjhill@realitydiluted.com>
Diffstat (limited to 'kernel_drivers')
-rw-r--r--kernel_drivers/v2/Makefile83
-rw-r--r--kernel_drivers/v2/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c57
-rw-r--r--kernel_drivers/v2/hal/inc/gc_hal_options.h4
-rw-r--r--kernel_drivers/v2/hal/kernel/gc_hal_kernel.c8
-rw-r--r--kernel_drivers/v2/hal/kernel/gc_hal_kernel_command.c29
-rw-r--r--kernel_drivers/v2/hal/os/linux/kernel/gc_hal_kernel_device.c4
-rw-r--r--kernel_drivers/v2/hal/os/linux/kernel/gc_hal_kernel_driver.c237
-rw-r--r--kernel_drivers/v2/hal/os/linux/kernel/gc_hal_kernel_os.c155
8 files changed, 514 insertions, 63 deletions
diff --git a/kernel_drivers/v2/Makefile b/kernel_drivers/v2/Makefile
index fd82023..486a45e 100644
--- a/kernel_drivers/v2/Makefile
+++ b/kernel_drivers/v2/Makefile
@@ -1,73 +1,30 @@
#
-# Makefile for Vivante GPU driver
-
-debug = 0
-profiler = 0
-newsignal = 0
-
-ifeq ($(CONFIG_GPU_VIVANTE_DEBUG),y)
- debug = 1
-endif
-
-ifeq ($(CONFIG_GPU_VIVANTE_PROFILER),y)
- profiler = 1
-endif
-
-ifeq ($(CONFIG_GPU_VIVANTE_NEWSIGNAL),y)
- newsignal = 1
-endif
-
+# Vivante GC860 for Ingenic JZ4770 SOC.
#
-# driver options
-#
-ccflags-y += -DENUM_WORKAROUND=0
-#ccflags-y += -DFLARE_ON
-
-ccflags-y += -DDBG=$(debug)
-ccflags-$(CONFIG_GPU_VIVANTE_DEBUG) += -DDEBUG -D_DEBUG
-
-#ccflags-y += -DNO_DMA_COHERENT
-ccflags-y += -DENABLE_ARM_L2_CACHE=0
-#ccflags-y += -DCONFIG_DOVE_GPU=1
-ccflags-y += -DgcdNO_POWER_MANAGEMENT=0
-ccflags-y += -DUSE_PLATFORM_DRIVER=1
-ccflags-y += -DVIVANTE_PROFILER=$(profiler)
-ccflags-y += -DENABLE_GPU_CLOCK_BY_DRIVER=1
-ccflags-y += -DUSE_NEW_LINUX_SIGNAL=$(newsignal)
-ccflags-y += -DNO_USER_DIRECT_ACCESS_FROM_KERNEL=0
-ccflags-y += -DgcdkREPORT_VIDMEM_USAGE=0
+obj-$(CONFIG_VIVANTE_GPU_GC860) += galcore.o
-ifeq ($(CONFIG_GPU_VIVANTE_ANDROID),y)
- ccflags-y += -DANDROID=1
-endif
+galcore-objs := hal/os/linux/kernel/gc_hal_kernel_linux.o \
+ hal/os/linux/kernel/gc_hal_kernel_debug.o \
+ hal/os/linux/kernel/gc_hal_kernel_device.o \
+ hal/os/linux/kernel/gc_hal_kernel_os.o \
+ hal/os/linux/kernel/gc_hal_kernel_driver.o \
+ hal/kernel/gc_hal_kernel_mmu.o \
+ hal/kernel/gc_hal_kernel_heap.o \
+ hal/kernel/gc_hal_kernel_video_memory.o \
+ hal/kernel/gc_hal_kernel_command.o \
+ hal/kernel/gc_hal_kernel_event.o \
+ hal/kernel/gc_hal_kernel.o \
+ arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.o
#
-# driver includes
+# Do a kernel flush_cache_all instead of user flush_cache_range
#
-ccflags-y += \
- -I$(obj)/hal/inc \
- -I$(obj)/hal/kernel \
- -I$(obj)/hal/user \
- -I$(obj)/arch/XAQ2/hal/kernel
+EXTRA_CFLAGS += -DFLUSH_CACHE_ALL_IN_KERNEL=1
#
-# driver module name
+# Make mmap() be cacheable and implement gckOS_CacheFlush()
#
-obj-$(CONFIG_GPU_VIVANTE_V2) += galcore.o
+#EXTRA_CFLAGS += -DFIXED_MMAP_AS_CACHEABLE=1
+EXTRA_CFLAGS += -DFIXED_MMAP_AS_CACHEABLE=0
-#
-# driver objects
-#
-galcore-objs += \
- hal/os/linux/kernel/gc_hal_kernel_debug.o \
- hal/os/linux/kernel/gc_hal_kernel_device.o \
- hal/os/linux/kernel/gc_hal_kernel_driver.o \
- hal/os/linux/kernel/gc_hal_kernel_linux.o \
- hal/os/linux/kernel/gc_hal_kernel_os.o \
- hal/kernel/gc_hal_kernel.o \
- hal/kernel/gc_hal_kernel_command.o \
- hal/kernel/gc_hal_kernel_event.o \
- hal/kernel/gc_hal_kernel_heap.o \
- hal/kernel/gc_hal_kernel_mmu.o \
- hal/kernel/gc_hal_kernel_video_memory.o \
- arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.o
+EXTRA_CFLAGS += -DLINUX -DDRIVER -DENUM_WORKAROUND=0 -DDBG=0 -DNO_DMA_COHERENT -DENABLE_ARM_L2_CACHE=0 -DgcdNO_POWER_MANAGEMENT=0 -DUSE_PLATFORM_DRIVER=1 -DVIVANTE_PROFILER=0 -DANDROID=0 -DENABLE_GPU_CLOCK_BY_DRIVER=0 -DUSE_NEW_LINUX_SIGNAL=0 -DNO_USER_DIRECT_ACCESS_FROM_KERNEL=0 -DgcdkREPORT_VIDMEM_USAGE=0 -I drivers/gpu/vivante/GC860-V2/hal/inc -I drivers/gpu/vivante/GC860-V2/hal/inc -I drivers/gpu/vivante/GC860-V2/hal/kernel -I drivers/gpu/vivante/GC860-V2/arch/XAQ2/hal/kernel -I drivers/gpu/vivante/GC860-V2/hal/user -DgcdENABLE_BANK_ALIGNMENT=0 -Wframe-larger-than=1032 -Werror -DgcdNULL_DRIVER_TEST=0
diff --git a/kernel_drivers/v2/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c b/kernel_drivers/v2/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
index d8ae1c0..5350f9f 100644
--- a/kernel_drivers/v2/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
+++ b/kernel_drivers/v2/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
@@ -19,6 +19,7 @@
*****************************************************************************/
+#include <linux/sched.h>
#include "gc_hal.h"
@@ -2588,7 +2589,11 @@ gckHARDWARE_GetIdle(
pollCount = Wait ? 100 : 1;
/* At most, try for 1 second. */
+#ifdef CONFIG_JZSOC
+ for (retry = 0; retry < 145; ++retry)
+#else
for (retry = 0; retry < 1000; ++retry)
+#endif
{
/* If we have to wait, try 100 polls per millisecond. */
for (poll = pollCount; poll > 0; --poll)
@@ -2613,7 +2618,17 @@ gckHARDWARE_GetIdle(
"%s: Waiting for idle: 0x%08X",
__FUNCTION__, idle);
+#ifdef CONFIG_JZSOC
+ if(retry < 50) {
+ if ((retry & 0x3) == 1)
+ schedule();
+ else
+ gcmkVERIFY_OK(gckOS_Delay(Hardware->os, 1));
+ } else
+ gcmkVERIFY_OK(gckOS_Delay(Hardware->os, 10));
+#else
gcmkVERIFY_OK(gckOS_Delay(Hardware->os, 1));
+#endif
}
else
{
@@ -2926,6 +2941,14 @@ gckHARDWARE_SetPowerManagementState(
((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))),
};
+#ifdef CONFIG_JZSOC
+ static const gctUINT halfClock =
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (32) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) |
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)));
+#endif
+
gcmkHEADER_ARG("Hardware=0x%x State=%d", Hardware, State);
/* Verify the arguments. */
@@ -3030,6 +3053,10 @@ gckHARDWARE_SetPowerManagementState(
if ((flag == 0) || (Hardware->settingPowerState))
{
+#ifdef CONFIG_JZSOC
+ Hardware->powerProcess = Hardware->powerThread = 0x0;
+#endif
+
/* Release the power mutex. */
gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
@@ -3042,6 +3069,10 @@ gckHARDWARE_SetPowerManagementState(
&& (Hardware->chipPowerState == gcvPOWER_OFF)
)
{
+#ifdef CONFIG_JZSOC
+ Hardware->powerProcess = Hardware->powerThread = 0x0;
+#endif
+
/* Release the power mutex. */
gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
@@ -3137,6 +3168,26 @@ gckHARDWARE_SetPowerManagementState(
gcmkONERROR(Hardware->stopIsr(Hardware->isrContext));
}
+#ifdef CONFIG_JZSOC
+ if (State == gcvPOWER_ON)
+ {
+ volatile static int i;
+
+ /* Write the clock control register. */
+ gcmkONERROR(gckOS_WriteRegister(os,
+ 0x00000,
+ halfClock));
+
+ /* Done loading the frequency scaler. */
+ gcmkONERROR(gckOS_WriteRegister(os,
+ 0x00000,
+ ((((gctUINT32) (halfClock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)))));
+
+ /* Wait for a while */
+ for (i = 0; i < 1000; i++);
+ }
+#endif
+
/* Write the clock control register. */
gcmkONERROR(gckOS_WriteRegister(os,
0x00000,
@@ -3198,6 +3249,9 @@ gckHARDWARE_SetPowerManagementState(
Hardware->chipPowerState = State;
Hardware->broadcast = broadcast;
Hardware->settingPowerState = gcvFALSE;
+#ifdef CONFIG_JZSOC
+ Hardware->powerProcess = Hardware->powerThread = 0x0;
+#endif
/* Release the power mutex. */
gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
@@ -3223,6 +3277,9 @@ OnError:
if (mutexAcquired)
{
Hardware->settingPowerState = gcvFALSE;
+#ifdef CONFIG_JZSOC
+ Hardware->powerProcess = Hardware->powerThread = 0x0;
+#endif
gcmkVERIFY_OK(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
}
diff --git a/kernel_drivers/v2/hal/inc/gc_hal_options.h b/kernel_drivers/v2/hal/inc/gc_hal_options.h
index 3e3a833..243804d 100644
--- a/kernel_drivers/v2/hal/inc/gc_hal_options.h
+++ b/kernel_drivers/v2/hal/inc/gc_hal_options.h
@@ -186,7 +186,11 @@
Size of the MMU page table in bytes. Each 4 bytes can hold 4kB worth of
virtual data.
*/
+#if defined(CONFIG_JZSOC) && ANDROID
+#define gcdMMU_SIZE (256 << 10) /* Fix for Asphalt 5 */
+#else
#define gcdMMU_SIZE (128 << 10)
+#endif
/*
gcdSECURE_USER
diff --git a/kernel_drivers/v2/hal/kernel/gc_hal_kernel.c b/kernel_drivers/v2/hal/kernel/gc_hal_kernel.c
index 71a0798..a6309ed 100644
--- a/kernel_drivers/v2/hal/kernel/gc_hal_kernel.c
+++ b/kernel_drivers/v2/hal/kernel/gc_hal_kernel.c
@@ -368,7 +368,15 @@ _AllocateMemory(
if (pool == gcvPOOL_SYSTEM)
{
/* Advance to contiguous memory. */
+#ifdef CONFIG_JZSOC
+ /*
+ * Do not use '__get_free_page' or kernel will hang.
+ * - Modified by <Wolfgang@ingenic.cn> on 20110218.
+ */
+ pool = gcvPOOL_VIRTUAL;
+#else
pool = gcvPOOL_CONTIGUOUS;
+#endif
}
else
if ((pool == gcvPOOL_CONTIGUOUS)
diff --git a/kernel_drivers/v2/hal/kernel/gc_hal_kernel_command.c b/kernel_drivers/v2/hal/kernel/gc_hal_kernel_command.c
index 7ef56ef..7a4ad94 100644
--- a/kernel_drivers/v2/hal/kernel/gc_hal_kernel_command.c
+++ b/kernel_drivers/v2/hal/kernel/gc_hal_kernel_command.c
@@ -484,6 +484,13 @@ gckCOMMAND_Destroy(
return gcvSTATUS_OK;
}
+#if FIXED_MMAP_AS_CACHEABLE && FLUSH_CACHE_ALL_IN_KERNEL
+gceSTATUS
+gckOS_CacheFlushAll(
+ IN gckOS Os
+ );
+#endif
+
/*******************************************************************************
**
** gckCOMMAND_Start
@@ -520,6 +527,11 @@ gckCOMMAND_Start(
return gcvSTATUS_OK;
}
+#if FIXED_MMAP_AS_CACHEABLE && FLUSH_CACHE_ALL_IN_KERNEL
+ /* Flush all caches. */
+ gcmkONERROR(gckOS_CacheFlushAll(Command->os));
+#endif
+
/* Extract the gckHARDWARE object. */
hardware = Command->kernel->hardware;
gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
@@ -773,6 +785,11 @@ gckCOMMAND_Commit(
return gcvSTATUS_OK;
#endif
+#if FIXED_MMAP_AS_CACHEABLE && FLUSH_CACHE_ALL_IN_KERNEL
+ /* Flush all caches. */
+ gcmkONERROR(gckOS_CacheFlushAll(Command->os));
+#endif
+
gcmkONERROR(
_AddMap(Command->os,
CommandBuffer,
@@ -836,6 +853,9 @@ gckCOMMAND_Commit(
/* Release the power mutex. */
if (powerAcquired)
{
+#ifdef CONFIG_JZSOC
+ hardware->powerProcess = hardware->powerThread = 0x0;
+#endif
/* Release the power mutex. */
gcmkONERROR(gckOS_ReleaseMutex(Command->os, hardware->powerMutex));
powerAcquired = gcvFALSE;
@@ -1361,6 +1381,9 @@ OnError:
if (powerAcquired)
{
+#ifdef CONFIG_JZSOC
+ hardware->powerProcess = hardware->powerThread = 0x0;
+#endif
/* Release the power mutex. */
gcmkONERROR(gckOS_ReleaseMutex(Command->os, hardware->powerMutex));
}
@@ -1463,6 +1486,9 @@ gckCOMMAND_Reserve(
if (powerAcquired)
{
+#ifdef CONFIG_JZSOC
+ hardware->powerProcess = hardware->powerThread = 0x0;
+#endif
/* Release the power mutex. */
gcmkONERROR(gckOS_ReleaseMutex(Command->os,
Command->kernel->hardware->powerMutex));
@@ -1550,6 +1576,9 @@ OnError:
if (powerAcquired)
{
+#ifdef CONFIG_JZSOC
+ hardware->powerProcess = hardware->powerThread = 0x0;
+#endif
/* Release the power mutex. */
gcmkONERROR(gckOS_ReleaseMutex(Command->os,
Command->kernel->hardware->powerMutex));
diff --git a/kernel_drivers/v2/hal/os/linux/kernel/gc_hal_kernel_device.c b/kernel_drivers/v2/hal/os/linux/kernel/gc_hal_kernel_device.c
index 8cba84e..7ff4588 100644
--- a/kernel_drivers/v2/hal/os/linux/kernel/gc_hal_kernel_device.c
+++ b/kernel_drivers/v2/hal/os/linux/kernel/gc_hal_kernel_device.c
@@ -725,7 +725,11 @@ gckGALDEVICE_Construct(
device->contiguousPhysical = (gctPHYS_ADDR) ContiguousBase;
device->contiguousSize = ContiguousSize;
+#if FIXED_MMAP_AS_CACHEABLE
+ device->contiguousBase = (gctPOINTER) ioremap_cachable(ContiguousBase, ContiguousSize);
+#else
device->contiguousBase = (gctPOINTER) ioremap_nocache(ContiguousBase, ContiguousSize);
+#endif
device->contiguousMapped = gcvTRUE;
if (device->contiguousBase == gcvNULL)
diff --git a/kernel_drivers/v2/hal/os/linux/kernel/gc_hal_kernel_driver.c b/kernel_drivers/v2/hal/os/linux/kernel/gc_hal_kernel_driver.c
index f5d25c7..2dcf52d 100644
--- a/kernel_drivers/v2/hal/os/linux/kernel/gc_hal_kernel_driver.c
+++ b/kernel_drivers/v2/hal/os/linux/kernel/gc_hal_kernel_driver.c
@@ -23,6 +23,7 @@
#include <linux/device.h>
#include <linux/slab.h>
+#include <linux/clk.h>
#include "gc_hal_kernel_linux.h"
#include "gc_hal_driver.h"
@@ -42,6 +43,39 @@ static gckGALDEVICE galDevice;
static int major = 199;
module_param(major, int, 0644);
+#ifdef CONFIG_MACH_JZ4770
+#include <asm/mach-jz4770/jz4770cpm.h>
+
+#ifndef IRQ_GPU
+#define IRQ_GPU 6
+#endif
+#ifndef GPU_BASE
+#define GPU_BASE 0x13040000
+#endif
+#ifndef JZ_GPU_MEM_BASE
+#define JZ_GPU_MEM_BASE 0 /* if GPU_MEM_BASE = 0, alloc gpu memory dynamicly on bootup */
+#endif
+#ifndef JZ_GPU_MEM_SIZE
+#define JZ_GPU_MEM_SIZE 0x400000 /* set default reserved memory 4M Bytes. */
+#endif
+
+int irqLine = IRQ_GPU;
+module_param(irqLine, int, 0644);
+
+long registerMemBase = GPU_BASE;
+module_param(registerMemBase, long, 0644);
+
+ulong registerMemSize = 256 << 10;
+module_param(registerMemSize, ulong, 0644);
+
+long contiguousSize = JZ_GPU_MEM_SIZE;
+module_param(contiguousSize, long, 0644);
+
+ulong contiguousBase = JZ_GPU_MEM_BASE;
+module_param(contiguousBase, ulong, 0644);
+
+#else /* CONFIG_MACH_JZ4770 */
+
int irqLine = -1;
module_param(irqLine, int, 0644);
@@ -56,6 +90,7 @@ module_param(contiguousSize, long, 0644);
ulong contiguousBase = 0;
module_param(contiguousBase, ulong, 0644);
+#endif /* CONFIG_MACH_JZ4770 */
long bankSize = 32 << 20;
module_param(bankSize, long, 0644);
@@ -75,17 +110,42 @@ module_param(baseAddress, ulong, 0644);
int showArgs = 1;
module_param(showArgs, int, 0644);
+#if ENABLE_GPU_CLOCK_BY_DRIVER
+unsigned long coreClock = 156000000;
+module_param(coreClock, ulong, 0644);
+#endif
+
static int drv_open(struct inode *inode, struct file *filp);
static int drv_release(struct inode *inode, struct file *filp);
static long drv_ioctl(struct file *filp, unsigned int ioctlCode,
unsigned long arg);
static int drv_mmap(struct file * filp, struct vm_area_struct * vma);
+#if defined(CONFIG_JZSOC) && defined(CONFIG_PREEMPT) && ANDROID
+/* Fix bug with WOWFish. */
+#include <linux/kernel_lock.h>
+static long fix_drv_ioctl(struct file *filp,
+ unsigned int ioctlCode, unsigned long arg)
+{
+ long ret;
+
+ lock_kernel();
+ ret = drv_ioctl(filp, ioctlCode, arg);
+ unlock_kernel();
+ return ret;
+}
+#endif
+
struct file_operations driver_fops =
{
.open = drv_open,
.release = drv_release,
+#if defined(CONFIG_JZSOC) && defined(CONFIG_PREEMPT) && ANDROID
+ /* Fix bug with WOWFish. */
+ .unlocked_ioctl = fix_drv_ioctl,
+#else
.unlocked_ioctl = drv_ioctl,
+#endif
.mmap = drv_mmap,
};
@@ -524,6 +584,12 @@ static int drv_mmap(struct file * filp, struct vm_area_struct * vma)
vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND;
vma->vm_pgoff = 0;
+#if FIXED_MMAP_AS_CACHEABLE
+ pgprot_val(vma->vm_page_prot) &= ~_CACHE_MASK;
+// pgprot_val(vma->vm_page_prot) |= _CACHE_UNCACHED; /* Uncacheable */
+ pgprot_val(vma->vm_page_prot) |= _CACHE_CACHABLE_NONCOHERENT; /* W-Back */
+#endif
+
if (device->contiguousMapped)
{
ret = io_remap_pfn_range(vma,
@@ -542,6 +608,54 @@ static int drv_mmap(struct file * filp, struct vm_area_struct * vma)
}
}
+#ifdef CONFIG_JZSOC
+static void enable_jzsoc_gpu_clock(void)
+{
+#ifdef CONFIG_MACH_JZ4770
+ {
+ /* JZ4770 GPU CLK2x 100MHz -- 500MHz */
+#define GPU_CLK_MAX 500000000
+// extern unsigned int cpm_get_pllout1(void);
+ unsigned int GPUCDR_VAL=0;
+ int div;
+ int gpu_use_pll1 = 1;
+ unsigned int pll_clk;
+ unsigned int gpu_clk = 0;
+
+ pll_clk = cpm_get_pllout1();
+ if ( pll_clk == 0 ) {
+ gpu_use_pll1 = 0; /* use pll0 */
+ pll_clk = cpm_get_pllout();
+#ifdef CONFIG_MACH_JZ4770
+ if ((INREG32(CPM_CPCCR) & CPCCR_PCS) != 0 )
+#else
+ if ((INREG32(CPM_CPCCR) & CPCCR_PCS) == 0 ) /* JZ4760 */
+#endif
+ pll_clk /= 2;
+ }
+
+ for ( div=1; div <= ((GPUCDR_GPUDIV_MASK>>GPUCDR_GPUDIV_LSB)+1); div++ ) {
+ gpu_clk = pll_clk/div;
+ if ( gpu_clk < GPU_CLK_MAX )
+ break;
+ }
+
+ cpm_stop_clock(CGM_GPU);
+ GPUCDR_VAL = (div-1);
+ if (gpu_use_pll1)
+ GPUCDR_VAL |= 1<<31;
+ REG_CPM_GPUCDR = GPUCDR_VAL;
+ cpm_start_clock(CGM_GPU);
+
+ printk("REG_CPM_GPUCDR= 0x%08x\n", GPUCDR_VAL);
+ printk("GPU CLOCK USE PLL%d\n", gpu_use_pll1);
+ printk("GPU GPU_CLK2x= %d MHz\n", gpu_clk/1000000);
+ }
+#else
+#error "Not defined SOC_JZ4770"
+#endif
+}
+#endif
#if !USE_PLATFORM_DRIVER
static int __init drv_init(void)
@@ -555,6 +669,32 @@ static int drv_init(void)
gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_DRIVER,
"Entering drv_init\n");
+#ifdef CONFIG_JZSOC
+ enable_jzsoc_gpu_clock();
+#endif
+
+#if ENABLE_GPU_CLOCK_BY_DRIVER && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
+ struct clk * clk = clk_get(NULL, "GCCLK");
+ if (IS_ERR(clk))
+ {
+ int retval = PTR_ERR(clk);
+ printk("clk get error: %d\n", retval);
+ return -ENODEV;
+ }
+
+ /*
+ * APMU_GC_156M, APMU_GC_312M, APMU_GC_PLL2, APMU_GC_PLL2_DIV2 currently.
+ * Use the 2X clock.
+ */
+ if (clk_set_rate(clk, coreClock * 2))
+ {
+ gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "[galcore] Can't set core clock.");
+ return -EAGAIN;
+ }
+ clk_enable(clk);
+#endif
+
if (showArgs)
{
printk("galcore options:\n");
@@ -649,7 +789,12 @@ static void __exit drv_exit(void)
static void drv_exit(void)
#endif
{
+#if ENABLE_GPU_CLOCK_BY_DRIVER && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
+ struct clk * clk = NULL;
+#endif
+#ifndef CONFIG_JZSOC
struct clk *clk = galDevice->clk;
+#endif
gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_DRIVER,
"[galcore] Entering drv_exit\n");
@@ -662,8 +807,14 @@ static void drv_exit(void)
gckGALDEVICE_Stop(galDevice);
gckGALDEVICE_Destroy(galDevice);
+#if ENABLE_GPU_CLOCK_BY_DRIVER && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
+ clk = clk_get(NULL, "GCCLK");
+ clk_disable(clk);
+#endif
+#ifndef CONFIG_JZSOC
clk_disable(clk);
clk_put(clk);
+#endif
}
#if !USE_PLATFORM_DRIVER
@@ -682,7 +833,9 @@ static int __devinit gpu_probe(struct platform_device *pdev)
{
int ret = -ENODEV;
struct resource *res;
+#ifndef CONFIG_JZSOC
struct clk *clk;
+#endif
res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,"gpu_irq");
if (!res) {
@@ -709,6 +862,7 @@ static int __devinit gpu_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "driver v2.5.3.2.2.p3, initializing\n");
+#ifndef CONFIG_JZSOC
clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(clk)) {
dev_err(&pdev->dev, "cannot get clock\n");
@@ -716,10 +870,16 @@ static int __devinit gpu_probe(struct platform_device *pdev)
goto gpu_probe_fail;
}
clk_enable(clk);
+#endif
ret = drv_init();
if(!ret) {
platform_set_drvdata(pdev,galDevice);
+#ifdef CONFIG_JZSOC
+
+ return ret;
+ }
+#else
galDevice->clk = clk;
dev_info(&pdev->dev, "GPU initialized, clocked at %luMHz\n",
@@ -730,6 +890,7 @@ static int __devinit gpu_probe(struct platform_device *pdev)
clk_disable(clk);
clk_put(clk);
+#endif
gpu_probe_fail:
printk(KERN_INFO "Failed to register gpu driver.\n");
@@ -757,7 +918,11 @@ static int __devinit gpu_suspend(struct platform_device *dev, pm_message_t state
return -1;
}
+#ifdef CONFIG_JZSOC
+ cpm_stop_clock(CGM_GPU);
+#else
clk_disable(galDevice->clk);
+#endif
return 0;
}
@@ -769,7 +934,11 @@ static int __devinit gpu_resume(struct platform_device *dev)
device = platform_get_drvdata(dev);
+#ifdef CONFIG_JZSOC
+ cpm_start_clock(CGM_GPU);
+#else
clk_enable(galDevice->clk);
+#endif
status = gckHARDWARE_SetPowerManagementState(device->kernel->hardware, gcvPOWER_ON);
@@ -800,17 +969,85 @@ static struct platform_driver gpu_driver = {
}
};
+#ifdef CONFIG_JZSOC
+static struct resource gpu_resources[] = {
+ {
+ .name = "gpu_irq",
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "gpu_base",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "gpu_mem",
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device * gpu_device;
+#endif
+
static int __init gpu_init(void)
{
int ret = 0;
+#ifdef CONFIG_JZSOC
+ gpu_resources[0].start = gpu_resources[0].end = irqLine;
+
+ gpu_resources[1].start = registerMemBase;
+ gpu_resources[1].end = registerMemBase + registerMemSize - 1;
+
+ gpu_resources[2].start = contiguousBase;
+ gpu_resources[2].end = contiguousBase + contiguousSize - 1;
+
+ /* Allocate device */
+ gpu_device = platform_device_alloc(DEVICE_NAME, -1);
+ if (!gpu_device)
+ {
+ printk(KERN_ERR "galcore: platform_device_alloc failed.\n");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ /* Insert resource */
+ ret = platform_device_add_resources(gpu_device, gpu_resources, 3);
+ if (ret)
+ {
+ printk(KERN_ERR "galcore: platform_device_add_resources failed.\n");
+ goto put_dev;
+ }
+
+ /* Add device */
+ ret = platform_device_add(gpu_device);
+ if (ret)
+ {
+ printk(KERN_ERR "galcore: platform_device_add failed.\n");
+ goto put_dev;
+ }
+
ret = platform_driver_register(&gpu_driver);
+ if (!ret)
+ {
+ goto out;
+ }
+
+ platform_device_del(gpu_device);
+put_dev:
+ platform_device_put(gpu_device);
+out:
+#else
+ ret = platform_driver_register(&gpu_driver);
+#endif
return ret;
}
static void __exit gpu_exit(void)
{
platform_driver_unregister(&gpu_driver);
+#ifdef CONFIG_JZSOC
+ platform_device_unregister(gpu_device);
+#endif
}
module_init(gpu_init);
diff --git a/kernel_drivers/v2/hal/os/linux/kernel/gc_hal_kernel_os.c b/kernel_drivers/v2/hal/os/linux/kernel/gc_hal_kernel_os.c
index 68fe846..7bc47fe 100644
--- a/kernel_drivers/v2/hal/os/linux/kernel/gc_hal_kernel_os.c
+++ b/kernel_drivers/v2/hal/os/linux/kernel/gc_hal_kernel_os.c
@@ -34,6 +34,18 @@
#include <linux/dma-mapping.h>
#endif /* NO_DMA_COHERENT */
+#if defined(CONFIG_MODULES) && defined(MODULE)
+extern unsigned long plat_do_mmap_pgoff(struct file *file, unsigned long addr,
+ unsigned long len, unsigned long prot,
+ unsigned long flags, unsigned long pgoff);
+
+extern int plat_do_munmap(struct mm_struct *mm, unsigned long start,
+ size_t len);
+
+#define do_mmap_pgoff plat_do_mmap_pgoff
+#define do_munmap plat_do_munmap
+#endif
+
#if !USE_NEW_LINUX_SIGNAL
#define USER_SIGNAL_TABLE_LEN_INIT 64
#endif
@@ -1044,7 +1056,16 @@ gckOS_MapMemory(
}
#else
mdlMap->vma->vm_page_prot = pgprot_noncached(mdlMap->vma->vm_page_prot);
+#if FIXED_MMAP_AS_CACHEABLE
+ /* Write-Back */
+ pgprot_val(mdlMap->vma->vm_page_prot) &= ~_CACHE_MASK;
+ pgprot_val(mdlMap->vma->vm_page_prot) |= _CACHE_CACHABLE_NONCOHERENT;
+#endif
+#ifdef VM_RESERVED
mdlMap->vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED;
+#else
+ mdlMap->vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_DONTDUMP;
+#endif
mdlMap->vma->vm_pgoff = 0;
if (remap_pfn_range(mdlMap->vma,
@@ -1298,7 +1319,11 @@ gckOS_AllocateNonPagedMemory(
reserved_size -= PAGE_SIZE;
}
+#if FIXED_MMAP_AS_CACHEABLE
+ addr = ioremap_cachable(virt_to_phys(vaddr), size);
+#else
addr = ioremap_nocache(virt_to_phys(vaddr), size);
+#endif
mdl->dmaHandle = virt_to_phys(vaddr);
mdl->kaddr = vaddr;
@@ -1421,7 +1446,16 @@ gckOS_AllocateNonPagedMemory(
}
#else
mdlMap->vma->vm_page_prot = pgprot_noncached(mdlMap->vma->vm_page_prot);
+#if FIXED_MMAP_AS_CACHEABLE
+ /* Write-Back */
+ pgprot_val(mdlMap->vma->vm_page_prot) &= ~_CACHE_MASK;
+ pgprot_val(mdlMap->vma->vm_page_prot) |= _CACHE_CACHABLE_NONCOHERENT;
+#endif
+#ifdef VM_RESERVED
mdlMap->vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED;
+#else
+ mdlMap->vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_DONTDUMP;
+#endif
mdlMap->vma->vm_pgoff = 0;
if (remap_pfn_range(mdlMap->vma,
@@ -1977,7 +2011,11 @@ gceSTATUS gckOS_MapPhysical(
{
/* Map memory as cached memory. */
request_mem_region(physical, Bytes, "MapRegion");
+#if FIXED_MMAP_AS_CACHEABLE
+ logical = (gctPOINTER) ioremap_cachable(physical, Bytes);
+#else
logical = (gctPOINTER) ioremap_nocache(physical, Bytes);
+#endif
if (logical == NULL)
{
@@ -2572,6 +2610,12 @@ gckOS_Delay(
if (Delay > 0)
{
+#ifdef CONFIG_MACH_JZ4770
+ unsigned long long clock;
+ unsigned int diffclock;
+ int flag;
+#endif
+
/* Convert milliseconds into seconds and microseconds. */
now.tv_sec = Delay / 1000;
now.tv_usec = (Delay % 1000) * 1000;
@@ -2579,8 +2623,21 @@ gckOS_Delay(
/* Convert timeval to jiffies. */
jiffies = timeval_to_jiffies(&now);
+#ifdef CONFIG_MACH_JZ4770
+ flag = 1;
+ clock = sched_clock();
+ while(flag) {
+ schedule_timeout_interruptible(jiffies);
+ diffclock = (unsigned int)(sched_clock() - clock);
+ if (diffclock < Delay * 1000000)
+ jiffies = 1;
+ else
+ flag = 0;
+ }
+#else
/* Schedule timeout. */
schedule_timeout_interruptible(jiffies);
+#endif
}
/* Success. */
@@ -2614,7 +2671,11 @@ gceSTATUS gckOS_MemoryBarrier(
/* Verify thearguments. */
gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+#ifdef CONFIG_MIPS
+ iob();
+#else
mb();
+#endif
/* Success. */
return gcvSTATUS_OK;
@@ -3013,9 +3074,18 @@ gceSTATUS gckOS_LockPages(
return gcvSTATUS_OUT_OF_RESOURCES;
}
+#ifdef VM_RESERVED
mdlMap->vma->vm_flags |= VM_RESERVED;
+#else
+ mdlMap->vma->vm_flags |= VM_DONTDUMP;
+#endif
/* Make this mapping non-cached. */
mdlMap->vma->vm_page_prot = pgprot_noncached(mdlMap->vma->vm_page_prot);
+#if FIXED_MMAP_AS_CACHEABLE
+ /* Write-Back */
+ pgprot_val(mdlMap->vma->vm_page_prot) &= ~_CACHE_MASK;
+ pgprot_val(mdlMap->vma->vm_page_prot) |= _CACHE_CACHABLE_NONCOHERENT;
+#endif
addr = mdl->addr;
@@ -4079,6 +4149,16 @@ gckOS_WaitSignal(
status = ((rc == 0) && !signal->event.done) ? gcvSTATUS_TIMEOUT
: gcvSTATUS_OK;
+#if defined(CONFIG_JZSOC) && ANDROID
+ /*
+ * Fix WOWFish suspend resume render bugs. Code from Yun.Li @ Vivante.
+ */
+ if (status == gcvSTATUS_OK)
+ {
+ INIT_COMPLETION(signal->event);
+ }
+#endif
+
/* Return status. */
gcmkFOOTER();
return status;
@@ -5673,6 +5753,75 @@ FreeAllMemoryRecord(
}
#endif
+#if defined(CONFIG_JZSOC) && FIXED_MMAP_AS_CACHEABLE
+static inline void flush_dcache_with_prefetch_allocate(void)
+{
+ int addr;
+
+ for (addr = KSEG0; addr < (KSEG0 + 16384); addr += 256) {
+ /* 256 = 32byte * 8 */
+ asm ( ".set\tmips32\n\t"
+ "pref %0, 0(%1)\n\t"
+ "pref %0, 32(%1)\n\t"
+ "pref %0, 64(%1)\n\t"
+ "pref %0, 96(%1)\n\t"
+ "pref %0, 128(%1)\n\t"
+ "pref %0, 160(%1)\n\t"
+ "pref %0, 192(%1)\n\t"
+ "pref %0, 224(%1)\n\t"
+ :
+ : "I" (30), "r"(addr));
+ }
+ asm ("sync");
+}
+
+static inline void flush_dcache_range_with_prefetch_allocate(unsigned int addr, int bytes)
+{
+ unsigned int start, end;
+
+ start = (addr & 0x00000FE0) | KSEG0; /* 0xFE0 = address offset (11:5) */
+ end = start + bytes + ((addr & (32-1))? 32 : 0);
+
+ for (; start < end; start += 32) { /* 32byte step */
+ asm ( ".set\tmips32\n\t"
+ "pref %0, 0x0000(%1)\n\t"
+ "pref %0, 0x1000(%1)\n\t"
+ "pref %0, 0x2000(%1)\n\t"
+ "pref %0, 0x3000(%1)\n\t"
+ :
+ : "I" (30), "r"(start));
+ }
+ asm ("sync");
+}
+
+static inline void jz_flush_cache(
+ IN gckOS Os,
+ IN gctHANDLE Process,
+ IN gctPOINTER Logical,
+ IN gctSIZE_T Bytes
+ )
+{
+ if (Bytes < 4096)
+ flush_dcache_range_with_prefetch_allocate((unsigned int)Logical, (int)Bytes);
+ else
+ flush_dcache_with_prefetch_allocate();
+
+ return;
+}
+
+#if defined(CONFIG_JZSOC) && FLUSH_CACHE_ALL_IN_KERNEL
+gceSTATUS
+gckOS_CacheFlushAll(
+ IN gckOS Os
+ )
+{
+ flush_dcache_with_prefetch_allocate();
+
+ return gcvSTATUS_OK;
+}
+#endif
+#endif
+
/*******************************************************************************
** gckOS_CacheFlush
**
@@ -5703,6 +5852,9 @@ gckOS_CacheFlush(
IN gctSIZE_T Bytes
)
{
+#if defined(CONFIG_JZSOC) && FIXED_MMAP_AS_CACHEABLE
+ jz_flush_cache(Os, Process, Logical, Bytes);
+#endif
return gcvSTATUS_OK;
}
@@ -5736,6 +5888,9 @@ gckOS_CacheInvalidate(
IN gctSIZE_T Bytes
)
{
+#if FIXED_MMAP_AS_CACHEABLE
+ dma_cache_wback_inv((u32)Logical, Bytes);
+#endif
return gcvSTATUS_OK;
}