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 if (mapping->sgt) in tegra_drm_mapping_release()
21 dma_unmap_sgtable(mapping->dev, mapping->sgt, mapping->direction, in tegra_drm_mapping_release()
24 host1x_bo_unpin(mapping->dev, mapping->bo, mapping->sgt); in tegra_drm_mapping_release()
25 host1x_bo_put(mapping->bo); in tegra_drm_mapping_release()
27 kfree(mapping); in tegra_drm_mapping_release()
30 void tegra_drm_mapping_put(struct tegra_drm_mapping *mapping) in tegra_drm_mapping_put() argument
32 kref_put(&mapping->ref, tegra_drm_mapping_release); in tegra_drm_mapping_put()
37 struct tegra_drm_mapping *mapping; in tegra_drm_channel_context_close() local
40 xa_for_each(&context->mappings, id, mapping) in tegra_drm_channel_context_close()
41 tegra_drm_mapping_put(mapping); in tegra_drm_channel_context_close()
43 xa_destroy(&context->mappings); in tegra_drm_channel_context_close()
45 host1x_channel_put(context->channel); in tegra_drm_channel_context_close()
56 xa_for_each(&file->contexts, id, context) in tegra_drm_uapi_close_file()
59 xa_for_each(&file->syncpoints, id, sp) in tegra_drm_uapi_close_file()
62 xa_destroy(&file->contexts); in tegra_drm_uapi_close_file()
63 xa_destroy(&file->syncpoints); in tegra_drm_uapi_close_file()
70 list_for_each_entry(client, &tegra->clients, list) in tegra_drm_find_client()
71 if (client->base.class == class) in tegra_drm_find_client()
77 int tegra_drm_ioctl_channel_open(struct drm_device *drm, void *data, struct drm_file *file) in tegra_drm_ioctl_channel_open() argument
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()
109 err = xa_alloc(&fpriv->contexts, &args->context, context, XA_LIMIT(1, U32_MAX), in tegra_drm_ioctl_channel_open()
114 context->client = client; in tegra_drm_ioctl_channel_open()
115 xa_init_flags(&context->mappings, XA_FLAGS_ALLOC1); in tegra_drm_ioctl_channel_open()
117 args->version = client->version; in tegra_drm_ioctl_channel_open()
118 args->capabilities = 0; in tegra_drm_ioctl_channel_open()
120 if (device_get_dma_attr(client->base.dev) == DEV_DMA_COHERENT) in tegra_drm_ioctl_channel_open()
121 args->capabilities |= DRM_TEGRA_CHANNEL_CAP_CACHE_COHERENT; in tegra_drm_ioctl_channel_open()
126 host1x_channel_put(context->channel); in tegra_drm_ioctl_channel_open()
133 int tegra_drm_ioctl_channel_close(struct drm_device *drm, void *data, struct drm_file *file) in tegra_drm_ioctl_channel_close() argument
135 struct tegra_drm_file *fpriv = file->driver_priv; in tegra_drm_ioctl_channel_close()
136 struct drm_tegra_channel_close *args = data; in tegra_drm_ioctl_channel_close()
139 mutex_lock(&fpriv->lock); in tegra_drm_ioctl_channel_close()
141 context = xa_load(&fpriv->contexts, args->context); in tegra_drm_ioctl_channel_close()
143 mutex_unlock(&fpriv->lock); in tegra_drm_ioctl_channel_close()
144 return -EINVAL; in tegra_drm_ioctl_channel_close()
147 xa_erase(&fpriv->contexts, args->context); in tegra_drm_ioctl_channel_close()
149 mutex_unlock(&fpriv->lock); in tegra_drm_ioctl_channel_close()
156 int tegra_drm_ioctl_channel_map(struct drm_device *drm, void *data, struct drm_file *file) in tegra_drm_ioctl_channel_map() argument
158 struct tegra_drm_file *fpriv = file->driver_priv; in tegra_drm_ioctl_channel_map()
159 struct drm_tegra_channel_map *args = data; in tegra_drm_ioctl_channel_map()
160 struct tegra_drm_mapping *mapping; in tegra_drm_ioctl_channel_map() local
164 if (args->flags & ~DRM_TEGRA_CHANNEL_MAP_READ_WRITE) in tegra_drm_ioctl_channel_map()
165 return -EINVAL; in tegra_drm_ioctl_channel_map()
167 mutex_lock(&fpriv->lock); in tegra_drm_ioctl_channel_map()
169 context = xa_load(&fpriv->contexts, args->context); in tegra_drm_ioctl_channel_map()
171 mutex_unlock(&fpriv->lock); in tegra_drm_ioctl_channel_map()
172 return -EINVAL; in tegra_drm_ioctl_channel_map()
175 mapping = kzalloc(sizeof(*mapping), GFP_KERNEL); in tegra_drm_ioctl_channel_map()
176 if (!mapping) { in tegra_drm_ioctl_channel_map()
177 err = -ENOMEM; in tegra_drm_ioctl_channel_map()
181 kref_init(&mapping->ref); in tegra_drm_ioctl_channel_map()
183 mapping->dev = context->client->base.dev; in tegra_drm_ioctl_channel_map()
184 mapping->bo = tegra_gem_lookup(file, args->handle); in tegra_drm_ioctl_channel_map()
185 if (!mapping->bo) { in tegra_drm_ioctl_channel_map()
186 err = -EINVAL; in tegra_drm_ioctl_channel_map()
190 if (context->client->base.group) { in tegra_drm_ioctl_channel_map()
192 host1x_bo_pin(mapping->dev, mapping->bo, &mapping->iova); in tegra_drm_ioctl_channel_map()
194 switch (args->flags & DRM_TEGRA_CHANNEL_MAP_READ_WRITE) { in tegra_drm_ioctl_channel_map()
196 mapping->direction = DMA_BIDIRECTIONAL; in tegra_drm_ioctl_channel_map()
200 mapping->direction = DMA_FROM_DEVICE; in tegra_drm_ioctl_channel_map()
204 mapping->direction = DMA_TO_DEVICE; in tegra_drm_ioctl_channel_map()
208 return -EINVAL; in tegra_drm_ioctl_channel_map()
211 mapping->sgt = host1x_bo_pin(mapping->dev, mapping->bo, NULL); in tegra_drm_ioctl_channel_map()
212 if (IS_ERR(mapping->sgt)) { in tegra_drm_ioctl_channel_map()
213 err = PTR_ERR(mapping->sgt); in tegra_drm_ioctl_channel_map()
217 err = dma_map_sgtable(mapping->dev, mapping->sgt, mapping->direction, in tegra_drm_ioctl_channel_map()
222 mapping->iova = sg_dma_address(mapping->sgt->sgl); in tegra_drm_ioctl_channel_map()
225 mapping->iova_end = mapping->iova + host1x_to_tegra_bo(mapping->bo)->gem.size; in tegra_drm_ioctl_channel_map()
227 err = xa_alloc(&context->mappings, &args->mapping, mapping, XA_LIMIT(1, U32_MAX), in tegra_drm_ioctl_channel_map()
232 mutex_unlock(&fpriv->lock); in tegra_drm_ioctl_channel_map()
237 if (mapping->sgt) { in tegra_drm_ioctl_channel_map()
238 dma_unmap_sgtable(mapping->dev, mapping->sgt, mapping->direction, in tegra_drm_ioctl_channel_map()
242 host1x_bo_unpin(mapping->dev, mapping->bo, mapping->sgt); in tegra_drm_ioctl_channel_map()
244 host1x_bo_put(mapping->bo); in tegra_drm_ioctl_channel_map()
245 kfree(mapping); in tegra_drm_ioctl_channel_map()
247 mutex_unlock(&fpriv->lock); in tegra_drm_ioctl_channel_map()
251 int tegra_drm_ioctl_channel_unmap(struct drm_device *drm, void *data, struct drm_file *file) in tegra_drm_ioctl_channel_unmap() argument
253 struct tegra_drm_file *fpriv = file->driver_priv; in tegra_drm_ioctl_channel_unmap()
254 struct drm_tegra_channel_unmap *args = data; in tegra_drm_ioctl_channel_unmap()
255 struct tegra_drm_mapping *mapping; in tegra_drm_ioctl_channel_unmap() local
258 mutex_lock(&fpriv->lock); in tegra_drm_ioctl_channel_unmap()
260 context = xa_load(&fpriv->contexts, args->context); in tegra_drm_ioctl_channel_unmap()
262 mutex_unlock(&fpriv->lock); in tegra_drm_ioctl_channel_unmap()
263 return -EINVAL; in tegra_drm_ioctl_channel_unmap()
266 mapping = xa_erase(&context->mappings, args->mapping); in tegra_drm_ioctl_channel_unmap()
268 mutex_unlock(&fpriv->lock); in tegra_drm_ioctl_channel_unmap()
270 if (!mapping) in tegra_drm_ioctl_channel_unmap()
271 return -EINVAL; in tegra_drm_ioctl_channel_unmap()
273 tegra_drm_mapping_put(mapping); in tegra_drm_ioctl_channel_unmap()
277 int tegra_drm_ioctl_syncpoint_allocate(struct drm_device *drm, void *data, struct drm_file *file) in tegra_drm_ioctl_syncpoint_allocate() argument
279 struct host1x *host1x = tegra_drm_to_host1x(drm->dev_private); in tegra_drm_ioctl_syncpoint_allocate()
280 struct tegra_drm_file *fpriv = file->driver_priv; in tegra_drm_ioctl_syncpoint_allocate()
281 struct drm_tegra_syncpoint_allocate *args = data; in tegra_drm_ioctl_syncpoint_allocate()
285 if (args->id) in tegra_drm_ioctl_syncpoint_allocate()
286 return -EINVAL; in tegra_drm_ioctl_syncpoint_allocate()
288 sp = host1x_syncpt_alloc(host1x, HOST1X_SYNCPT_CLIENT_MANAGED, current->comm); in tegra_drm_ioctl_syncpoint_allocate()
290 return -EBUSY; in tegra_drm_ioctl_syncpoint_allocate()
292 args->id = host1x_syncpt_id(sp); in tegra_drm_ioctl_syncpoint_allocate()
294 err = xa_insert(&fpriv->syncpoints, args->id, sp, GFP_KERNEL); in tegra_drm_ioctl_syncpoint_allocate()
303 int tegra_drm_ioctl_syncpoint_free(struct drm_device *drm, void *data, struct drm_file *file) in tegra_drm_ioctl_syncpoint_free() argument
305 struct tegra_drm_file *fpriv = file->driver_priv; in tegra_drm_ioctl_syncpoint_free()
306 struct drm_tegra_syncpoint_allocate *args = data; in tegra_drm_ioctl_syncpoint_free()
309 mutex_lock(&fpriv->lock); in tegra_drm_ioctl_syncpoint_free()
310 sp = xa_erase(&fpriv->syncpoints, args->id); in tegra_drm_ioctl_syncpoint_free()
311 mutex_unlock(&fpriv->lock); in tegra_drm_ioctl_syncpoint_free()
314 return -EINVAL; in tegra_drm_ioctl_syncpoint_free()
321 int tegra_drm_ioctl_syncpoint_wait(struct drm_device *drm, void *data, struct drm_file *file) in tegra_drm_ioctl_syncpoint_wait() argument
323 struct host1x *host1x = tegra_drm_to_host1x(drm->dev_private); in tegra_drm_ioctl_syncpoint_wait()
324 struct drm_tegra_syncpoint_wait *args = data; in tegra_drm_ioctl_syncpoint_wait()
328 if (args->padding != 0) in tegra_drm_ioctl_syncpoint_wait()
329 return -EINVAL; in tegra_drm_ioctl_syncpoint_wait()
331 sp = host1x_syncpt_get_by_id_noref(host1x, args->id); in tegra_drm_ioctl_syncpoint_wait()
333 return -EINVAL; in tegra_drm_ioctl_syncpoint_wait()
335 timeout_jiffies = drm_timeout_abs_to_jiffies(args->timeout_ns); in tegra_drm_ioctl_syncpoint_wait()
337 return host1x_syncpt_wait(sp, args->threshold, timeout_jiffies, &args->value); in tegra_drm_ioctl_syncpoint_wait()