diff --git a/drivers/mxc/amd-gpu/kgsl_hal.c b/drivers/mxc/amd-gpu/kgsl_hal.c index 5495308ced8..202ce530d79 100644 --- a/drivers/mxc/amd-gpu/kgsl_hal.c +++ b/drivers/mxc/amd-gpu/kgsl_hal.c @@ -71,7 +71,7 @@ kgsl_hal_allocphysical(unsigned int virtaddr, unsigned int numpages, unsigned in int i; void *va; - va = gsl_linux_map_alloc(virtaddr, numpages*PAGE_SIZE); + va = kgsl_mem_entry_alloc(virtaddr, numpages*PAGE_SIZE); if (!va) return GSL_FAILURE_OUTOFMEM; @@ -91,7 +91,7 @@ kgsl_hal_freephysical(unsigned int virtaddr, unsigned int numpages, unsigned int { /* free physical memory */ - gsl_linux_map_free(virtaddr); + kgsl_mem_entry_free(virtaddr); return GSL_SUCCESS; } @@ -215,7 +215,7 @@ kgsl_hal_init(void) #endif if (gsl_driver.enable_mmu) { - gsl_linux_map_init(); + kgsl_mem_entry_init(); hal->memspace[GSL_HAL_MEM1].mmio_virt_base = (void *)GSL_LINUX_MAP_RANGE_START; hal->memspace[GSL_HAL_MEM1].gpu_base = GSL_LINUX_MAP_RANGE_START; hal->memspace[GSL_HAL_MEM1].sizebytes = GSL_HAL_SHMEM_SIZE_EMEM_MMU; @@ -268,7 +268,7 @@ kgsl_hal_close(void) } if (gsl_driver.enable_mmu) { - gsl_linux_map_destroy(); + kgsl_mem_entry_destroy(); } /* release hal struct */ diff --git a/drivers/mxc/amd-gpu/kgsl_hwaccess.h b/drivers/mxc/amd-gpu/kgsl_hwaccess.h deleted file mode 100644 index 3e23e23f91b..00000000000 --- a/drivers/mxc/amd-gpu/kgsl_hwaccess.h +++ /dev/null @@ -1,93 +0,0 @@ -/* Copyright (c) 2008-2010, Advanced Micro Devices. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Advanced Micro Devices nor - * the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef __GSL_HWACCESS_LINUX_H -#define __GSL_HWACCESS_LINUX_H - -#include -#include -#include - -#include "kgsl_halconfig.h" // EMEM_MMU stuff -#include "kgsl_linux_map.h" // GSL_LINUX_MAP_RANGE_START etc. - -static __inline void -kgsl_hwaccess_memread(void *dst, unsigned int gpubase, unsigned int gpuoffset, unsigned int sizebytes, unsigned int touserspace) -{ - if (gsl_driver.enable_mmu && (gpubase >= GSL_LINUX_MAP_RANGE_START) && (gpubase < GSL_LINUX_MAP_RANGE_END)) { - gsl_linux_map_read(dst, gpubase+gpuoffset, sizebytes, touserspace); - } else { - if (touserspace) - { - if (copy_to_user(dst, (void *)(gpubase + gpuoffset), sizebytes)) - { - return; - } - } - else - { - memcpy(dst, (void *) (gpubase + gpuoffset), sizebytes); - } - } -} - -//---------------------------------------------------------------------------- - -static __inline void -kgsl_hwaccess_memwrite(unsigned int gpubase, unsigned int gpuoffset, void *src, unsigned int sizebytes, unsigned int fromuserspace) -{ - if (gsl_driver.enable_mmu && (gpubase >= GSL_LINUX_MAP_RANGE_START) && (gpubase < GSL_LINUX_MAP_RANGE_END)) { - gsl_linux_map_write(src, gpubase+gpuoffset, sizebytes, fromuserspace); - } else { - if (fromuserspace) - { - if (copy_from_user((void *)(gpubase + gpuoffset), src, sizebytes)) - { - return; - } - } - else - { - memcpy((void *)(gpubase + gpuoffset), src, sizebytes); - } - } -} - -//---------------------------------------------------------------------------- - -static __inline void -kgsl_hwaccess_memset(unsigned int gpubase, unsigned int gpuoffset, unsigned int value, unsigned int sizebytes) -{ - if (gsl_driver.enable_mmu && (gpubase >= GSL_LINUX_MAP_RANGE_START) && (gpubase < GSL_LINUX_MAP_RANGE_END)) { - gsl_linux_map_set(gpuoffset+gpubase, value, sizebytes); - } else { - memset((void *)(gpubase + gpuoffset), value, sizebytes); - } -} - -#endif // __GSL_HWACCESS_WINCE_MX51_H diff --git a/drivers/mxc/amd-gpu/kgsl_linux_map.c b/drivers/mxc/amd-gpu/kgsl_linux_map.c index 48fad5c9fd9..1b9cb5523c0 100644 --- a/drivers/mxc/amd-gpu/kgsl_linux_map.c +++ b/drivers/mxc/amd-gpu/kgsl_linux_map.c @@ -25,7 +25,7 @@ #include "kgsl_linux_map.h" -struct gsl_linux_map +struct kgsl_mem_entry { struct list_head list; unsigned int gpu_addr; @@ -33,62 +33,62 @@ struct gsl_linux_map unsigned int size; }; -static LIST_HEAD(gsl_linux_map_list); -static DEFINE_MUTEX(gsl_linux_map_mutex); +static LIST_HEAD(kgsl_mem_entry_list); +static DEFINE_MUTEX(kgsl_mem_entry_mutex); -int gsl_linux_map_init() +int kgsl_mem_entry_init() { - mutex_lock(&gsl_linux_map_mutex); - INIT_LIST_HEAD(&gsl_linux_map_list); - mutex_unlock(&gsl_linux_map_mutex); + mutex_lock(&kgsl_mem_entry_mutex); + INIT_LIST_HEAD(&kgsl_mem_entry_list); + mutex_unlock(&kgsl_mem_entry_mutex); return 0; } -void *gsl_linux_map_alloc(unsigned int gpu_addr, unsigned int size) +void *kgsl_mem_entry_alloc(unsigned int gpu_addr, unsigned int size) { - struct gsl_linux_map * map; + struct kgsl_mem_entry * map; struct list_head *p; void *va; - mutex_lock(&gsl_linux_map_mutex); + mutex_lock(&kgsl_mem_entry_mutex); - list_for_each(p, &gsl_linux_map_list){ - map = list_entry(p, struct gsl_linux_map, list); + list_for_each(p, &kgsl_mem_entry_list){ + map = list_entry(p, struct kgsl_mem_entry, list); if(map->gpu_addr == gpu_addr){ - mutex_unlock(&gsl_linux_map_mutex); + mutex_unlock(&kgsl_mem_entry_mutex); return map->kernel_virtual_addr; } } va = __vmalloc(size, GFP_KERNEL, pgprot_noncached(pgprot_kernel)); if(va == NULL){ - mutex_unlock(&gsl_linux_map_mutex); + mutex_unlock(&kgsl_mem_entry_mutex); return NULL; } - map = (struct gsl_linux_map *)kmalloc(sizeof(*map), GFP_KERNEL); + map = (struct kgsl_mem_entry *)kmalloc(sizeof(*map), GFP_KERNEL); map->gpu_addr = gpu_addr; map->kernel_virtual_addr = va; map->size = size; INIT_LIST_HEAD(&map->list); - list_add_tail(&map->list, &gsl_linux_map_list); + list_add_tail(&map->list, &kgsl_mem_entry_list); - mutex_unlock(&gsl_linux_map_mutex); + mutex_unlock(&kgsl_mem_entry_mutex); return va; } -void gsl_linux_map_free(unsigned int gpu_addr) +void kgsl_mem_entry_free(unsigned int gpu_addr) { int found = 0; - struct gsl_linux_map * map; + struct kgsl_mem_entry * map; struct list_head *p; - mutex_lock(&gsl_linux_map_mutex); + mutex_lock(&kgsl_mem_entry_mutex); - list_for_each(p, &gsl_linux_map_list){ - map = list_entry(p, struct gsl_linux_map, list); + list_for_each(p, &kgsl_mem_entry_list){ + map = list_entry(p, struct kgsl_mem_entry, list); if(map->gpu_addr == gpu_addr){ found = 1; break; @@ -101,41 +101,41 @@ void gsl_linux_map_free(unsigned int gpu_addr) kfree(map); } - mutex_unlock(&gsl_linux_map_mutex); + mutex_unlock(&kgsl_mem_entry_mutex); } void *kgsl_sharedmem_find(unsigned int gpu_addr) { - struct gsl_linux_map * map; + struct kgsl_mem_entry * map; struct list_head *p; - mutex_lock(&gsl_linux_map_mutex); + mutex_lock(&kgsl_mem_entry_mutex); - list_for_each(p, &gsl_linux_map_list){ - map = list_entry(p, struct gsl_linux_map, list); + list_for_each(p, &kgsl_mem_entry_list){ + map = list_entry(p, struct kgsl_mem_entry, list); if(map->gpu_addr == gpu_addr){ - mutex_unlock(&gsl_linux_map_mutex); + mutex_unlock(&kgsl_mem_entry_mutex); return map->kernel_virtual_addr; } } - mutex_unlock(&gsl_linux_map_mutex); + mutex_unlock(&kgsl_mem_entry_mutex); return NULL; } -void *gsl_linux_map_read(void *dst, unsigned int gpuoffset, unsigned int sizebytes, unsigned int touserspace) +void *kgsl_mem_entry_read(void *dst, unsigned int gpuoffset, unsigned int sizebytes, unsigned int touserspace) { - struct gsl_linux_map * map; + struct kgsl_mem_entry * map; struct list_head *p; - mutex_lock(&gsl_linux_map_mutex); + mutex_lock(&kgsl_mem_entry_mutex); - list_for_each(p, &gsl_linux_map_list){ - map = list_entry(p, struct gsl_linux_map, list); + list_for_each(p, &kgsl_mem_entry_list){ + map = list_entry(p, struct kgsl_mem_entry, list); if(map->gpu_addr <= gpuoffset && (map->gpu_addr + map->size) > gpuoffset){ void *src = map->kernel_virtual_addr + (gpuoffset - map->gpu_addr); - mutex_unlock(&gsl_linux_map_mutex); + mutex_unlock(&kgsl_mem_entry_mutex); if (touserspace) { return (void *)copy_to_user(dst, map->kernel_virtual_addr + gpuoffset - map->gpu_addr, sizebytes); @@ -147,23 +147,23 @@ void *gsl_linux_map_read(void *dst, unsigned int gpuoffset, unsigned int sizebyt } } - mutex_unlock(&gsl_linux_map_mutex); + mutex_unlock(&kgsl_mem_entry_mutex); return NULL; } -void *gsl_linux_map_write(void *src, unsigned int gpuoffset, unsigned int sizebytes, unsigned int fromuserspace) +void *kgsl_mem_entry_write(void *src, unsigned int gpuoffset, unsigned int sizebytes, unsigned int fromuserspace) { - struct gsl_linux_map * map; + struct kgsl_mem_entry * map; struct list_head *p; - mutex_lock(&gsl_linux_map_mutex); + mutex_lock(&kgsl_mem_entry_mutex); - list_for_each(p, &gsl_linux_map_list){ - map = list_entry(p, struct gsl_linux_map, list); + list_for_each(p, &kgsl_mem_entry_list){ + map = list_entry(p, struct kgsl_mem_entry, list); if(map->gpu_addr <= gpuoffset && (map->gpu_addr + map->size) > gpuoffset){ void *dst = map->kernel_virtual_addr + (gpuoffset - map->gpu_addr); - mutex_unlock(&gsl_linux_map_mutex); + mutex_unlock(&kgsl_mem_entry_mutex); if (fromuserspace) { return (void *)copy_from_user(map->kernel_virtual_addr + gpuoffset - map->gpu_addr, src, sizebytes); @@ -175,47 +175,47 @@ void *gsl_linux_map_write(void *src, unsigned int gpuoffset, unsigned int sizeby } } - mutex_unlock(&gsl_linux_map_mutex); + mutex_unlock(&kgsl_mem_entry_mutex); return NULL; } -void *gsl_linux_map_set(unsigned int gpuoffset, unsigned int value, unsigned int sizebytes) +void *kgsl_mem_entry_set(unsigned int gpuoffset, unsigned int value, unsigned int sizebytes) { - struct gsl_linux_map * map; + struct kgsl_mem_entry * map; struct list_head *p; - mutex_lock(&gsl_linux_map_mutex); + mutex_lock(&kgsl_mem_entry_mutex); - list_for_each(p, &gsl_linux_map_list){ - map = list_entry(p, struct gsl_linux_map, list); + list_for_each(p, &kgsl_mem_entry_list){ + map = list_entry(p, struct kgsl_mem_entry, list); if(map->gpu_addr <= gpuoffset && (map->gpu_addr + map->size) > gpuoffset){ void *ptr = map->kernel_virtual_addr + (gpuoffset - map->gpu_addr); - mutex_unlock(&gsl_linux_map_mutex); + mutex_unlock(&kgsl_mem_entry_mutex); return memset(ptr, value, sizebytes); } } - mutex_unlock(&gsl_linux_map_mutex); + mutex_unlock(&kgsl_mem_entry_mutex); return NULL; } -int gsl_linux_map_destroy() +int kgsl_mem_entry_destroy() { - struct gsl_linux_map * map; + struct kgsl_mem_entry * map; struct list_head *p, *tmp; - mutex_lock(&gsl_linux_map_mutex); + mutex_lock(&kgsl_mem_entry_mutex); - list_for_each_safe(p, tmp, &gsl_linux_map_list){ - map = list_entry(p, struct gsl_linux_map, list); + list_for_each_safe(p, tmp, &kgsl_mem_entry_list){ + map = list_entry(p, struct kgsl_mem_entry, list); vfree(map->kernel_virtual_addr); list_del(&map->list); kfree(map); } - INIT_LIST_HEAD(&gsl_linux_map_list); + INIT_LIST_HEAD(&kgsl_mem_entry_list); - mutex_unlock(&gsl_linux_map_mutex); + mutex_unlock(&kgsl_mem_entry_mutex); return 0; } diff --git a/drivers/mxc/amd-gpu/kgsl_linux_map.h b/drivers/mxc/amd-gpu/kgsl_linux_map.h index 4942bcaffbf..b9399a30320 100644 --- a/drivers/mxc/amd-gpu/kgsl_linux_map.h +++ b/drivers/mxc/amd-gpu/kgsl_linux_map.h @@ -32,13 +32,13 @@ #define GSL_LINUX_MAP_RANGE_START (1024*1024) #define GSL_LINUX_MAP_RANGE_END (GSL_LINUX_MAP_RANGE_START+GSL_HAL_SHMEM_SIZE_EMEM_MMU) -int gsl_linux_map_init(void); -void *gsl_linux_map_alloc(unsigned int gpu_addr, unsigned int size); -void gsl_linux_map_free(unsigned int gpu_addr); -void *gsl_linux_map_read(void *dst, unsigned int gpuoffset, unsigned int sizebytes, unsigned int touserspace); -void *gsl_linux_map_write(void *src, unsigned int gpuoffset, unsigned int sizebytes, unsigned int fromuserspace); -void *gsl_linux_map_set(unsigned int gpuoffset, unsigned int value, unsigned int sizebytes); -int gsl_linux_map_destroy(void); +int kgsl_mem_entry_init(void); +void *kgsl_mem_entry_alloc(unsigned int gpu_addr, unsigned int size); +void kgsl_mem_entry_free(unsigned int gpu_addr); +void *kgsl_mem_entry_read(void *dst, unsigned int gpuoffset, unsigned int sizebytes, unsigned int touserspace); +void *kgsl_mem_entry_write(void *src, unsigned int gpuoffset, unsigned int sizebytes, unsigned int fromuserspace); +void *kgsl_mem_entry_set(unsigned int gpuoffset, unsigned int value, unsigned int sizebytes); +int kgsl_mem_entry_destroy(void); void *kgsl_sharedmem_find(unsigned int gpu_addr); diff --git a/drivers/mxc/amd-gpu/kgsl_sharedmem.c b/drivers/mxc/amd-gpu/kgsl_sharedmem.c index 1868efa0d27..af29029f779 100644 --- a/drivers/mxc/amd-gpu/kgsl_sharedmem.c +++ b/drivers/mxc/amd-gpu/kgsl_sharedmem.c @@ -18,12 +18,15 @@ #include #include +#include + #include #include "kgsl_types.h" #include "kgsl_driver.h" #include "kgsl_sharedmem.h" -#include "kgsl_hwaccess.h" +#include "kgsl_halconfig.h" +#include "kgsl_linux_map.h" #include "kgsl_debug.h" #include "kgsl_log.h" @@ -499,7 +502,22 @@ KGSL_MEM_VDBG( "--> int kgsl_sharedmem_read(struct kgsl_memde gpuoffsetbytes = (memdesc->gpuaddr - shmem->apertures[aperture_index].memarena->gpubaseaddr) + offsetbytes; - kgsl_hwaccess_memread(dst, shmem->apertures[aperture_index].memarena->hostbaseaddr, gpuoffsetbytes, sizebytes, touserspace); + if (gsl_driver.enable_mmu && (shmem->apertures[aperture_index].memarena->hostbaseaddr >= GSL_LINUX_MAP_RANGE_START) && (shmem->apertures[aperture_index].memarena->hostbaseaddr < GSL_LINUX_MAP_RANGE_END)) { + kgsl_mem_entry_read(dst, shmem->apertures[aperture_index].memarena->hostbaseaddr+gpuoffsetbytes, sizebytes, touserspace); + } else { + if (touserspace) + { + if (copy_to_user(dst, (void *)(shmem->apertures[aperture_index].memarena->hostbaseaddr + gpuoffsetbytes), sizebytes)) + { + return; + } + } + else + { + memcpy(dst, (void *) (shmem->apertures[aperture_index].memarena->hostbaseaddr + gpuoffsetbytes), sizebytes); + } + } + KGSL_MEM_VDBG("<-- kgsl_sharedmem_read. Return value %d\n", GSL_SUCCESS ); @@ -554,7 +572,21 @@ KGSL_MEM_VDBG( "--> int kgsl_sharedmem_write(struct kgsl_memd gpuoffsetbytes = (memdesc->gpuaddr - shmem->apertures[aperture_index].memarena->gpubaseaddr) + offsetbytes; - kgsl_hwaccess_memwrite(shmem->apertures[aperture_index].memarena->hostbaseaddr, gpuoffsetbytes, src, sizebytes, fromuserspace); + if (gsl_driver.enable_mmu && (shmem->apertures[aperture_index].memarena->hostbaseaddr >= GSL_LINUX_MAP_RANGE_START) && (shmem->apertures[aperture_index].memarena->hostbaseaddr < GSL_LINUX_MAP_RANGE_END)) { + kgsl_mem_entry_write(src, shmem->apertures[aperture_index].memarena->hostbaseaddr + gpuoffsetbytes, sizebytes, fromuserspace); + } else { + if (fromuserspace) + { + if (copy_from_user((void *)(shmem->apertures[aperture_index].memarena->hostbaseaddr + gpuoffsetbytes), src, sizebytes)) + { + return; + } + } + else + { + memcpy((void *)(shmem->apertures[aperture_index].memarena->hostbaseaddr + gpuoffsetbytes), src, sizebytes); + } + } KGSL_DEBUG(GSL_DBGFLAGS_PM4MEM, KGSL_DEBUG_DUMPMEMWRITE((memdesc->gpuaddr + offsetbytes), sizebytes, src)); @@ -610,7 +642,11 @@ KGSL_MEM_VDBG( "--> int kgsl_sharedmem_set(struct kgsl_memdes gpuoffsetbytes = (memdesc->gpuaddr - shmem->apertures[aperture_index].memarena->gpubaseaddr) + offsetbytes; - kgsl_hwaccess_memset(shmem->apertures[aperture_index].memarena->hostbaseaddr, gpuoffsetbytes, value, sizebytes); + if (gsl_driver.enable_mmu && (shmem->apertures[aperture_index].memarena->hostbaseaddr >= GSL_LINUX_MAP_RANGE_START) && (shmem->apertures[aperture_index].memarena->hostbaseaddr < GSL_LINUX_MAP_RANGE_END)) { + kgsl_mem_entry_set(shmem->apertures[aperture_index].memarena->hostbaseaddr + gpuoffsetbytes, value, sizebytes); + } else { + memset((void *)(shmem->apertures[aperture_index].memarena->hostbaseaddr + gpuoffsetbytes), value, sizebytes); + } KGSL_DEBUG(GSL_DBGFLAGS_PM4MEM, KGSL_DEBUG_DUMPMEMSET((memdesc->gpuaddr + offsetbytes), sizebytes, value));