diff options
-rw-r--r-- | kernel_drivers/v2/Makefile | 83 | ||||
-rw-r--r-- | kernel_drivers/v2/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c | 57 | ||||
-rw-r--r-- | kernel_drivers/v2/hal/inc/gc_hal_options.h | 4 | ||||
-rw-r--r-- | kernel_drivers/v2/hal/kernel/gc_hal_kernel.c | 8 | ||||
-rw-r--r-- | kernel_drivers/v2/hal/kernel/gc_hal_kernel_command.c | 29 | ||||
-rw-r--r-- | kernel_drivers/v2/hal/os/linux/kernel/gc_hal_kernel_device.c | 4 | ||||
-rw-r--r-- | kernel_drivers/v2/hal/os/linux/kernel/gc_hal_kernel_driver.c | 237 | ||||
-rw-r--r-- | kernel_drivers/v2/hal/os/linux/kernel/gc_hal_kernel_os.c | 155 |
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; } |