summaryrefslogtreecommitdiff
path: root/kernel_drivers
diff options
context:
space:
mode:
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;
}