diff options
Diffstat (limited to 'drivers/gpu/arm/t6xx/kbase/src/common/mali_kbase_config.c')
-rwxr-xr-x | drivers/gpu/arm/t6xx/kbase/src/common/mali_kbase_config.c | 607 |
1 files changed, 607 insertions, 0 deletions
diff --git a/drivers/gpu/arm/t6xx/kbase/src/common/mali_kbase_config.c b/drivers/gpu/arm/t6xx/kbase/src/common/mali_kbase_config.c new file mode 100755 index 00000000000..5ae5ad908b7 --- /dev/null +++ b/drivers/gpu/arm/t6xx/kbase/src/common/mali_kbase_config.c @@ -0,0 +1,607 @@ +/* + * + * (C) COPYRIGHT 2011-2013 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the + * GNU General Public License version 2 as published by the Free Software + * Foundation, and any use by you of this program is subject to the terms + * of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained + * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + + + +#include <kbase/src/common/mali_kbase.h> +#include <kbase/src/common/mali_kbase_defs.h> +#include <kbase/src/common/mali_kbase_cpuprops.h> +#ifdef CONFIG_UMP +#include <linux/ump-common.h> +#endif /* CONFIG_UMP */ + +/* Specifies how many attributes are permitted in the config (excluding terminating attribute). + * This is used in validation function so we can detect if configuration is properly terminated. This value can be + * changed if we need to introduce more attributes or many memory regions need to be defined */ +#define ATTRIBUTE_COUNT_MAX 32 + +/* right now we allow only 2 memory attributes (excluding termination attribute) */ +#define MEMORY_ATTRIBUTE_COUNT_MAX 2 + +/* Limits for gpu frequency configuration parameters. These will use for config validation. */ +#define MAX_GPU_ALLOWED_FREQ_KHZ 1000000 +#define MIN_GPU_ALLOWED_FREQ_KHZ 1 + +/* Default irq throttle time. This is the default desired minimum time in between two consecutive + * interrupts from the gpu. The irq throttle gpu register is set after this value. */ +#define DEFAULT_IRQ_THROTTLE_TIME_US 20 + +/*** Begin Scheduling defaults ***/ + +/** + * Default scheduling tick granuality, in nanoseconds + */ +#define DEFAULT_JS_SCHEDULING_TICK_NS 100000000u /* 100ms */ + +/** + * Default minimum number of scheduling ticks before jobs are soft-stopped. + * + * This defines the time-slice for a job (which may be different from that of a context) + */ +#define DEFAULT_JS_SOFT_STOP_TICKS 1 /* Between 0.1 and 0.2s before soft-stop */ + +/** + * Default minimum number of scheduling ticks before jobs are hard-stopped + */ +#define DEFAULT_JS_HARD_STOP_TICKS_SS_HW_ISSUE_8408 12 /* 1.2s before hard-stop, for a certain GLES2 test at 128x128 (bound by combined vertex+tiler job) */ +#define DEFAULT_JS_HARD_STOP_TICKS_SS 2 /* Between 0.2 and 0.3s before hard-stop */ + +/** + * Default minimum number of scheduling ticks before jobs are hard-stopped + * during dumping + */ +#define DEFAULT_JS_HARD_STOP_TICKS_NSS 600 /* 60s @ 100ms tick */ + +/** + * Default minimum number of scheduling ticks before the GPU is reset + * to clear a "stuck" job + */ +#define DEFAULT_JS_RESET_TICKS_SS_HW_ISSUE_8408 18 /* 1.8s before resetting GPU, for a certain GLES2 test at 128x128 (bound by combined vertex+tiler job) */ +#define DEFAULT_JS_RESET_TICKS_SS 3 /* 0.3-0.4s before GPU is reset */ + +/** + * Default minimum number of scheduling ticks before the GPU is reset + * to clear a "stuck" job during dumping. + */ +#define DEFAULT_JS_RESET_TICKS_NSS 601 /* 60.1s @ 100ms tick */ + +/** + * Number of milliseconds given for other jobs on the GPU to be + * soft-stopped when the GPU needs to be reset. + */ +#define DEFAULT_JS_RESET_TIMEOUT_MS 3000 + +/** + * Default timeslice that a context is scheduled in for, in nanoseconds. + * + * When a context has used up this amount of time across its jobs, it is + * scheduled out to let another run. + * + * @note the resolution is nanoseconds (ns) here, because that's the format + * often used by the OS. + */ +#define DEFAULT_JS_CTX_TIMESLICE_NS 50000000 /* 0.05s - at 20fps a ctx does at least 1 frame before being scheduled out. At 40fps, 2 frames, etc */ + +/** + * Default initial runtime of a context for CFS, in ticks. + * + * This value is relative to that of the least-run context, and defines where + * in the CFS queue a new context is added. + */ +#define DEFAULT_JS_CFS_CTX_RUNTIME_INIT_SLICES 1 + +/** + * Default minimum runtime value of a context for CFS, in ticks. + * + * This value is relative to that of the least-run context. This prevents + * "stored-up timeslices" DoS attacks. + */ +#define DEFAULT_JS_CFS_CTX_RUNTIME_MIN_SLICES 2 + +/** + * Default setting for whether to prefer security or performance. + * + * Currently affects only r0p0-15dev0 HW and earlier. + */ +#define DEFAULT_SECURE_BUT_LOSS_OF_PERFORMANCE MALI_FALSE + +/** + * Default setting for read Address ID limiting on AXI. + */ +#define DEFAULT_ARID_LIMIT KBASE_AID_32 + +/** + * Default setting for write Address ID limiting on AXI. + */ +#define DEFAULT_AWID_LIMIT KBASE_AID_32 + +/** + * Default setting for using alternative hardware counters. + */ +#define DEFAULT_ALTERNATIVE_HWC MALI_FALSE + +/*** End Scheduling defaults ***/ + +/*** Begin Power Manager defaults */ + +#define DEFAULT_PM_DVFS_FREQ 500 /* Milliseconds */ + +/** + * Default poweroff tick granuality, in nanoseconds + */ +#define DEFAULT_PM_GPU_POWEROFF_TICK_NS 400000 /* 400us */ + +/** + * Default number of poweroff ticks before shader cores are powered off + */ +#define DEFAULT_PM_POWEROFF_TICK_SHADER 2 /* 400-800us */ + +/** + * Default number of poweroff ticks before GPU is powered off + */ +#define DEFAULT_PM_POWEROFF_TICK_GPU 2 /* 400-800us */ + +/*** End Power Manager defaults ***/ + +/** + * Default value for KBASE_CONFIG_ATTR_CPU_SPEED_FUNC. + * Points to @ref kbase_cpuprops_get_default_clock_speed. + */ +#define DEFAULT_CPU_SPEED_FUNC ((uintptr_t)kbase_cpuprops_get_default_clock_speed) + +int kbasep_get_config_attribute_count(const kbase_attribute *attributes) +{ + int count = 1; + + KBASE_DEBUG_ASSERT(attributes != NULL); + + while (attributes->id != KBASE_CONFIG_ATTR_END) { + attributes++; + count++; + } + + return count; +} + +const kbase_attribute *kbasep_get_next_attribute(const kbase_attribute *attributes, int attribute_id) +{ + KBASE_DEBUG_ASSERT(attributes != NULL); + + while (attributes->id != KBASE_CONFIG_ATTR_END) { + if (attributes->id == attribute_id) + return attributes; + + attributes++; + } + return NULL; +} + +KBASE_EXPORT_TEST_API(kbasep_get_next_attribute) + +uintptr_t kbasep_get_config_value(struct kbase_device *kbdev, const kbase_attribute *attributes, int attribute_id) +{ + const kbase_attribute *attr; + + KBASE_DEBUG_ASSERT(attributes != NULL); + + attr = kbasep_get_next_attribute(attributes, attribute_id); + if (attr != NULL) + return attr->data; + + /* default values */ + switch (attribute_id) { + case KBASE_CONFIG_ATTR_MEMORY_PER_PROCESS_LIMIT: + return (uintptr_t) -1; +#ifdef CONFIG_UMP + case KBASE_CONFIG_ATTR_UMP_DEVICE: + return UMP_DEVICE_W_SHIFT; +#endif /* CONFIG_UMP */ + case KBASE_CONFIG_ATTR_MEMORY_OS_SHARED_MAX: + return (uintptr_t) -1; + case KBASE_CONFIG_ATTR_MEMORY_OS_SHARED_PERF_GPU: + return KBASE_MEM_PERF_NORMAL; + case KBASE_CONFIG_ATTR_GPU_IRQ_THROTTLE_TIME_US: + return DEFAULT_IRQ_THROTTLE_TIME_US; + /* Begin scheduling defaults */ + case KBASE_CONFIG_ATTR_JS_SCHEDULING_TICK_NS: + return DEFAULT_JS_SCHEDULING_TICK_NS; + case KBASE_CONFIG_ATTR_JS_SOFT_STOP_TICKS: + return DEFAULT_JS_SOFT_STOP_TICKS; + case KBASE_CONFIG_ATTR_JS_HARD_STOP_TICKS_SS: + if (kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_8408)) + return DEFAULT_JS_HARD_STOP_TICKS_SS_HW_ISSUE_8408; + else + return DEFAULT_JS_HARD_STOP_TICKS_SS; + case KBASE_CONFIG_ATTR_JS_HARD_STOP_TICKS_NSS: + return DEFAULT_JS_HARD_STOP_TICKS_NSS; + case KBASE_CONFIG_ATTR_JS_CTX_TIMESLICE_NS: + return DEFAULT_JS_CTX_TIMESLICE_NS; + case KBASE_CONFIG_ATTR_JS_CFS_CTX_RUNTIME_INIT_SLICES: + return DEFAULT_JS_CFS_CTX_RUNTIME_INIT_SLICES; + case KBASE_CONFIG_ATTR_JS_CFS_CTX_RUNTIME_MIN_SLICES: + return DEFAULT_JS_CFS_CTX_RUNTIME_MIN_SLICES; + case KBASE_CONFIG_ATTR_JS_RESET_TICKS_SS: + if (kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_8408)) + return DEFAULT_JS_RESET_TICKS_SS_HW_ISSUE_8408; + else + return DEFAULT_JS_RESET_TICKS_SS; + case KBASE_CONFIG_ATTR_JS_RESET_TICKS_NSS: + return DEFAULT_JS_RESET_TICKS_NSS; + case KBASE_CONFIG_ATTR_JS_RESET_TIMEOUT_MS: + return DEFAULT_JS_RESET_TIMEOUT_MS; + /* End scheduling defaults */ + case KBASE_CONFIG_ATTR_POWER_MANAGEMENT_CALLBACKS: + return 0; + case KBASE_CONFIG_ATTR_PLATFORM_FUNCS: + return 0; + case KBASE_CONFIG_ATTR_SECURE_BUT_LOSS_OF_PERFORMANCE: + return DEFAULT_SECURE_BUT_LOSS_OF_PERFORMANCE; + case KBASE_CONFIG_ATTR_CPU_SPEED_FUNC: + return DEFAULT_CPU_SPEED_FUNC; + case KBASE_CONFIG_ATTR_GPU_SPEED_FUNC: + return 0; + case KBASE_CONFIG_ATTR_ARID_LIMIT: + return DEFAULT_ARID_LIMIT; + case KBASE_CONFIG_ATTR_AWID_LIMIT: + return DEFAULT_AWID_LIMIT; + case KBASE_CONFIG_ATTR_ALTERNATIVE_HWC: + return DEFAULT_ALTERNATIVE_HWC; + case KBASE_CONFIG_ATTR_POWER_MANAGEMENT_DVFS_FREQ: + return DEFAULT_PM_DVFS_FREQ; + case KBASE_CONFIG_ATTR_PM_GPU_POWEROFF_TICK_NS: + return DEFAULT_PM_GPU_POWEROFF_TICK_NS; + case KBASE_CONFIG_ATTR_PM_POWEROFF_TICK_SHADER: + return DEFAULT_PM_POWEROFF_TICK_SHADER; + case KBASE_CONFIG_ATTR_PM_POWEROFF_TICK_GPU: + return DEFAULT_PM_POWEROFF_TICK_GPU; + + default: + KBASE_DEBUG_PRINT_ERROR(KBASE_CORE, "kbasep_get_config_value. Cannot get value of attribute with id=%d and no default value defined", attribute_id); + return 0; + } +} + +KBASE_EXPORT_TEST_API(kbasep_get_config_value) + +mali_bool kbasep_platform_device_init(kbase_device *kbdev) +{ + kbase_platform_funcs_conf *platform_funcs; + + platform_funcs = (kbase_platform_funcs_conf *) kbasep_get_config_value(kbdev, kbdev->config_attributes, KBASE_CONFIG_ATTR_PLATFORM_FUNCS); + if (platform_funcs) { + if (platform_funcs->platform_init_func) + return platform_funcs->platform_init_func(kbdev); + } + return MALI_TRUE; +} + +void kbasep_platform_device_term(kbase_device *kbdev) +{ + kbase_platform_funcs_conf *platform_funcs; + + platform_funcs = (kbase_platform_funcs_conf *) kbasep_get_config_value(kbdev, kbdev->config_attributes, KBASE_CONFIG_ATTR_PLATFORM_FUNCS); + if (platform_funcs) { + if (platform_funcs->platform_term_func) + platform_funcs->platform_term_func(kbdev); + } +} + +#ifdef CONFIG_UMP +static mali_bool kbasep_validate_ump_device(int ump_device) +{ + mali_bool valid; + + switch (ump_device) { + case UMP_DEVICE_W_SHIFT: + case UMP_DEVICE_X_SHIFT: + case UMP_DEVICE_Y_SHIFT: + case UMP_DEVICE_Z_SHIFT: + valid = MALI_TRUE; + break; + default: + valid = MALI_FALSE; + break; + } + return valid; +} +#endif /* CONFIG_UMP */ + +static mali_bool kbasep_validate_memory_performance(kbase_memory_performance performance) +{ + return performance <= KBASE_MEM_PERF_MAX_VALUE; +} + +static mali_bool kbasep_validate_memory_resource(const kbase_memory_resource *memory_resource) +{ + KBASE_DEBUG_ASSERT(memory_resource != NULL); + + if (memory_resource->name == NULL) { + KBASE_DEBUG_PRINT_WARN(KBASE_CORE, "Unnamed memory region found"); + return MALI_FALSE; + } + + if (memory_resource->base & ((1 << PAGE_SHIFT) - 1)) { + KBASE_DEBUG_PRINT_WARN(KBASE_CORE, "Base address of \"%s\" memory region is not page aligned", memory_resource->name); + return MALI_FALSE; + } + + if (memory_resource->size & ((1 << PAGE_SHIFT) - 1)) { + KBASE_DEBUG_PRINT_WARN(KBASE_CORE, "Size of \"%s\" memory region is not a multiple of page size", memory_resource->name); + return MALI_FALSE; + } + + if (memory_resource->attributes != NULL) { /* we allow NULL attribute list */ + int i; + + for (i = 0; memory_resource->attributes[i].id != KBASE_MEM_ATTR_END; i++) { + if (i >= MEMORY_ATTRIBUTE_COUNT_MAX) { + KBASE_DEBUG_PRINT_WARN(KBASE_CORE, "More than MEMORY_ATTRIBUTE_COUNT_MAX=%d configuration attributes defined. Is memory attribute list properly terminated?", MEMORY_ATTRIBUTE_COUNT_MAX); + return MALI_FALSE; + } + switch (memory_resource->attributes[i].id) { + case KBASE_MEM_ATTR_PERF_CPU: + if (MALI_TRUE != kbasep_validate_memory_performance((kbase_memory_performance) memory_resource->attributes[i].data)) { + KBASE_DEBUG_PRINT_WARN(KBASE_CORE, "CPU performance of \"%s\" region is invalid: %d", memory_resource->name, (kbase_memory_performance) memory_resource->attributes[i].data); + return MALI_FALSE; + } + break; + + case KBASE_MEM_ATTR_PERF_GPU: + if (MALI_TRUE != kbasep_validate_memory_performance((kbase_memory_performance) memory_resource->attributes[i].data)) { + KBASE_DEBUG_PRINT_WARN(KBASE_CORE, "GPU performance of \"%s\" region is invalid: %d", memory_resource->name, (kbase_memory_performance) memory_resource->attributes[i].data); + return MALI_FALSE; + } + break; + default: + KBASE_DEBUG_PRINT_WARN(KBASE_CORE, "Invalid memory attribute found in \"%s\" memory region: %d", memory_resource->name, memory_resource->attributes[i].id); + return MALI_FALSE; + } + } + } + + return MALI_TRUE; +} + +static mali_bool kbasep_validate_gpu_clock_freq(kbase_device *kbdev, const kbase_attribute *attributes) +{ + uintptr_t freq_min = kbasep_get_config_value(kbdev, attributes, KBASE_CONFIG_ATTR_GPU_FREQ_KHZ_MIN); + uintptr_t freq_max = kbasep_get_config_value(kbdev, attributes, KBASE_CONFIG_ATTR_GPU_FREQ_KHZ_MAX); + + if ((freq_min > MAX_GPU_ALLOWED_FREQ_KHZ) || (freq_min < MIN_GPU_ALLOWED_FREQ_KHZ) || (freq_max > MAX_GPU_ALLOWED_FREQ_KHZ) || (freq_max < MIN_GPU_ALLOWED_FREQ_KHZ) || (freq_min > freq_max)) { + KBASE_DEBUG_PRINT_WARN(KBASE_CORE, "Invalid GPU frequencies found in configuration: min=%ldkHz, max=%ldkHz.", freq_min, freq_max); + return MALI_FALSE; + } + + return MALI_TRUE; +} + +static mali_bool kbasep_validate_pm_callback(const kbase_pm_callback_conf *callbacks) +{ + if (callbacks == NULL) { + /* Having no callbacks is valid */ + return MALI_TRUE; + } + + if ((callbacks->power_off_callback != NULL && callbacks->power_on_callback == NULL) || (callbacks->power_off_callback == NULL && callbacks->power_on_callback != NULL)) { + KBASE_DEBUG_PRINT_WARN(KBASE_CORE, "Invalid power management callbacks: Only one of power_off_callback and power_on_callback was specified"); + return MALI_FALSE; + } + return MALI_TRUE; +} + +static mali_bool kbasep_validate_cpu_speed_func(kbase_cpuprops_clock_speed_function fcn) +{ + return fcn != NULL; +} + +mali_bool kbasep_validate_configuration_attributes(kbase_device *kbdev, const kbase_attribute *attributes) +{ + int i; + mali_bool had_gpu_freq_min = MALI_FALSE, had_gpu_freq_max = MALI_FALSE; + + KBASE_DEBUG_ASSERT(attributes); + + for (i = 0; attributes[i].id != KBASE_CONFIG_ATTR_END; i++) { + if (i >= ATTRIBUTE_COUNT_MAX) { + KBASE_DEBUG_PRINT_WARN(KBASE_CORE, "More than ATTRIBUTE_COUNT_MAX=%d configuration attributes defined. Is attribute list properly terminated?", ATTRIBUTE_COUNT_MAX); + return MALI_FALSE; + } + + switch (attributes[i].id) { + case KBASE_CONFIG_ATTR_MEMORY_RESOURCE: + if (MALI_FALSE == kbasep_validate_memory_resource((kbase_memory_resource *) attributes[i].data)) { + KBASE_DEBUG_PRINT_WARN(KBASE_CORE, "Invalid memory region found in configuration"); + return MALI_FALSE; + } + break; + + case KBASE_CONFIG_ATTR_MEMORY_OS_SHARED_MAX: + /* Some shared memory is required for GPU page tables, see MIDBASE-1534 */ + if (0 == attributes[i].data) { + KBASE_DEBUG_PRINT_WARN(KBASE_CORE, "Maximum OS Shared Memory Maximum is set to 0 which is not supported"); + return MALI_FALSE; + } + break; + + case KBASE_CONFIG_ATTR_MEMORY_OS_SHARED_PERF_GPU: + if (MALI_FALSE == kbasep_validate_memory_performance((kbase_memory_performance) attributes[i].data)) { + KBASE_DEBUG_PRINT_WARN(KBASE_CORE, "Shared OS memory GPU performance attribute has invalid value: %d", (kbase_memory_performance) attributes[i].data); + return MALI_FALSE; + } + break; + + case KBASE_CONFIG_ATTR_MEMORY_PER_PROCESS_LIMIT: + /* any value is allowed */ + break; +#ifdef CONFIG_UMP + case KBASE_CONFIG_ATTR_UMP_DEVICE: + if (MALI_FALSE == kbasep_validate_ump_device(attributes[i].data)) { + KBASE_DEBUG_PRINT_WARN(KBASE_CORE, "Unknown UMP device found in configuration: %d", (int)attributes[i].data); + return MALI_FALSE; + } + break; +#endif /* CONFIG_UMP */ + + case KBASE_CONFIG_ATTR_GPU_FREQ_KHZ_MIN: + had_gpu_freq_min = MALI_TRUE; + if (MALI_FALSE == kbasep_validate_gpu_clock_freq(kbdev, attributes)) { + /* Warning message handled by kbasep_validate_gpu_clock_freq() */ + return MALI_FALSE; + } + break; + + case KBASE_CONFIG_ATTR_GPU_FREQ_KHZ_MAX: + had_gpu_freq_max = MALI_TRUE; + if (MALI_FALSE == kbasep_validate_gpu_clock_freq(kbdev, attributes)) { + /* Warning message handled by kbasep_validate_gpu_clock_freq() */ + return MALI_FALSE; + } + break; + + /* Only non-zero unsigned 32-bit values accepted */ + case KBASE_CONFIG_ATTR_JS_SCHEDULING_TICK_NS: +#if CSTD_CPU_64BIT + if (attributes[i].data == 0u || (u64) attributes[i].data > (u64) U32_MAX) +#else + if (attributes[i].data == 0u) +#endif + { + KBASE_DEBUG_PRINT_WARN(KBASE_CORE, "Invalid Job Scheduling Configuration attribute for " "KBASE_CONFIG_ATTR_JS_SCHEDULING_TICKS_NS: %d", (int)attributes[i].data); + return MALI_FALSE; + } + break; + + /* All these Job Scheduling attributes are FALLTHROUGH: only unsigned 32-bit values accepted */ + case KBASE_CONFIG_ATTR_JS_SOFT_STOP_TICKS: + case KBASE_CONFIG_ATTR_JS_HARD_STOP_TICKS_SS: + case KBASE_CONFIG_ATTR_JS_HARD_STOP_TICKS_NSS: + case KBASE_CONFIG_ATTR_JS_RESET_TICKS_SS: + case KBASE_CONFIG_ATTR_JS_RESET_TICKS_NSS: + case KBASE_CONFIG_ATTR_JS_RESET_TIMEOUT_MS: + case KBASE_CONFIG_ATTR_JS_CTX_TIMESLICE_NS: + case KBASE_CONFIG_ATTR_JS_CFS_CTX_RUNTIME_INIT_SLICES: + case KBASE_CONFIG_ATTR_JS_CFS_CTX_RUNTIME_MIN_SLICES: +#if CSTD_CPU_64BIT + if ((u64) attributes[i].data > (u64) U32_MAX) { + KBASE_DEBUG_PRINT_WARN(KBASE_CORE, "Job Scheduling Configuration attribute exceeds 32-bits: " "id==%d val==%d", attributes[i].id, (int)attributes[i].data); + return MALI_FALSE; + } +#endif + break; + + case KBASE_CONFIG_ATTR_GPU_IRQ_THROTTLE_TIME_US: +#if CSTD_CPU_64BIT + if ((u64) attributes[i].data > (u64) U32_MAX) { + KBASE_DEBUG_PRINT_WARN(KBASE_CORE, "IRQ throttle time attribute exceeds 32-bits: " "id==%d val==%d", attributes[i].id, (int)attributes[i].data); + return MALI_FALSE; + } +#endif + break; + + case KBASE_CONFIG_ATTR_POWER_MANAGEMENT_CALLBACKS: + if (MALI_FALSE == kbasep_validate_pm_callback((kbase_pm_callback_conf *) attributes[i].data)) { + /* Warning message handled by kbasep_validate_pm_callback() */ + return MALI_FALSE; + } + break; + + case KBASE_CONFIG_ATTR_SECURE_BUT_LOSS_OF_PERFORMANCE: + if (attributes[i].data != MALI_TRUE && attributes[i].data != MALI_FALSE) { + KBASE_DEBUG_PRINT_WARN(KBASE_CORE, "Value for KBASE_CONFIG_ATTR_SECURE_BUT_LOSS_OF_PERFORMANCE was not " "MALI_TRUE or MALI_FALSE: %u", (unsigned int)attributes[i].data); + return MALI_FALSE; + } + break; + + case KBASE_CONFIG_ATTR_CPU_SPEED_FUNC: + if (MALI_FALSE == kbasep_validate_cpu_speed_func((kbase_cpuprops_clock_speed_function) attributes[i].data)) { + KBASE_DEBUG_PRINT_WARN(KBASE_CORE, "Invalid function pointer in KBASE_CONFIG_ATTR_CPU_SPEED_FUNC"); + return MALI_FALSE; + } + break; + + case KBASE_CONFIG_ATTR_GPU_SPEED_FUNC: + if (0 == attributes[i].data) { + KBASE_DEBUG_PRINT_WARN(KBASE_CORE, "Invalid function pointer in KBASE_CONFIG_ATTR_GPU_SPEED_FUNC"); + return MALI_FALSE; + } + break; + + case KBASE_CONFIG_ATTR_PLATFORM_FUNCS: + /* any value is allowed */ + break; + + case KBASE_CONFIG_ATTR_AWID_LIMIT: + case KBASE_CONFIG_ATTR_ARID_LIMIT: + if ((u32) attributes[i].data > 0x3) { + KBASE_DEBUG_PRINT_WARN(KBASE_CORE, "Invalid AWID or ARID limit"); + return MALI_FALSE; + } + break; + + case KBASE_CONFIG_ATTR_ALTERNATIVE_HWC: + if (attributes[i].data != MALI_TRUE && attributes[i].data != MALI_FALSE) { + KBASE_DEBUG_PRINT_WARN(KBASE_CORE, "Value for KBASE_CONFIG_ATTR_ALTERNATIVE_HWC was not " "MALI_TRUE or MALI_FALSE: %u", (unsigned int)attributes[i].data); + return MALI_FALSE; + } + break; + + case KBASE_CONFIG_ATTR_POWER_MANAGEMENT_DVFS_FREQ: +#if CSTD_CPU_64BIT + if ((u64) attributes[i].data > (u64) U32_MAX) { + KBASE_DEBUG_PRINT_WARN(KBASE_CORE, "PM DVFS interval exceeds 32-bits: " "id==%d val==%d", attributes[i].id, (int)attributes[i].data); + return MALI_FALSE; + } +#endif + break; + + case KBASE_CONFIG_ATTR_PM_GPU_POWEROFF_TICK_NS: +#if CSTD_CPU_64BIT + if (attributes[i].data == 0u || (u64) attributes[i].data > (u64) U32_MAX) { +#else + if (attributes[i].data == 0u) { +#endif + KBASE_DEBUG_PRINT_WARN(KBASE_CORE, "Invalid Power Manager Configuration attribute for " "KBASE_CONFIG_ATTR_PM_GPU_POWEROFF_TICK_NS: %d", (int)attributes[i].data); + return MALI_FALSE; + } + break; + + case KBASE_CONFIG_ATTR_PM_POWEROFF_TICK_SHADER: + case KBASE_CONFIG_ATTR_PM_POWEROFF_TICK_GPU: +#if CSTD_CPU_64BIT + if ((u64) attributes[i].data > (u64) U32_MAX) { + KBASE_DEBUG_PRINT_WARN(KBASE_CORE, "Power Manager Configuration attribute exceeds 32-bits: " "id==%d val==%d", attributes[i].id, (int)attributes[i].data); + return MALI_FALSE; + } +#endif + break; + + default: + KBASE_DEBUG_PRINT_WARN(KBASE_CORE, "Invalid attribute found in configuration: %d", attributes[i].id); + return MALI_FALSE; + } + } + + if (!had_gpu_freq_min) { + KBASE_DEBUG_PRINT_WARN(KBASE_CORE, "Configuration does not include mandatory attribute KBASE_CONFIG_ATTR_GPU_FREQ_KHZ_MIN"); + return MALI_FALSE; + } + + if (!had_gpu_freq_max) { + KBASE_DEBUG_PRINT_WARN(KBASE_CORE, "Configuration does not include mandatory attribute KBASE_CONFIG_ATTR_GPU_FREQ_KHZ_MAX"); + return MALI_FALSE; + } + + return MALI_TRUE; +} |