2 * Copyright (C) 2012 Avionic Design GmbH
3 * Copyright (C) 2012-2013 NVIDIA CORPORATION. All rights reserved.
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.
10 #include <linux/module.h>
11 #include <linux/of_address.h>
12 #include <linux/of_platform.h>
14 #include <linux/dma-mapping.h>
15 #include <asm/dma-iommu.h>
20 #include "host1x_client.h"
26 #define DRIVER_NAME "tegra"
27 #define DRIVER_DESC "NVIDIA Tegra graphics"
28 #define DRIVER_DATE "20120330"
29 #define DRIVER_MAJOR 0
30 #define DRIVER_MINOR 0
31 #define DRIVER_PATCHLEVEL 0
33 struct tegra_drm_file
{
34 struct list_head contexts
;
37 struct host1x_subdev
{
38 struct host1x_client
*client
;
39 struct device_node
*np
;
40 struct list_head list
;
43 static int host1x_subdev_add(struct tegra_drm
*tegra
, struct device_node
*np
)
45 struct host1x_subdev
*subdev
;
47 subdev
= kzalloc(sizeof(*subdev
), GFP_KERNEL
);
51 INIT_LIST_HEAD(&subdev
->list
);
52 subdev
->np
= of_node_get(np
);
54 list_add_tail(&subdev
->list
, &tegra
->subdevs
);
59 static int host1x_subdev_register(struct tegra_drm
*tegra
,
60 struct host1x_subdev
*subdev
,
61 struct host1x_client
*client
)
63 mutex_lock(&tegra
->subdevs_lock
);
64 list_del_init(&subdev
->list
);
65 list_add_tail(&subdev
->list
, &tegra
->active
);
66 subdev
->client
= client
;
67 mutex_unlock(&tegra
->subdevs_lock
);
72 static int host1x_subdev_unregister(struct tegra_drm
*tegra
,
73 struct host1x_subdev
*subdev
)
75 mutex_lock(&tegra
->subdevs_lock
);
76 list_del_init(&subdev
->list
);
77 mutex_unlock(&tegra
->subdevs_lock
);
79 of_node_put(subdev
->np
);
85 static int tegra_parse_dt(struct tegra_drm
*tegra
)
87 static const char * const compat
[] = {
89 "nvidia,tegra20-hdmi",
90 "nvidia,tegra20-gr2d",
92 "nvidia,tegra30-hdmi",
93 "nvidia,tegra30-gr2d",
98 for (i
= 0; i
< ARRAY_SIZE(compat
); i
++) {
99 struct device_node
*np
;
101 for_each_child_of_node(tegra
->dev
->of_node
, np
) {
102 if (of_device_is_compatible(np
, compat
[i
]) &&
103 of_device_is_available(np
)) {
104 err
= host1x_subdev_add(tegra
, np
);
114 int tegra_drm_alloc(struct platform_device
*pdev
)
116 struct tegra_drm
*tegra
;
119 tegra
= devm_kzalloc(&pdev
->dev
, sizeof(*tegra
), GFP_KERNEL
);
123 mutex_init(&tegra
->subdevs_lock
);
124 INIT_LIST_HEAD(&tegra
->subdevs
);
125 INIT_LIST_HEAD(&tegra
->active
);
126 mutex_init(&tegra
->clients_lock
);
127 INIT_LIST_HEAD(&tegra
->clients
);
128 tegra
->dev
= &pdev
->dev
;
130 err
= tegra_parse_dt(tegra
);
132 dev_err(&pdev
->dev
, "failed to parse DT: %d\n", err
);
136 host1x_set_drm_data(&pdev
->dev
, tegra
);
141 int tegra_drm_init(struct tegra_drm
*tegra
, struct drm_device
*drm
)
143 struct host1x_client
*client
;
145 mutex_lock(&tegra
->clients_lock
);
147 list_for_each_entry(client
, &tegra
->clients
, list
) {
148 if (client
->ops
&& client
->ops
->drm_init
) {
149 int err
= client
->ops
->drm_init(client
, drm
);
152 "DRM setup failed for %s: %d\n",
153 dev_name(client
->dev
), err
);
154 mutex_unlock(&tegra
->clients_lock
);
160 mutex_unlock(&tegra
->clients_lock
);
165 int tegra_drm_exit(struct tegra_drm
*tegra
)
167 struct platform_device
*pdev
= to_platform_device(tegra
->dev
);
168 struct host1x_client
*client
;
173 mutex_lock(&tegra
->clients_lock
);
175 list_for_each_entry_reverse(client
, &tegra
->clients
, list
) {
176 if (client
->ops
&& client
->ops
->drm_exit
) {
177 int err
= client
->ops
->drm_exit(client
);
180 "DRM cleanup failed for %s: %d\n",
181 dev_name(client
->dev
), err
);
182 mutex_unlock(&tegra
->clients_lock
);
188 mutex_unlock(&tegra
->clients_lock
);
190 drm_platform_exit(&tegra_drm_driver
, pdev
);
196 int host1x_register_client(struct tegra_drm
*tegra
,
197 struct host1x_client
*client
)
199 struct host1x_subdev
*subdev
, *tmp
;
202 mutex_lock(&tegra
->clients_lock
);
203 list_add_tail(&client
->list
, &tegra
->clients
);
204 mutex_unlock(&tegra
->clients_lock
);
206 list_for_each_entry_safe(subdev
, tmp
, &tegra
->subdevs
, list
)
207 if (subdev
->np
== client
->dev
->of_node
)
208 host1x_subdev_register(tegra
, subdev
, client
);
210 if (list_empty(&tegra
->subdevs
)) {
211 struct platform_device
*pdev
= to_platform_device(tegra
->dev
);
213 err
= drm_platform_init(&tegra_drm_driver
, pdev
);
215 dev_err(tegra
->dev
, "drm_platform_init(): %d\n", err
);
223 int host1x_unregister_client(struct tegra_drm
*tegra
,
224 struct host1x_client
*client
)
226 struct host1x_subdev
*subdev
, *tmp
;
229 list_for_each_entry_safe(subdev
, tmp
, &tegra
->active
, list
) {
230 if (subdev
->client
== client
) {
231 err
= tegra_drm_exit(tegra
);
233 dev_err(tegra
->dev
, "tegra_drm_exit(): %d\n",
238 host1x_subdev_unregister(tegra
, subdev
);
243 mutex_lock(&tegra
->clients_lock
);
244 list_del_init(&client
->list
);
245 mutex_unlock(&tegra
->clients_lock
);
250 static int tegra_drm_load(struct drm_device
*drm
, unsigned long flags
)
252 struct tegra_drm
*tegra
;
255 tegra
= host1x_get_drm_data(drm
->dev
);
256 drm
->dev_private
= tegra
;
259 drm_mode_config_init(drm
);
261 err
= tegra_drm_init(tegra
, drm
);
266 * We don't use the drm_irq_install() helpers provided by the DRM
267 * core, so we need to set this manually in order to allow the
268 * DRM_IOCTL_WAIT_VBLANK to operate correctly.
270 drm
->irq_enabled
= true;
272 err
= drm_vblank_init(drm
, drm
->mode_config
.num_crtc
);
276 err
= tegra_drm_fb_init(drm
);
280 drm_kms_helper_poll_init(drm
);
285 static int tegra_drm_unload(struct drm_device
*drm
)
287 drm_kms_helper_poll_fini(drm
);
288 tegra_drm_fb_exit(drm
);
290 drm_mode_config_cleanup(drm
);
295 static int tegra_drm_open(struct drm_device
*drm
, struct drm_file
*filp
)
297 struct tegra_drm_file
*fpriv
;
299 fpriv
= kzalloc(sizeof(*fpriv
), GFP_KERNEL
);
303 INIT_LIST_HEAD(&fpriv
->contexts
);
304 filp
->driver_priv
= fpriv
;
309 static void tegra_drm_context_free(struct tegra_drm_context
*context
)
311 context
->client
->ops
->close_channel(context
);
315 static void tegra_drm_lastclose(struct drm_device
*drm
)
317 struct tegra_drm
*tegra
= drm
->dev_private
;
319 tegra_fbdev_restore_mode(tegra
->fbdev
);
322 #ifdef CONFIG_DRM_TEGRA_STAGING
323 static struct tegra_drm_context
*tegra_drm_get_context(__u64 context
)
325 return (struct tegra_drm_context
*)(uintptr_t)context
;
328 static bool tegra_drm_file_owns_context(struct tegra_drm_file
*file
,
329 struct tegra_drm_context
*context
)
331 struct tegra_drm_context
*ctx
;
333 list_for_each_entry(ctx
, &file
->contexts
, list
)
340 static int tegra_gem_create(struct drm_device
*drm
, void *data
,
341 struct drm_file
*file
)
343 struct drm_tegra_gem_create
*args
= data
;
346 bo
= tegra_bo_create_with_handle(file
, drm
, args
->size
,
354 static int tegra_gem_mmap(struct drm_device
*drm
, void *data
,
355 struct drm_file
*file
)
357 struct drm_tegra_gem_mmap
*args
= data
;
358 struct drm_gem_object
*gem
;
361 gem
= drm_gem_object_lookup(drm
, file
, args
->handle
);
365 bo
= to_tegra_bo(gem
);
367 args
->offset
= drm_vma_node_offset_addr(&bo
->gem
.vma_node
);
369 drm_gem_object_unreference(gem
);
374 static int tegra_syncpt_read(struct drm_device
*drm
, void *data
,
375 struct drm_file
*file
)
377 struct drm_tegra_syncpt_read
*args
= data
;
378 struct host1x
*host
= dev_get_drvdata(drm
->dev
);
379 struct host1x_syncpt
*sp
= host1x_syncpt_get(host
, args
->id
);
384 args
->value
= host1x_syncpt_read_min(sp
);
388 static int tegra_syncpt_incr(struct drm_device
*drm
, void *data
,
389 struct drm_file
*file
)
391 struct drm_tegra_syncpt_incr
*args
= data
;
392 struct host1x
*host
= dev_get_drvdata(drm
->dev
);
393 struct host1x_syncpt
*sp
= host1x_syncpt_get(host
, args
->id
);
398 return host1x_syncpt_incr(sp
);
401 static int tegra_syncpt_wait(struct drm_device
*drm
, void *data
,
402 struct drm_file
*file
)
404 struct drm_tegra_syncpt_wait
*args
= data
;
405 struct host1x
*host
= dev_get_drvdata(drm
->dev
);
406 struct host1x_syncpt
*sp
= host1x_syncpt_get(host
, args
->id
);
411 return host1x_syncpt_wait(sp
, args
->thresh
, args
->timeout
,
415 static int tegra_open_channel(struct drm_device
*drm
, void *data
,
416 struct drm_file
*file
)
418 struct tegra_drm_file
*fpriv
= file
->driver_priv
;
419 struct tegra_drm
*tegra
= drm
->dev_private
;
420 struct drm_tegra_open_channel
*args
= data
;
421 struct tegra_drm_context
*context
;
422 struct host1x_client
*client
;
425 context
= kzalloc(sizeof(*context
), GFP_KERNEL
);
429 list_for_each_entry(client
, &tegra
->clients
, list
)
430 if (client
->class == args
->client
) {
431 err
= client
->ops
->open_channel(client
, context
);
435 context
->client
= client
;
436 list_add(&context
->list
, &fpriv
->contexts
);
437 args
->context
= (uintptr_t)context
;
445 static int tegra_close_channel(struct drm_device
*drm
, void *data
,
446 struct drm_file
*file
)
448 struct drm_tegra_close_channel
*args
= data
;
449 struct tegra_drm_file
*fpriv
= file
->driver_priv
;
450 struct tegra_drm_context
*context
;
452 context
= tegra_drm_get_context(args
->context
);
454 if (!tegra_drm_file_owns_context(fpriv
, context
))
457 list_del(&context
->list
);
458 tegra_drm_context_free(context
);
463 static int tegra_get_syncpt(struct drm_device
*drm
, void *data
,
464 struct drm_file
*file
)
466 struct tegra_drm_file
*fpriv
= file
->driver_priv
;
467 struct drm_tegra_get_syncpt
*args
= data
;
468 struct tegra_drm_context
*context
;
469 struct host1x_syncpt
*syncpt
;
471 context
= tegra_drm_get_context(args
->context
);
473 if (!tegra_drm_file_owns_context(fpriv
, context
))
476 if (args
->index
>= context
->client
->num_syncpts
)
479 syncpt
= context
->client
->syncpts
[args
->index
];
480 args
->id
= host1x_syncpt_id(syncpt
);
485 static int tegra_submit(struct drm_device
*drm
, void *data
,
486 struct drm_file
*file
)
488 struct tegra_drm_file
*fpriv
= file
->driver_priv
;
489 struct drm_tegra_submit
*args
= data
;
490 struct tegra_drm_context
*context
;
492 context
= tegra_drm_get_context(args
->context
);
494 if (!tegra_drm_file_owns_context(fpriv
, context
))
497 return context
->client
->ops
->submit(context
, args
, drm
, file
);
501 static const struct drm_ioctl_desc tegra_drm_ioctls
[] = {
502 #ifdef CONFIG_DRM_TEGRA_STAGING
503 DRM_IOCTL_DEF_DRV(TEGRA_GEM_CREATE
, tegra_gem_create
, DRM_UNLOCKED
| DRM_AUTH
),
504 DRM_IOCTL_DEF_DRV(TEGRA_GEM_MMAP
, tegra_gem_mmap
, DRM_UNLOCKED
),
505 DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_READ
, tegra_syncpt_read
, DRM_UNLOCKED
),
506 DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_INCR
, tegra_syncpt_incr
, DRM_UNLOCKED
),
507 DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_WAIT
, tegra_syncpt_wait
, DRM_UNLOCKED
),
508 DRM_IOCTL_DEF_DRV(TEGRA_OPEN_CHANNEL
, tegra_open_channel
, DRM_UNLOCKED
),
509 DRM_IOCTL_DEF_DRV(TEGRA_CLOSE_CHANNEL
, tegra_close_channel
, DRM_UNLOCKED
),
510 DRM_IOCTL_DEF_DRV(TEGRA_GET_SYNCPT
, tegra_get_syncpt
, DRM_UNLOCKED
),
511 DRM_IOCTL_DEF_DRV(TEGRA_SUBMIT
, tegra_submit
, DRM_UNLOCKED
),
515 static const struct file_operations tegra_drm_fops
= {
516 .owner
= THIS_MODULE
,
518 .release
= drm_release
,
519 .unlocked_ioctl
= drm_ioctl
,
520 .mmap
= tegra_drm_mmap
,
524 .compat_ioctl
= drm_compat_ioctl
,
526 .llseek
= noop_llseek
,
529 static struct drm_crtc
*tegra_crtc_from_pipe(struct drm_device
*drm
, int pipe
)
531 struct drm_crtc
*crtc
;
533 list_for_each_entry(crtc
, &drm
->mode_config
.crtc_list
, head
) {
534 struct tegra_dc
*dc
= to_tegra_dc(crtc
);
536 if (dc
->pipe
== pipe
)
543 static u32
tegra_drm_get_vblank_counter(struct drm_device
*dev
, int crtc
)
545 /* TODO: implement real hardware counter using syncpoints */
546 return drm_vblank_count(dev
, crtc
);
549 static int tegra_drm_enable_vblank(struct drm_device
*drm
, int pipe
)
551 struct drm_crtc
*crtc
= tegra_crtc_from_pipe(drm
, pipe
);
552 struct tegra_dc
*dc
= to_tegra_dc(crtc
);
557 tegra_dc_enable_vblank(dc
);
562 static void tegra_drm_disable_vblank(struct drm_device
*drm
, int pipe
)
564 struct drm_crtc
*crtc
= tegra_crtc_from_pipe(drm
, pipe
);
565 struct tegra_dc
*dc
= to_tegra_dc(crtc
);
568 tegra_dc_disable_vblank(dc
);
571 static void tegra_drm_preclose(struct drm_device
*drm
, struct drm_file
*file
)
573 struct tegra_drm_file
*fpriv
= file
->driver_priv
;
574 struct tegra_drm_context
*context
, *tmp
;
575 struct drm_crtc
*crtc
;
577 list_for_each_entry(crtc
, &drm
->mode_config
.crtc_list
, head
)
578 tegra_dc_cancel_page_flip(crtc
, file
);
580 list_for_each_entry_safe(context
, tmp
, &fpriv
->contexts
, list
)
581 tegra_drm_context_free(context
);
586 #ifdef CONFIG_DEBUG_FS
587 static int tegra_debugfs_framebuffers(struct seq_file
*s
, void *data
)
589 struct drm_info_node
*node
= (struct drm_info_node
*)s
->private;
590 struct drm_device
*drm
= node
->minor
->dev
;
591 struct drm_framebuffer
*fb
;
593 mutex_lock(&drm
->mode_config
.fb_lock
);
595 list_for_each_entry(fb
, &drm
->mode_config
.fb_list
, head
) {
596 seq_printf(s
, "%3d: user size: %d x %d, depth %d, %d bpp, refcount %d\n",
597 fb
->base
.id
, fb
->width
, fb
->height
, fb
->depth
,
599 atomic_read(&fb
->refcount
.refcount
));
602 mutex_unlock(&drm
->mode_config
.fb_lock
);
607 static struct drm_info_list tegra_debugfs_list
[] = {
608 { "framebuffers", tegra_debugfs_framebuffers
, 0 },
611 static int tegra_debugfs_init(struct drm_minor
*minor
)
613 return drm_debugfs_create_files(tegra_debugfs_list
,
614 ARRAY_SIZE(tegra_debugfs_list
),
615 minor
->debugfs_root
, minor
);
618 static void tegra_debugfs_cleanup(struct drm_minor
*minor
)
620 drm_debugfs_remove_files(tegra_debugfs_list
,
621 ARRAY_SIZE(tegra_debugfs_list
), minor
);
625 struct drm_driver tegra_drm_driver
= {
626 .driver_features
= DRIVER_MODESET
| DRIVER_GEM
,
627 .load
= tegra_drm_load
,
628 .unload
= tegra_drm_unload
,
629 .open
= tegra_drm_open
,
630 .preclose
= tegra_drm_preclose
,
631 .lastclose
= tegra_drm_lastclose
,
633 .get_vblank_counter
= tegra_drm_get_vblank_counter
,
634 .enable_vblank
= tegra_drm_enable_vblank
,
635 .disable_vblank
= tegra_drm_disable_vblank
,
637 #if defined(CONFIG_DEBUG_FS)
638 .debugfs_init
= tegra_debugfs_init
,
639 .debugfs_cleanup
= tegra_debugfs_cleanup
,
642 .gem_free_object
= tegra_bo_free_object
,
643 .gem_vm_ops
= &tegra_bo_vm_ops
,
644 .dumb_create
= tegra_bo_dumb_create
,
645 .dumb_map_offset
= tegra_bo_dumb_map_offset
,
646 .dumb_destroy
= drm_gem_dumb_destroy
,
648 .ioctls
= tegra_drm_ioctls
,
649 .num_ioctls
= ARRAY_SIZE(tegra_drm_ioctls
),
650 .fops
= &tegra_drm_fops
,
655 .major
= DRIVER_MAJOR
,
656 .minor
= DRIVER_MINOR
,
657 .patchlevel
= DRIVER_PATCHLEVEL
,