Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(68)

Side by Side Diff: arch/arm/mach-tegra/nv/include/mach/iovmm.h

Issue 3256004: [ARM] tegra: add nvos/nvrm/nvmap drivers (Closed) Base URL: ssh://git@gitrw.chromium.org/kernel.git
Patch Set: remove ap15 headers Created 10 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * arch/arm/mach-tegra/include/mach/iovmm.h
3 *
4 * Copyright (c) 2010, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed i the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21 #include <linux/list.h>
22 #include <linux/platform_device.h>
23 #include <linux/rbtree.h>
24 #include <linux/rwsem.h>
25 #include <linux/spinlock.h>
26 #include <linux/types.h>
27
28 #ifndef _MACH_TEGRA_IOVMM_H_
29 #define _MACH_TEGRA_IOVMM_H_
30
31 #if defined(CONFIG_ARCH_TEGRA_1x_SOC) || defined(CONFIG_ARCH_TEGRA_2x_SOC)
32 typedef u32 tegra_iovmm_addr_t;
33 #else
34 #error "Unsupported tegra architecture family"
35 #endif
36
37 struct tegra_iovmm_device_ops;
38
39 /* each I/O virtual memory manager unit should register a device with
40 * the iovmm system
41 */
42 struct tegra_iovmm_device {
43 struct tegra_iovmm_device_ops *ops;
44 const char *name;
45 struct list_head list;
46 int pgsize_bits;
47 };
48
49 /* tegra_iovmm_domain serves a purpose analagous to mm_struct as defined in
50 * <linux/mm_types.h> - it defines a virtual address space within which
51 * tegra_iovmm_areas can be created.
52 */
53 struct tegra_iovmm_domain {
54 atomic_t clients;
55 atomic_t locks;
56 spinlock_t block_lock;
57 unsigned long flags;
58 wait_queue_head_t delay_lock; /* when lock_client fails */
59 struct rw_semaphore map_lock;
60 struct rb_root all_blocks; /* ordered by address */
61 struct rb_root free_blocks; /* ordered by size */
62 struct tegra_iovmm_device *dev;
63 };
64
65 /* tegra_iovmm_client is analagous to an individual task in the task group
66 * which owns an mm_struct.
67 */
68
69 struct iovmm_share_group;
70
71 struct tegra_iovmm_client {
72 const char *name;
73 unsigned long flags;
74 struct iovmm_share_group *group;
75 struct tegra_iovmm_domain *domain;
76 struct list_head list;
77 };
78
79 /* tegra_iovmm_area serves a purpose analagous to vm_area_struct as defined
80 * in <linux/mm_types.h> - it defines a virtual memory area which can be
81 * mapped to physical memory by a client-provided mapping function. */
82
83 struct tegra_iovmm_area {
84 struct tegra_iovmm_domain *domain;
85 tegra_iovmm_addr_t iovm_start;
86 tegra_iovmm_addr_t iovm_length;
87 pgprot_t pgprot;
88 struct tegra_iovmm_area_ops *ops;
89 };
90
91 struct tegra_iovmm_device_ops {
92 /* maps a VMA using the page residency functions provided by the VMA */
93 int (*map)(struct tegra_iovmm_device *dev,
94 struct tegra_iovmm_area *io_vma);
95 /* marks all PTEs in a VMA as invalid; decommits the virtual addres
96 * space (potentially freeing PDEs when decommit is true.) */
97 void (*unmap)(struct tegra_iovmm_device *dev,
98 struct tegra_iovmm_area *io_vma, bool decommit);
99 void (*map_pfn)(struct tegra_iovmm_device *dev,
100 struct tegra_iovmm_area *io_vma,
101 tegra_iovmm_addr_t offs, unsigned long pfn);
102 /* ensures that a domain is resident in the hardware's mapping region
103 * so that it may be used by a client */
104 int (*lock_domain)(struct tegra_iovmm_device *dev,
105 struct tegra_iovmm_domain *domain);
106 void (*unlock_domain)(struct tegra_iovmm_device *dev,
107 struct tegra_iovmm_domain *domain);
108 /* allocates a vmm_domain for the specified client; may return the same
109 * domain for multiple clients */
110 struct tegra_iovmm_domain* (*alloc_domain)(
111 struct tegra_iovmm_device *dev,
112 struct tegra_iovmm_client *client);
113 void (*free_domain)(struct tegra_iovmm_device *dev,
114 struct tegra_iovmm_domain *domain);
115 };
116
117 struct tegra_iovmm_area_ops {
118 /* ensures that the page of data starting at the specified offset
119 * from the start of the iovma is resident and pinned for use by
120 * DMA, returns the system pfn, or an invalid pfn if the
121 * operation fails. */
122 unsigned long (*lock_makeresident)(struct tegra_iovmm_area *area,
123 tegra_iovmm_addr_t offs);
124 /* called when the page is unmapped from the I/O VMA */
125 void (*release)(struct tegra_iovmm_area *area, tegra_iovmm_addr_t offs);
126 };
127
128 #ifdef CONFIG_TEGRA_IOVMM
129 /* called by clients to allocate an I/O VMM client mapping context which
130 * will be shared by all clients in the same share_group */
131 struct tegra_iovmm_client *tegra_iovmm_alloc_client(const char *name,
132 const char *share_group);
133
134 size_t tegra_iovmm_get_vm_size(struct tegra_iovmm_client *client);
135
136 void tegra_iovmm_free_client(struct tegra_iovmm_client *client);
137
138 /* called by clients to ensure that their mapping context is resident
139 * before performing any DMA operations addressing I/O VMM regions.
140 * client_lock may return -EINTR. */
141 int tegra_iovmm_client_lock(struct tegra_iovmm_client *client);
142 int tegra_iovmm_client_trylock(struct tegra_iovmm_client *client);
143
144 /* called by clients after DMA operations are complete */
145 void tegra_iovmm_client_unlock(struct tegra_iovmm_client *client);
146
147 /* called by clients to allocate a new iovmm_area and reserve I/O virtual
148 * address space for it. if ops is NULL, clients should subsequently call
149 * tegra_iovmm_vm_map_pages and/or tegra_iovmm_vm_insert_pfn to explicitly
150 * map the I/O virtual address to an OS-allocated page or physical address,
151 * respectively. VM operations may be called before this call returns */
152 struct tegra_iovmm_area *tegra_iovmm_create_vm(
153 struct tegra_iovmm_client *client, struct tegra_iovmm_area_ops *ops,
154 unsigned long size, pgprot_t pgprot);
155
156 /* called by clients to "zap" an iovmm_area, and replace all mappings
157 * in it with invalid ones, without freeing the virtual address range */
158 void tegra_iovmm_zap_vm(struct tegra_iovmm_area *vm);
159
160 /* after zapping a demand-loaded iovmm_area, the client should unzap it
161 * to allow the VMM device to remap the page range. */
162 void tegra_iovmm_unzap_vm(struct tegra_iovmm_area *vm);
163
164 /* called by clients to return an iovmm_area to the free pool for the domain */
165 void tegra_iovmm_free_vm(struct tegra_iovmm_area *vm);
166
167 /* called by client software to map the page-aligned I/O address vaddr to
168 * a specific physical address pfn. I/O VMA should have been created with
169 * a NULL tegra_iovmm_area_ops structure. */
170 void tegra_iovmm_vm_insert_pfn(struct tegra_iovmm_area *area,
171 tegra_iovmm_addr_t vaddr, unsigned long pfn);
172
173 /* called by clients to return the iovmm_area containing addr, or NULL if
174 * addr has not been allocated. caller should call tegra_iovmm_put_area when
175 * finished using the returned pointer */
176 struct tegra_iovmm_area *tegra_iovmm_find_area_get(
177 struct tegra_iovmm_client *client, tegra_iovmm_addr_t addr);
178
179 struct tegra_iovmm_area *tegra_iovmm_area_get(struct tegra_iovmm_area *vm);
180 void tegra_iovmm_area_put(struct tegra_iovmm_area *vm);
181
182 /* called by drivers to initialize a tegra_iovmm_domain structure */
183 int tegra_iovmm_domain_init(struct tegra_iovmm_domain *domain,
184 struct tegra_iovmm_device *dev, tegra_iovmm_addr_t start,
185 tegra_iovmm_addr_t end);
186
187 /* called by drivers to register an I/O VMM device with the system */
188 int tegra_iovmm_register(struct tegra_iovmm_device *dev);
189
190 /* called by drivers to remove an I/O VMM device from the system */
191 int tegra_iovmm_unregister(struct tegra_iovmm_device *dev);
192
193
194
195 #else /* CONFIG_TEGRA_IOVMM */
196
197 static inline struct tegra_iovmm_client *tegra_iovmm_alloc_client(
198 const char *name, const char *share_group)
199 {
200 return NULL;
201 }
202
203 static inline size_t tegra_iovmm_get_vm_size(struct tegra_iovmm_client *client)
204 {
205 return 0;
206 }
207
208 static inline void tegra_iovmm_free_client(struct tegra_iovmm_client *client)
209 {}
210
211 static inline int tegra_iovmm_client_lock(struct tegra_iovmm_client *client)
212 {
213 return 0;
214 }
215
216 static inline int tegra_iovmm_client_trylock(struct tegra_iovmm_client *client)
217 {
218 return 0;
219 }
220
221 static inline void tegra_iovmm_client_unlock(struct tegra_iovmm_client *client)
222 {}
223
224 static inline struct tegra_iovmm_area *tegra_iovmm_create_vm(
225 struct tegra_iovmm_client *client, struct tegra_iovmm_area_ops *ops,
226 unsigned long size, pgprot_t pgprot)
227 {
228 return NULL;
229 }
230
231 static inline void tegra_iovmm_zap_vm(struct tegra_iovmm_area *vm) { }
232
233 static inline void tegra_iovmm_unzap_vm(struct tegra_iovmm_area *vm) { }
234
235 static inline void tegra_iovmm_free_vm(struct tegra_iovmm_area *vm) { }
236
237 static inline void tegra_iovmm_vm_insert_pfn(struct tegra_iovmm_area *area,
238 tegra_iovmm_addr_t vaddr, unsigned long pfn) { }
239
240 static inline struct tegra_iovmm_area *tegra_iovmm_find_area_get(
241 struct tegra_iovmm_client *client, tegra_iovmm_addr_t addr)
242 {
243 return NULL;
244 }
245
246 static inline struct tegra_iovmm_area *tegra_iovmm_area_get(
247 struct tegra_iovmm_area *vm)
248 {
249 return NULL;
250 }
251
252 static inline void tegra_iovmm_area_put(struct tegra_iovmm_area *vm) { }
253
254 static inline int tegra_iovmm_domain_init(struct tegra_iovmm_domain *domain,
255 struct tegra_iovmm_device *dev, tegra_iovmm_addr_t start,
256 tegra_iovmm_addr_t end)
257 {
258 return 0;
259 }
260
261 static inline int tegra_iovmm_register(struct tegra_iovmm_device *dev)
262 {
263 return 0;
264 }
265
266 static inline int tegra_iovmm_unregister(struct tegra_iovmm_device *dev)
267 {
268 return 0;
269 }
270 #endif /* CONFIG_TEGRA_IOVMM */
271
272
273 #endif
OLDNEW
« no previous file with comments | « arch/arm/mach-tegra/nv/include/linux/nvos_ioctl.h ('k') | arch/arm/mach-tegra/nv/include/mach/nvrm_linux.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698