213 lines
6.5 KiB
C
213 lines
6.5 KiB
C
|
/*
|
||
|
* Copyright (C) 2010-2011 ARM Limited. All rights reserved.
|
||
|
* Copyright (C) 2011 STMicroelectronics R&D 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.
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @file mali_osk_mali.c
|
||
|
* Implementation of the OS abstraction layer which is specific for the Mali kernel device driver
|
||
|
*/
|
||
|
#include <linux/kernel.h>
|
||
|
#include <linux/platform_device.h>
|
||
|
#include <linux/stm/platform.h>
|
||
|
#include <linux/ioport.h>
|
||
|
#include <linux/string.h>
|
||
|
|
||
|
#include <asm/uaccess.h>
|
||
|
|
||
|
#include "mali_kernel_common.h" /* MALI_xxx macros */
|
||
|
#include "mali_osk.h" /* kernel side OS functions */
|
||
|
#include "mali_uk_types.h"
|
||
|
#include "mali_kernel_linux.h" /* exports initialize/terminate_kernel_device() */
|
||
|
|
||
|
extern struct platform_device *mali_platform_device;
|
||
|
|
||
|
/* Help to convert platform device resources into mali resources */
|
||
|
struct mali_resource_properties
|
||
|
{
|
||
|
const char *name;
|
||
|
_mali_osk_resource_type_t type;
|
||
|
u32 has_irq;
|
||
|
u32 mmu_id;
|
||
|
};
|
||
|
|
||
|
struct mali_resource_properties mali_resource_table[] = {
|
||
|
{ "MALI400GP", MALI400GP, 1, 1 },
|
||
|
{ "MALI400PP-0", MALI400PP, 1, 2 },
|
||
|
{ "MALI400PP-1", MALI400PP, 1, 3 },
|
||
|
{ "MALI400PP-2", MALI400PP, 1, 4 },
|
||
|
{ "MALI400PP-3", MALI400PP, 1, 5 },
|
||
|
{ "MMU-1", MMU, 1, 1 },
|
||
|
{ "MMU-2", MMU, 1, 2 },
|
||
|
{ "MMU-3", MMU, 1, 3 },
|
||
|
{ "MMU-4", MMU, 1, 4 },
|
||
|
{ "MMU-5", MMU, 1, 5 },
|
||
|
{ "MALI400L2", MALI400L2, 0, 0 },
|
||
|
{ "OS_MEMORY", OS_MEMORY, 0, 0 },
|
||
|
{ "MEMORY", MEMORY, 0, 0 },
|
||
|
{ "EXTERNAL_MEMORY_RANGE", MEM_VALIDATION, 0, 0 }
|
||
|
};
|
||
|
|
||
|
/* is called from mali_kernel_constructor in common code */
|
||
|
_mali_osk_errcode_t _mali_osk_init( void )
|
||
|
{
|
||
|
if (0 != initialize_kernel_device()) MALI_ERROR(_MALI_OSK_ERR_FAULT);
|
||
|
|
||
|
mali_osk_low_level_mem_init();
|
||
|
|
||
|
MALI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/* is called from mali_kernel_deconstructor in common code */
|
||
|
void _mali_osk_term( void )
|
||
|
{
|
||
|
mali_osk_low_level_mem_term();
|
||
|
terminate_kernel_device();
|
||
|
}
|
||
|
|
||
|
static struct mali_resource_properties *get_resource_properties(const char *name)
|
||
|
{
|
||
|
int i;
|
||
|
for(i=0;i<ARRAY_SIZE(mali_resource_table);i++)
|
||
|
{
|
||
|
if(!strcmp(mali_resource_table[i].name,name))
|
||
|
return &mali_resource_table[i];
|
||
|
}
|
||
|
|
||
|
MALI_PRINT(("Cannot find resource name %s\n", name));
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
static int mali_get_mem_resources(_mali_osk_resource_t *resources, struct stm_mali_resource *mem_resources, int num_resources, int *index)
|
||
|
{
|
||
|
int n = 0;
|
||
|
while(n < num_resources)
|
||
|
{
|
||
|
struct mali_resource_properties *properties;
|
||
|
struct stm_mali_resource *mem_resource;
|
||
|
_mali_osk_resource_t *mali_resource = &resources[*index];
|
||
|
mem_resource = &mem_resources[n];
|
||
|
if(!(properties = get_resource_properties(mem_resource->name)))
|
||
|
return _MALI_OSK_ERR_FAULT;
|
||
|
|
||
|
mali_resource->type = properties->type;
|
||
|
mali_resource->base = mem_resource->start;
|
||
|
mali_resource->size = mem_resource->end - mem_resource->start + 1;
|
||
|
|
||
|
switch(properties->type)
|
||
|
{
|
||
|
case MEMORY:
|
||
|
case OS_MEMORY:
|
||
|
mali_resource->flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE;
|
||
|
mali_resource->alloc_order = n;
|
||
|
break;
|
||
|
case MEM_VALIDATION:
|
||
|
mali_resource->flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_WRITEABLE | _MALI_PP_READABLE;
|
||
|
break;
|
||
|
default:
|
||
|
MALI_PRINT(("Resource %s should not be passed as mem_resources\n",mem_resource->name));
|
||
|
return _MALI_OSK_ERR_FAULT;
|
||
|
}
|
||
|
|
||
|
MALI_DEBUG_PRINT(3, ("Constructed resources for %s\n",mem_resource->name));
|
||
|
mali_resource->description = mem_resource->name;
|
||
|
(*index)++;
|
||
|
n++;
|
||
|
}
|
||
|
return _MALI_OSK_ERR_OK;
|
||
|
}
|
||
|
|
||
|
_mali_osk_errcode_t _mali_osk_resources_init( _mali_osk_resource_t **arch_config, u32 *num_resources )
|
||
|
{
|
||
|
struct resource *platform_resource;
|
||
|
_mali_osk_resource_t *resources;
|
||
|
int n,resource_count;
|
||
|
struct stm_mali_config *mali_config = (struct stm_mali_config *)
|
||
|
mali_platform_device->dev.platform_data;
|
||
|
|
||
|
resource_count = mali_platform_device->num_resources +
|
||
|
mali_config->num_mem_resources +
|
||
|
mali_config->num_ext_resources;
|
||
|
|
||
|
resources = kzalloc((resource_count * sizeof(_mali_osk_resource_t)),GFP_KERNEL);
|
||
|
if(!resources)
|
||
|
MALI_ERROR(_MALI_OSK_ERR_NOMEM);
|
||
|
|
||
|
resource_count = 0;
|
||
|
n = 0;
|
||
|
while((platform_resource = platform_get_resource(mali_platform_device,IORESOURCE_MEM,n)) != NULL)
|
||
|
{
|
||
|
_mali_osk_resource_t *mali_resource = &resources[resource_count];
|
||
|
struct mali_resource_properties *properties;
|
||
|
if(!(properties = get_resource_properties(platform_resource->name)))
|
||
|
goto error;
|
||
|
|
||
|
mali_resource->type = properties->type;
|
||
|
mali_resource->base = platform_resource->start;
|
||
|
mali_resource->size = 0;
|
||
|
|
||
|
switch(properties->type)
|
||
|
{
|
||
|
case MEMORY:
|
||
|
case OS_MEMORY:
|
||
|
case MEM_VALIDATION:
|
||
|
MALI_PRINT(("Mali Memory resource %s should be passed in platfrom priv data not IORESOURCE_MEM\n",platform_resource->name));
|
||
|
goto error;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
mali_resource->mmu_id = properties->mmu_id;
|
||
|
if(properties->has_irq)
|
||
|
{
|
||
|
int irq;
|
||
|
MALI_DEBUG_PRINT(3, ("finding IRQ for %s\n",platform_resource->name));
|
||
|
if((irq = platform_get_irq_byname(mali_platform_device,platform_resource->name)) < 0)
|
||
|
{
|
||
|
MALI_PRINT(("Unable to find IRQ resource for %s\n",platform_resource->name));
|
||
|
goto error;
|
||
|
}
|
||
|
MALI_DEBUG_PRINT(3, ("found IRQ %d for %s\n",irq,platform_resource->name));
|
||
|
mali_resource->irq = irq;
|
||
|
}
|
||
|
|
||
|
MALI_DEBUG_PRINT(3, ("Constructed resources for %s\n",platform_resource->name));
|
||
|
mali_resource->description = platform_resource->name;
|
||
|
resource_count++;
|
||
|
n++;
|
||
|
}
|
||
|
|
||
|
/* Memory resources */
|
||
|
/* Memory resources allocated by Linux kernel and Memory managed by
|
||
|
* mali driver memory allocator */
|
||
|
if (mali_config->mem)
|
||
|
mali_get_mem_resources(resources, mali_config->mem,
|
||
|
mali_config->num_mem_resources, &resource_count);
|
||
|
|
||
|
/* External memory regions for mali to directly render */
|
||
|
if (mali_config->ext_mem)
|
||
|
mali_get_mem_resources(resources, mali_config->ext_mem,
|
||
|
mali_config->num_ext_resources, &resource_count);
|
||
|
|
||
|
*num_resources = resource_count;
|
||
|
*arch_config = resources;
|
||
|
return _MALI_OSK_ERR_OK;
|
||
|
|
||
|
error:
|
||
|
kfree(resources);
|
||
|
*arch_config = NULL;
|
||
|
MALI_ERROR(_MALI_OSK_ERR_FAULT);
|
||
|
}
|
||
|
|
||
|
void _mali_osk_resources_term( _mali_osk_resource_t **arch_config, u32 num_resources )
|
||
|
{
|
||
|
kfree(*arch_config);
|
||
|
}
|