xref: /openbmc/linux/drivers/gpu/drm/tegra/drm.c (revision 8c0b9ee8)
1 /*
2  * Copyright (C) 2012 Avionic Design GmbH
3  * Copyright (C) 2012-2013 NVIDIA CORPORATION.  All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  */
9 
10 #include <linux/host1x.h>
11 #include <linux/iommu.h>
12 
13 #include <drm/drm_atomic.h>
14 #include <drm/drm_atomic_helper.h>
15 
16 #include "drm.h"
17 #include "gem.h"
18 
19 #define DRIVER_NAME "tegra"
20 #define DRIVER_DESC "NVIDIA Tegra graphics"
21 #define DRIVER_DATE "20120330"
22 #define DRIVER_MAJOR 0
23 #define DRIVER_MINOR 0
24 #define DRIVER_PATCHLEVEL 0
25 
26 struct tegra_drm_file {
27 	struct list_head contexts;
28 };
29 
30 static void tegra_atomic_schedule(struct tegra_drm *tegra,
31 				  struct drm_atomic_state *state)
32 {
33 	tegra->commit.state = state;
34 	schedule_work(&tegra->commit.work);
35 }
36 
37 static void tegra_atomic_complete(struct tegra_drm *tegra,
38 				  struct drm_atomic_state *state)
39 {
40 	struct drm_device *drm = tegra->drm;
41 
42 	/*
43 	 * Everything below can be run asynchronously without the need to grab
44 	 * any modeset locks at all under one condition: It must be guaranteed
45 	 * that the asynchronous work has either been cancelled (if the driver
46 	 * supports it, which at least requires that the framebuffers get
47 	 * cleaned up with drm_atomic_helper_cleanup_planes()) or completed
48 	 * before the new state gets committed on the software side with
49 	 * drm_atomic_helper_swap_state().
50 	 *
51 	 * This scheme allows new atomic state updates to be prepared and
52 	 * checked in parallel to the asynchronous completion of the previous
53 	 * update. Which is important since compositors need to figure out the
54 	 * composition of the next frame right after having submitted the
55 	 * current layout.
56 	 */
57 
58 	drm_atomic_helper_commit_pre_planes(drm, state);
59 	drm_atomic_helper_commit_planes(drm, state);
60 	drm_atomic_helper_commit_post_planes(drm, state);
61 
62 	drm_atomic_helper_wait_for_vblanks(drm, state);
63 
64 	drm_atomic_helper_cleanup_planes(drm, state);
65 	drm_atomic_state_free(state);
66 }
67 
68 static void tegra_atomic_work(struct work_struct *work)
69 {
70 	struct tegra_drm *tegra = container_of(work, struct tegra_drm,
71 					       commit.work);
72 
73 	tegra_atomic_complete(tegra, tegra->commit.state);
74 }
75 
76 static int tegra_atomic_commit(struct drm_device *drm,
77 			       struct drm_atomic_state *state, bool async)
78 {
79 	struct tegra_drm *tegra = drm->dev_private;
80 	int err;
81 
82 	err = drm_atomic_helper_prepare_planes(drm, state);
83 	if (err)
84 		return err;
85 
86 	/* serialize outstanding asynchronous commits */
87 	mutex_lock(&tegra->commit.lock);
88 	flush_work(&tegra->commit.work);
89 
90 	/*
91 	 * This is the point of no return - everything below never fails except
92 	 * when the hw goes bonghits. Which means we can commit the new state on
93 	 * the software side now.
94 	 */
95 
96 	drm_atomic_helper_swap_state(drm, state);
97 
98 	if (async)
99 		tegra_atomic_schedule(tegra, state);
100 	else
101 		tegra_atomic_complete(tegra, state);
102 
103 	mutex_unlock(&tegra->commit.lock);
104 	return 0;
105 }
106 
107 static const struct drm_mode_config_funcs tegra_drm_mode_funcs = {
108 	.fb_create = tegra_fb_create,
109 #ifdef CONFIG_DRM_TEGRA_FBDEV
110 	.output_poll_changed = tegra_fb_output_poll_changed,
111 #endif
112 	.atomic_check = drm_atomic_helper_check,
113 	.atomic_commit = tegra_atomic_commit,
114 };
115 
116 static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
117 {
118 	struct host1x_device *device = to_host1x_device(drm->dev);
119 	struct tegra_drm *tegra;
120 	int err;
121 
122 	tegra = kzalloc(sizeof(*tegra), GFP_KERNEL);
123 	if (!tegra)
124 		return -ENOMEM;
125 
126 	if (iommu_present(&platform_bus_type)) {
127 		tegra->domain = iommu_domain_alloc(&platform_bus_type);
128 		if (!tegra->domain) {
129 			err = -ENOMEM;
130 			goto free;
131 		}
132 
133 		DRM_DEBUG("IOMMU context initialized\n");
134 		drm_mm_init(&tegra->mm, 0, SZ_2G);
135 	}
136 
137 	mutex_init(&tegra->clients_lock);
138 	INIT_LIST_HEAD(&tegra->clients);
139 
140 	mutex_init(&tegra->commit.lock);
141 	INIT_WORK(&tegra->commit.work, tegra_atomic_work);
142 
143 	drm->dev_private = tegra;
144 	tegra->drm = drm;
145 
146 	drm_mode_config_init(drm);
147 
148 	drm->mode_config.min_width = 0;
149 	drm->mode_config.min_height = 0;
150 
151 	drm->mode_config.max_width = 4096;
152 	drm->mode_config.max_height = 4096;
153 
154 	drm->mode_config.funcs = &tegra_drm_mode_funcs;
155 
156 	err = tegra_drm_fb_prepare(drm);
157 	if (err < 0)
158 		goto config;
159 
160 	drm_kms_helper_poll_init(drm);
161 
162 	err = host1x_device_init(device);
163 	if (err < 0)
164 		goto fbdev;
165 
166 	drm_mode_config_reset(drm);
167 
168 	/*
169 	 * We don't use the drm_irq_install() helpers provided by the DRM
170 	 * core, so we need to set this manually in order to allow the
171 	 * DRM_IOCTL_WAIT_VBLANK to operate correctly.
172 	 */
173 	drm->irq_enabled = true;
174 
175 	err = drm_vblank_init(drm, drm->mode_config.num_crtc);
176 	if (err < 0)
177 		goto device;
178 
179 	err = tegra_drm_fb_init(drm);
180 	if (err < 0)
181 		goto vblank;
182 
183 	return 0;
184 
185 vblank:
186 	drm_vblank_cleanup(drm);
187 device:
188 	host1x_device_exit(device);
189 fbdev:
190 	drm_kms_helper_poll_fini(drm);
191 	tegra_drm_fb_free(drm);
192 config:
193 	drm_mode_config_cleanup(drm);
194 
195 	if (tegra->domain) {
196 		iommu_domain_free(tegra->domain);
197 		drm_mm_takedown(&tegra->mm);
198 	}
199 free:
200 	kfree(tegra);
201 	return err;
202 }
203 
204 static int tegra_drm_unload(struct drm_device *drm)
205 {
206 	struct host1x_device *device = to_host1x_device(drm->dev);
207 	struct tegra_drm *tegra = drm->dev_private;
208 	int err;
209 
210 	drm_kms_helper_poll_fini(drm);
211 	tegra_drm_fb_exit(drm);
212 	drm_mode_config_cleanup(drm);
213 	drm_vblank_cleanup(drm);
214 
215 	err = host1x_device_exit(device);
216 	if (err < 0)
217 		return err;
218 
219 	if (tegra->domain) {
220 		iommu_domain_free(tegra->domain);
221 		drm_mm_takedown(&tegra->mm);
222 	}
223 
224 	kfree(tegra);
225 
226 	return 0;
227 }
228 
229 static int tegra_drm_open(struct drm_device *drm, struct drm_file *filp)
230 {
231 	struct tegra_drm_file *fpriv;
232 
233 	fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL);
234 	if (!fpriv)
235 		return -ENOMEM;
236 
237 	INIT_LIST_HEAD(&fpriv->contexts);
238 	filp->driver_priv = fpriv;
239 
240 	return 0;
241 }
242 
243 static void tegra_drm_context_free(struct tegra_drm_context *context)
244 {
245 	context->client->ops->close_channel(context);
246 	kfree(context);
247 }
248 
249 static void tegra_drm_lastclose(struct drm_device *drm)
250 {
251 #ifdef CONFIG_DRM_TEGRA_FBDEV
252 	struct tegra_drm *tegra = drm->dev_private;
253 
254 	tegra_fbdev_restore_mode(tegra->fbdev);
255 #endif
256 }
257 
258 static struct host1x_bo *
259 host1x_bo_lookup(struct drm_device *drm, struct drm_file *file, u32 handle)
260 {
261 	struct drm_gem_object *gem;
262 	struct tegra_bo *bo;
263 
264 	gem = drm_gem_object_lookup(drm, file, handle);
265 	if (!gem)
266 		return NULL;
267 
268 	mutex_lock(&drm->struct_mutex);
269 	drm_gem_object_unreference(gem);
270 	mutex_unlock(&drm->struct_mutex);
271 
272 	bo = to_tegra_bo(gem);
273 	return &bo->base;
274 }
275 
276 static int host1x_reloc_copy_from_user(struct host1x_reloc *dest,
277 				       struct drm_tegra_reloc __user *src,
278 				       struct drm_device *drm,
279 				       struct drm_file *file)
280 {
281 	u32 cmdbuf, target;
282 	int err;
283 
284 	err = get_user(cmdbuf, &src->cmdbuf.handle);
285 	if (err < 0)
286 		return err;
287 
288 	err = get_user(dest->cmdbuf.offset, &src->cmdbuf.offset);
289 	if (err < 0)
290 		return err;
291 
292 	err = get_user(target, &src->target.handle);
293 	if (err < 0)
294 		return err;
295 
296 	err = get_user(dest->target.offset, &src->target.offset);
297 	if (err < 0)
298 		return err;
299 
300 	err = get_user(dest->shift, &src->shift);
301 	if (err < 0)
302 		return err;
303 
304 	dest->cmdbuf.bo = host1x_bo_lookup(drm, file, cmdbuf);
305 	if (!dest->cmdbuf.bo)
306 		return -ENOENT;
307 
308 	dest->target.bo = host1x_bo_lookup(drm, file, target);
309 	if (!dest->target.bo)
310 		return -ENOENT;
311 
312 	return 0;
313 }
314 
315 int tegra_drm_submit(struct tegra_drm_context *context,
316 		     struct drm_tegra_submit *args, struct drm_device *drm,
317 		     struct drm_file *file)
318 {
319 	unsigned int num_cmdbufs = args->num_cmdbufs;
320 	unsigned int num_relocs = args->num_relocs;
321 	unsigned int num_waitchks = args->num_waitchks;
322 	struct drm_tegra_cmdbuf __user *cmdbufs =
323 		(void __user *)(uintptr_t)args->cmdbufs;
324 	struct drm_tegra_reloc __user *relocs =
325 		(void __user *)(uintptr_t)args->relocs;
326 	struct drm_tegra_waitchk __user *waitchks =
327 		(void __user *)(uintptr_t)args->waitchks;
328 	struct drm_tegra_syncpt syncpt;
329 	struct host1x_job *job;
330 	int err;
331 
332 	/* We don't yet support other than one syncpt_incr struct per submit */
333 	if (args->num_syncpts != 1)
334 		return -EINVAL;
335 
336 	job = host1x_job_alloc(context->channel, args->num_cmdbufs,
337 			       args->num_relocs, args->num_waitchks);
338 	if (!job)
339 		return -ENOMEM;
340 
341 	job->num_relocs = args->num_relocs;
342 	job->num_waitchk = args->num_waitchks;
343 	job->client = (u32)args->context;
344 	job->class = context->client->base.class;
345 	job->serialize = true;
346 
347 	while (num_cmdbufs) {
348 		struct drm_tegra_cmdbuf cmdbuf;
349 		struct host1x_bo *bo;
350 
351 		if (copy_from_user(&cmdbuf, cmdbufs, sizeof(cmdbuf))) {
352 			err = -EFAULT;
353 			goto fail;
354 		}
355 
356 		bo = host1x_bo_lookup(drm, file, cmdbuf.handle);
357 		if (!bo) {
358 			err = -ENOENT;
359 			goto fail;
360 		}
361 
362 		host1x_job_add_gather(job, bo, cmdbuf.words, cmdbuf.offset);
363 		num_cmdbufs--;
364 		cmdbufs++;
365 	}
366 
367 	/* copy and resolve relocations from submit */
368 	while (num_relocs--) {
369 		err = host1x_reloc_copy_from_user(&job->relocarray[num_relocs],
370 						  &relocs[num_relocs], drm,
371 						  file);
372 		if (err < 0)
373 			goto fail;
374 	}
375 
376 	if (copy_from_user(job->waitchk, waitchks,
377 			   sizeof(*waitchks) * num_waitchks)) {
378 		err = -EFAULT;
379 		goto fail;
380 	}
381 
382 	if (copy_from_user(&syncpt, (void __user *)(uintptr_t)args->syncpts,
383 			   sizeof(syncpt))) {
384 		err = -EFAULT;
385 		goto fail;
386 	}
387 
388 	job->is_addr_reg = context->client->ops->is_addr_reg;
389 	job->syncpt_incrs = syncpt.incrs;
390 	job->syncpt_id = syncpt.id;
391 	job->timeout = 10000;
392 
393 	if (args->timeout && args->timeout < 10000)
394 		job->timeout = args->timeout;
395 
396 	err = host1x_job_pin(job, context->client->base.dev);
397 	if (err)
398 		goto fail;
399 
400 	err = host1x_job_submit(job);
401 	if (err)
402 		goto fail_submit;
403 
404 	args->fence = job->syncpt_end;
405 
406 	host1x_job_put(job);
407 	return 0;
408 
409 fail_submit:
410 	host1x_job_unpin(job);
411 fail:
412 	host1x_job_put(job);
413 	return err;
414 }
415 
416 
417 #ifdef CONFIG_DRM_TEGRA_STAGING
418 static struct tegra_drm_context *tegra_drm_get_context(__u64 context)
419 {
420 	return (struct tegra_drm_context *)(uintptr_t)context;
421 }
422 
423 static bool tegra_drm_file_owns_context(struct tegra_drm_file *file,
424 					struct tegra_drm_context *context)
425 {
426 	struct tegra_drm_context *ctx;
427 
428 	list_for_each_entry(ctx, &file->contexts, list)
429 		if (ctx == context)
430 			return true;
431 
432 	return false;
433 }
434 
435 static int tegra_gem_create(struct drm_device *drm, void *data,
436 			    struct drm_file *file)
437 {
438 	struct drm_tegra_gem_create *args = data;
439 	struct tegra_bo *bo;
440 
441 	bo = tegra_bo_create_with_handle(file, drm, args->size, args->flags,
442 					 &args->handle);
443 	if (IS_ERR(bo))
444 		return PTR_ERR(bo);
445 
446 	return 0;
447 }
448 
449 static int tegra_gem_mmap(struct drm_device *drm, void *data,
450 			  struct drm_file *file)
451 {
452 	struct drm_tegra_gem_mmap *args = data;
453 	struct drm_gem_object *gem;
454 	struct tegra_bo *bo;
455 
456 	gem = drm_gem_object_lookup(drm, file, args->handle);
457 	if (!gem)
458 		return -EINVAL;
459 
460 	bo = to_tegra_bo(gem);
461 
462 	args->offset = drm_vma_node_offset_addr(&bo->gem.vma_node);
463 
464 	drm_gem_object_unreference(gem);
465 
466 	return 0;
467 }
468 
469 static int tegra_syncpt_read(struct drm_device *drm, void *data,
470 			     struct drm_file *file)
471 {
472 	struct host1x *host = dev_get_drvdata(drm->dev->parent);
473 	struct drm_tegra_syncpt_read *args = data;
474 	struct host1x_syncpt *sp;
475 
476 	sp = host1x_syncpt_get(host, args->id);
477 	if (!sp)
478 		return -EINVAL;
479 
480 	args->value = host1x_syncpt_read_min(sp);
481 	return 0;
482 }
483 
484 static int tegra_syncpt_incr(struct drm_device *drm, void *data,
485 			     struct drm_file *file)
486 {
487 	struct host1x *host1x = dev_get_drvdata(drm->dev->parent);
488 	struct drm_tegra_syncpt_incr *args = data;
489 	struct host1x_syncpt *sp;
490 
491 	sp = host1x_syncpt_get(host1x, args->id);
492 	if (!sp)
493 		return -EINVAL;
494 
495 	return host1x_syncpt_incr(sp);
496 }
497 
498 static int tegra_syncpt_wait(struct drm_device *drm, void *data,
499 			     struct drm_file *file)
500 {
501 	struct host1x *host1x = dev_get_drvdata(drm->dev->parent);
502 	struct drm_tegra_syncpt_wait *args = data;
503 	struct host1x_syncpt *sp;
504 
505 	sp = host1x_syncpt_get(host1x, args->id);
506 	if (!sp)
507 		return -EINVAL;
508 
509 	return host1x_syncpt_wait(sp, args->thresh, args->timeout,
510 				  &args->value);
511 }
512 
513 static int tegra_open_channel(struct drm_device *drm, void *data,
514 			      struct drm_file *file)
515 {
516 	struct tegra_drm_file *fpriv = file->driver_priv;
517 	struct tegra_drm *tegra = drm->dev_private;
518 	struct drm_tegra_open_channel *args = data;
519 	struct tegra_drm_context *context;
520 	struct tegra_drm_client *client;
521 	int err = -ENODEV;
522 
523 	context = kzalloc(sizeof(*context), GFP_KERNEL);
524 	if (!context)
525 		return -ENOMEM;
526 
527 	list_for_each_entry(client, &tegra->clients, list)
528 		if (client->base.class == args->client) {
529 			err = client->ops->open_channel(client, context);
530 			if (err)
531 				break;
532 
533 			list_add(&context->list, &fpriv->contexts);
534 			args->context = (uintptr_t)context;
535 			context->client = client;
536 			return 0;
537 		}
538 
539 	kfree(context);
540 	return err;
541 }
542 
543 static int tegra_close_channel(struct drm_device *drm, void *data,
544 			       struct drm_file *file)
545 {
546 	struct tegra_drm_file *fpriv = file->driver_priv;
547 	struct drm_tegra_close_channel *args = data;
548 	struct tegra_drm_context *context;
549 
550 	context = tegra_drm_get_context(args->context);
551 
552 	if (!tegra_drm_file_owns_context(fpriv, context))
553 		return -EINVAL;
554 
555 	list_del(&context->list);
556 	tegra_drm_context_free(context);
557 
558 	return 0;
559 }
560 
561 static int tegra_get_syncpt(struct drm_device *drm, void *data,
562 			    struct drm_file *file)
563 {
564 	struct tegra_drm_file *fpriv = file->driver_priv;
565 	struct drm_tegra_get_syncpt *args = data;
566 	struct tegra_drm_context *context;
567 	struct host1x_syncpt *syncpt;
568 
569 	context = tegra_drm_get_context(args->context);
570 
571 	if (!tegra_drm_file_owns_context(fpriv, context))
572 		return -ENODEV;
573 
574 	if (args->index >= context->client->base.num_syncpts)
575 		return -EINVAL;
576 
577 	syncpt = context->client->base.syncpts[args->index];
578 	args->id = host1x_syncpt_id(syncpt);
579 
580 	return 0;
581 }
582 
583 static int tegra_submit(struct drm_device *drm, void *data,
584 			struct drm_file *file)
585 {
586 	struct tegra_drm_file *fpriv = file->driver_priv;
587 	struct drm_tegra_submit *args = data;
588 	struct tegra_drm_context *context;
589 
590 	context = tegra_drm_get_context(args->context);
591 
592 	if (!tegra_drm_file_owns_context(fpriv, context))
593 		return -ENODEV;
594 
595 	return context->client->ops->submit(context, args, drm, file);
596 }
597 
598 static int tegra_get_syncpt_base(struct drm_device *drm, void *data,
599 				 struct drm_file *file)
600 {
601 	struct tegra_drm_file *fpriv = file->driver_priv;
602 	struct drm_tegra_get_syncpt_base *args = data;
603 	struct tegra_drm_context *context;
604 	struct host1x_syncpt_base *base;
605 	struct host1x_syncpt *syncpt;
606 
607 	context = tegra_drm_get_context(args->context);
608 
609 	if (!tegra_drm_file_owns_context(fpriv, context))
610 		return -ENODEV;
611 
612 	if (args->syncpt >= context->client->base.num_syncpts)
613 		return -EINVAL;
614 
615 	syncpt = context->client->base.syncpts[args->syncpt];
616 
617 	base = host1x_syncpt_get_base(syncpt);
618 	if (!base)
619 		return -ENXIO;
620 
621 	args->id = host1x_syncpt_base_id(base);
622 
623 	return 0;
624 }
625 
626 static int tegra_gem_set_tiling(struct drm_device *drm, void *data,
627 				struct drm_file *file)
628 {
629 	struct drm_tegra_gem_set_tiling *args = data;
630 	enum tegra_bo_tiling_mode mode;
631 	struct drm_gem_object *gem;
632 	unsigned long value = 0;
633 	struct tegra_bo *bo;
634 
635 	switch (args->mode) {
636 	case DRM_TEGRA_GEM_TILING_MODE_PITCH:
637 		mode = TEGRA_BO_TILING_MODE_PITCH;
638 
639 		if (args->value != 0)
640 			return -EINVAL;
641 
642 		break;
643 
644 	case DRM_TEGRA_GEM_TILING_MODE_TILED:
645 		mode = TEGRA_BO_TILING_MODE_TILED;
646 
647 		if (args->value != 0)
648 			return -EINVAL;
649 
650 		break;
651 
652 	case DRM_TEGRA_GEM_TILING_MODE_BLOCK:
653 		mode = TEGRA_BO_TILING_MODE_BLOCK;
654 
655 		if (args->value > 5)
656 			return -EINVAL;
657 
658 		value = args->value;
659 		break;
660 
661 	default:
662 		return -EINVAL;
663 	}
664 
665 	gem = drm_gem_object_lookup(drm, file, args->handle);
666 	if (!gem)
667 		return -ENOENT;
668 
669 	bo = to_tegra_bo(gem);
670 
671 	bo->tiling.mode = mode;
672 	bo->tiling.value = value;
673 
674 	drm_gem_object_unreference(gem);
675 
676 	return 0;
677 }
678 
679 static int tegra_gem_get_tiling(struct drm_device *drm, void *data,
680 				struct drm_file *file)
681 {
682 	struct drm_tegra_gem_get_tiling *args = data;
683 	struct drm_gem_object *gem;
684 	struct tegra_bo *bo;
685 	int err = 0;
686 
687 	gem = drm_gem_object_lookup(drm, file, args->handle);
688 	if (!gem)
689 		return -ENOENT;
690 
691 	bo = to_tegra_bo(gem);
692 
693 	switch (bo->tiling.mode) {
694 	case TEGRA_BO_TILING_MODE_PITCH:
695 		args->mode = DRM_TEGRA_GEM_TILING_MODE_PITCH;
696 		args->value = 0;
697 		break;
698 
699 	case TEGRA_BO_TILING_MODE_TILED:
700 		args->mode = DRM_TEGRA_GEM_TILING_MODE_TILED;
701 		args->value = 0;
702 		break;
703 
704 	case TEGRA_BO_TILING_MODE_BLOCK:
705 		args->mode = DRM_TEGRA_GEM_TILING_MODE_BLOCK;
706 		args->value = bo->tiling.value;
707 		break;
708 
709 	default:
710 		err = -EINVAL;
711 		break;
712 	}
713 
714 	drm_gem_object_unreference(gem);
715 
716 	return err;
717 }
718 
719 static int tegra_gem_set_flags(struct drm_device *drm, void *data,
720 			       struct drm_file *file)
721 {
722 	struct drm_tegra_gem_set_flags *args = data;
723 	struct drm_gem_object *gem;
724 	struct tegra_bo *bo;
725 
726 	if (args->flags & ~DRM_TEGRA_GEM_FLAGS)
727 		return -EINVAL;
728 
729 	gem = drm_gem_object_lookup(drm, file, args->handle);
730 	if (!gem)
731 		return -ENOENT;
732 
733 	bo = to_tegra_bo(gem);
734 	bo->flags = 0;
735 
736 	if (args->flags & DRM_TEGRA_GEM_BOTTOM_UP)
737 		bo->flags |= TEGRA_BO_BOTTOM_UP;
738 
739 	drm_gem_object_unreference(gem);
740 
741 	return 0;
742 }
743 
744 static int tegra_gem_get_flags(struct drm_device *drm, void *data,
745 			       struct drm_file *file)
746 {
747 	struct drm_tegra_gem_get_flags *args = data;
748 	struct drm_gem_object *gem;
749 	struct tegra_bo *bo;
750 
751 	gem = drm_gem_object_lookup(drm, file, args->handle);
752 	if (!gem)
753 		return -ENOENT;
754 
755 	bo = to_tegra_bo(gem);
756 	args->flags = 0;
757 
758 	if (bo->flags & TEGRA_BO_BOTTOM_UP)
759 		args->flags |= DRM_TEGRA_GEM_BOTTOM_UP;
760 
761 	drm_gem_object_unreference(gem);
762 
763 	return 0;
764 }
765 #endif
766 
767 static const struct drm_ioctl_desc tegra_drm_ioctls[] = {
768 #ifdef CONFIG_DRM_TEGRA_STAGING
769 	DRM_IOCTL_DEF_DRV(TEGRA_GEM_CREATE, tegra_gem_create, DRM_UNLOCKED),
770 	DRM_IOCTL_DEF_DRV(TEGRA_GEM_MMAP, tegra_gem_mmap, DRM_UNLOCKED),
771 	DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_READ, tegra_syncpt_read, DRM_UNLOCKED),
772 	DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_INCR, tegra_syncpt_incr, DRM_UNLOCKED),
773 	DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_WAIT, tegra_syncpt_wait, DRM_UNLOCKED),
774 	DRM_IOCTL_DEF_DRV(TEGRA_OPEN_CHANNEL, tegra_open_channel, DRM_UNLOCKED),
775 	DRM_IOCTL_DEF_DRV(TEGRA_CLOSE_CHANNEL, tegra_close_channel, DRM_UNLOCKED),
776 	DRM_IOCTL_DEF_DRV(TEGRA_GET_SYNCPT, tegra_get_syncpt, DRM_UNLOCKED),
777 	DRM_IOCTL_DEF_DRV(TEGRA_SUBMIT, tegra_submit, DRM_UNLOCKED),
778 	DRM_IOCTL_DEF_DRV(TEGRA_GET_SYNCPT_BASE, tegra_get_syncpt_base, DRM_UNLOCKED),
779 	DRM_IOCTL_DEF_DRV(TEGRA_GEM_SET_TILING, tegra_gem_set_tiling, DRM_UNLOCKED),
780 	DRM_IOCTL_DEF_DRV(TEGRA_GEM_GET_TILING, tegra_gem_get_tiling, DRM_UNLOCKED),
781 	DRM_IOCTL_DEF_DRV(TEGRA_GEM_SET_FLAGS, tegra_gem_set_flags, DRM_UNLOCKED),
782 	DRM_IOCTL_DEF_DRV(TEGRA_GEM_GET_FLAGS, tegra_gem_get_flags, DRM_UNLOCKED),
783 #endif
784 };
785 
786 static const struct file_operations tegra_drm_fops = {
787 	.owner = THIS_MODULE,
788 	.open = drm_open,
789 	.release = drm_release,
790 	.unlocked_ioctl = drm_ioctl,
791 	.mmap = tegra_drm_mmap,
792 	.poll = drm_poll,
793 	.read = drm_read,
794 #ifdef CONFIG_COMPAT
795 	.compat_ioctl = drm_compat_ioctl,
796 #endif
797 	.llseek = noop_llseek,
798 };
799 
800 static struct drm_crtc *tegra_crtc_from_pipe(struct drm_device *drm,
801 					     unsigned int pipe)
802 {
803 	struct drm_crtc *crtc;
804 
805 	list_for_each_entry(crtc, &drm->mode_config.crtc_list, head) {
806 		if (pipe == drm_crtc_index(crtc))
807 			return crtc;
808 	}
809 
810 	return NULL;
811 }
812 
813 static u32 tegra_drm_get_vblank_counter(struct drm_device *drm, int pipe)
814 {
815 	struct drm_crtc *crtc = tegra_crtc_from_pipe(drm, pipe);
816 
817 	if (!crtc)
818 		return 0;
819 
820 	/* TODO: implement real hardware counter using syncpoints */
821 	return drm_crtc_vblank_count(crtc);
822 }
823 
824 static int tegra_drm_enable_vblank(struct drm_device *drm, int pipe)
825 {
826 	struct drm_crtc *crtc = tegra_crtc_from_pipe(drm, pipe);
827 	struct tegra_dc *dc = to_tegra_dc(crtc);
828 
829 	if (!crtc)
830 		return -ENODEV;
831 
832 	tegra_dc_enable_vblank(dc);
833 
834 	return 0;
835 }
836 
837 static void tegra_drm_disable_vblank(struct drm_device *drm, int pipe)
838 {
839 	struct drm_crtc *crtc = tegra_crtc_from_pipe(drm, pipe);
840 	struct tegra_dc *dc = to_tegra_dc(crtc);
841 
842 	if (crtc)
843 		tegra_dc_disable_vblank(dc);
844 }
845 
846 static void tegra_drm_preclose(struct drm_device *drm, struct drm_file *file)
847 {
848 	struct tegra_drm_file *fpriv = file->driver_priv;
849 	struct tegra_drm_context *context, *tmp;
850 	struct drm_crtc *crtc;
851 
852 	list_for_each_entry(crtc, &drm->mode_config.crtc_list, head)
853 		tegra_dc_cancel_page_flip(crtc, file);
854 
855 	list_for_each_entry_safe(context, tmp, &fpriv->contexts, list)
856 		tegra_drm_context_free(context);
857 
858 	kfree(fpriv);
859 }
860 
861 #ifdef CONFIG_DEBUG_FS
862 static int tegra_debugfs_framebuffers(struct seq_file *s, void *data)
863 {
864 	struct drm_info_node *node = (struct drm_info_node *)s->private;
865 	struct drm_device *drm = node->minor->dev;
866 	struct drm_framebuffer *fb;
867 
868 	mutex_lock(&drm->mode_config.fb_lock);
869 
870 	list_for_each_entry(fb, &drm->mode_config.fb_list, head) {
871 		seq_printf(s, "%3d: user size: %d x %d, depth %d, %d bpp, refcount %d\n",
872 			   fb->base.id, fb->width, fb->height, fb->depth,
873 			   fb->bits_per_pixel,
874 			   atomic_read(&fb->refcount.refcount));
875 	}
876 
877 	mutex_unlock(&drm->mode_config.fb_lock);
878 
879 	return 0;
880 }
881 
882 static struct drm_info_list tegra_debugfs_list[] = {
883 	{ "framebuffers", tegra_debugfs_framebuffers, 0 },
884 };
885 
886 static int tegra_debugfs_init(struct drm_minor *minor)
887 {
888 	return drm_debugfs_create_files(tegra_debugfs_list,
889 					ARRAY_SIZE(tegra_debugfs_list),
890 					minor->debugfs_root, minor);
891 }
892 
893 static void tegra_debugfs_cleanup(struct drm_minor *minor)
894 {
895 	drm_debugfs_remove_files(tegra_debugfs_list,
896 				 ARRAY_SIZE(tegra_debugfs_list), minor);
897 }
898 #endif
899 
900 static struct drm_driver tegra_drm_driver = {
901 	.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
902 	.load = tegra_drm_load,
903 	.unload = tegra_drm_unload,
904 	.open = tegra_drm_open,
905 	.preclose = tegra_drm_preclose,
906 	.lastclose = tegra_drm_lastclose,
907 
908 	.get_vblank_counter = tegra_drm_get_vblank_counter,
909 	.enable_vblank = tegra_drm_enable_vblank,
910 	.disable_vblank = tegra_drm_disable_vblank,
911 
912 #if defined(CONFIG_DEBUG_FS)
913 	.debugfs_init = tegra_debugfs_init,
914 	.debugfs_cleanup = tegra_debugfs_cleanup,
915 #endif
916 
917 	.gem_free_object = tegra_bo_free_object,
918 	.gem_vm_ops = &tegra_bo_vm_ops,
919 
920 	.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
921 	.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
922 	.gem_prime_export = tegra_gem_prime_export,
923 	.gem_prime_import = tegra_gem_prime_import,
924 
925 	.dumb_create = tegra_bo_dumb_create,
926 	.dumb_map_offset = tegra_bo_dumb_map_offset,
927 	.dumb_destroy = drm_gem_dumb_destroy,
928 
929 	.ioctls = tegra_drm_ioctls,
930 	.num_ioctls = ARRAY_SIZE(tegra_drm_ioctls),
931 	.fops = &tegra_drm_fops,
932 
933 	.name = DRIVER_NAME,
934 	.desc = DRIVER_DESC,
935 	.date = DRIVER_DATE,
936 	.major = DRIVER_MAJOR,
937 	.minor = DRIVER_MINOR,
938 	.patchlevel = DRIVER_PATCHLEVEL,
939 };
940 
941 int tegra_drm_register_client(struct tegra_drm *tegra,
942 			      struct tegra_drm_client *client)
943 {
944 	mutex_lock(&tegra->clients_lock);
945 	list_add_tail(&client->list, &tegra->clients);
946 	mutex_unlock(&tegra->clients_lock);
947 
948 	return 0;
949 }
950 
951 int tegra_drm_unregister_client(struct tegra_drm *tegra,
952 				struct tegra_drm_client *client)
953 {
954 	mutex_lock(&tegra->clients_lock);
955 	list_del_init(&client->list);
956 	mutex_unlock(&tegra->clients_lock);
957 
958 	return 0;
959 }
960 
961 static int host1x_drm_probe(struct host1x_device *dev)
962 {
963 	struct drm_driver *driver = &tegra_drm_driver;
964 	struct drm_device *drm;
965 	int err;
966 
967 	drm = drm_dev_alloc(driver, &dev->dev);
968 	if (!drm)
969 		return -ENOMEM;
970 
971 	drm_dev_set_unique(drm, dev_name(&dev->dev));
972 	dev_set_drvdata(&dev->dev, drm);
973 
974 	err = drm_dev_register(drm, 0);
975 	if (err < 0)
976 		goto unref;
977 
978 	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", driver->name,
979 		 driver->major, driver->minor, driver->patchlevel,
980 		 driver->date, drm->primary->index);
981 
982 	return 0;
983 
984 unref:
985 	drm_dev_unref(drm);
986 	return err;
987 }
988 
989 static int host1x_drm_remove(struct host1x_device *dev)
990 {
991 	struct drm_device *drm = dev_get_drvdata(&dev->dev);
992 
993 	drm_dev_unregister(drm);
994 	drm_dev_unref(drm);
995 
996 	return 0;
997 }
998 
999 #ifdef CONFIG_PM_SLEEP
1000 static int host1x_drm_suspend(struct device *dev)
1001 {
1002 	struct drm_device *drm = dev_get_drvdata(dev);
1003 
1004 	drm_kms_helper_poll_disable(drm);
1005 
1006 	return 0;
1007 }
1008 
1009 static int host1x_drm_resume(struct device *dev)
1010 {
1011 	struct drm_device *drm = dev_get_drvdata(dev);
1012 
1013 	drm_kms_helper_poll_enable(drm);
1014 
1015 	return 0;
1016 }
1017 #endif
1018 
1019 static const struct dev_pm_ops host1x_drm_pm_ops = {
1020 	SET_SYSTEM_SLEEP_PM_OPS(host1x_drm_suspend, host1x_drm_resume)
1021 };
1022 
1023 static const struct of_device_id host1x_drm_subdevs[] = {
1024 	{ .compatible = "nvidia,tegra20-dc", },
1025 	{ .compatible = "nvidia,tegra20-hdmi", },
1026 	{ .compatible = "nvidia,tegra20-gr2d", },
1027 	{ .compatible = "nvidia,tegra20-gr3d", },
1028 	{ .compatible = "nvidia,tegra30-dc", },
1029 	{ .compatible = "nvidia,tegra30-hdmi", },
1030 	{ .compatible = "nvidia,tegra30-gr2d", },
1031 	{ .compatible = "nvidia,tegra30-gr3d", },
1032 	{ .compatible = "nvidia,tegra114-dsi", },
1033 	{ .compatible = "nvidia,tegra114-hdmi", },
1034 	{ .compatible = "nvidia,tegra114-gr3d", },
1035 	{ .compatible = "nvidia,tegra124-dc", },
1036 	{ .compatible = "nvidia,tegra124-sor", },
1037 	{ .compatible = "nvidia,tegra124-hdmi", },
1038 	{ /* sentinel */ }
1039 };
1040 
1041 static struct host1x_driver host1x_drm_driver = {
1042 	.driver = {
1043 		.name = "drm",
1044 		.pm = &host1x_drm_pm_ops,
1045 	},
1046 	.probe = host1x_drm_probe,
1047 	.remove = host1x_drm_remove,
1048 	.subdevs = host1x_drm_subdevs,
1049 };
1050 
1051 static int __init host1x_drm_init(void)
1052 {
1053 	int err;
1054 
1055 	err = host1x_driver_register(&host1x_drm_driver);
1056 	if (err < 0)
1057 		return err;
1058 
1059 	err = platform_driver_register(&tegra_dc_driver);
1060 	if (err < 0)
1061 		goto unregister_host1x;
1062 
1063 	err = platform_driver_register(&tegra_dsi_driver);
1064 	if (err < 0)
1065 		goto unregister_dc;
1066 
1067 	err = platform_driver_register(&tegra_sor_driver);
1068 	if (err < 0)
1069 		goto unregister_dsi;
1070 
1071 	err = platform_driver_register(&tegra_hdmi_driver);
1072 	if (err < 0)
1073 		goto unregister_sor;
1074 
1075 	err = platform_driver_register(&tegra_dpaux_driver);
1076 	if (err < 0)
1077 		goto unregister_hdmi;
1078 
1079 	err = platform_driver_register(&tegra_gr2d_driver);
1080 	if (err < 0)
1081 		goto unregister_dpaux;
1082 
1083 	err = platform_driver_register(&tegra_gr3d_driver);
1084 	if (err < 0)
1085 		goto unregister_gr2d;
1086 
1087 	return 0;
1088 
1089 unregister_gr2d:
1090 	platform_driver_unregister(&tegra_gr2d_driver);
1091 unregister_dpaux:
1092 	platform_driver_unregister(&tegra_dpaux_driver);
1093 unregister_hdmi:
1094 	platform_driver_unregister(&tegra_hdmi_driver);
1095 unregister_sor:
1096 	platform_driver_unregister(&tegra_sor_driver);
1097 unregister_dsi:
1098 	platform_driver_unregister(&tegra_dsi_driver);
1099 unregister_dc:
1100 	platform_driver_unregister(&tegra_dc_driver);
1101 unregister_host1x:
1102 	host1x_driver_unregister(&host1x_drm_driver);
1103 	return err;
1104 }
1105 module_init(host1x_drm_init);
1106 
1107 static void __exit host1x_drm_exit(void)
1108 {
1109 	platform_driver_unregister(&tegra_gr3d_driver);
1110 	platform_driver_unregister(&tegra_gr2d_driver);
1111 	platform_driver_unregister(&tegra_dpaux_driver);
1112 	platform_driver_unregister(&tegra_hdmi_driver);
1113 	platform_driver_unregister(&tegra_sor_driver);
1114 	platform_driver_unregister(&tegra_dsi_driver);
1115 	platform_driver_unregister(&tegra_dc_driver);
1116 	host1x_driver_unregister(&host1x_drm_driver);
1117 }
1118 module_exit(host1x_drm_exit);
1119 
1120 MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>");
1121 MODULE_DESCRIPTION("NVIDIA Tegra DRM driver");
1122 MODULE_LICENSE("GPL v2");
1123