aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_memory_engine.h
blob: 3b41cee4a12d7cfc915cc7a8ac6b1ab43c87e09e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*
 * Copyright (C) 2010-2012 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.
 */

#ifndef __MALI_KERNEL_MEMORY_ENGINE_H__
#define  __MALI_KERNEL_MEMORY_ENGINE_H__

typedef void * mali_allocation_engine;

typedef enum { MALI_MEM_ALLOC_FINISHED, MALI_MEM_ALLOC_PARTIAL, MALI_MEM_ALLOC_NONE, MALI_MEM_ALLOC_INTERNAL_FAILURE } mali_physical_memory_allocation_result;

typedef struct mali_physical_memory_allocation
{
	void (*release)(void * ctx, void * handle); /**< Function to call on to release the physical memory */
	void * ctx;
	void * handle;
	struct mali_physical_memory_allocation * next;
} mali_physical_memory_allocation;

struct mali_page_table_block;

typedef struct mali_page_table_block
{
	void (*release)(struct mali_page_table_block *page_table_block);
	void * ctx;
	void * handle;
	u32 size; /**< In bytes, should be a multiple of MALI_MMU_PAGE_SIZE to avoid internal fragementation */
	u32 phys_base; /**< Mali physical address */
	mali_io_address mapping;
} mali_page_table_block;


/** @addtogroup _mali_osk_low_level_memory
 * @{ */

typedef enum
{
	MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE = 0x1,
	MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE     = 0x2,
} mali_memory_allocation_flag;

/**
 * Supplying this 'magic' physical address requests that the OS allocate the
 * physical address at page commit time, rather than committing a specific page
 */
#define MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC ((u32)(-1))

typedef struct mali_memory_allocation
{
	/* Information about the allocation */
	void * mapping; /**< CPU virtual address where the memory is mapped at */
	u32 mali_address; /**< The Mali seen address of the memory allocation */
	u32 size; /**< Size of the allocation */
	u32 permission; /**< Permission settings */
	mali_memory_allocation_flag flags;
	u32 cache_settings; /* type: mali_memory_cache_settings, found in <linux/mali/mali_utgard_uk_types.h> Ump DD breaks if we include it...*/

	_mali_osk_lock_t * lock;

	/* Manager specific information pointers */
	void * mali_addr_mapping_info; /**< Mali address allocation specific info */
	void * process_addr_mapping_info; /**< Mapping manager specific info */

	mali_physical_memory_allocation physical_allocation;

	_mali_osk_list_t list; /**< List for linking together memory allocations into the session's memory head */
} mali_memory_allocation;
/** @} */ /* end group _mali_osk_low_level_memory */


typedef struct mali_physical_memory_allocator
{
	mali_physical_memory_allocation_result (*allocate)(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info);
	mali_physical_memory_allocation_result (*allocate_page_table_block)(void * ctx, mali_page_table_block * block); /* MALI_MEM_ALLOC_PARTIAL not allowed */
	void (*destroy)(struct mali_physical_memory_allocator * allocator);
	u32 (*stat)(struct mali_physical_memory_allocator * allocator);
	void * ctx;
	const char * name; /**< Descriptive name for use in mali_allocation_engine_report_allocators, or NULL */
	u32 alloc_order; /**< Order in which the allocations should happen */
	struct mali_physical_memory_allocator * next;
} mali_physical_memory_allocator;

typedef struct mali_kernel_mem_address_manager
{
	_mali_osk_errcode_t (*allocate)(mali_memory_allocation *); /**< Function to call to reserve an address */
	void (*release)(mali_memory_allocation *); /**< Function to call to free the address allocated */

	 /**
	  * Function called for each physical sub allocation.
	  * Called for each physical block allocated by the physical memory manager.
	  * @param[in] descriptor The memory descriptor in question
	  * @param[in] off Offset from the start of range
	  * @param[in,out] phys_addr A pointer to the physical address of the start of the
	  * physical block. When *phys_addr == MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC
	  * is used, this requests the function to allocate the physical page
	  * itself, and return it through the pointer provided.
	  * @param[in] size Length in bytes of the physical block
	  * @return _MALI_OSK_ERR_OK on success.
	  * A value of type _mali_osk_errcode_t other than _MALI_OSK_ERR_OK indicates failure.
	  * Specifically, _MALI_OSK_ERR_UNSUPPORTED indicates that the function
	  * does not support allocating physical pages itself.
	  */
	 _mali_osk_errcode_t (*map_physical)(mali_memory_allocation * descriptor, u32 offset, u32 *phys_addr, u32 size);

	 /**
	  * Function called to remove a physical sub allocation.
	  * Called on error paths where one of the address managers fails.
	  *
	  * @note this is optional. For address managers where this is not
	  * implemented, the value of this member is NULL. The memory engine
	  * currently does not require the mali address manager to be able to
	  * unmap individual pages, but the process address manager must have this
	  * capability.
	  *
	  * @param[in] descriptor The memory descriptor in question
	  * @param[in] off Offset from the start of range
	  * @param[in] size Length in bytes of the physical block
	  * @param[in] flags flags to use on a per-page basis. For OS-allocated
	  * physical pages, this must include _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR.
	  * @return _MALI_OSK_ERR_OK on success.
	  * A value of type _mali_osk_errcode_t other than _MALI_OSK_ERR_OK indicates failure.
	  */
	void (*unmap_physical)(mali_memory_allocation * descriptor, u32 offset, u32 size, _mali_osk_mem_mapregion_flags_t flags);

} mali_kernel_mem_address_manager;

mali_allocation_engine mali_allocation_engine_create(mali_kernel_mem_address_manager * mali_address_manager, mali_kernel_mem_address_manager * process_address_manager);

void mali_allocation_engine_destroy(mali_allocation_engine engine);

int mali_allocation_engine_allocate_memory(mali_allocation_engine engine, mali_memory_allocation * descriptor, mali_physical_memory_allocator * physical_provider, _mali_osk_list_t *tracking_list );
void mali_allocation_engine_release_memory(mali_allocation_engine engine, mali_memory_allocation * descriptor);

void mali_allocation_engine_release_pt1_mali_pagetables_unmap(mali_allocation_engine engine, mali_memory_allocation * descriptor);
void mali_allocation_engine_release_pt2_physical_memory_free(mali_allocation_engine engine, mali_memory_allocation * descriptor);

int mali_allocation_engine_map_physical(mali_allocation_engine engine, mali_memory_allocation * descriptor, u32 offset, u32 phys, u32 cpu_usage_adjust, u32 size);
void mali_allocation_engine_unmap_physical(mali_allocation_engine engine, mali_memory_allocation * descriptor, u32 offset, u32 size, _mali_osk_mem_mapregion_flags_t unmap_flags);

int mali_allocation_engine_allocate_page_tables(mali_allocation_engine, mali_page_table_block * descriptor, mali_physical_memory_allocator * physical_provider);

void mali_allocation_engine_report_allocators(mali_physical_memory_allocator * physical_provider);

u32 mali_allocation_engine_memory_usage(mali_physical_memory_allocator *allocator);

#endif /* __MALI_KERNEL_MEMORY_ENGINE_H__ */