import OT_8063_20170412 mali driver
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / gpu / mt8127 / mali / ump / common / ump_kernel_descriptor_mapping.c
CommitLineData
6fa3eb70
S
1/*
2 * This confidential and proprietary software may be used only as
3 * authorised by a licensing agreement from ARM Limited
bdc132d7 4 * (C) COPYRIGHT 2008-2011, 2013-2015 ARM Limited
6fa3eb70
S
5 * ALL RIGHTS RESERVED
6 * The entire notice above must be reproduced on all authorised
7 * copies and copies may only be made to the extent permitted
8 * by a licensing agreement from ARM Limited.
9 */
10
11#include "mali_kernel_common.h"
12#include "mali_osk.h"
13#include "mali_osk_bitops.h"
14#include "ump_kernel_common.h"
15#include "ump_kernel_descriptor_mapping.h"
16
17#define MALI_PAD_INT(x) (((x) + (BITS_PER_LONG - 1)) & ~(BITS_PER_LONG - 1))
18
19/**
20 * Allocate a descriptor table capable of holding 'count' mappings
21 * @param count Number of mappings in the table
22 * @return Pointer to a new table, NULL on error
23 */
bdc132d7 24static ump_descriptor_table *descriptor_table_alloc(int count);
6fa3eb70
S
25
26/**
27 * Free a descriptor table
28 * @param table The table to free
29 */
bdc132d7 30static void descriptor_table_free(ump_descriptor_table *table);
6fa3eb70 31
bdc132d7 32ump_descriptor_mapping *ump_descriptor_mapping_create(int init_entries, int max_entries)
6fa3eb70 33{
bdc132d7 34 ump_descriptor_mapping *map = _mali_osk_calloc(1, sizeof(ump_descriptor_mapping));
6fa3eb70
S
35
36 init_entries = MALI_PAD_INT(init_entries);
37 max_entries = MALI_PAD_INT(max_entries);
38
39 if (NULL != map) {
40 map->table = descriptor_table_alloc(init_entries);
41 if (NULL != map->table) {
42 map->lock = _mali_osk_mutex_rw_init(_MALI_OSK_LOCKFLAG_UNORDERED, 0);
bdc132d7 43 if (NULL != map->lock) {
6fa3eb70
S
44 _mali_osk_set_nonatomic_bit(0, map->table->usage); /* reserve bit 0 to prevent NULL/zero logic to kick in */
45 map->max_nr_mappings_allowed = max_entries;
46 map->current_nr_mappings = init_entries;
47 return map;
48 }
49 descriptor_table_free(map->table);
50 }
51 _mali_osk_free(map);
52 }
53 return NULL;
54}
55
bdc132d7 56void ump_descriptor_mapping_destroy(ump_descriptor_mapping *map)
6fa3eb70
S
57{
58 descriptor_table_free(map->table);
59 _mali_osk_mutex_rw_term(map->lock);
60 _mali_osk_free(map);
61}
62
bdc132d7 63int ump_descriptor_mapping_allocate_mapping(ump_descriptor_mapping *map, void *target)
6fa3eb70
S
64{
65 int descriptor = -1;/*-EFAULT;*/
66 _mali_osk_mutex_rw_wait(map->lock, _MALI_OSK_LOCKMODE_RW);
67 descriptor = _mali_osk_find_first_zero_bit(map->table->usage, map->current_nr_mappings);
68 if (descriptor == map->current_nr_mappings) {
69 int nr_mappings_new;
70 /* no free descriptor, try to expand the table */
bdc132d7
S
71 ump_descriptor_table *new_table;
72 ump_descriptor_table *old_table = map->table;
73 nr_mappings_new = map->current_nr_mappings * 2;
6fa3eb70
S
74
75 if (map->current_nr_mappings >= map->max_nr_mappings_allowed) {
76 descriptor = -1;
77 goto unlock_and_exit;
78 }
79
80 new_table = descriptor_table_alloc(nr_mappings_new);
81 if (NULL == new_table) {
82 descriptor = -1;
83 goto unlock_and_exit;
84 }
85
86 _mali_osk_memcpy(new_table->usage, old_table->usage, (sizeof(unsigned long)*map->current_nr_mappings) / BITS_PER_LONG);
bdc132d7 87 _mali_osk_memcpy(new_table->mappings, old_table->mappings, map->current_nr_mappings * sizeof(void *));
6fa3eb70
S
88 map->table = new_table;
89 map->current_nr_mappings = nr_mappings_new;
90 descriptor_table_free(old_table);
91 }
92
93 /* we have found a valid descriptor, set the value and usage bit */
94 _mali_osk_set_nonatomic_bit(descriptor, map->table->usage);
95 map->table->mappings[descriptor] = target;
96
97unlock_and_exit:
98 _mali_osk_mutex_rw_signal(map->lock, _MALI_OSK_LOCKMODE_RW);
99 return descriptor;
100}
101
bdc132d7 102int ump_descriptor_mapping_get(ump_descriptor_mapping *map, int descriptor, void **target)
6fa3eb70
S
103{
104 int result = -1;/*-EFAULT;*/
105 DEBUG_ASSERT(map);
106 _mali_osk_mutex_rw_wait(map->lock, _MALI_OSK_LOCKMODE_RO);
107 if ((descriptor > 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage)) {
108 *target = map->table->mappings[descriptor];
109 result = 0;
110 } else *target = NULL;
111 _mali_osk_mutex_rw_signal(map->lock, _MALI_OSK_LOCKMODE_RO);
112 return result;
113}
114
bdc132d7 115int ump_descriptor_mapping_set(ump_descriptor_mapping *map, int descriptor, void *target)
6fa3eb70
S
116{
117 int result = -1;/*-EFAULT;*/
118 _mali_osk_mutex_rw_wait(map->lock, _MALI_OSK_LOCKMODE_RO);
119 if ((descriptor > 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage)) {
120 map->table->mappings[descriptor] = target;
121 result = 0;
122 }
123 _mali_osk_mutex_rw_signal(map->lock, _MALI_OSK_LOCKMODE_RO);
124 return result;
125}
126
bdc132d7 127void ump_descriptor_mapping_free(ump_descriptor_mapping *map, int descriptor)
6fa3eb70
S
128{
129 _mali_osk_mutex_rw_wait(map->lock, _MALI_OSK_LOCKMODE_RW);
130 if ((descriptor > 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage)) {
131 map->table->mappings[descriptor] = NULL;
132 _mali_osk_clear_nonatomic_bit(descriptor, map->table->usage);
133 }
134 _mali_osk_mutex_rw_signal(map->lock, _MALI_OSK_LOCKMODE_RW);
135}
136
bdc132d7 137static ump_descriptor_table *descriptor_table_alloc(int count)
6fa3eb70 138{
bdc132d7 139 ump_descriptor_table *table;
6fa3eb70 140
bdc132d7 141 table = _mali_osk_calloc(1, sizeof(ump_descriptor_table) + ((sizeof(unsigned long) * count) / BITS_PER_LONG) + (sizeof(void *) * count));
6fa3eb70
S
142
143 if (NULL != table) {
bdc132d7
S
144 table->usage = (u32 *)((u8 *)table + sizeof(ump_descriptor_table));
145 table->mappings = (void **)((u8 *)table + sizeof(ump_descriptor_table) + ((sizeof(unsigned long) * count) / BITS_PER_LONG));
6fa3eb70
S
146 }
147
148 return table;
149}
150
bdc132d7 151static void descriptor_table_free(ump_descriptor_table *table)
6fa3eb70
S
152{
153 _mali_osk_free(table);
154}
155