Lines Matching +full:data +full:- +full:mapping

1 // SPDX-License-Identifier: GPL-2.0-only
17 struct tegra_drm_mapping *mapping = in tegra_drm_mapping_release() local
20 host1x_bo_unpin(mapping->map); in tegra_drm_mapping_release()
21 host1x_bo_put(mapping->bo); in tegra_drm_mapping_release()
23 kfree(mapping); in tegra_drm_mapping_release()
26 void tegra_drm_mapping_put(struct tegra_drm_mapping *mapping) in tegra_drm_mapping_put() argument
28 kref_put(&mapping->ref, tegra_drm_mapping_release); in tegra_drm_mapping_put()
33 struct tegra_drm_mapping *mapping; in tegra_drm_channel_context_close() local
36 if (context->memory_context) in tegra_drm_channel_context_close()
37 host1x_memory_context_put(context->memory_context); in tegra_drm_channel_context_close()
39 xa_for_each(&context->mappings, id, mapping) in tegra_drm_channel_context_close()
40 tegra_drm_mapping_put(mapping); in tegra_drm_channel_context_close()
42 xa_destroy(&context->mappings); in tegra_drm_channel_context_close()
44 host1x_channel_put(context->channel); in tegra_drm_channel_context_close()
55 xa_for_each(&file->contexts, id, context) in tegra_drm_uapi_close_file()
58 xa_for_each(&file->syncpoints, id, sp) in tegra_drm_uapi_close_file()
61 xa_destroy(&file->contexts); in tegra_drm_uapi_close_file()
62 xa_destroy(&file->syncpoints); in tegra_drm_uapi_close_file()
69 list_for_each_entry(client, &tegra->clients, list) in tegra_drm_find_client()
70 if (client->base.class == class) in tegra_drm_find_client()
76 int tegra_drm_ioctl_channel_open(struct drm_device *drm, void *data, struct drm_file *file) in tegra_drm_ioctl_channel_open() argument
78 struct host1x *host = tegra_drm_to_host1x(drm->dev_private); in tegra_drm_ioctl_channel_open()
79 struct tegra_drm_file *fpriv = file->driver_priv; in tegra_drm_ioctl_channel_open()
80 struct tegra_drm *tegra = drm->dev_private; in tegra_drm_ioctl_channel_open()
81 struct drm_tegra_channel_open *args = data; in tegra_drm_ioctl_channel_open()
86 if (args->flags) in tegra_drm_ioctl_channel_open()
87 return -EINVAL; in tegra_drm_ioctl_channel_open()
91 return -ENOMEM; in tegra_drm_ioctl_channel_open()
93 client = tegra_drm_find_client(tegra, args->host1x_class); in tegra_drm_ioctl_channel_open()
95 err = -ENODEV; in tegra_drm_ioctl_channel_open()
99 if (client->shared_channel) { in tegra_drm_ioctl_channel_open()
100 context->channel = host1x_channel_get(client->shared_channel); in tegra_drm_ioctl_channel_open()
102 context->channel = host1x_channel_request(&client->base); in tegra_drm_ioctl_channel_open()
103 if (!context->channel) { in tegra_drm_ioctl_channel_open()
104 err = -EBUSY; in tegra_drm_ioctl_channel_open()
110 if (device_iommu_mapped(client->base.dev) && client->ops->can_use_memory_ctx) { in tegra_drm_ioctl_channel_open()
113 err = client->ops->can_use_memory_ctx(client, &supported); in tegra_drm_ioctl_channel_open()
118 context->memory_context = host1x_memory_context_alloc( in tegra_drm_ioctl_channel_open()
119 host, client->base.dev, get_task_pid(current, PIDTYPE_TGID)); in tegra_drm_ioctl_channel_open()
121 if (IS_ERR(context->memory_context)) { in tegra_drm_ioctl_channel_open()
122 if (PTR_ERR(context->memory_context) != -EOPNOTSUPP) { in tegra_drm_ioctl_channel_open()
123 err = PTR_ERR(context->memory_context); in tegra_drm_ioctl_channel_open()
130 context->memory_context = NULL; in tegra_drm_ioctl_channel_open()
135 err = xa_alloc(&fpriv->contexts, &args->context, context, XA_LIMIT(1, U32_MAX), in tegra_drm_ioctl_channel_open()
140 context->client = client; in tegra_drm_ioctl_channel_open()
141 xa_init_flags(&context->mappings, XA_FLAGS_ALLOC1); in tegra_drm_ioctl_channel_open()
143 args->version = client->version; in tegra_drm_ioctl_channel_open()
144 args->capabilities = 0; in tegra_drm_ioctl_channel_open()
146 if (device_get_dma_attr(client->base.dev) == DEV_DMA_COHERENT) in tegra_drm_ioctl_channel_open()
147 args->capabilities |= DRM_TEGRA_CHANNEL_CAP_CACHE_COHERENT; in tegra_drm_ioctl_channel_open()
152 if (context->memory_context) in tegra_drm_ioctl_channel_open()
153 host1x_memory_context_put(context->memory_context); in tegra_drm_ioctl_channel_open()
155 host1x_channel_put(context->channel); in tegra_drm_ioctl_channel_open()
162 int tegra_drm_ioctl_channel_close(struct drm_device *drm, void *data, struct drm_file *file) in tegra_drm_ioctl_channel_close() argument
164 struct tegra_drm_file *fpriv = file->driver_priv; in tegra_drm_ioctl_channel_close()
165 struct drm_tegra_channel_close *args = data; in tegra_drm_ioctl_channel_close()
168 mutex_lock(&fpriv->lock); in tegra_drm_ioctl_channel_close()
170 context = xa_load(&fpriv->contexts, args->context); in tegra_drm_ioctl_channel_close()
172 mutex_unlock(&fpriv->lock); in tegra_drm_ioctl_channel_close()
173 return -EINVAL; in tegra_drm_ioctl_channel_close()
176 xa_erase(&fpriv->contexts, args->context); in tegra_drm_ioctl_channel_close()
178 mutex_unlock(&fpriv->lock); in tegra_drm_ioctl_channel_close()
185 int tegra_drm_ioctl_channel_map(struct drm_device *drm, void *data, struct drm_file *file) in tegra_drm_ioctl_channel_map() argument
187 struct tegra_drm_file *fpriv = file->driver_priv; in tegra_drm_ioctl_channel_map()
188 struct drm_tegra_channel_map *args = data; in tegra_drm_ioctl_channel_map()
189 struct tegra_drm_mapping *mapping; in tegra_drm_ioctl_channel_map() local
195 if (args->flags & ~DRM_TEGRA_CHANNEL_MAP_READ_WRITE) in tegra_drm_ioctl_channel_map()
196 return -EINVAL; in tegra_drm_ioctl_channel_map()
198 mutex_lock(&fpriv->lock); in tegra_drm_ioctl_channel_map()
200 context = xa_load(&fpriv->contexts, args->context); in tegra_drm_ioctl_channel_map()
202 mutex_unlock(&fpriv->lock); in tegra_drm_ioctl_channel_map()
203 return -EINVAL; in tegra_drm_ioctl_channel_map()
206 mapping = kzalloc(sizeof(*mapping), GFP_KERNEL); in tegra_drm_ioctl_channel_map()
207 if (!mapping) { in tegra_drm_ioctl_channel_map()
208 err = -ENOMEM; in tegra_drm_ioctl_channel_map()
212 kref_init(&mapping->ref); in tegra_drm_ioctl_channel_map()
214 if (context->memory_context) in tegra_drm_ioctl_channel_map()
215 mapping_dev = &context->memory_context->dev; in tegra_drm_ioctl_channel_map()
217 mapping_dev = context->client->base.dev; in tegra_drm_ioctl_channel_map()
219 mapping->bo = tegra_gem_lookup(file, args->handle); in tegra_drm_ioctl_channel_map()
220 if (!mapping->bo) { in tegra_drm_ioctl_channel_map()
221 err = -EINVAL; in tegra_drm_ioctl_channel_map()
225 switch (args->flags & DRM_TEGRA_CHANNEL_MAP_READ_WRITE) { in tegra_drm_ioctl_channel_map()
239 err = -EINVAL; in tegra_drm_ioctl_channel_map()
243 mapping->map = host1x_bo_pin(mapping_dev, mapping->bo, direction, NULL); in tegra_drm_ioctl_channel_map()
244 if (IS_ERR(mapping->map)) { in tegra_drm_ioctl_channel_map()
245 err = PTR_ERR(mapping->map); in tegra_drm_ioctl_channel_map()
249 mapping->iova = mapping->map->phys; in tegra_drm_ioctl_channel_map()
250 mapping->iova_end = mapping->iova + host1x_to_tegra_bo(mapping->bo)->gem.size; in tegra_drm_ioctl_channel_map()
252 err = xa_alloc(&context->mappings, &args->mapping, mapping, XA_LIMIT(1, U32_MAX), in tegra_drm_ioctl_channel_map()
257 mutex_unlock(&fpriv->lock); in tegra_drm_ioctl_channel_map()
262 host1x_bo_unpin(mapping->map); in tegra_drm_ioctl_channel_map()
264 host1x_bo_put(mapping->bo); in tegra_drm_ioctl_channel_map()
266 kfree(mapping); in tegra_drm_ioctl_channel_map()
268 mutex_unlock(&fpriv->lock); in tegra_drm_ioctl_channel_map()
272 int tegra_drm_ioctl_channel_unmap(struct drm_device *drm, void *data, struct drm_file *file) in tegra_drm_ioctl_channel_unmap() argument
274 struct tegra_drm_file *fpriv = file->driver_priv; in tegra_drm_ioctl_channel_unmap()
275 struct drm_tegra_channel_unmap *args = data; in tegra_drm_ioctl_channel_unmap()
276 struct tegra_drm_mapping *mapping; in tegra_drm_ioctl_channel_unmap() local
279 mutex_lock(&fpriv->lock); in tegra_drm_ioctl_channel_unmap()
281 context = xa_load(&fpriv->contexts, args->context); in tegra_drm_ioctl_channel_unmap()
283 mutex_unlock(&fpriv->lock); in tegra_drm_ioctl_channel_unmap()
284 return -EINVAL; in tegra_drm_ioctl_channel_unmap()
287 mapping = xa_erase(&context->mappings, args->mapping); in tegra_drm_ioctl_channel_unmap()
289 mutex_unlock(&fpriv->lock); in tegra_drm_ioctl_channel_unmap()
291 if (!mapping) in tegra_drm_ioctl_channel_unmap()
292 return -EINVAL; in tegra_drm_ioctl_channel_unmap()
294 tegra_drm_mapping_put(mapping); in tegra_drm_ioctl_channel_unmap()
298 int tegra_drm_ioctl_syncpoint_allocate(struct drm_device *drm, void *data, struct drm_file *file) in tegra_drm_ioctl_syncpoint_allocate() argument
300 struct host1x *host1x = tegra_drm_to_host1x(drm->dev_private); in tegra_drm_ioctl_syncpoint_allocate()
301 struct tegra_drm_file *fpriv = file->driver_priv; in tegra_drm_ioctl_syncpoint_allocate()
302 struct drm_tegra_syncpoint_allocate *args = data; in tegra_drm_ioctl_syncpoint_allocate()
306 if (args->id) in tegra_drm_ioctl_syncpoint_allocate()
307 return -EINVAL; in tegra_drm_ioctl_syncpoint_allocate()
309 sp = host1x_syncpt_alloc(host1x, HOST1X_SYNCPT_CLIENT_MANAGED, current->comm); in tegra_drm_ioctl_syncpoint_allocate()
311 return -EBUSY; in tegra_drm_ioctl_syncpoint_allocate()
313 args->id = host1x_syncpt_id(sp); in tegra_drm_ioctl_syncpoint_allocate()
315 err = xa_insert(&fpriv->syncpoints, args->id, sp, GFP_KERNEL); in tegra_drm_ioctl_syncpoint_allocate()
324 int tegra_drm_ioctl_syncpoint_free(struct drm_device *drm, void *data, struct drm_file *file) in tegra_drm_ioctl_syncpoint_free() argument
326 struct tegra_drm_file *fpriv = file->driver_priv; in tegra_drm_ioctl_syncpoint_free()
327 struct drm_tegra_syncpoint_allocate *args = data; in tegra_drm_ioctl_syncpoint_free()
330 mutex_lock(&fpriv->lock); in tegra_drm_ioctl_syncpoint_free()
331 sp = xa_erase(&fpriv->syncpoints, args->id); in tegra_drm_ioctl_syncpoint_free()
332 mutex_unlock(&fpriv->lock); in tegra_drm_ioctl_syncpoint_free()
335 return -EINVAL; in tegra_drm_ioctl_syncpoint_free()
342 int tegra_drm_ioctl_syncpoint_wait(struct drm_device *drm, void *data, struct drm_file *file) in tegra_drm_ioctl_syncpoint_wait() argument
344 struct host1x *host1x = tegra_drm_to_host1x(drm->dev_private); in tegra_drm_ioctl_syncpoint_wait()
345 struct drm_tegra_syncpoint_wait *args = data; in tegra_drm_ioctl_syncpoint_wait()
349 if (args->padding != 0) in tegra_drm_ioctl_syncpoint_wait()
350 return -EINVAL; in tegra_drm_ioctl_syncpoint_wait()
352 sp = host1x_syncpt_get_by_id_noref(host1x, args->id); in tegra_drm_ioctl_syncpoint_wait()
354 return -EINVAL; in tegra_drm_ioctl_syncpoint_wait()
356 timeout_jiffies = drm_timeout_abs_to_jiffies(args->timeout_ns); in tegra_drm_ioctl_syncpoint_wait()
358 return host1x_syncpt_wait(sp, args->threshold, timeout_jiffies, &args->value); in tegra_drm_ioctl_syncpoint_wait()