2 * Copyright (C) 2012 Avionic Design GmbH
3 * Copyright (C) 2012 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>
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
26 static int tegra_drm_load(struct drm_device
*drm
, unsigned long flags
)
28 struct device
*dev
= drm
->dev
;
29 struct host1x
*host1x
;
32 host1x
= dev_get_drvdata(dev
);
33 drm
->dev_private
= host1x
;
36 drm_mode_config_init(drm
);
38 err
= host1x_drm_init(host1x
, drm
);
42 err
= drm_vblank_init(drm
, drm
->mode_config
.num_crtc
);
46 err
= tegra_drm_fb_init(drm
);
50 drm_kms_helper_poll_init(drm
);
55 static int tegra_drm_unload(struct drm_device
*drm
)
57 drm_kms_helper_poll_fini(drm
);
58 tegra_drm_fb_exit(drm
);
60 drm_mode_config_cleanup(drm
);
65 static int tegra_drm_open(struct drm_device
*drm
, struct drm_file
*filp
)
70 static void tegra_drm_lastclose(struct drm_device
*drm
)
72 struct host1x
*host1x
= drm
->dev_private
;
74 drm_fbdev_cma_restore_mode(host1x
->fbdev
);
77 static struct drm_ioctl_desc tegra_drm_ioctls
[] = {
80 static const struct file_operations tegra_drm_fops
= {
83 .release
= drm_release
,
84 .unlocked_ioctl
= drm_ioctl
,
85 .mmap
= drm_gem_cma_mmap
,
90 .compat_ioctl
= drm_compat_ioctl
,
92 .llseek
= noop_llseek
,
95 static struct drm_crtc
*tegra_crtc_from_pipe(struct drm_device
*drm
, int pipe
)
97 struct drm_crtc
*crtc
;
99 list_for_each_entry(crtc
, &drm
->mode_config
.crtc_list
, head
) {
100 struct tegra_dc
*dc
= to_tegra_dc(crtc
);
102 if (dc
->pipe
== pipe
)
109 static u32
tegra_drm_get_vblank_counter(struct drm_device
*dev
, int crtc
)
111 /* TODO: implement real hardware counter using syncpoints */
112 return drm_vblank_count(dev
, crtc
);
115 static int tegra_drm_enable_vblank(struct drm_device
*drm
, int pipe
)
117 struct drm_crtc
*crtc
= tegra_crtc_from_pipe(drm
, pipe
);
118 struct tegra_dc
*dc
= to_tegra_dc(crtc
);
123 tegra_dc_enable_vblank(dc
);
128 static void tegra_drm_disable_vblank(struct drm_device
*drm
, int pipe
)
130 struct drm_crtc
*crtc
= tegra_crtc_from_pipe(drm
, pipe
);
131 struct tegra_dc
*dc
= to_tegra_dc(crtc
);
134 tegra_dc_disable_vblank(dc
);
137 static void tegra_drm_preclose(struct drm_device
*drm
, struct drm_file
*file
)
139 struct drm_crtc
*crtc
;
141 list_for_each_entry(crtc
, &drm
->mode_config
.crtc_list
, head
)
142 tegra_dc_cancel_page_flip(crtc
, file
);
145 #ifdef CONFIG_DEBUG_FS
146 static int tegra_debugfs_framebuffers(struct seq_file
*s
, void *data
)
148 struct drm_info_node
*node
= (struct drm_info_node
*)s
->private;
149 struct drm_device
*drm
= node
->minor
->dev
;
150 struct drm_framebuffer
*fb
;
152 mutex_lock(&drm
->mode_config
.fb_lock
);
154 list_for_each_entry(fb
, &drm
->mode_config
.fb_list
, head
) {
155 seq_printf(s
, "%3d: user size: %d x %d, depth %d, %d bpp, refcount %d\n",
156 fb
->base
.id
, fb
->width
, fb
->height
, fb
->depth
,
158 atomic_read(&fb
->refcount
.refcount
));
161 mutex_unlock(&drm
->mode_config
.fb_lock
);
166 static struct drm_info_list tegra_debugfs_list
[] = {
167 { "framebuffers", tegra_debugfs_framebuffers
, 0 },
170 static int tegra_debugfs_init(struct drm_minor
*minor
)
172 return drm_debugfs_create_files(tegra_debugfs_list
,
173 ARRAY_SIZE(tegra_debugfs_list
),
174 minor
->debugfs_root
, minor
);
177 static void tegra_debugfs_cleanup(struct drm_minor
*minor
)
179 drm_debugfs_remove_files(tegra_debugfs_list
,
180 ARRAY_SIZE(tegra_debugfs_list
), minor
);
184 struct drm_driver tegra_drm_driver
= {
185 .driver_features
= DRIVER_BUS_PLATFORM
| DRIVER_MODESET
| DRIVER_GEM
,
186 .load
= tegra_drm_load
,
187 .unload
= tegra_drm_unload
,
188 .open
= tegra_drm_open
,
189 .preclose
= tegra_drm_preclose
,
190 .lastclose
= tegra_drm_lastclose
,
192 .get_vblank_counter
= tegra_drm_get_vblank_counter
,
193 .enable_vblank
= tegra_drm_enable_vblank
,
194 .disable_vblank
= tegra_drm_disable_vblank
,
196 #if defined(CONFIG_DEBUG_FS)
197 .debugfs_init
= tegra_debugfs_init
,
198 .debugfs_cleanup
= tegra_debugfs_cleanup
,
201 .gem_free_object
= drm_gem_cma_free_object
,
202 .gem_vm_ops
= &drm_gem_cma_vm_ops
,
203 .dumb_create
= drm_gem_cma_dumb_create
,
204 .dumb_map_offset
= drm_gem_cma_dumb_map_offset
,
205 .dumb_destroy
= drm_gem_cma_dumb_destroy
,
207 .ioctls
= tegra_drm_ioctls
,
208 .num_ioctls
= ARRAY_SIZE(tegra_drm_ioctls
),
209 .fops
= &tegra_drm_fops
,
214 .major
= DRIVER_MAJOR
,
215 .minor
= DRIVER_MINOR
,
216 .patchlevel
= DRIVER_PATCHLEVEL
,