summaryrefslogtreecommitdiff
path: root/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/platform/ux500/ump_kernel_api_hwmem.c
blob: b321b504839c5ee9fe0e78386ca9de00881b7fd9 (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
153
154
155
156
157
158
159
/*
 * Copyright (C) ST-Ericsson SA 2011
 * Author: Magnus Wendt <magnus.wendt@stericsson.com> for
 * ST-Ericsson.
 * License terms: GNU General Public License (GPL), version 2.
 */

#include "ump_kernel_types.h"
#include "mali_kernel_common.h"

#include <linux/hwmem.h>
#include <linux/err.h>


/* The UMP kernel API for hwmem has been mapped so that
 * ump_dd_handle == hwmem_alloc
 * ump_secure_id == hwmem global name
 *
 * The current implementation is limited to contiguous memory
 */

ump_secure_id ump_dd_secure_id_get(ump_dd_handle memh)
{
	int hwmem_name = hwmem_get_name((struct hwmem_alloc *) memh);

	if (unlikely(hwmem_name < 0)) {
		MALI_DEBUG_PRINT(1, ("%s: Invalid Alloc 0x%x\n",__func__, memh));
		return UMP_INVALID_SECURE_ID;
	}

	return (ump_secure_id)hwmem_name;
}



ump_dd_handle ump_dd_handle_create_from_secure_id(ump_secure_id secure_id)
{
	struct hwmem_alloc *alloc;
	enum hwmem_mem_type mem_type;
	enum hwmem_access access;

	alloc = hwmem_resolve_by_name((int) secure_id);

	if (IS_ERR(alloc)) {
		MALI_DEBUG_PRINT(1, ("%s: Invalid UMP id %d\n",__func__, secure_id));
		return UMP_DD_HANDLE_INVALID;
	}

	hwmem_get_info(alloc, NULL, &mem_type, &access);

	if (unlikely((access & (HWMEM_ACCESS_READ | HWMEM_ACCESS_WRITE | HWMEM_ACCESS_IMPORT)) !=
	                       (HWMEM_ACCESS_READ | HWMEM_ACCESS_WRITE | HWMEM_ACCESS_IMPORT))) {
		MALI_DEBUG_PRINT(1, ("%s: Access denied on UMP id %d, (access==%d)\n",
			__func__, secure_id, access));
		hwmem_release(alloc);
		return UMP_DD_HANDLE_INVALID;
	}

	if (unlikely(HWMEM_MEM_CONTIGUOUS_SYS != mem_type)) {
		MALI_DEBUG_PRINT(1, ("%s: UMP id %d is non-contiguous! (not supported)\n",
			__func__, secure_id));
		hwmem_release(alloc);
		return UMP_DD_HANDLE_INVALID;
	}

	return (ump_dd_handle)alloc;
}



unsigned long ump_dd_phys_block_count_get(ump_dd_handle memh)
{
	return 1;
}



ump_dd_status_code ump_dd_phys_blocks_get(ump_dd_handle memh,
                                          ump_dd_physical_block * blocks,
                                          unsigned long num_blocks)
{
	struct hwmem_mem_chunk hwmem_mem_chunk;
	size_t hwmem_mem_chunk_length = 1;

	int hwmem_result;
	struct hwmem_alloc *alloc = (struct hwmem_alloc *)memh;

	if (unlikely(blocks == NULL)) {
		MALI_DEBUG_PRINT(1, ("%s: blocks == NULL\n",__func__));
		return UMP_DD_INVALID;
	}

	if (unlikely(1 != num_blocks)) {
		MALI_DEBUG_PRINT(1, ("%s: num_blocks == %d (!= 1)\n",__func__, num_blocks));
		return UMP_DD_INVALID;
	}

	MALI_DEBUG_PRINT(5, ("Returning physical block information. Alloc: 0x%x\n", memh));

	/* It might not look natural to pin here, but it matches the usage by the mali kernel module */
	hwmem_result = hwmem_pin(alloc, &hwmem_mem_chunk, &hwmem_mem_chunk_length);

	if (unlikely(hwmem_result < 0)) {
		MALI_DEBUG_PRINT(1, ("%s: Pin failed. Alloc: 0x%x\n",__func__, memh));
		return UMP_DD_INVALID;
	}

	blocks[0].addr = hwmem_mem_chunk.paddr;
	blocks[0].size = hwmem_mem_chunk.size;

	hwmem_set_domain(alloc, HWMEM_ACCESS_READ | HWMEM_ACCESS_WRITE,
		HWMEM_DOMAIN_SYNC, NULL);

	return UMP_DD_SUCCESS;
}



ump_dd_status_code ump_dd_phys_block_get(ump_dd_handle memh,
                                         unsigned long index,
                                         ump_dd_physical_block * block)
{
	if (unlikely(0 != index))	{
		MALI_DEBUG_PRINT(1, ("%s: index == %d (!= 0)\n",__func__, index));
		return UMP_DD_INVALID;
	}
	return ump_dd_phys_blocks_get(memh, block, 1);
}



unsigned long ump_dd_size_get(ump_dd_handle memh)
{
	struct hwmem_alloc *alloc = (struct hwmem_alloc *)memh;
	int size;

	hwmem_get_info(alloc, &size, NULL, NULL);

	return size;
}



void ump_dd_reference_add(ump_dd_handle memh)
{
	/* This is never called from tha mali kernel driver */
}



void ump_dd_reference_release(ump_dd_handle memh)
{
	struct hwmem_alloc *alloc = (struct hwmem_alloc *)memh;

	hwmem_unpin(alloc);
	hwmem_release(alloc);

	return;
}