diff options
Diffstat (limited to 'drivers/mxc')
29 files changed, 2143 insertions, 340 deletions
diff --git a/drivers/mxc/amd-gpu/Kconfig b/drivers/mxc/amd-gpu/Kconfig index 629d8cbbc989..f4f442787deb 100644 --- a/drivers/mxc/amd-gpu/Kconfig +++ b/drivers/mxc/amd-gpu/Kconfig @@ -6,7 +6,7 @@ menu "MXC GPU support" config MXC_AMD_GPU tristate "MXC GPU support" - depends on ARCH_MX35 || ARCH_MX51 || ARCH_MX53 || ARCH_MX50 + depends on ARCH_MX35 || ARCH_MX51 || ARCH_MX53 ---help--- Say Y to get the GPU driver support. diff --git a/drivers/mxc/amd-gpu/Makefile b/drivers/mxc/amd-gpu/Makefile index 84cf02e5b3a3..a661de4d6a76 100644 --- a/drivers/mxc/amd-gpu/Makefile +++ b/drivers/mxc/amd-gpu/Makefile @@ -25,7 +25,25 @@ gpu-objs += common/gsl_cmdstream.o \ common/gsl_yamato.o \ platform/hal/linux/gsl_linux_map.o \ platform/hal/linux/gsl_kmod.o \ - platform/hal/linux/gsl_hal.o \ platform/hal/linux/gsl_kmod_cleanup.o \ platform/hal/linux/misc.o \ os/kernel/src/linux/kos_lib.o +ifeq ($(CONFIG_ARCH_MX5),y) +EXTRA_CFLAGS += -DMX51=1 \ + -I$(obj)/platform/hal/MX51 \ + -I$(obj)/platform/hal/MX51/linux \ + -I$(obj)/platform/hal/MX51/memcfg + +gpu-objs += platform/hal/MX51/linux/gsl_hal.o \ + platform/hal/MX51/memcfg/gsl_memcfg.o +endif + +ifeq ($(CONFIG_ARCH_MX35),y) +EXTRA_CFLAGS += -DMX35=1 \ + -I$(obj)/platform/hal/MX35 \ + -I$(obj)/platform/hal/MX35/linux \ + -I$(obj)/platform/hal/MX35/memcfg + +gpu-objs += platform/hal/MX35/linux/gsl_hal.o \ + platform/hal/MX35/memcfg/gsl_memcfg.o +endif diff --git a/drivers/mxc/amd-gpu/common/gsl_device.c b/drivers/mxc/amd-gpu/common/gsl_device.c index 537b277918c4..bcb557e69d6d 100644 --- a/drivers/mxc/amd-gpu/common/gsl_device.c +++ b/drivers/mxc/amd-gpu/common/gsl_device.c @@ -15,7 +15,7 @@ * 02110-1301, USA. * */ - + #include "gsl.h" #include "gsl_hal.h" #ifdef _LINUX @@ -55,19 +55,10 @@ kgsl_device_init(gsl_device_t *device, gsl_deviceid_t device_id) { int status = GSL_SUCCESS; gsl_devconfig_t config; - gsl_hal_t *hal = (gsl_hal_t *)gsl_driver.hal; kgsl_log_write( KGSL_LOG_GROUP_DEVICE | KGSL_LOG_LEVEL_TRACE, "--> int kgsl_device_init(gsl_device_t *device=0x%08x, gsl_deviceid_t device_id=%D )\n", device, device_id ); - if ((GSL_DEVICE_YAMATO == device_id) && !(hal->has_z430)) { - return GSL_FAILURE_NOTSUPPORTED; - } - - if ((GSL_DEVICE_G12 == device_id) && !(hal->has_z160)) { - return GSL_FAILURE_NOTSUPPORTED; - } - if (device->flags & GSL_FLAGS_INITIALIZED) { kgsl_log_write( KGSL_LOG_GROUP_DEVICE | KGSL_LOG_LEVEL_TRACE, "<-- kgsl_device_init. Return value %B\n", GSL_SUCCESS ); @@ -135,7 +126,7 @@ kgsl_device_init(gsl_device_t *device, gsl_deviceid_t device_id) return (status); } -#ifndef _LINUX +#ifndef _LINUX // Create timestamp event device->timestamp_event = kos_event_create(0); if( !device->timestamp_event ) @@ -146,7 +137,7 @@ kgsl_device_init(gsl_device_t *device, gsl_deviceid_t device_id) #else // Create timestamp wait queue init_waitqueue_head(&device->timestamp_waitq); -#endif +#endif // // Read the chip ID after the device has been initialized. @@ -170,10 +161,6 @@ kgsl_device_close(gsl_device_t *device) kgsl_log_write( KGSL_LOG_GROUP_DEVICE | KGSL_LOG_LEVEL_TRACE, "--> int kgsl_device_close(gsl_device_t *device=0x%08x )\n", device ); - if (!(device->flags & GSL_FLAGS_INITIALIZED)) { - return status; - } - /* make sure the device is stopped before close kgsl_device_close is only called for last running caller process */ @@ -187,8 +174,12 @@ kgsl_device_close(gsl_device_t *device) status = kgsl_cmdstream_close(device); if( status != GSL_SUCCESS ) return status; - if (device->ftbl.device_close) { - status = device->ftbl.device_close(device); + if (device->flags & GSL_FLAGS_INITIALIZED) + { + if (device->ftbl.device_close) + { + status = device->ftbl.device_close(device); + } } // DumpX allocates memstore from MMU aperture @@ -198,7 +189,7 @@ kgsl_device_close(gsl_device_t *device) kgsl_sharedmem_free0(&device->memstore, GSL_CALLER_PROCESSID_GET()); } -#ifndef _LINUX +#ifndef _LINUX // destroy timestamp event if(device->timestamp_event) { @@ -208,10 +199,10 @@ kgsl_device_close(gsl_device_t *device) } #else wake_up_interruptible_all(&(device->timestamp_waitq)); -#endif +#endif kgsl_log_write( KGSL_LOG_GROUP_DEVICE | KGSL_LOG_LEVEL_TRACE, "<-- kgsl_device_close. Return value %B\n", status ); - + return (status); } @@ -434,27 +425,16 @@ kgsl_device_start(gsl_deviceid_t device_id, gsl_flags_t flags) { int status = GSL_FAILURE_NOTINITIALIZED; gsl_device_t *device; - gsl_hal_t *hal = (gsl_hal_t *)gsl_driver.hal; kgsl_log_write( KGSL_LOG_GROUP_DEVICE | KGSL_LOG_LEVEL_TRACE, "--> int kgsl_device_start(gsl_deviceid_t device_id=%D, gsl_flags_t flags=%d)\n", device_id, flags ); GSL_API_MUTEX_LOCK(); - if ((GSL_DEVICE_G12 == device_id) && !(hal->has_z160)) { - GSL_API_MUTEX_UNLOCK(); - return GSL_FAILURE_NOTSUPPORTED; - } - - if ((GSL_DEVICE_YAMATO == device_id) && !(hal->has_z430)) { - GSL_API_MUTEX_UNLOCK(); - return GSL_FAILURE_NOTSUPPORTED; - } - device = &gsl_driver.device[device_id-1]; // device_id is 1 based - + kgsl_device_active(device); - + if (!(device->flags & GSL_FLAGS_INITIALIZED)) { GSL_API_MUTEX_UNLOCK(); @@ -549,7 +529,7 @@ kgsl_device_idle(gsl_deviceid_t device_id, unsigned int timeout) device = &gsl_driver.device[device_id-1]; // device_id is 1 based kgsl_device_active(device); - + if (device->ftbl.device_idle) { status = device->ftbl.device_idle(device, timeout); diff --git a/drivers/mxc/amd-gpu/common/gsl_driver.c b/drivers/mxc/amd-gpu/common/gsl_driver.c index b8c5170a1425..fd4bcc0df96a 100644 --- a/drivers/mxc/amd-gpu/common/gsl_driver.c +++ b/drivers/mxc/amd-gpu/common/gsl_driver.c @@ -198,12 +198,13 @@ kgsl_driver_entry(gsl_flags_t flags) if (status == GSL_SUCCESS) { // init devices - status = GSL_FAILURE; for (i = 0; i < GSL_DEVICE_MAX; i++) { - if (kgsl_device_init(&gsl_driver.device[i], (gsl_deviceid_t)(i + 1)) == GSL_SUCCESS) { - status = GSL_SUCCESS; - } + status = kgsl_device_init(&gsl_driver.device[i], (gsl_deviceid_t)(i + 1)); + if (status != GSL_SUCCESS) + { + break; + } } } diff --git a/drivers/mxc/amd-gpu/common/gsl_g12.c b/drivers/mxc/amd-gpu/common/gsl_g12.c index 14cfdb61b6a1..513f6728a842 100644 --- a/drivers/mxc/amd-gpu/common/gsl_g12.c +++ b/drivers/mxc/amd-gpu/common/gsl_g12.c @@ -91,8 +91,6 @@ typedef struct static gsl_z1xx_t g_z1xx = {0}; -extern int z160_version; - //---------------------------------------------------------------------------- @@ -465,10 +463,6 @@ kgsl_g12_getproperty(gsl_device_t *device, gsl_property_type_t type, void *value #ifndef GSL_NO_MMU devinfo->mmu_enabled = kgsl_mmu_isenabled(&device->mmu); #endif - if (z160_version == 1) - devinfo->high_precision = 1; - else - devinfo->high_precision = 0; status = GSL_SUCCESS; } diff --git a/drivers/mxc/amd-gpu/common/gsl_yamato.c b/drivers/mxc/amd-gpu/common/gsl_yamato.c index e52d4274c6a6..d74c9efe2f36 100644 --- a/drivers/mxc/amd-gpu/common/gsl_yamato.c +++ b/drivers/mxc/amd-gpu/common/gsl_yamato.c @@ -541,7 +541,6 @@ kgsl_yamato_getproperty(gsl_device_t *device, gsl_property_type_t type, void *va devinfo->gmem_hostbaseaddr = device->gmemspace.mmio_virt_base; devinfo->gmem_gpubaseaddr = device->gmemspace.gpu_base; devinfo->gmem_sizebytes = device->gmemspace.sizebytes; - devinfo->high_precision = 0; status = GSL_SUCCESS; } diff --git a/drivers/mxc/amd-gpu/include/api/gsl_types.h b/drivers/mxc/amd-gpu/include/api/gsl_types.h index 310c1a9f5d00..99f389deee84 100644 --- a/drivers/mxc/amd-gpu/include/api/gsl_types.h +++ b/drivers/mxc/amd-gpu/include/api/gsl_types.h @@ -267,7 +267,6 @@ typedef struct _gsl_devinfo_t { unsigned int gmem_gpubaseaddr; void * gmem_hostbaseaddr; // if gmem_hostbaseaddr is NULL, we would know its not mapped into mmio space unsigned int gmem_sizebytes; - unsigned int high_precision; /* mx50 z160 has higher gradient/texture precision */ } gsl_devinfo_t; diff --git a/drivers/mxc/amd-gpu/include/gsl_driver.h b/drivers/mxc/amd-gpu/include/gsl_driver.h index 42dff457dc49..1e1d43da431d 100644 --- a/drivers/mxc/amd-gpu/include/gsl_driver.h +++ b/drivers/mxc/amd-gpu/include/gsl_driver.h @@ -72,7 +72,6 @@ typedef struct _gsl_driver_t { gsl_flags_t dmi_mode; // single, double, or triple buffering int dmi_frame; // set to -1 when DMI is enabled int dmi_max_frame; // indicates the maximum frame # that we will support - int enable_mmu; } gsl_driver_t; diff --git a/drivers/mxc/amd-gpu/include/gsl_hal.h b/drivers/mxc/amd-gpu/include/gsl_hal.h index fcf9f0891f16..8a8a10cfb862 100644 --- a/drivers/mxc/amd-gpu/include/gsl_hal.h +++ b/drivers/mxc/amd-gpu/include/gsl_hal.h @@ -122,15 +122,6 @@ typedef struct _gsl_shmemconfig_t gsl_apertureconfig_t apertures[GSL_SHMEM_MAX_APERTURES]; } gsl_shmemconfig_t; -typedef struct _gsl_hal_t { - gsl_memregion_t z160_regspace; - gsl_memregion_t z430_regspace; - gsl_memregion_t memchunk; - gsl_memregion_t memspace[GSL_SHMEM_MAX_APERTURES]; - unsigned int has_z160; - unsigned int has_z430; -} gsl_hal_t; - ////////////////////////////////////////////////////////////////////////////// // HAL API @@ -141,6 +132,7 @@ KGSLHAL_API int kgsl_hal_getshmemconfig(gsl_shmemconfig_t *config); KGSLHAL_API int kgsl_hal_getdevconfig(gsl_deviceid_t device_id, gsl_devconfig_t *config); KGSLHAL_API int kgsl_hal_setpowerstate(gsl_deviceid_t device_id, int state, unsigned int value); KGSLHAL_API gsl_chipid_t kgsl_hal_getchipid(gsl_deviceid_t device_id); +KGSLHAL_API int kgsl_hal_getplatformtype(char *platform); KGSLHAL_API int kgsl_hal_allocphysical(unsigned int virtaddr, unsigned int numpages, unsigned int scattergatterlist[]); KGSLHAL_API int kgsl_hal_freephysical(unsigned int virtaddr, unsigned int numpages, unsigned int scattergatterlist[]); diff --git a/drivers/mxc/amd-gpu/platform/hal/MX35/gsl_buildconfig.h b/drivers/mxc/amd-gpu/platform/hal/MX35/gsl_buildconfig.h new file mode 100644 index 000000000000..9cfe9fe5b3b8 --- /dev/null +++ b/drivers/mxc/amd-gpu/platform/hal/MX35/gsl_buildconfig.h @@ -0,0 +1,62 @@ +/* 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__BUILDCONFIG_H +#define __GSL__BUILDCONFIG_H + +#define GSL_BLD_G12 + +#define GSL_LOCKING_COURSEGRAIN +#define GSL_MMU_TRANSLATION_ENABLED +//#define GSL_MMU_PAGETABLE_PERPROCESS + +#if defined(_WIN32_WCE) && (_WIN32_WCE >= 600) +#define GSL_DEVICE_SHADOW_MEMSTORE_TO_USER +#endif + +//#define GSL_LOG + +#define GSL_STATS_MEM +#define GSL_STATS_RINGBUFFER +#define GSL_STATS_MMU + +#define GSL_RB_USE_MEM_RPTR +#define GSL_RB_USE_MEM_TIMESTAMP +//#define GSL_RB_USE_WPTR_POLLING + + +#define GSL_CALLER_PROCESS_MAX 10 +#define GSL_SHMEM_MAX_APERTURES 3 + +#ifdef _WIN32 +#ifndef _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_DEPRECATE +#endif +#endif // _WIN32 + +#endif // __GSL__BUILDCONFIG_H diff --git a/drivers/mxc/amd-gpu/platform/hal/MX35/gsl_config.h b/drivers/mxc/amd-gpu/platform/hal/MX35/gsl_config.h new file mode 100644 index 000000000000..58a38c608de9 --- /dev/null +++ b/drivers/mxc/amd-gpu/platform/hal/MX35/gsl_config.h @@ -0,0 +1,195 @@ +/* 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__CONFIG_H +#define __GSL__CONFIG_H + + +// --------------------- +// G12 MH arbiter config +// --------------------- +static const REG_MH_ARBITER_CONFIG gsl_cfg_g12_mharb = +{ + 0x10, // SAME_PAGE_LIMIT + 0, // SAME_PAGE_GRANULARITY + 1, // L1_ARB_ENABLE + 1, // L1_ARB_HOLD_ENABLE + 0, // L2_ARB_CONTROL + 1, // PAGE_SIZE + 1, // TC_REORDER_ENABLE + 1, // TC_ARB_HOLD_ENABLE + 0, // IN_FLIGHT_LIMIT_ENABLE + 0x8, // IN_FLIGHT_LIMIT + 1, // CP_CLNT_ENABLE + 1, // VGT_CLNT_ENABLE + 1, // TC_CLNT_ENABLE + 1, // RB_CLNT_ENABLE + 1, // PA_CLNT_ENABLE +}; + +// ----------------------------- +// interrupt block register data +// ----------------------------- +static const gsl_intrblock_reg_t gsl_cfg_intrblock_reg[GSL_INTR_BLOCK_COUNT] = +{ + { // Yamato MH + 0, + 0, + 0, + 0, + 0, + 0 + }, + { // Yamato CP + 0, + 0, + 0, + 0, + 0, + 0 + }, + { // Yamato RBBM + 0, + 0, + 0, + 0, + 0, + 0 + }, + { // Yamato SQ + 0, + 0, + 0, + 0, + 0, + 0 + }, + { // G12 + GSL_INTR_BLOCK_G12, + GSL_INTR_G12_MH, +#ifndef _Z180 + GSL_INTR_G12_FBC, +#else + GSL_INTR_G12_FIFO, +#endif //_Z180 + (ADDR_VGC_IRQSTATUS >> 2), + (ADDR_VGC_IRQSTATUS >> 2), + (ADDR_VGC_IRQENABLE >> 2) + }, + { // G12 MH + GSL_INTR_BLOCK_G12_MH, + GSL_INTR_G12_MH_AXI_READ_ERROR, + GSL_INTR_G12_MH_MMU_PAGE_FAULT, + ADDR_MH_INTERRUPT_STATUS, // G12 MH offsets are considered to be dword based, therefore no down shift + ADDR_MH_INTERRUPT_CLEAR, + ADDR_MH_INTERRUPT_MASK + }, +}; + +// ----------------------- +// interrupt mask bit data +// ----------------------- +static const int gsl_cfg_intr_mask[GSL_INTR_COUNT] = +{ + 0, + 0, + 0, + + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + 0, + 0, + 0, + + 0, + 0, + + (1 << VGC_IRQENABLE_MH_FSHIFT), + (1 << VGC_IRQENABLE_G2D_FSHIFT), + (1 << VGC_IRQENABLE_FIFO_FSHIFT), +#ifndef _Z180 + (1 << VGC_IRQENABLE_FBC_FSHIFT), +#endif + 0, + 0, + 0, +}; + +// ----------------- +// mmu register data +// ----------------- +static const gsl_mmu_reg_t gsl_cfg_mmu_reg[GSL_DEVICE_MAX] = +{ + { // Yamato + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + }, + { // G12 - MH offsets are considered to be dword based, therefore no down shift + ADDR_MH_MMU_CONFIG, + ADDR_MH_MMU_MPU_BASE, + ADDR_MH_MMU_MPU_END, + ADDR_MH_MMU_VA_RANGE, + ADDR_MH_MMU_PT_BASE, + ADDR_MH_MMU_PAGE_FAULT, + ADDR_MH_MMU_TRAN_ERROR, + ADDR_MH_MMU_INVALIDATE, + } +}; + +// ----------------- +// mh interrupt data +// ----------------- +static const gsl_mh_intr_t gsl_cfg_mh_intr[GSL_DEVICE_MAX] = +{ + { // Yamato + 0, + 0, + 0, + }, + { // G12 + GSL_INTR_G12_MH_AXI_READ_ERROR, + GSL_INTR_G12_MH_AXI_WRITE_ERROR, + GSL_INTR_G12_MH_MMU_PAGE_FAULT, + } +}; + +#endif // __GSL__CONFIG_H diff --git a/drivers/mxc/amd-gpu/platform/hal/MX35/gsl_halconfig.h b/drivers/mxc/amd-gpu/platform/hal/MX35/gsl_halconfig.h new file mode 100644 index 000000000000..011041236013 --- /dev/null +++ b/drivers/mxc/amd-gpu/platform/hal/MX35/gsl_halconfig.h @@ -0,0 +1,63 @@ +/* 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_HALCONFIG_H +#define __GSL_HALCONFIG_H + + + +#define GSL_HAL_PLATFORM "i.MX35G" + + +#define GSL_HAL_GPUBASE_GMEM 0x00100000 // 1MB +#define GSL_HAL_GPUBASE_GMEM_PHYS 0x20000000 // 1MB + +#define GSL_HAL_GPUBASE_REG_YDX 0x30000000 +#define GSL_HAL_GPUBASE_REG_G12 0x20000000 + +#define GSL_HAL_SIZE_REG_YDX 0x00020000 // 128KB +#define GSL_HAL_SIZE_REG_G12 0x00001000 // 4KB +#define GSL_HAL_SIZE_GMEM 0x00040000 // 256KB - 0 to 384KB in 128KB increments + +#if defined(_LINUX) && defined(GSL_MMU_TRANSLATION_ENABLED) +#define GSL_HAL_SHMEM_SIZE_EMEM1 0x02400000 // 36MB +#define GSL_HAL_SHMEM_SIZE_EMEM2 0x00400000 // 4MB +#define GSL_HAL_SHMEM_SIZE_PHYS 0x00400000 // 4MB +#elif defined(_LINUX) //MX35 Linux can able to allocate only 4MB +#define GSL_HAL_SHMEM_SIZE_EMEM1 0x00400000 // 4MB +#define GSL_HAL_SHMEM_SIZE_EMEM2 0x00200000 // 2MB +#define GSL_HAL_SHMEM_SIZE_PHYS 0x00200000 // 2MB +#else //Not possible to allocate 24 MB on WinCE +#define GSL_HAL_SHMEM_SIZE_EMEM1 0x00D00000 // 13MB +#define GSL_HAL_SHMEM_SIZE_EMEM2 0x00200000 // 2MB +#define GSL_HAL_SHMEM_SIZE_PHYS 0x00100000 // 1MB +#endif + +#define MX35_G12_INTERRUPT 16 + +#endif // __GSL_HALCONFIG_H diff --git a/drivers/mxc/amd-gpu/platform/hal/MX35/linux/gsl_hal.c b/drivers/mxc/amd-gpu/platform/hal/MX35/linux/gsl_hal.c new file mode 100644 index 000000000000..294cd9eb5af9 --- /dev/null +++ b/drivers/mxc/amd-gpu/platform/hal/MX35/linux/gsl_hal.c @@ -0,0 +1,524 @@ +/* Copyright (c) 2008-2010, Advanced Micro Devices. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + */ + +#include "gsl_hal.h" +#include "gsl_halconfig.h" +#include "gsl_linux_map.h" + +#include <linux/clk.h> +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/vmalloc.h> + +#include <asm/atomic.h> +#include <asm/uaccess.h> +#include <asm/tlbflush.h> +#include <asm/cacheflush.h> + +////////////////////////////////////////////////////////////////////////////// +// constants +////////////////////////////////////////////////////////////////////////////// + + +////////////////////////////////////////////////////////////////////////////// +// defines +////////////////////////////////////////////////////////////////////////////// + +#define GSL_HAL_MEM1 0 +#define GSL_HAL_MEM2 1 +#define GSL_HAL_MEM3 2 + +//#define GSL_HAL_DEBUG +////////////////////////////////////////////////////////////////////////////// +// types +////////////////////////////////////////////////////////////////////////////// + +typedef struct _gsl_hal_t { + gsl_memregion_t z160_regspace; +#if 0 + gsl_memregion_t z430_regspace; +#endif + gsl_memregion_t memchunk; + gsl_memregion_t memspace[GSL_SHMEM_MAX_APERTURES]; +} gsl_hal_t; + +////////////////////////////////////////////////////////////////////////////// +// functions +////////////////////////////////////////////////////////////////////////////// + +KGSLHAL_API int +kgsl_hal_allocphysical(unsigned int virtaddr, unsigned int numpages, unsigned int scattergatterlist[]) +{ + // + // allocate physically contiguous memory + // + + int i; + void *va; + + va = (void*)gsl_linux_map_alloc(virtaddr, numpages*PAGE_SIZE); + + if (!va) + return (GSL_FAILURE_OUTOFMEM); + + for(i = 0; i < numpages; i++) + { + scattergatterlist[i] = page_to_phys(vmalloc_to_page(va)); + va += PAGE_SIZE; + } + + return (GSL_SUCCESS); +} + +// --------------------------------------------------------------------------- + +KGSLHAL_API int +kgsl_hal_freephysical(unsigned int virtaddr, unsigned int numpages, unsigned int scattergatterlist[]) +{ + // + // free physical memory + // + + gsl_linux_map_free(virtaddr); + + return(GSL_SUCCESS); +} + +//---------------------------------------------------------------------------- + +KGSLHAL_API int +kgsl_hal_init(void) +{ + gsl_hal_t *hal; + unsigned long totalsize, mem1size; + unsigned int va, pa; + + if (gsl_driver.hal) + { + return (GSL_FAILURE_ALREADYINITIALIZED); + } + + gsl_driver.hal = (void *)kos_malloc(sizeof(gsl_hal_t)); + + if (!gsl_driver.hal) + { + return (GSL_FAILURE_OUTOFMEM); + } + + kos_memset(gsl_driver.hal, 0, sizeof(gsl_hal_t)); + + + // overlay structure on hal memory + hal = (gsl_hal_t *) gsl_driver.hal; + +#if 0 + // setup register space + hal->z430_regspace.mmio_phys_base = GSL_HAL_GPUBASE_REG_YDX; + hal->z430_regspace.sizebytes = GSL_HAL_SIZE_REG_YDX; + hal->z430_regspace.mmio_virt_base = (unsigned char*)ioremap(hal->z430_regspace.mmio_phys_base, hal->z430_regspace.sizebytes); + + if (hal->z430_regspace.mmio_virt_base == NULL) + { + return (GSL_FAILURE_SYSTEMERROR); + } + +#ifdef GSL_HAL_DEBUG + printk(KERN_INFO "%s: hal->z430_regspace.mmio_phys_base = 0x%p\n", __func__, (void*)hal->z430_regspace.mmio_phys_base); + printk(KERN_INFO "%s: hal->z430_regspace.mmio_virt_base = 0x%p\n", __func__, (void*)hal->z430_regspace.mmio_virt_base); + printk(KERN_INFO "%s: hal->z430_regspace.sizebytes = 0x%08x\n", __func__, hal->z430_regspace.sizebytes); +#endif +#endif + + hal->z160_regspace.mmio_phys_base = GSL_HAL_GPUBASE_REG_G12; + hal->z160_regspace.sizebytes = GSL_HAL_SIZE_REG_G12; + hal->z160_regspace.mmio_virt_base = (unsigned char*)ioremap(hal->z160_regspace.mmio_phys_base, hal->z160_regspace.sizebytes); + + if (hal->z160_regspace.mmio_virt_base == NULL) + { + return (GSL_FAILURE_SYSTEMERROR); + } + +#ifdef GSL_HAL_DEBUG + printk(KERN_INFO "%s: hal->z160_regspace.mmio_phys_base = 0x%p\n", __func__, (void*)hal->z160_regspace.mmio_phys_base); + printk(KERN_INFO "%s: hal->z160_regspace.mmio_virt_base = 0x%p\n", __func__, (void*)hal->z160_regspace.mmio_virt_base); + printk(KERN_INFO "%s: hal->z160_regspace.sizebytes = 0x%08x\n", __func__, hal->z160_regspace.sizebytes); +#endif + +#ifdef GSL_MMU_TRANSLATION_ENABLED + totalsize = GSL_HAL_SHMEM_SIZE_EMEM2 + GSL_HAL_SHMEM_SIZE_PHYS; + mem1size = GSL_HAL_SHMEM_SIZE_EMEM1; +#else + totalsize = GSL_HAL_SHMEM_SIZE_EMEM1 + GSL_HAL_SHMEM_SIZE_EMEM2 + GSL_HAL_SHMEM_SIZE_PHYS; + mem1size = GSL_HAL_SHMEM_SIZE_EMEM1; +#endif + + // allocate a single chunk of physical memory + va = (unsigned int)dma_alloc_coherent(0, totalsize, (dma_addr_t *)&pa, GFP_DMA | GFP_KERNEL); + + if (va) + { + kos_memset((void *)va, 0, totalsize); + + hal->memchunk.mmio_virt_base = (void *)va; + hal->memchunk.mmio_phys_base = pa; + hal->memchunk.sizebytes = totalsize; + +#ifdef GSL_HAL_DEBUG + printk(KERN_INFO "%s: hal->memchunk.mmio_phys_base = 0x%p\n", __func__, (void*)hal->memchunk.mmio_phys_base); + printk(KERN_INFO "%s: hal->memchunk.mmio_virt_base = 0x%p\n", __func__, (void*)hal->memchunk.mmio_virt_base); + printk(KERN_INFO "%s: hal->memchunk.sizebytes = 0x%08x\n", __func__, hal->memchunk.sizebytes); +#endif + + hal->memspace[GSL_HAL_MEM2].mmio_virt_base = (void *) va; + hal->memspace[GSL_HAL_MEM2].gpu_base = pa; + hal->memspace[GSL_HAL_MEM2].sizebytes = GSL_HAL_SHMEM_SIZE_EMEM2; + va += GSL_HAL_SHMEM_SIZE_EMEM2; + pa += GSL_HAL_SHMEM_SIZE_EMEM2; + +#ifdef GSL_HAL_DEBUG + printk(KERN_INFO "%s: hal->memspace[GSL_HAL_MEM2].gpu_base = 0x%p\n", __func__, (void*)hal->memspace[GSL_HAL_MEM2].gpu_base); + printk(KERN_INFO "%s: hal->memspace[GSL_HAL_MEM2].mmio_virt_base = 0x%p\n", __func__, (void*)hal->memspace[GSL_HAL_MEM2].mmio_virt_base); + printk(KERN_INFO "%s: hal->memspace[GSL_HAL_MEM2].sizebytes = 0x%08x\n", __func__, hal->memspace[GSL_HAL_MEM2].sizebytes); +#endif + + hal->memspace[GSL_HAL_MEM3].mmio_virt_base = (void *) va; + hal->memspace[GSL_HAL_MEM3].gpu_base = pa; + hal->memspace[GSL_HAL_MEM3].sizebytes = GSL_HAL_SHMEM_SIZE_PHYS; + va += GSL_HAL_SHMEM_SIZE_PHYS; + pa += GSL_HAL_SHMEM_SIZE_PHYS; + +#ifdef GSL_HAL_DEBUG + printk(KERN_INFO "%s: hal->memspace[GSL_HAL_MEM3].gpu_base = 0x%p\n", __func__, (void*)hal->memspace[GSL_HAL_MEM3].gpu_base); + printk(KERN_INFO "%s: hal->memspace[GSL_HAL_MEM3].mmio_virt_base = 0x%p\n", __func__, (void*)hal->memspace[GSL_HAL_MEM3].mmio_virt_base); + printk(KERN_INFO "%s: hal->memspace[GSL_HAL_MEM3].sizebytes = 0x%08x\n", __func__, hal->memspace[GSL_HAL_MEM3].sizebytes); +#endif + +#ifdef GSL_MMU_TRANSLATION_ENABLED + gsl_linux_map_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 = mem1size; +#else + hal->memspace[GSL_HAL_MEM1].mmio_virt_base = (void *) va; + hal->memspace[GSL_HAL_MEM1].gpu_base = pa; + hal->memspace[GSL_HAL_MEM1].sizebytes = mem1size; +#endif + +#ifdef GSL_HAL_DEBUG + printk(KERN_INFO "%s: hal->memspace[GSL_HAL_MEM1].gpu_base = 0x%p\n", __func__, (void*)hal->memspace[GSL_HAL_MEM1].gpu_base); + printk(KERN_INFO "%s: hal->memspace[GSL_HAL_MEM1].mmio_virt_base = 0x%p\n", __func__, (void*)hal->memspace[GSL_HAL_MEM1].mmio_virt_base); + printk(KERN_INFO "%s: hal->memspace[GSL_HAL_MEM1].sizebytes = 0x%08x\n", __func__, hal->memspace[GSL_HAL_MEM1].sizebytes); +#endif + } + else + { + kgsl_hal_close(); + return (GSL_FAILURE_SYSTEMERROR); + } + + return GSL_SUCCESS; +} + +//---------------------------------------------------------------------------- + +KGSLHAL_API int +kgsl_hal_close(void) +{ + gsl_hal_t *hal; + + if (gsl_driver.hal) + { + // overlay structure on hal memory + hal = (gsl_hal_t *) gsl_driver.hal; + + // unmap registers +#if 0 + if (hal->z430_regspace.mmio_virt_base) + { + iounmap(hal->z430_regspace.mmio_virt_base); + } +#endif + if (hal->z160_regspace.mmio_virt_base) + { + iounmap(hal->z160_regspace.mmio_virt_base); + } + + // free physical block + if (hal->memchunk.mmio_virt_base) + { + dma_free_coherent(0, hal->memchunk.sizebytes, hal->memchunk.mmio_virt_base, hal->memchunk.mmio_phys_base); + } + +#ifdef GSL_MMU_TRANSLATION_ENABLED + gsl_linux_map_destroy(); +#endif + + // release hal struct + kos_memset(hal, 0, sizeof(gsl_hal_t)); + kos_free(gsl_driver.hal); + gsl_driver.hal = NULL; + } + + return (GSL_SUCCESS); +} + +//---------------------------------------------------------------------------- + +KGSLHAL_API int +kgsl_hal_getshmemconfig(gsl_shmemconfig_t *config) +{ + int status = GSL_FAILURE_DEVICEERROR; + gsl_hal_t *hal = (gsl_hal_t *) gsl_driver.hal; + + kos_memset(config, 0, sizeof(gsl_shmemconfig_t)); + + if (hal) + { + config->numapertures = GSL_SHMEM_MAX_APERTURES; + +#ifdef GSL_MMU_TRANSLATION_ENABLED + config->apertures[0].id = GSL_APERTURE_MMU; +#else + config->apertures[0].id = GSL_APERTURE_EMEM; +#endif + config->apertures[0].channel = GSL_CHANNEL_1; + config->apertures[0].hostbase = (unsigned int)hal->memspace[GSL_HAL_MEM1].mmio_virt_base; + config->apertures[0].gpubase = hal->memspace[GSL_HAL_MEM1].gpu_base; + config->apertures[0].sizebytes = hal->memspace[GSL_HAL_MEM1].sizebytes; + + config->apertures[1].id = GSL_APERTURE_EMEM; + config->apertures[1].channel = GSL_CHANNEL_2; + config->apertures[1].hostbase = (unsigned int)hal->memspace[GSL_HAL_MEM2].mmio_virt_base; + config->apertures[1].gpubase = hal->memspace[GSL_HAL_MEM2].gpu_base; + config->apertures[1].sizebytes = hal->memspace[GSL_HAL_MEM2].sizebytes; + + config->apertures[2].id = GSL_APERTURE_PHYS; + config->apertures[2].channel = GSL_CHANNEL_1; + config->apertures[2].hostbase = (unsigned int)hal->memspace[GSL_HAL_MEM3].mmio_virt_base; + config->apertures[2].gpubase = hal->memspace[GSL_HAL_MEM3].gpu_base; + config->apertures[2].sizebytes = hal->memspace[GSL_HAL_MEM3].sizebytes; + + status = GSL_SUCCESS; + } + + return (status); +} + +//---------------------------------------------------------------------------- + +KGSLHAL_API int +kgsl_hal_getdevconfig(gsl_deviceid_t device_id, gsl_devconfig_t *config) +{ + int status = GSL_FAILURE_DEVICEERROR; + gsl_hal_t *hal = (gsl_hal_t *) gsl_driver.hal; + + kos_memset(config, 0, sizeof(gsl_devconfig_t)); + + if (hal) + { + switch (device_id) + { + case GSL_DEVICE_YAMATO: + { +#if 0 + mh_mmu_config_u mmu_config = {0}; + + config->gmemspace.gpu_base = 0; + config->gmemspace.mmio_virt_base = 0; + config->gmemspace.mmio_phys_base = 0; + config->gmemspace.sizebytes = GSL_HAL_SIZE_GMEM; + + config->regspace.gpu_base = 0; + config->regspace.mmio_virt_base = (unsigned char *)hal->z430_regspace.mmio_virt_base; + config->regspace.mmio_phys_base = (unsigned int) hal->z430_regspace.mmio_phys_base; + config->regspace.sizebytes = GSL_HAL_SIZE_REG_YDX; + + mmu_config.f.mmu_enable = 1; +#ifdef GSL_MMU_TRANSLATION_ENABLED + mmu_config.f.split_mode_enable = 0; + mmu_config.f.rb_w_clnt_behavior = 1; + mmu_config.f.cp_w_clnt_behavior = 1; + mmu_config.f.cp_r0_clnt_behavior = 1; + mmu_config.f.cp_r1_clnt_behavior = 1; + mmu_config.f.cp_r2_clnt_behavior = 1; + mmu_config.f.cp_r3_clnt_behavior = 1; + mmu_config.f.cp_r4_clnt_behavior = 1; + mmu_config.f.vgt_r0_clnt_behavior = 1; + mmu_config.f.vgt_r1_clnt_behavior = 1; + mmu_config.f.tc_r_clnt_behavior = 1; + mmu_config.f.pa_w_clnt_behavior = 1; +#endif // GSL_MMU_TRANSLATION_ENABLED + + config->mmu_config = mmu_config.val; +#ifdef GSL_MMU_TRANSLATION_ENABLED + config->va_base = hal->memspace[GSL_HAL_MEM1].gpu_base; + config->va_range = hal->memspace[GSL_HAL_MEM1].sizebytes; +#else + config->va_base = 0x00000000; + config->va_range = 0x00000000; +#endif // GSL_MMU_TRANSLATION_ENABLED + + // turn off memory protection unit by setting acceptable physical address range to include all pages + config->mpu_base = 0x00000000; // hal->memchunk.mmio_virt_base; + config->mpu_range = 0xFFFFF000; // hal->memchunk.sizebytes; + + status = GSL_SUCCESS; +#endif + break; + } + + case GSL_DEVICE_G12: + { +#ifndef GSL_MMU_TRANSLATION_ENABLED + unsigned int mmu_config = {0}; +#endif + config->regspace.gpu_base = 0; + config->regspace.mmio_virt_base = (unsigned char *)hal->z160_regspace.mmio_virt_base; + config->regspace.mmio_phys_base = (unsigned int) hal->z160_regspace.mmio_phys_base; + config->regspace.sizebytes = GSL_HAL_SIZE_REG_G12; + + + +#ifdef GSL_MMU_TRANSLATION_ENABLED + config->mmu_config = 0x00555551; + config->va_base = hal->memspace[GSL_HAL_MEM1].gpu_base; + config->va_range = hal->memspace[GSL_HAL_MEM1].sizebytes; +#else + config->mmu_config = mmu_config; + config->va_base = 0x00000000; + config->va_range = 0x00000000; +#endif // GSL_MMU_TRANSLATION_ENABLED + + config->mpu_base = 0x00000000; //(unsigned int) hal->memchunk.mmio_virt_base; + config->mpu_range = 0xFFFFF000; //hal->memchunk.sizebytes; + + status = GSL_SUCCESS; + break; + } + + default: + + break; + } + } + + return (status); +} + +//---------------------------------------------------------------------------- +// +// kgsl_hal_getchipid +// +// The proper platform method, build from RBBM_PERIPHIDx and RBBM_PATCH_RELEASE +// +KGSLHAL_API gsl_chipid_t +kgsl_hal_getchipid(gsl_deviceid_t device_id) +{ + return (0); +} + +//---------------------------------------------------------------------------- + +KGSLHAL_API int +kgsl_hal_getplatformtype(char *platform) +{ + if (gsl_driver.hal) + { + kos_strcpy(platform, GSL_HAL_PLATFORM); + return (GSL_SUCCESS); + } + else + { + return (GSL_FAILURE_NOTINITIALIZED); + } +} + +//--------------------------------------------------------------------------- + +KGSLHAL_API int +kgsl_hal_setpowerstate(gsl_deviceid_t device_id, int state, unsigned int value) +{ + gsl_device_t *device = &gsl_driver.device[device_id-1]; // device_id is 1 based + struct clk *gpu_clk = 0; + + // unreferenced formal parameters + (void) value; + + switch (device_id) + { + case GSL_DEVICE_G12: + gpu_clk = clk_get(0, "gpu2d_clk"); + break; + default: + return (GSL_FAILURE_DEVICEERROR); + } + + if (!gpu_clk) + return (GSL_FAILURE_DEVICEERROR); + + switch (state) + { + case GSL_PWRFLAGS_CLK_ON: + break; + case GSL_PWRFLAGS_POWER_ON: + clk_enable(gpu_clk); + kgsl_device_autogate_init(&gsl_driver.device[device_id-1]); + break; + case GSL_PWRFLAGS_CLK_OFF: + break; + case GSL_PWRFLAGS_POWER_OFF: + if (device->ftbl.device_idle(device, GSL_TIMEOUT_DEFAULT) != GSL_SUCCESS) + { + return (GSL_FAILURE_DEVICEERROR); + } + kgsl_device_autogate_exit(&gsl_driver.device[device_id-1]); + clk_disable(gpu_clk); + break; + default: + break; + } + + return (GSL_SUCCESS); +} + +KGSLHAL_API int kgsl_clock(gsl_deviceid_t dev, int enable) +{ + struct clk *gpu_clk = 0; + + switch (dev) + { + case GSL_DEVICE_G12: + gpu_clk = clk_get(0, "gpu2d_clk"); + break; + default: + printk(KERN_ERR "GPU device %d is invalid!\n", dev); + return (GSL_FAILURE_DEVICEERROR); + } + + if (IS_ERR(gpu_clk)) { + printk(KERN_ERR "%s: GPU clock get failed!\n", __func__); + return (GSL_FAILURE_DEVICEERROR); + } + + if (enable) + clk_enable(gpu_clk); + else + clk_disable(gpu_clk); + + return (GSL_SUCCESS); +} diff --git a/drivers/mxc/amd-gpu/platform/hal/MX35/memcfg/gsl_memcfg.c b/drivers/mxc/amd-gpu/platform/hal/MX35/memcfg/gsl_memcfg.c new file mode 100644 index 000000000000..f3ca6191d7c2 --- /dev/null +++ b/drivers/mxc/amd-gpu/platform/hal/MX35/memcfg/gsl_memcfg.c @@ -0,0 +1,31 @@ +/* Copyright (c) 2008-2010, Advanced Micro Devices. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + */ + +#include "kos_libapi.h" + +// +// Return the maximum amount of memory that can be allocated to the Z160. This number +// will be constrained to 2MB as a minimum and the original hardcoded value for the caller +// as a maximum. If the return value is outside of this range, then the original value in +// the caller will be used. For this reason, returning 0 is used to signify to use the +// original value as the default. +// +KOS_DLLEXPORT unsigned long kgsl_get_z160_memory_amount(void) +{ + return(0); +} diff --git a/drivers/mxc/amd-gpu/platform/hal/MX35/memcfg/gsl_memcfg.h b/drivers/mxc/amd-gpu/platform/hal/MX35/memcfg/gsl_memcfg.h new file mode 100644 index 000000000000..164a17c925c4 --- /dev/null +++ b/drivers/mxc/amd-gpu/platform/hal/MX35/memcfg/gsl_memcfg.h @@ -0,0 +1,41 @@ +/* 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_MEMCFG_H +#define GSL_MEMCFG_H + +// +// Return the maximum amount of memory that can be allocated to the Z430. This number +// will be constrained to 2MB as a minimum and the original hardcoded value for the caller +// as a maximum. If the return value is outside of this range, then the original value in +// the caller will be used. For this reason, returning 0 is used to signify to use the +// original value as the default. +// +KOS_DLLEXPORT unsigned long kgsl_get_z160_memory_amount(void); + +#endif diff --git a/drivers/mxc/amd-gpu/platform/hal/MX51/gsl_buildconfig.h b/drivers/mxc/amd-gpu/platform/hal/MX51/gsl_buildconfig.h new file mode 100644 index 000000000000..82824f511d5e --- /dev/null +++ b/drivers/mxc/amd-gpu/platform/hal/MX51/gsl_buildconfig.h @@ -0,0 +1,62 @@ +/* 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__BUILDCONFIG_H +#define __GSL__BUILDCONFIG_H + +#define GSL_BLD_YAMATO +#define GSL_BLD_G12 + +#define GSL_LOCKING_COURSEGRAIN + +#define GSL_STATS_MEM +#define GSL_STATS_RINGBUFFER +#define GSL_STATS_MMU + +#define GSL_RB_USE_MEM_RPTR +#define GSL_RB_USE_MEM_TIMESTAMP +#define GSL_RB_TIMESTAMP_INTERUPT +//#define GSL_RB_USE_WPTR_POLLING + +#if defined(_WIN32_WCE) && (_WIN32_WCE >= 600) +#define GSL_DEVICE_SHADOW_MEMSTORE_TO_USER +#endif + +//#define GSL_MMU_TRANSLATION_ENABLED +//#define GSL_MMU_PAGETABLE_PERPROCESS + +#define GSL_CALLER_PROCESS_MAX 10 +#define GSL_SHMEM_MAX_APERTURES 3 + +#ifdef _WIN32 +#ifndef _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_DEPRECATE +#endif +#endif // _WIN32 + +#endif // __GSL__BUILDCONFIG_H diff --git a/drivers/mxc/amd-gpu/platform/hal/MX51/gsl_config.h b/drivers/mxc/amd-gpu/platform/hal/MX51/gsl_config.h new file mode 100644 index 000000000000..6fad1d01277f --- /dev/null +++ b/drivers/mxc/amd-gpu/platform/hal/MX51/gsl_config.h @@ -0,0 +1,222 @@ +/* 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__CONFIG_H +#define __GSL__CONFIG_H + +// ------------------------ +// Yamato ringbuffer config +// ------------------------ +static const unsigned int gsl_cfg_rb_sizelog2quadwords = GSL_RB_SIZE_32K; +static const unsigned int gsl_cfg_rb_blksizequadwords = GSL_RB_SIZE_16; + +// ------------------------ +// Yamato MH arbiter config +// ------------------------ +static const mh_arbiter_config_t gsl_cfg_yamato_mharb = +{ + 0x10, // same_page_limit + 0, // same_page_granularity + 1, // l1_arb_enable + 1, // l1_arb_hold_enable + 0, // l2_arb_control + 1, // page_size + 1, // tc_reorder_enable + 1, // tc_arb_hold_enable + 1, // in_flight_limit_enable + 0x8, // in_flight_limit + 1, // cp_clnt_enable + 1, // vgt_clnt_enable + 1, // tc_clnt_enable + 1, // rb_clnt_enable + 1, // pa_clnt_enable +}; + +// --------------------- +// G12 MH arbiter config +// --------------------- +static const REG_MH_ARBITER_CONFIG gsl_cfg_g12_mharb = +{ + 0x10, // SAME_PAGE_LIMIT + 0, // SAME_PAGE_GRANULARITY + 1, // L1_ARB_ENABLE + 1, // L1_ARB_HOLD_ENABLE + 0, // L2_ARB_CONTROL + 1, // PAGE_SIZE + 1, // TC_REORDER_ENABLE + 1, // TC_ARB_HOLD_ENABLE + 0, // IN_FLIGHT_LIMIT_ENABLE + 0x8, // IN_FLIGHT_LIMIT + 1, // CP_CLNT_ENABLE + 1, // VGT_CLNT_ENABLE + 1, // TC_CLNT_ENABLE + 1, // RB_CLNT_ENABLE + 1, // PA_CLNT_ENABLE +}; + +// ----------------------------- +// interrupt block register data +// ----------------------------- +static const gsl_intrblock_reg_t gsl_cfg_intrblock_reg[GSL_INTR_BLOCK_COUNT] = +{ + { // Yamato MH + GSL_INTR_BLOCK_YDX_MH, + GSL_INTR_YDX_MH_AXI_READ_ERROR, + GSL_INTR_YDX_MH_MMU_PAGE_FAULT, + mmMH_INTERRUPT_STATUS, + mmMH_INTERRUPT_CLEAR, + mmMH_INTERRUPT_MASK + }, + { // Yamato CP + GSL_INTR_BLOCK_YDX_CP, + GSL_INTR_YDX_CP_SW_INT, + GSL_INTR_YDX_CP_RING_BUFFER, + mmCP_INT_STATUS, + mmCP_INT_ACK, + mmCP_INT_CNTL + }, + { // Yamato RBBM + GSL_INTR_BLOCK_YDX_RBBM, + GSL_INTR_YDX_RBBM_READ_ERROR, + GSL_INTR_YDX_RBBM_GUI_IDLE, + mmRBBM_INT_STATUS, + mmRBBM_INT_ACK, + mmRBBM_INT_CNTL + }, + { // Yamato SQ + GSL_INTR_BLOCK_YDX_SQ, + GSL_INTR_YDX_SQ_PS_WATCHDOG, + GSL_INTR_YDX_SQ_VS_WATCHDOG, + mmSQ_INT_STATUS, + mmSQ_INT_ACK, + mmSQ_INT_CNTL + }, + { // G12 + GSL_INTR_BLOCK_G12, + GSL_INTR_G12_MH, +#ifndef _Z180 + GSL_INTR_G12_FBC, +#else + GSL_INTR_G12_FIFO, +#endif //_Z180 + (ADDR_VGC_IRQSTATUS >> 2), + (ADDR_VGC_IRQSTATUS >> 2), + (ADDR_VGC_IRQENABLE >> 2) + }, + { // G12 MH + GSL_INTR_BLOCK_G12_MH, + GSL_INTR_G12_MH_AXI_READ_ERROR, + GSL_INTR_G12_MH_MMU_PAGE_FAULT, + ADDR_MH_INTERRUPT_STATUS, // G12 MH offsets are considered to be dword based, therefore no down shift + ADDR_MH_INTERRUPT_CLEAR, + ADDR_MH_INTERRUPT_MASK + }, +}; + +// ----------------------- +// interrupt mask bit data +// ----------------------- +static const int gsl_cfg_intr_mask[GSL_INTR_COUNT] = +{ + MH_INTERRUPT_MASK__AXI_READ_ERROR, + MH_INTERRUPT_MASK__AXI_WRITE_ERROR, + MH_INTERRUPT_MASK__MMU_PAGE_FAULT, + + CP_INT_CNTL__SW_INT_MASK, + CP_INT_CNTL__T0_PACKET_IN_IB_MASK, + CP_INT_CNTL__OPCODE_ERROR_MASK, + CP_INT_CNTL__PROTECTED_MODE_ERROR_MASK, + CP_INT_CNTL__RESERVED_BIT_ERROR_MASK, + CP_INT_CNTL__IB_ERROR_MASK, + CP_INT_CNTL__IB2_INT_MASK, + CP_INT_CNTL__IB1_INT_MASK, + CP_INT_CNTL__RB_INT_MASK, + + RBBM_INT_CNTL__RDERR_INT_MASK, + RBBM_INT_CNTL__DISPLAY_UPDATE_INT_MASK, + RBBM_INT_CNTL__GUI_IDLE_INT_MASK, + + SQ_INT_CNTL__PS_WATCHDOG_MASK, + SQ_INT_CNTL__VS_WATCHDOG_MASK, + + (1 << VGC_IRQENABLE_MH_FSHIFT), + (1 << VGC_IRQENABLE_G2D_FSHIFT), + (1 << VGC_IRQENABLE_FIFO_FSHIFT), +#ifndef _Z180 + (1 << VGC_IRQENABLE_FBC_FSHIFT), +#endif + (1 << MH_INTERRUPT_MASK_AXI_READ_ERROR_FSHIFT), + (1 << MH_INTERRUPT_MASK_AXI_WRITE_ERROR_FSHIFT), + (1 << MH_INTERRUPT_MASK_MMU_PAGE_FAULT_FSHIFT), +}; + +// ----------------- +// mmu register data +// ----------------- +static const gsl_mmu_reg_t gsl_cfg_mmu_reg[GSL_DEVICE_MAX] = +{ + { // Yamato + mmMH_MMU_CONFIG, + mmMH_MMU_MPU_BASE, + mmMH_MMU_MPU_END, + mmMH_MMU_VA_RANGE, + mmMH_MMU_PT_BASE, + mmMH_MMU_PAGE_FAULT, + mmMH_MMU_TRAN_ERROR, + mmMH_MMU_INVALIDATE, + }, + { // G12 - MH offsets are considered to be dword based, therefore no down shift + ADDR_MH_MMU_CONFIG, + ADDR_MH_MMU_MPU_BASE, + ADDR_MH_MMU_MPU_END, + ADDR_MH_MMU_VA_RANGE, + ADDR_MH_MMU_PT_BASE, + ADDR_MH_MMU_PAGE_FAULT, + ADDR_MH_MMU_TRAN_ERROR, + ADDR_MH_MMU_INVALIDATE, + } +}; + +// ----------------- +// mh interrupt data +// ----------------- +static const gsl_mh_intr_t gsl_cfg_mh_intr[GSL_DEVICE_MAX] = +{ + { // Yamato + GSL_INTR_YDX_MH_AXI_READ_ERROR, + GSL_INTR_YDX_MH_AXI_WRITE_ERROR, + GSL_INTR_YDX_MH_MMU_PAGE_FAULT, + }, + { // G12 + GSL_INTR_G12_MH_AXI_READ_ERROR, + GSL_INTR_G12_MH_AXI_WRITE_ERROR, + GSL_INTR_G12_MH_MMU_PAGE_FAULT, + } +}; + +#endif // __GSL__CONFIG_H diff --git a/drivers/mxc/amd-gpu/platform/hal/MX51/gsl_halconfig.h b/drivers/mxc/amd-gpu/platform/hal/MX51/gsl_halconfig.h new file mode 100644 index 000000000000..589c56fa9bfa --- /dev/null +++ b/drivers/mxc/amd-gpu/platform/hal/MX51/gsl_halconfig.h @@ -0,0 +1,58 @@ +/* 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_HALCONFIG_H +#define __GSL_HALCONFIG_H + + +#define GSL_HAL_PLATFORM "i.MX51" + +#define GSL_HAL_GPUBASE_GMEM 0x00100000 // 1MB +#define GSL_HAL_GPUBASE_GMEM_PHYS 0x20000000 // 1MB + +#define GSL_HAL_GPUBASE_REG_YDX 0x30000000 +#define GSL_HAL_GPUBASE_REG_G12 0xD0000000 + +#define GSL_HAL_SIZE_REG_YDX 0x00020000 // 128KB +#define GSL_HAL_SIZE_REG_G12 0x00001000 // 4KB +#define GSL_HAL_SIZE_GMEM 0x00020000 // 128KB - 0 to 384KB in 128KB increments + +#if defined(GSL_MMU_TRANSLATION_ENABLED) +#define GSL_HAL_SHMEM_SIZE_EMEM1 0x02400000 // 36MB +#define GSL_HAL_SHMEM_SIZE_EMEM2 0x00400000 // 4MB +#define GSL_HAL_SHMEM_SIZE_PHYS 0x00400000 // 4MB +#else +#define GSL_HAL_SHMEM_SIZE_EMEM1 0x00D00000 // 13MB +#define GSL_HAL_SHMEM_SIZE_EMEM2 0x00200000 // 2MB +#define GSL_HAL_SHMEM_SIZE_PHYS 0x00100000 // 1MB +#endif + +#define MX51_G12_INTERRUPT 84 // Interrupt line taken from Reference Manual +#define MX51_YDX_INTERRUPT 12 // Interrupt line taken from Reference Manual + +#endif // __GSL_HALCONFIG_H diff --git a/drivers/mxc/amd-gpu/platform/hal/MX51/linux/gsl_hal.c b/drivers/mxc/amd-gpu/platform/hal/MX51/linux/gsl_hal.c new file mode 100644 index 000000000000..965416b59ec1 --- /dev/null +++ b/drivers/mxc/amd-gpu/platform/hal/MX51/linux/gsl_hal.c @@ -0,0 +1,598 @@ +/* Copyright (c) 2008-2010, Advanced Micro Devices. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + */ + +#include "gsl_hal.h" +#include "gsl_halconfig.h" +#include "gsl_memcfg.h" +#include "gsl_linux_map.h" + +#include <linux/clk.h> +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/vmalloc.h> + +#include <asm/atomic.h> +#include <asm/uaccess.h> +#include <asm/tlbflush.h> +#include <asm/cacheflush.h> + +////////////////////////////////////////////////////////////////////////////// +// constants +////////////////////////////////////////////////////////////////////////////// + + +////////////////////////////////////////////////////////////////////////////// +// defines +////////////////////////////////////////////////////////////////////////////// + +#define GSL_HAL_MEM1 0 +#define GSL_HAL_MEM2 1 +#define GSL_HAL_MEM3 2 + +//#define GSL_HAL_DEBUG + +////////////////////////////////////////////////////////////////////////////// +// types +////////////////////////////////////////////////////////////////////////////// + +typedef struct _gsl_hal_t { + gsl_memregion_t z160_regspace; + gsl_memregion_t z430_regspace; + gsl_memregion_t memchunk; + gsl_memregion_t memspace[GSL_SHMEM_MAX_APERTURES]; +} gsl_hal_t; + +extern phys_addr_t gpu_2d_regbase; +extern int gpu_2d_regsize; +extern phys_addr_t gpu_3d_regbase; +extern int gpu_3d_regsize; +extern int gmem_size; +extern phys_addr_t gpu_reserved_mem; +extern int gpu_reserved_mem_size; + +////////////////////////////////////////////////////////////////////////////// +// functions +////////////////////////////////////////////////////////////////////////////// + +KGSLHAL_API int +kgsl_hal_allocphysical(unsigned int virtaddr, unsigned int numpages, unsigned int scattergatterlist[]) +{ + // + // allocate physically contiguous memory + // + + int i; + void *va; + + va = gsl_linux_map_alloc(virtaddr, numpages*PAGE_SIZE); + + if (!va) + return (GSL_FAILURE_OUTOFMEM); + + for(i = 0; i < numpages; i++) + { + scattergatterlist[i] = page_to_phys(vmalloc_to_page(va)); + va += PAGE_SIZE; + } + + return (GSL_SUCCESS); +} + +// --------------------------------------------------------------------------- + +KGSLHAL_API int +kgsl_hal_freephysical(unsigned int virtaddr, unsigned int numpages, unsigned int scattergatterlist[]) +{ + // + // free physical memory + // + + gsl_linux_map_free(virtaddr); + + return(GSL_SUCCESS); +} + +//---------------------------------------------------------------------------- + +KGSLHAL_API int +kgsl_hal_init(void) +{ + gsl_hal_t *hal; + unsigned long totalsize, mem1size; + unsigned int va, pa; + + if (gsl_driver.hal) + { + return (GSL_FAILURE_ALREADYINITIALIZED); + } + + gsl_driver.hal = (void *)kos_malloc(sizeof(gsl_hal_t)); + + if (!gsl_driver.hal) + { + return (GSL_FAILURE_OUTOFMEM); + } + + kos_memset(gsl_driver.hal, 0, sizeof(gsl_hal_t)); + + + // overlay structure on hal memory + hal = (gsl_hal_t *) gsl_driver.hal; + + // setup register space + if(gpu_3d_regbase && gpu_3d_regsize){ + hal->z430_regspace.mmio_phys_base = gpu_3d_regbase; + hal->z430_regspace.sizebytes = gpu_3d_regsize; + }else{ + hal->z430_regspace.mmio_phys_base = GSL_HAL_GPUBASE_REG_YDX; + hal->z430_regspace.sizebytes = GSL_HAL_SIZE_REG_YDX; + } + hal->z430_regspace.mmio_virt_base = (unsigned char*)ioremap(hal->z430_regspace.mmio_phys_base, hal->z430_regspace.sizebytes); + + if (hal->z430_regspace.mmio_virt_base == NULL) + { + return (GSL_FAILURE_SYSTEMERROR); + } + +#ifdef GSL_HAL_DEBUG + printk(KERN_INFO "%s: hal->z430_regspace.mmio_phys_base = 0x%p\n", __func__, (void*)hal->z430_regspace.mmio_phys_base); + printk(KERN_INFO "%s: hal->z430_regspace.mmio_virt_base = 0x%p\n", __func__, (void*)hal->z430_regspace.mmio_virt_base); + printk(KERN_INFO "%s: hal->z430_regspace.sizebytes = 0x%08x\n", __func__, hal->z430_regspace.sizebytes); +#endif + + if(gpu_2d_regbase && gpu_2d_regsize){ + hal->z160_regspace.mmio_phys_base = gpu_2d_regbase; + hal->z160_regspace.sizebytes = gpu_2d_regsize; + }else{ + hal->z160_regspace.mmio_phys_base = GSL_HAL_GPUBASE_REG_G12; + hal->z160_regspace.sizebytes = GSL_HAL_SIZE_REG_G12; + } + hal->z160_regspace.mmio_virt_base = (unsigned char*)ioremap(hal->z160_regspace.mmio_phys_base, hal->z160_regspace.sizebytes); + + if (hal->z160_regspace.mmio_virt_base == NULL) + { + return (GSL_FAILURE_SYSTEMERROR); + } + +#ifdef GSL_HAL_DEBUG + printk(KERN_INFO "%s: hal->z160_regspace.mmio_phys_base = 0x%p\n", __func__, (void*)hal->z160_regspace.mmio_phys_base); + printk(KERN_INFO "%s: hal->z160_regspace.mmio_virt_base = 0x%p\n", __func__, (void*)hal->z160_regspace.mmio_virt_base); + printk(KERN_INFO "%s: hal->z160_regspace.sizebytes = 0x%08x\n", __func__, hal->z160_regspace.sizebytes); +#endif + +#ifdef GSL_MMU_TRANSLATION_ENABLED + totalsize = GSL_HAL_SHMEM_SIZE_EMEM2 + GSL_HAL_SHMEM_SIZE_PHYS; + mem1size = GSL_HAL_SHMEM_SIZE_EMEM1; + if (gpu_reserved_mem && gpu_reserved_mem_size >= totalsize) + { + pa = gpu_reserved_mem; + va = (unsigned int)ioremap(gpu_reserved_mem, totalsize); + } + else + { + va = (unsigned int)dma_alloc_coherent(0, totalsize, (dma_addr_t *)&pa, GFP_DMA | GFP_KERNEL); + } +#else + if(gpu_reserved_mem && gpu_reserved_mem_size >= SZ_8M){ + totalsize = gpu_reserved_mem_size; + pa = gpu_reserved_mem; + va = (unsigned int)ioremap(gpu_reserved_mem, gpu_reserved_mem_size); + }else{ + gpu_reserved_mem = 0; + totalsize = GSL_HAL_SHMEM_SIZE_EMEM1 + GSL_HAL_SHMEM_SIZE_EMEM2 + GSL_HAL_SHMEM_SIZE_PHYS; + va = (unsigned int)dma_alloc_coherent(0, totalsize, (dma_addr_t *)&pa, GFP_DMA | GFP_KERNEL); + } + mem1size = totalsize - (GSL_HAL_SHMEM_SIZE_EMEM2 + GSL_HAL_SHMEM_SIZE_PHYS); +#endif + + if (va) + { + kos_memset((void *)va, 0, totalsize); + + hal->memchunk.mmio_virt_base = (void *)va; + hal->memchunk.mmio_phys_base = pa; + hal->memchunk.sizebytes = totalsize; + +#ifdef GSL_HAL_DEBUG + printk(KERN_INFO "%s: hal->memchunk.mmio_phys_base = 0x%p\n", __func__, (void*)hal->memchunk.mmio_phys_base); + printk(KERN_INFO "%s: hal->memchunk.mmio_virt_base = 0x%p\n", __func__, (void*)hal->memchunk.mmio_virt_base); + printk(KERN_INFO "%s: hal->memchunk.sizebytes = 0x%08x\n", __func__, hal->memchunk.sizebytes); +#endif + + hal->memspace[GSL_HAL_MEM2].mmio_virt_base = (void *) va; + hal->memspace[GSL_HAL_MEM2].gpu_base = pa; + hal->memspace[GSL_HAL_MEM2].sizebytes = GSL_HAL_SHMEM_SIZE_EMEM2; + va += GSL_HAL_SHMEM_SIZE_EMEM2; + pa += GSL_HAL_SHMEM_SIZE_EMEM2; + +#ifdef GSL_HAL_DEBUG + printk(KERN_INFO "%s: hal->memspace[GSL_HAL_MEM2].gpu_base = 0x%p\n", __func__, (void*)hal->memspace[GSL_HAL_MEM2].gpu_base); + printk(KERN_INFO "%s: hal->memspace[GSL_HAL_MEM2].mmio_virt_base = 0x%p\n", __func__, (void*)hal->memspace[GSL_HAL_MEM2].mmio_virt_base); + printk(KERN_INFO "%s: hal->memspace[GSL_HAL_MEM2].sizebytes = 0x%08x\n", __func__, hal->memspace[GSL_HAL_MEM2].sizebytes); +#endif + + hal->memspace[GSL_HAL_MEM3].mmio_virt_base = (void *) va; + hal->memspace[GSL_HAL_MEM3].gpu_base = pa; + hal->memspace[GSL_HAL_MEM3].sizebytes = GSL_HAL_SHMEM_SIZE_PHYS; + va += GSL_HAL_SHMEM_SIZE_PHYS; + pa += GSL_HAL_SHMEM_SIZE_PHYS; + +#ifdef GSL_HAL_DEBUG + printk(KERN_INFO "%s: hal->memspace[GSL_HAL_MEM3].gpu_base = 0x%p\n", __func__, (void*)hal->memspace[GSL_HAL_MEM3].gpu_base); + printk(KERN_INFO "%s: hal->memspace[GSL_HAL_MEM3].mmio_virt_base = 0x%p\n", __func__, (void*)hal->memspace[GSL_HAL_MEM3].mmio_virt_base); + printk(KERN_INFO "%s: hal->memspace[GSL_HAL_MEM3].sizebytes = 0x%08x\n", __func__, hal->memspace[GSL_HAL_MEM3].sizebytes); +#endif + +#ifdef GSL_MMU_TRANSLATION_ENABLED + gsl_linux_map_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 = mem1size; +#else + hal->memspace[GSL_HAL_MEM1].mmio_virt_base = (void *) va; + hal->memspace[GSL_HAL_MEM1].gpu_base = pa; + hal->memspace[GSL_HAL_MEM1].sizebytes = mem1size; +#endif + +#ifdef GSL_HAL_DEBUG + printk(KERN_INFO "%s: hal->memspace[GSL_HAL_MEM1].gpu_base = 0x%p\n", __func__, (void*)hal->memspace[GSL_HAL_MEM1].gpu_base); + printk(KERN_INFO "%s: hal->memspace[GSL_HAL_MEM1].mmio_virt_base = 0x%p\n", __func__, (void*)hal->memspace[GSL_HAL_MEM1].mmio_virt_base); + printk(KERN_INFO "%s: hal->memspace[GSL_HAL_MEM1].sizebytes = 0x%08x\n", __func__, hal->memspace[GSL_HAL_MEM1].sizebytes); +#endif + } + else + { + kgsl_hal_close(); + return (GSL_FAILURE_SYSTEMERROR); + } + + return GSL_SUCCESS; +} + +//---------------------------------------------------------------------------- + +KGSLHAL_API int +kgsl_hal_close(void) +{ + gsl_hal_t *hal; + + if (gsl_driver.hal) + { + // overlay structure on hal memory + hal = (gsl_hal_t *) gsl_driver.hal; + + // unmap registers + if (hal->z430_regspace.mmio_virt_base) + { + iounmap(hal->z430_regspace.mmio_virt_base); + } + if (hal->z160_regspace.mmio_virt_base) + { + iounmap(hal->z160_regspace.mmio_virt_base); + } + + // free physical block + if (hal->memchunk.mmio_virt_base && gpu_reserved_mem) + { + iounmap(hal->memchunk.mmio_virt_base); + } + else + { + dma_free_coherent(0, hal->memchunk.sizebytes, hal->memchunk.mmio_virt_base, hal->memchunk.mmio_phys_base); + } + +#ifdef GSL_MMU_TRANSLATION_ENABLED + gsl_linux_map_destroy(); +#endif + + // release hal struct + kos_memset(hal, 0, sizeof(gsl_hal_t)); + kos_free(gsl_driver.hal); + gsl_driver.hal = NULL; + } + + return (GSL_SUCCESS); +} + +//---------------------------------------------------------------------------- + +KGSLHAL_API int +kgsl_hal_getshmemconfig(gsl_shmemconfig_t *config) +{ + int status = GSL_FAILURE_DEVICEERROR; + gsl_hal_t *hal = (gsl_hal_t *) gsl_driver.hal; + + kos_memset(config, 0, sizeof(gsl_shmemconfig_t)); + + if (hal) + { + config->numapertures = GSL_SHMEM_MAX_APERTURES; + +#ifdef GSL_MMU_TRANSLATION_ENABLED + config->apertures[0].id = GSL_APERTURE_MMU; +#else + config->apertures[0].id = GSL_APERTURE_EMEM; +#endif + config->apertures[0].channel = GSL_CHANNEL_1; + config->apertures[0].hostbase = (unsigned int)hal->memspace[GSL_HAL_MEM1].mmio_virt_base; + config->apertures[0].gpubase = hal->memspace[GSL_HAL_MEM1].gpu_base; + config->apertures[0].sizebytes = hal->memspace[GSL_HAL_MEM1].sizebytes; + + config->apertures[1].id = GSL_APERTURE_EMEM; + config->apertures[1].channel = GSL_CHANNEL_2; + config->apertures[1].hostbase = (unsigned int)hal->memspace[GSL_HAL_MEM2].mmio_virt_base; + config->apertures[1].gpubase = hal->memspace[GSL_HAL_MEM2].gpu_base; + config->apertures[1].sizebytes = hal->memspace[GSL_HAL_MEM2].sizebytes; + + config->apertures[2].id = GSL_APERTURE_PHYS; + config->apertures[2].channel = GSL_CHANNEL_1; + config->apertures[2].hostbase = (unsigned int)hal->memspace[GSL_HAL_MEM3].mmio_virt_base; + config->apertures[2].gpubase = hal->memspace[GSL_HAL_MEM3].gpu_base; + config->apertures[2].sizebytes = hal->memspace[GSL_HAL_MEM3].sizebytes; + + status = GSL_SUCCESS; + } + + return (status); +} + +//---------------------------------------------------------------------------- + +KGSLHAL_API int +kgsl_hal_getdevconfig(gsl_deviceid_t device_id, gsl_devconfig_t *config) +{ + int status = GSL_FAILURE_DEVICEERROR; + gsl_hal_t *hal = (gsl_hal_t *) gsl_driver.hal; + + kos_memset(config, 0, sizeof(gsl_devconfig_t)); + + if (hal) + { + switch (device_id) + { + case GSL_DEVICE_YAMATO: + { + mh_mmu_config_u mmu_config = {0}; + + config->gmemspace.gpu_base = 0; + config->gmemspace.mmio_virt_base = 0; + config->gmemspace.mmio_phys_base = 0; + if(gmem_size){ + config->gmemspace.sizebytes = gmem_size; + }else{ + config->gmemspace.sizebytes = GSL_HAL_SIZE_GMEM; + } + + config->regspace.gpu_base = 0; + config->regspace.mmio_virt_base = (unsigned char *)hal->z430_regspace.mmio_virt_base; + config->regspace.mmio_phys_base = (unsigned int) hal->z430_regspace.mmio_phys_base; + config->regspace.sizebytes = GSL_HAL_SIZE_REG_YDX; + + mmu_config.f.mmu_enable = 1; +#ifdef GSL_MMU_TRANSLATION_ENABLED + mmu_config.f.split_mode_enable = 0; + mmu_config.f.rb_w_clnt_behavior = 1; + mmu_config.f.cp_w_clnt_behavior = 1; + mmu_config.f.cp_r0_clnt_behavior = 1; + mmu_config.f.cp_r1_clnt_behavior = 1; + mmu_config.f.cp_r2_clnt_behavior = 1; + mmu_config.f.cp_r3_clnt_behavior = 1; + mmu_config.f.cp_r4_clnt_behavior = 1; + mmu_config.f.vgt_r0_clnt_behavior = 1; + mmu_config.f.vgt_r1_clnt_behavior = 1; + mmu_config.f.tc_r_clnt_behavior = 1; + mmu_config.f.pa_w_clnt_behavior = 1; +#endif // GSL_MMU_TRANSLATION_ENABLED + + config->mmu_config = mmu_config.val; +#ifdef GSL_MMU_TRANSLATION_ENABLED + config->va_base = hal->memspace[GSL_HAL_MEM1].gpu_base; + config->va_range = hal->memspace[GSL_HAL_MEM1].sizebytes; +#else + config->va_base = 0x00000000; + config->va_range = 0x00000000; +#endif // GSL_MMU_TRANSLATION_ENABLED + + // turn off memory protection unit by setting acceptable physical address range to include all pages + config->mpu_base = 0x00000000; // hal->memchunk.mmio_virt_base; + config->mpu_range = 0xFFFFF000; // hal->memchunk.sizebytes; + + status = GSL_SUCCESS; + break; + } + + case GSL_DEVICE_G12: + { + mh_mmu_config_u mmu_config = {0}; + + config->regspace.gpu_base = 0; + config->regspace.mmio_virt_base = (unsigned char *)hal->z160_regspace.mmio_virt_base; + config->regspace.mmio_phys_base = (unsigned int) hal->z160_regspace.mmio_phys_base; + config->regspace.sizebytes = GSL_HAL_SIZE_REG_G12; + + mmu_config.f.mmu_enable = 1; + +#ifdef GSL_MMU_TRANSLATION_ENABLED + config->mmu_config = 0x00555551; + config->va_base = hal->memspace[GSL_HAL_MEM1].gpu_base; + config->va_range = hal->memspace[GSL_HAL_MEM1].sizebytes; +#else + config->mmu_config = mmu_config.val; + config->va_base = 0x00000000; + config->va_range = 0x00000000; +#endif // GSL_MMU_TRANSLATION_ENABLED + + config->mpu_base = 0x00000000; //(unsigned int) hal->memchunk.mmio_virt_base; + config->mpu_range = 0xFFFFF000; //hal->memchunk.sizebytes; + + status = GSL_SUCCESS; + break; + } + + default: + + break; + } + } + + return (status); +} + +//---------------------------------------------------------------------------- +// +// kgsl_hal_getchipid +// +// The proper platform method, build from RBBM_PERIPHIDx and RBBM_PATCH_RELEASE +// +KGSLHAL_API gsl_chipid_t +kgsl_hal_getchipid(gsl_deviceid_t device_id) +{ + gsl_device_t *device = &gsl_driver.device[device_id-1]; + gsl_chipid_t chipid; + unsigned int coreid, majorid, minorid, patchid, revid; + + // YDX + device->ftbl.device_regread(device, mmRBBM_PERIPHID1, &coreid); + coreid &= 0xF; + + // 2. + device->ftbl.device_regread(device, mmRBBM_PERIPHID2, &majorid); + majorid = (majorid >> 4) & 0xF; + + device->ftbl.device_regread(device, mmRBBM_PATCH_RELEASE, &revid); + + // 2. + minorid = ((revid >> 0) & 0xFF); // this is a 16bit field, but extremely unlikely it would ever get this high + + // 1 + patchid = ((revid >> 16) & 0xFF); + + chipid = ((coreid << 24) | (majorid << 16) | (minorid << 8) | (patchid << 0)); + + return (chipid); +} + +//---------------------------------------------------------------------------- + +KGSLHAL_API int +kgsl_hal_getplatformtype(char *platform) +{ + if (gsl_driver.hal) + { + kos_strcpy(platform, GSL_HAL_PLATFORM); + return (GSL_SUCCESS); + } + else + { + return (GSL_FAILURE_NOTINITIALIZED); + } +} + +//--------------------------------------------------------------------------- + +KGSLHAL_API int +kgsl_hal_setpowerstate(gsl_deviceid_t device_id, int state, unsigned int value) +{ + gsl_device_t *device = &gsl_driver.device[device_id-1]; + struct clk *gpu_clk = 0; + struct clk *garb_clk = clk_get(0, "garb_clk"); + struct clk *emi_garb_clk = clk_get(0, "emi_garb_clk"); + + // unreferenced formal parameters + (void) value; + + switch (device_id) + { + case GSL_DEVICE_G12: + gpu_clk = clk_get(0, "gpu2d_clk"); + break; + case GSL_DEVICE_YAMATO: + gpu_clk = clk_get(0, "gpu3d_clk"); + break; + default: + return (GSL_FAILURE_DEVICEERROR); + } + + if (!gpu_clk) + return (GSL_FAILURE_DEVICEERROR); + + switch (state) + { + case GSL_PWRFLAGS_CLK_ON: + break; + case GSL_PWRFLAGS_POWER_ON: + clk_enable(gpu_clk); + clk_enable(garb_clk); + clk_enable(emi_garb_clk); + kgsl_device_autogate_init(&gsl_driver.device[device_id-1]); + break; + case GSL_PWRFLAGS_CLK_OFF: + break; + case GSL_PWRFLAGS_POWER_OFF: + if (device->ftbl.device_idle(device, GSL_TIMEOUT_DEFAULT) != GSL_SUCCESS) + { + return (GSL_FAILURE_DEVICEERROR); + } + kgsl_device_autogate_exit(&gsl_driver.device[device_id-1]); + clk_disable(gpu_clk); + clk_disable(garb_clk); + clk_disable(emi_garb_clk); + break; + default: + break; + } + + return (GSL_SUCCESS); +} + +KGSLHAL_API int kgsl_clock(gsl_deviceid_t dev, int enable) +{ + struct clk *gpu_clk; + struct clk *garb_clk = clk_get(0, "garb_clk"); + struct clk *emi_garb_clk = clk_get(0, "emi_garb_clk"); + + switch (dev) + { + case GSL_DEVICE_G12: + gpu_clk = clk_get(0, "gpu2d_clk"); + break; + case GSL_DEVICE_YAMATO: + gpu_clk = clk_get(0, "gpu3d_clk"); + break; + default: + printk(KERN_ERR "GPU device %d is invalid!\n", dev); + return (GSL_FAILURE_DEVICEERROR); + } + + if (IS_ERR(gpu_clk)) { + printk(KERN_ERR "%s: GPU clock get failed!\n", __func__); + return (GSL_FAILURE_DEVICEERROR); + } + + if (enable) { + clk_enable(gpu_clk); + clk_enable(garb_clk); + clk_enable(emi_garb_clk); + } else { + clk_disable(gpu_clk); + clk_disable(garb_clk); + clk_disable(emi_garb_clk); + } + + return (GSL_SUCCESS); +} diff --git a/drivers/mxc/amd-gpu/platform/hal/MX51/memcfg/gsl_memcfg.c b/drivers/mxc/amd-gpu/platform/hal/MX51/memcfg/gsl_memcfg.c new file mode 100644 index 000000000000..93fab327a830 --- /dev/null +++ b/drivers/mxc/amd-gpu/platform/hal/MX51/memcfg/gsl_memcfg.c @@ -0,0 +1,31 @@ +/* Copyright (c) 2008-2010, Advanced Micro Devices. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + */ + +#include "kos_libapi.h" + +// +// Return the maximum amount of memory that can be allocated to the Z430. This number +// will be constrained to 2MB as a minimum and the original hardcoded value for the caller +// as a maximum. If the return value is outside of this range, then the original value in +// the caller will be used. For this reason, returning 0 is used to signify to use the +// original value as the default. +// +KOS_DLLEXPORT unsigned long kgsl_get_z430_memory_amount(void) +{ + return(0); +} diff --git a/drivers/mxc/amd-gpu/platform/hal/MX51/memcfg/gsl_memcfg.h b/drivers/mxc/amd-gpu/platform/hal/MX51/memcfg/gsl_memcfg.h new file mode 100644 index 000000000000..e68387f1609a --- /dev/null +++ b/drivers/mxc/amd-gpu/platform/hal/MX51/memcfg/gsl_memcfg.h @@ -0,0 +1,40 @@ +/* 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_MEMCFG_H +#define GSL_MEMCFG_H + +// +// Return the maximum amount of memory that can be allocated to the Z430. This number +// will be constrained to 2MB as a minimum and the original hardcoded value for the caller +// as a maximum. If the return value is outside of this range, then the original value in +// the caller will be used. For this reason, returning 0 is used to signify to use the +// original value as the default. +// +KOS_DLLEXPORT unsigned long kgsl_get_z430_memory_amount(void); +#endif diff --git a/drivers/mxc/amd-gpu/platform/hal/linux/gsl_hwaccess.h b/drivers/mxc/amd-gpu/platform/hal/linux/gsl_hwaccess.h index 305b2ee9066d..65eadb1e79cf 100644 --- a/drivers/mxc/amd-gpu/platform/hal/linux/gsl_hwaccess.h +++ b/drivers/mxc/amd-gpu/platform/hal/linux/gsl_hwaccess.h @@ -40,9 +40,14 @@ OSINLINE 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)) { +#ifdef GSL_MMU_TRANSLATION_ENABLED + if(gpubase >= GSL_LINUX_MAP_RANGE_START && gpubase < GSL_LINUX_MAP_RANGE_END) + { gsl_linux_map_read(dst, gpubase+gpuoffset, sizebytes, touserspace); - } else { + } + else +#endif + { mb(); dsb(); if (touserspace) @@ -66,9 +71,14 @@ kgsl_hwaccess_memread(void *dst, unsigned int gpubase, unsigned int gpuoffset, u OSINLINE 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)) { +#ifdef GSL_MMU_TRANSLATION_ENABLED + if(gpubase >= GSL_LINUX_MAP_RANGE_START && gpubase < GSL_LINUX_MAP_RANGE_END) + { gsl_linux_map_write(src, gpubase+gpuoffset, sizebytes, fromuserspace); - } else { + } + else +#endif + { mb(); dsb(); if (fromuserspace) @@ -92,9 +102,12 @@ kgsl_hwaccess_memwrite(unsigned int gpubase, unsigned int gpuoffset, void *src, OSINLINE 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 { +#ifdef GSL_MMU_TRANSLATION_ENABLED + if(gpubase >= GSL_LINUX_MAP_RANGE_START && gpubase < GSL_LINUX_MAP_RANGE_END) + gsl_linux_map_set(gpuoffset+gpubase, value, sizebytes); + else +#endif + { mb(); dsb(); kos_memset((void *)(gpubase + gpuoffset), value, sizebytes); diff --git a/drivers/mxc/amd-gpu/platform/hal/linux/gsl_kmod.c b/drivers/mxc/amd-gpu/platform/hal/linux/gsl_kmod.c index bef8684ad131..30f783e1cf12 100644 --- a/drivers/mxc/amd-gpu/platform/hal/linux/gsl_kmod.c +++ b/drivers/mxc/amd-gpu/platform/hal/linux/gsl_kmod.c @@ -39,7 +39,7 @@ #include <linux/platform_device.h> #include <linux/vmalloc.h> -int gpu_2d_irq, gpu_3d_irq; +static int gpu_2d_irq, gpu_3d_irq; phys_addr_t gpu_2d_regbase; int gpu_2d_regsize; @@ -48,7 +48,6 @@ int gpu_3d_regsize; int gmem_size; phys_addr_t gpu_reserved_mem; int gpu_reserved_mem_size; -int z160_version; static ssize_t gsl_kmod_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr); static ssize_t gsl_kmod_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr); @@ -58,7 +57,9 @@ static int gsl_kmod_fault(struct vm_area_struct *vma, struct vm_fault *vmf); static int gsl_kmod_open(struct inode *inode, struct file *fd); static int gsl_kmod_release(struct inode *inode, struct file *fd); static irqreturn_t z160_irq_handler(int irq, void *dev_id); +#if defined(MX51) static irqreturn_t z430_irq_handler(int irq, void *dev_id); +#endif static int gsl_kmod_major; static struct class *gsl_kmod_class; @@ -633,24 +634,34 @@ static int gsl_kmod_mmap(struct file *fd, struct vm_area_struct *vma) unsigned long pfn = vma->vm_pgoff; unsigned long size = vma->vm_end - vma->vm_start; unsigned long prot = pgprot_writecombine(vma->vm_page_prot); - unsigned long addr = vma->vm_pgoff << PAGE_SHIFT; - void *va = NULL; - - if (gsl_driver.enable_mmu && (addr < GSL_LINUX_MAP_RANGE_END) && (addr >= GSL_LINUX_MAP_RANGE_START)) { - va = gsl_linux_map_find(addr); - while (size > 0) { - if (remap_pfn_range(vma, start, vmalloc_to_pfn(va), PAGE_SIZE, prot)) { - return -EAGAIN; - } - start += PAGE_SIZE; - va += PAGE_SIZE; - size -= PAGE_SIZE; +#ifdef GSL_MMU_TRANSLATION_ENABLED + unsigned long addr = vma->vm_pgoff << PAGE_SHIFT; + void *va; +#endif + +#ifdef GSL_MMU_TRANSLATION_ENABLED + if (addr < GSL_LINUX_MAP_RANGE_END && addr >= GSL_LINUX_MAP_RANGE_START) + { + va = gsl_linux_map_find(addr); + while (size > 0) + { + if (remap_pfn_range(vma, start, vmalloc_to_pfn(va), PAGE_SIZE, prot)) + { + return -EAGAIN; + } + start += PAGE_SIZE; + va += PAGE_SIZE; + size -= PAGE_SIZE; + } } - } else { - if (remap_pfn_range(vma, start, pfn, size, prot)) { - status = -EAGAIN; + else +#endif + { + if (remap_pfn_range(vma, start, pfn, size, prot)) + { + status = -EAGAIN; + } } - } vma->vm_ops = &gsl_kmod_vmops; @@ -742,11 +753,13 @@ static irqreturn_t z160_irq_handler(int irq, void *dev_id) return IRQ_HANDLED; } +#if defined(MX51) static irqreturn_t z430_irq_handler(int irq, void *dev_id) { kgsl_intr_isr(); return IRQ_HANDLED; } +#endif static int gpu_probe(struct platform_device *pdev) { @@ -754,11 +767,6 @@ static int gpu_probe(struct platform_device *pdev) struct resource *res; struct device *dev; - if (pdev->dev.platform_data) - z160_version = *((int *)(pdev->dev.platform_data)); - else - z160_version = 0; - for(i = 0; i < 2; i++){ res = platform_get_resource(pdev, IORESOURCE_IRQ, i); if (!res) { @@ -803,26 +811,24 @@ static int gpu_probe(struct platform_device *pdev) } } - if (gpu_3d_irq > 0) + if (kgsl_driver_init() != GSL_SUCCESS) { - if (request_irq(gpu_3d_irq, z430_irq_handler, 0, "ydx", NULL) < 0) { - printk(KERN_ERR "%s: request_irq error\n", __func__); - gpu_3d_irq = 0; - goto request_irq_error; - } + printk(KERN_ERR "%s: kgsl_driver_init error\n", __func__); + goto kgsl_driver_init_error; } - if (gpu_2d_irq > 0) +#if defined(MX51) + if (request_irq(gpu_3d_irq, z430_irq_handler, 0, "ydx", NULL) < 0) { - if (request_irq(gpu_2d_irq, z160_irq_handler, 0, "g12", NULL) < 0) { - printk(KERN_ERR "2D Acceleration Enabled, OpenVG Disabled!\n"); - gpu_2d_irq = 0; - } + printk(KERN_ERR "%s: request_irq error\n", __func__); + goto request_irq_error; } +#endif - if (kgsl_driver_init() != GSL_SUCCESS) { - printk(KERN_ERR "%s: kgsl_driver_init error\n", __func__); - goto kgsl_driver_init_error; + if (request_irq(gpu_2d_irq, z160_irq_handler, 0, "g12", NULL) < 0) + { + printk(KERN_ERR "2D Acceleration Enabled, OpenVG Disabled!\n"); + gpu_2d_irq = 0; } gsl_kmod_major = register_chrdev(0, "gsl_kmod", &gsl_kmod_fops); @@ -862,15 +868,9 @@ class_create_error: register_chrdev_error: unregister_chrdev(gsl_kmod_major, "gsl_kmod"); +request_irq_error: kgsl_driver_init_error: kgsl_driver_close(); - if (gpu_2d_irq > 0) { - free_irq(gpu_2d_irq, NULL); - } - if (gpu_3d_irq > 0) { - free_irq(gpu_3d_irq, NULL); - } -request_irq_error: return 0; // TODO: return proper error code } @@ -879,7 +879,7 @@ static int gpu_remove(struct platform_device *pdev) device_destroy(gsl_kmod_class, MKDEV(gsl_kmod_major, 0)); class_destroy(gsl_kmod_class); unregister_chrdev(gsl_kmod_major, "gsl_kmod"); - +#if defined(MX51) if (gpu_3d_irq) { free_irq(gpu_3d_irq, NULL); @@ -889,7 +889,12 @@ static int gpu_remove(struct platform_device *pdev) { free_irq(gpu_2d_irq, NULL); } - +#elif defined(MX35) + if (gpu_2d_irq) + { + free_irq(gpu_2d_irq, NULL); + } +#endif kgsl_driver_close(); return 0; } @@ -960,5 +965,9 @@ static void __exit gsl_kmod_exit(void) module_init(gsl_kmod_init); module_exit(gsl_kmod_exit); MODULE_AUTHOR("Advanced Micro Devices"); -MODULE_DESCRIPTION("AMD graphics core driver for i.MX"); +#if defined(MX51) +MODULE_DESCRIPTION("AMD 2D/3D graphics core driver for i.MX51"); +#elif defined(MX35) +MODULE_DESCRIPTION("AMD 2D graphics core driver for i.MX35"); +#endif MODULE_LICENSE("GPL v2"); diff --git a/drivers/mxc/amd-gpu/platform/hal/linux/gsl_linux_map.h b/drivers/mxc/amd-gpu/platform/hal/linux/gsl_linux_map.h index ebbe94a75e10..0469d2b912be 100644 --- a/drivers/mxc/amd-gpu/platform/hal/linux/gsl_linux_map.h +++ b/drivers/mxc/amd-gpu/platform/hal/linux/gsl_linux_map.h @@ -32,7 +32,7 @@ #include "gsl_halconfig.h" #define GSL_LINUX_MAP_RANGE_START (1024*1024) -#define GSL_LINUX_MAP_RANGE_END (GSL_LINUX_MAP_RANGE_START+GSL_HAL_SHMEM_SIZE_EMEM1_MMU) +#define GSL_LINUX_MAP_RANGE_END (GSL_LINUX_MAP_RANGE_START+GSL_HAL_SHMEM_SIZE_EMEM1) int gsl_linux_map_init(void); void *gsl_linux_map_alloc(unsigned int gpu_addr, unsigned int size); diff --git a/drivers/mxc/ipu3/ipu_capture.c b/drivers/mxc/ipu3/ipu_capture.c index b9967135eac1..e801705f8fe9 100644 --- a/drivers/mxc/ipu3/ipu_capture.c +++ b/drivers/mxc/ipu3/ipu_capture.c @@ -26,7 +26,6 @@ #include <linux/delay.h> #include <linux/ipu.h> #include <linux/clk.h> -#include <mach/mxc_dvfs.h> #include "ipu_prv.h" #include "ipu_regs.h" @@ -94,12 +93,6 @@ ipu_csi_init_interface(uint16_t width, uint16_t height, uint32_t pixel_fmt, cfg_param.force_eof << CSI_SENS_CONF_FORCE_EOF_SHIFT | cfg_param.data_en_pol << CSI_SENS_CONF_DATA_EN_POL_SHIFT; - if (g_ipu_clk_enabled == false) { - stop_dvfs_per(); - g_ipu_clk_enabled = true; - clk_enable(g_ipu_clk); - } - spin_lock_irqsave(&ipu_lock, lock_flags); __raw_writel(data, CSI_SENS_CONF(csi)); @@ -185,13 +178,36 @@ int _ipu_csi_mclk_set(uint32_t pixel_clk, uint32_t csi) */ int ipu_csi_enable_mclk(int csi, bool flag, bool wait) { + struct clk *clk; if (flag) { - clk_enable(g_csi_clk[csi]); + if (cpu_is_mx53()) { + if (csi == 0) { + clk = clk_get(NULL, "ssi_ext1_clk"); + clk_enable(clk); + clk_put(clk); + } else { + pr_err("invalid csi num %d\n", csi); + return -EINVAL; + } + } else + // CCWMX51 - Both CSIs from master clock 0 + clk_enable(g_csi_clk[0]); if (wait == true) msleep(10); } else { - clk_disable(g_csi_clk[csi]); + if (cpu_is_mx53()) { + if (csi == 0) { + clk = clk_get(NULL, "ssi_ext1_clk"); + clk_disable(clk); + clk_put(clk); + } else { + pr_err("invalid csi num %d\n", csi); + return -EINVAL; + } + } else + // CCWMX51 - Both CSIs from master clock 0 + clk_disable(g_csi_clk[0]); } return 0; @@ -210,12 +226,6 @@ void ipu_csi_get_window_size(uint32_t *width, uint32_t *height, uint32_t csi) uint32_t reg; unsigned long lock_flags; - if (g_ipu_clk_enabled == false) { - stop_dvfs_per(); - g_ipu_clk_enabled = true; - clk_enable(g_ipu_clk); - } - spin_lock_irqsave(&ipu_lock, lock_flags); reg = __raw_readl(CSI_ACT_FRM_SIZE(csi)); @@ -237,12 +247,6 @@ void ipu_csi_set_window_size(uint32_t width, uint32_t height, uint32_t csi) { unsigned long lock_flags; - if (g_ipu_clk_enabled == false) { - stop_dvfs_per(); - g_ipu_clk_enabled = true; - clk_enable(g_ipu_clk); - } - spin_lock_irqsave(&ipu_lock, lock_flags); __raw_writel((width - 1) | (height - 1) << 16, CSI_ACT_FRM_SIZE(csi)); @@ -263,12 +267,6 @@ void ipu_csi_set_window_pos(uint32_t left, uint32_t top, uint32_t csi) uint32_t temp; unsigned long lock_flags; - if (g_ipu_clk_enabled == false) { - stop_dvfs_per(); - g_ipu_clk_enabled = true; - clk_enable(g_ipu_clk); - } - spin_lock_irqsave(&ipu_lock, lock_flags); temp = __raw_readl(CSI_OUT_FRM_CTRL(csi)); @@ -291,12 +289,6 @@ void _ipu_csi_horizontal_downsize_enable(uint32_t csi) uint32_t temp; unsigned long lock_flags; - if (g_ipu_clk_enabled == false) { - stop_dvfs_per(); - g_ipu_clk_enabled = true; - clk_enable(g_ipu_clk); - } - spin_lock_irqsave(&ipu_lock, lock_flags); temp = __raw_readl(CSI_OUT_FRM_CTRL(csi)); @@ -317,12 +309,6 @@ void _ipu_csi_horizontal_downsize_disable(uint32_t csi) uint32_t temp; unsigned long lock_flags; - if (g_ipu_clk_enabled == false) { - stop_dvfs_per(); - g_ipu_clk_enabled = true; - clk_enable(g_ipu_clk); - } - spin_lock_irqsave(&ipu_lock, lock_flags); temp = __raw_readl(CSI_OUT_FRM_CTRL(csi)); @@ -343,12 +329,6 @@ void _ipu_csi_vertical_downsize_enable(uint32_t csi) uint32_t temp; unsigned long lock_flags; - if (g_ipu_clk_enabled == false) { - stop_dvfs_per(); - g_ipu_clk_enabled = true; - clk_enable(g_ipu_clk); - } - spin_lock_irqsave(&ipu_lock, lock_flags); temp = __raw_readl(CSI_OUT_FRM_CTRL(csi)); @@ -369,12 +349,6 @@ void _ipu_csi_vertical_downsize_disable(uint32_t csi) uint32_t temp; unsigned long lock_flags; - if (g_ipu_clk_enabled == false) { - stop_dvfs_per(); - g_ipu_clk_enabled = true; - clk_enable(g_ipu_clk); - } - spin_lock_irqsave(&ipu_lock, lock_flags); temp = __raw_readl(CSI_OUT_FRM_CTRL(csi)); @@ -401,12 +375,6 @@ void ipu_csi_set_test_generator(bool active, uint32_t r_value, uint32_t temp; unsigned long lock_flags; - if (g_ipu_clk_enabled == false) { - stop_dvfs_per(); - g_ipu_clk_enabled = true; - clk_enable(g_ipu_clk); - } - spin_lock_irqsave(&ipu_lock, lock_flags); temp = __raw_readl(CSI_TST_CTRL(csi)); @@ -442,12 +410,6 @@ void _ipu_csi_ccir_err_detection_enable(uint32_t csi) { uint32_t temp; - if (g_ipu_clk_enabled == false) { - stop_dvfs_per(); - g_ipu_clk_enabled = true; - clk_enable(g_ipu_clk); - } - temp = __raw_readl(CSI_CCIR_CODE_1(csi)); temp |= CSI_CCIR_ERR_DET_EN; __raw_writel(temp, CSI_CCIR_CODE_1(csi)); @@ -464,12 +426,6 @@ void _ipu_csi_ccir_err_detection_disable(uint32_t csi) { uint32_t temp; - if (g_ipu_clk_enabled == false) { - stop_dvfs_per(); - g_ipu_clk_enabled = true; - clk_enable(g_ipu_clk); - } - temp = __raw_readl(CSI_CCIR_CODE_1(csi)); temp &= ~CSI_CCIR_ERR_DET_EN; __raw_writel(temp, CSI_CCIR_CODE_1(csi)); @@ -495,12 +451,6 @@ int _ipu_csi_set_mipi_di(uint32_t num, uint32_t di_val, uint32_t csi) goto err; } - if (g_ipu_clk_enabled == false) { - stop_dvfs_per(); - g_ipu_clk_enabled = true; - clk_enable(g_ipu_clk); - } - spin_lock_irqsave(&ipu_lock, lock_flags); temp = __raw_readl(CSI_MIPI_DI(csi)); @@ -558,12 +508,6 @@ int _ipu_csi_set_skip_isp(uint32_t skip, uint32_t max_ratio, uint32_t csi) goto err; } - if (g_ipu_clk_enabled == false) { - stop_dvfs_per(); - g_ipu_clk_enabled = true; - clk_enable(g_ipu_clk); - } - spin_lock_irqsave(&ipu_lock, lock_flags); temp = __raw_readl(CSI_SKIP(csi)); @@ -601,12 +545,6 @@ int _ipu_csi_set_skip_smfc(uint32_t skip, uint32_t max_ratio, goto err; } - if (g_ipu_clk_enabled == false) { - stop_dvfs_per(); - g_ipu_clk_enabled = true; - clk_enable(g_ipu_clk); - } - spin_lock_irqsave(&ipu_lock, lock_flags); temp = __raw_readl(CSI_SKIP(csi)); @@ -674,12 +612,6 @@ void _ipu_smfc_set_wmc(ipu_channel_t channel, bool set, uint32_t level) uint32_t temp; unsigned long lock_flags; - if (g_ipu_clk_enabled == false) { - stop_dvfs_per(); - g_ipu_clk_enabled = true; - clk_enable(g_ipu_clk); - } - spin_lock_irqsave(&ipu_lock, lock_flags); temp = __raw_readl(SMFC_WMC); diff --git a/drivers/mxc/ipu3/ipu_common.c b/drivers/mxc/ipu3/ipu_common.c index b1b8a8b39ae1..eae3b549d765 100644 --- a/drivers/mxc/ipu3/ipu_common.c +++ b/drivers/mxc/ipu3/ipu_common.c @@ -354,8 +354,8 @@ static int ipu_probe(struct platform_device *pdev) g_di_clk[0] = plat_data->di_clk[0]; g_di_clk[1] = plat_data->di_clk[1]; - g_csi_clk[0] = plat_data->csi_clk[0]; - g_csi_clk[1] = plat_data->csi_clk[1]; + g_csi_clk[0] = clk_get(&pdev->dev, "csi_mclk1"); + g_csi_clk[1] = clk_get(&pdev->dev, "csi_mclk2"); __raw_writel(0x807FFFFF, IPU_MEM_RST); while (__raw_readl(IPU_MEM_RST) & 0x80000000) ; @@ -1883,29 +1883,29 @@ int32_t ipu_disable_channel(ipu_channel_t channel, bool wait_for_stop) if ((channel == MEM_BG_SYNC) || (channel == MEM_FG_SYNC) || (channel == MEM_DC_SYNC)) { - if (channel == MEM_FG_SYNC) - ipu_disp_set_window_pos(channel, 0, 0); + int timeout = 50; + int irq; _ipu_dp_dc_disable(channel, false); /* - * wait for BG channel EOF then disable FG-IDMAC, - * it avoid FG NFB4EOF error. + * wait for display channel EOF then disable IDMAC, + * it avoid NFB4EOF error. */ - if (channel == MEM_FG_SYNC) { - int timeout = 50; - - __raw_writel(IPUIRQ_2_MASK(IPU_IRQ_BG_SYNC_EOF), - IPUIRQ_2_STATREG(IPU_IRQ_BG_SYNC_EOF)); - while ((__raw_readl(IPUIRQ_2_STATREG(IPU_IRQ_BG_SYNC_EOF)) & - IPUIRQ_2_MASK(IPU_IRQ_BG_SYNC_EOF)) == 0) { - msleep(10); - timeout -= 10; - if (timeout <= 0) { - dev_err(g_ipu_dev, "warning: wait for bg sync eof timeout\n"); - break; - } - } + if (channel == MEM_BG_SYNC) + irq = IPU_IRQ_BG_SYNC_EOF; + if (channel == MEM_FG_SYNC) + irq = IPU_IRQ_FG_SYNC_EOF; + else + irq = IPU_IRQ_DC_SYNC_EOF; + __raw_writel(IPUIRQ_2_MASK(irq), + IPUIRQ_2_STATREG(irq)); + while ((__raw_readl(IPUIRQ_2_STATREG(irq)) & + IPUIRQ_2_MASK(irq)) == 0) { + msleep(10); + timeout -= 10; + if (timeout <= 0) + break; } } else if (wait_for_stop) { while (idma_is_set(IDMAC_CHA_BUSY, in_dma) || diff --git a/drivers/mxc/ipu3/ipu_disp.c b/drivers/mxc/ipu3/ipu_disp.c index 14dde404990b..7ce04d8bca9e 100644 --- a/drivers/mxc/ipu3/ipu_disp.c +++ b/drivers/mxc/ipu3/ipu_disp.c @@ -318,34 +318,22 @@ static void _ipu_dc_map_clear(int map) } static void _ipu_dc_write_tmpl(int word, u32 opcode, u32 operand, int map, - int wave, int glue, int sync, int stop) + int wave, int glue, int sync) { u32 reg; - - if (opcode == WRG) { - reg = sync; - reg |= (glue << 4); - reg |= (++wave << 11); - reg |= ((operand & 0x1FFFF) << 15); - __raw_writel(reg, ipu_dc_tmpl_reg + word * 2); - - reg = (operand >> 17); - reg |= opcode << 7; - reg |= (stop << 9); - __raw_writel(reg, ipu_dc_tmpl_reg + word * 2 + 1); - } else { - reg = sync; - reg |= (glue << 4); - reg |= (++wave << 11); - reg |= (++map << 15); - reg |= (operand << 20) & 0xFFF00000; - __raw_writel(reg, ipu_dc_tmpl_reg + word * 2); - - reg = (operand >> 12); - reg |= opcode << 4; - reg |= (stop << 9); - __raw_writel(reg, ipu_dc_tmpl_reg + word * 2 + 1); - } + int stop = 1; + + reg = sync; + reg |= (glue << 4); + reg |= (++wave << 11); + reg |= (++map << 15); + reg |= (operand << 20) & 0xFFF00000; + __raw_writel(reg, ipu_dc_tmpl_reg + word * 2); + + reg = (operand >> 12); + reg |= opcode << 4; + reg |= (stop << 9); + __raw_writel(reg, ipu_dc_tmpl_reg + word * 2 + 1); } static void _ipu_dc_link_event(int chan, int event, int addr, int priority) @@ -735,26 +723,6 @@ static bool dc_swap; static irqreturn_t dc_irq_handler(int irq, void *dev_id) { struct completion *comp = dev_id; - uint32_t reg; - uint32_t dc_chan; - - if (irq == IPU_IRQ_DC_FC_1) - dc_chan = 1; - else - dc_chan = 5; - - if (!dc_swap) { - reg = __raw_readl(DC_WR_CH_CONF(dc_chan)); - reg &= ~DC_WR_CH_CONF_PROG_TYPE_MASK; - __raw_writel(reg, DC_WR_CH_CONF(dc_chan)); - - reg = __raw_readl(IPU_DISP_GEN); - if (g_dc_di_assignment[dc_chan]) - reg &= ~DI1_COUNTER_RELEASE; - else - reg &= ~DI0_COUNTER_RELEASE; - __raw_writel(reg, IPU_DISP_GEN); - } complete(comp); return IRQ_HANDLED; @@ -838,6 +806,19 @@ void _ipu_dp_dc_disable(ipu_channel_t channel, bool swap) __raw_writel(reg, DC_WR_CH_CONF(dc_chan)); spin_unlock_irqrestore(&ipu_lock, lock_flags); } else { + spin_lock_irqsave(&ipu_lock, lock_flags); + reg = __raw_readl(DC_WR_CH_CONF(dc_chan)); + reg &= ~DC_WR_CH_CONF_PROG_TYPE_MASK; + __raw_writel(reg, DC_WR_CH_CONF(dc_chan)); + + reg = __raw_readl(IPU_DISP_GEN); + if (g_dc_di_assignment[dc_chan]) + reg &= ~DI1_COUNTER_RELEASE; + else + reg &= ~DI0_COUNTER_RELEASE; + __raw_writel(reg, IPU_DISP_GEN); + + spin_unlock_irqrestore(&ipu_lock, lock_flags); /* Clock is already off because it must be done quickly, but we need to fix the ref count */ clk_disable(g_pixel_clk[g_dc_di_assignment[dc_chan]]); @@ -1062,13 +1043,9 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk, dev_dbg(g_ipu_dev, "pixel clk = %d\n", pixel_clk); if (sig.ext_clk) { - /* - * Set the PLL to be an even multiple of the pixel clock. - * Not round div for tvout and ldb. - * Did not consider both DI come from the same ext clk, if - * meet such case, ext clk rate should be set specially. - */ - if (clk_get_usecount(g_pixel_clk[disp]) == 0) { + /* Set the PLL to be an even multiple of the pixel clock. not round div for tvout*/ + if ((clk_get_usecount(g_pixel_clk[0]) == 0) && + (clk_get_usecount(g_pixel_clk[1]) == 0)) { di_parent = clk_get_parent(g_di_clk[disp]); if (strcmp(di_parent->name, "tve_clk") != 0 && strcmp(di_parent->name, "ldb_di0_clk") != 0 && @@ -1117,7 +1094,7 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk, di_gen = __raw_readl(DI_GENERAL(disp)); if (sig.interlaced) { - if (g_ipu_hw_rev >= 2) { + if (cpu_is_mx51_rev(CHIP_REV_2_0)) { /* Setup internal HSYNC waveform */ _ipu_di_sync_config( disp, /* display */ @@ -1357,7 +1334,7 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk, } /* Init template microcode */ - _ipu_dc_write_tmpl(0, WROD(0), 0, map, SYNC_WAVE, 0, 8, 1); + _ipu_dc_write_tmpl(0, WROD(0), 0, map, SYNC_WAVE, 0, 8); if (sig.Hsync_pol) di_gen |= DI_GEN_POLARITY_3; @@ -1424,27 +1401,27 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk, (pixel_fmt == IPU_PIX_FMT_UYVY) || (pixel_fmt == IPU_PIX_FMT_YVYU) || (pixel_fmt == IPU_PIX_FMT_VYUY)) { - _ipu_dc_write_tmpl(8, WROD(0), 0, (map - 1), SYNC_WAVE, 0, 5, 1); - _ipu_dc_write_tmpl(9, WROD(0), 0, map, SYNC_WAVE, 0, 5, 1); + _ipu_dc_write_tmpl(8, WROD(0), 0, (map - 1), SYNC_WAVE, 0, 5); + _ipu_dc_write_tmpl(9, WROD(0), 0, map, SYNC_WAVE, 0, 5); /* configure user events according to DISP NUM */ __raw_writel((width - 1), DC_UGDE_3(disp)); } - _ipu_dc_write_tmpl(2, WROD(0), 0, map, SYNC_WAVE, 8, 5, 1); - _ipu_dc_write_tmpl(3, WRG, 0, map, SYNC_WAVE, 4, 5, 1); - _ipu_dc_write_tmpl(4, WROD(0), 0, map, SYNC_WAVE, 0, 5, 1); + _ipu_dc_write_tmpl(2, WROD(0), 0, map, SYNC_WAVE, 8, 5); + _ipu_dc_write_tmpl(3, WROD(0), 0, map, SYNC_WAVE, 4, 5); + _ipu_dc_write_tmpl(4, WROD(0), 0, map, SYNC_WAVE, 0, 5); } else { if ((pixel_fmt == IPU_PIX_FMT_YUYV) || (pixel_fmt == IPU_PIX_FMT_UYVY) || (pixel_fmt == IPU_PIX_FMT_YVYU) || (pixel_fmt == IPU_PIX_FMT_VYUY)) { - _ipu_dc_write_tmpl(10, WROD(0), 0, (map - 1), SYNC_WAVE, 0, 5, 1); - _ipu_dc_write_tmpl(11, WROD(0), 0, map, SYNC_WAVE, 0, 5, 1); + _ipu_dc_write_tmpl(10, WROD(0), 0, (map - 1), SYNC_WAVE, 0, 5); + _ipu_dc_write_tmpl(11, WROD(0), 0, map, SYNC_WAVE, 0, 5); /* configure user events according to DISP NUM */ __raw_writel(width - 1, DC_UGDE_3(disp)); } - _ipu_dc_write_tmpl(5, WROD(0), 0, map, SYNC_WAVE, 8, 5, 1); - _ipu_dc_write_tmpl(6, WRG, 0, map, SYNC_WAVE, 4, 5, 1); - _ipu_dc_write_tmpl(7, WROD(0), 0, map, SYNC_WAVE, 0, 5, 1); + _ipu_dc_write_tmpl(5, WROD(0), 0, map, SYNC_WAVE, 8, 5); + _ipu_dc_write_tmpl(6, WROD(0), 0, map, SYNC_WAVE, 4, 5); + _ipu_dc_write_tmpl(7, WROD(0), 0, map, SYNC_WAVE, 0, 5); } if (sig.Hsync_pol) @@ -1531,7 +1508,7 @@ int ipu_init_async_panel(int disp, int type, uint32_t cycle_time, _ipu_di_data_pin_config(disp, ASYNC_SER_WAVE, DI_PIN_SER_RS, 2, 0, 0); - _ipu_dc_write_tmpl(0x64, WROD(0), 0, map, ASYNC_SER_WAVE, 0, 0, 1); + _ipu_dc_write_tmpl(0x64, WROD(0), 0, map, ASYNC_SER_WAVE, 0, 0); /* Configure DC for serial panel */ __raw_writel(0x14, DC_DISP_CONF1(DC_DISP_ID_SERIAL)); @@ -1808,39 +1785,6 @@ int32_t ipu_disp_set_window_pos(ipu_channel_t channel, int16_t x_pos, } EXPORT_SYMBOL(ipu_disp_set_window_pos); -int32_t ipu_disp_get_window_pos(ipu_channel_t channel, int16_t *x_pos, - int16_t *y_pos) -{ - u32 reg; - unsigned long lock_flags; - uint32_t flow = 0; - - if (channel == MEM_FG_SYNC) - flow = DP_SYNC; - else if (channel == MEM_FG_ASYNC0) - flow = DP_ASYNC0; - else if (channel == MEM_FG_ASYNC1) - flow = DP_ASYNC1; - else - return -EINVAL; - - if (!g_ipu_clk_enabled) - clk_enable(g_ipu_clk); - spin_lock_irqsave(&ipu_lock, lock_flags); - - reg = __raw_readl(DP_FG_POS(flow)); - - *x_pos = (reg >> 16) & 0x7FF; - *y_pos = reg & 0x7FF; - - spin_unlock_irqrestore(&ipu_lock, lock_flags); - if (!g_ipu_clk_enabled) - clk_disable(g_ipu_clk); - - return 0; -} -EXPORT_SYMBOL(ipu_disp_get_window_pos); - void ipu_disp_direct_write(ipu_channel_t channel, u32 value, u32 offset) { if (channel == DIRECT_ASYNC0) diff --git a/drivers/mxc/ipu3/ipu_regs.h b/drivers/mxc/ipu3/ipu_regs.h index 4a78e14df560..19fde8846aa7 100644 --- a/drivers/mxc/ipu3/ipu_regs.h +++ b/drivers/mxc/ipu3/ipu_regs.h @@ -664,6 +664,5 @@ enum di_sync_wave { /* DC template opcodes */ #define WROD(lf) (0x18 | (lf << 1)) -#define WRG (0x01) #endif diff --git a/drivers/mxc/vpu/mxc_vpu.c b/drivers/mxc/vpu/mxc_vpu.c index 9fc25edc33fa..f62e3d46a67c 100644 --- a/drivers/mxc/vpu/mxc_vpu.c +++ b/drivers/mxc/vpu/mxc_vpu.c @@ -73,7 +73,6 @@ static struct vpu_mem_desc user_data_mem = { 0 }; static struct vpu_mem_desc share_mem = { 0 }; static void __iomem *vpu_base; -static int vpu_irq; static u32 phy_vpu_base_addr; static struct mxc_vpu_platform_data *vpu_plat; @@ -540,7 +539,7 @@ static int vpu_map_mem(struct file *fp, struct vm_area_struct *vm) request_size); vm->vm_flags |= VM_IO | VM_RESERVED; - vm->vm_page_prot = pgprot_writecombine(vm->vm_page_prot); + vm->vm_page_prot = pgprot_noncached(vm->vm_page_prot); return remap_pfn_range(vm, vm->vm_start, vm->vm_pgoff, request_size, vm->vm_page_prot) ? -EAGAIN : 0; @@ -636,9 +635,8 @@ static int vpu_dev_probe(struct platform_device *pdev) err = -ENXIO; goto err_out_class; } - vpu_irq = res->start; - err = request_irq(vpu_irq, vpu_irq_handler, 0, "VPU_CODEC_IRQ", + err = request_irq(res->start, vpu_irq_handler, 0, "VPU_CODEC_IRQ", (void *)(&vpu_data)); if (err) goto err_out_class; @@ -662,7 +660,6 @@ static int vpu_dev_probe(struct platform_device *pdev) static int vpu_dev_remove(struct platform_device *pdev) { - free_irq(vpu_irq, &vpu_data); iounmap(vpu_base); iram_free(iram.start, VPU_IRAM_SIZE); @@ -693,9 +690,7 @@ static int vpu_suspend(struct platform_device *pdev, pm_message_t state) for (i = 0; i < vpu_clk_usercount; i++) clk_disable(vpu_clk); - if (!cpu_is_mx37()) - return 0; - else { + if (!cpu_is_mx53()) { clk_enable(vpu_clk); if (bitwork_mem.cpu_addr != 0) { SAVE_WORK_REGS; @@ -711,7 +706,8 @@ static int vpu_suspend(struct platform_device *pdev, pm_message_t state) clk_disable(vpu_clk); } - mxc_pg_enable(pdev); + if (cpu_is_mx37() || cpu_is_mx51()) + mxc_pg_enable(pdev); return 0; @@ -725,10 +721,11 @@ static int vpu_resume(struct platform_device *pdev) { int i; - if (cpu_is_mx37()) + if (cpu_is_mx37() || cpu_is_mx51()) mxc_pg_disable(pdev); - else - goto recover_clk; + + if (cpu_is_mx53()) + goto recover_clk; clk_enable(vpu_clk); if (bitwork_mem.cpu_addr != 0) { @@ -799,7 +796,6 @@ recover_clk: /* Recover vpu clock */ for (i = 0; i < vpu_clk_usercount; i++) clk_enable(vpu_clk); - printk("vpu_resume end\n"); return 0; } @@ -832,6 +828,7 @@ static int __init vpu_init(void) static void __exit vpu_exit(void) { + free_irq(MXC_INT_VPU, (void *)(&vpu_data)); if (vpu_major > 0) { device_destroy(vpu_class, MKDEV(vpu_major, 0)); class_destroy(vpu_class); |