aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_drv.c
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2009-06-05 08:42:42 -0400
committerDave Airlie <airlied@redhat.com>2009-06-14 22:01:53 -0400
commit771fe6b912fca54f03e8a72eb63058b582775362 (patch)
tree58aa5469ba8058c2b564d50807395ad6cd7bd7e4 /drivers/gpu/drm/radeon/radeon_drv.c
parentba4e7d973dd09b66912ac4c0856add8b0703a997 (diff)
drm/radeon: introduce kernel modesetting for radeon hardware
Add kernel modesetting support to radeon driver, use the ttm memory manager to manage memory and DRM/GEM to provide userspace API. In order to avoid backward compatibility issue and to allow clean design and code the radeon kernel modesetting use different code path than old radeon/drm driver. When kernel modesetting is enabled the IOCTL of radeon/drm driver are considered as invalid and an error message is printed in the log and they return failure. KMS enabled userspace will use new API to talk with the radeon/drm driver. The new API provide functions to create/destroy/share/mmap buffer object which are then managed by the kernel memory manager (here TTM). In order to submit command to the GPU the userspace provide a buffer holding the command stream, along this buffer userspace have to provide a list of buffer object used by the command stream. The kernel radeon driver will then place buffer in GPU accessible memory and will update command stream to reflect the position of the different buffers. The kernel will also perform security check on command stream provided by the user, we want to catch and forbid any illegal use of the GPU such as DMA into random system memory or into memory not owned by the process supplying the command stream. This part of the code is still incomplete and this why we propose that patch as a staging driver addition, future security might forbid current experimental userspace to run. This code support the following hardware : R1XX,R2XX,R3XX,R4XX,R5XX (radeon up to X1950). Works is underway to provide support for R6XX, R7XX and newer hardware (radeon from HD2XXX to HD4XXX). Authors: Jerome Glisse <jglisse@redhat.com> Dave Airlie <airlied@redhat.com> Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Jerome Glisse <jglisse@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com> Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_drv.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c215
1 files changed, 211 insertions, 4 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 13a60f4d4227..f70c351bb43e 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -35,12 +35,92 @@
35#include "radeon_drv.h" 35#include "radeon_drv.h"
36 36
37#include "drm_pciids.h" 37#include "drm_pciids.h"
38#include <linux/console.h>
39
40
41#if defined(CONFIG_DRM_RADEON_KMS)
42/*
43 * KMS wrapper.
44 */
45#define KMS_DRIVER_MAJOR 2
46#define KMS_DRIVER_MINOR 0
47#define KMS_DRIVER_PATCHLEVEL 0
48int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
49int radeon_driver_unload_kms(struct drm_device *dev);
50int radeon_driver_firstopen_kms(struct drm_device *dev);
51void radeon_driver_lastclose_kms(struct drm_device *dev);
52int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv);
53void radeon_driver_postclose_kms(struct drm_device *dev,
54 struct drm_file *file_priv);
55void radeon_driver_preclose_kms(struct drm_device *dev,
56 struct drm_file *file_priv);
57int radeon_suspend_kms(struct drm_device *dev, pm_message_t state);
58int radeon_resume_kms(struct drm_device *dev);
59u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc);
60int radeon_enable_vblank_kms(struct drm_device *dev, int crtc);
61void radeon_disable_vblank_kms(struct drm_device *dev, int crtc);
62void radeon_driver_irq_preinstall_kms(struct drm_device *dev);
63int radeon_driver_irq_postinstall_kms(struct drm_device *dev);
64void radeon_driver_irq_uninstall_kms(struct drm_device *dev);
65irqreturn_t radeon_driver_irq_handler_kms(DRM_IRQ_ARGS);
66int radeon_master_create_kms(struct drm_device *dev, struct drm_master *master);
67void radeon_master_destroy_kms(struct drm_device *dev,
68 struct drm_master *master);
69int radeon_dma_ioctl_kms(struct drm_device *dev, void *data,
70 struct drm_file *file_priv);
71int radeon_gem_object_init(struct drm_gem_object *obj);
72void radeon_gem_object_free(struct drm_gem_object *obj);
73extern struct drm_ioctl_desc radeon_ioctls_kms[];
74extern int radeon_max_kms_ioctl;
75int radeon_mmap(struct file *filp, struct vm_area_struct *vma);
76#if defined(CONFIG_DEBUG_FS)
77int radeon_debugfs_init(struct drm_minor *minor);
78void radeon_debugfs_cleanup(struct drm_minor *minor);
79#endif
80#endif
81
38 82
39int radeon_no_wb; 83int radeon_no_wb;
84#if defined(CONFIG_DRM_RADEON_KMS)
85int radeon_modeset = -1;
86int radeon_dynclks = -1;
87int radeon_r4xx_atom = 0;
88int radeon_agpmode = 0;
89int radeon_vram_limit = 0;
90int radeon_gart_size = 512; /* default gart size */
91int radeon_benchmarking = 0;
92int radeon_connector_table = 0;
93#endif
40 94
41MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); 95MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers");
42module_param_named(no_wb, radeon_no_wb, int, 0444); 96module_param_named(no_wb, radeon_no_wb, int, 0444);
43 97
98#if defined(CONFIG_DRM_RADEON_KMS)
99MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
100module_param_named(modeset, radeon_modeset, int, 0400);
101
102MODULE_PARM_DESC(dynclks, "Disable/Enable dynamic clocks");
103module_param_named(dynclks, radeon_dynclks, int, 0444);
104
105MODULE_PARM_DESC(r4xx_atom, "Enable ATOMBIOS modesetting for R4xx");
106module_param_named(r4xx_atom, radeon_r4xx_atom, int, 0444);
107
108MODULE_PARM_DESC(vramlimit, "Restrict VRAM for testing");
109module_param_named(vramlimit, radeon_vram_limit, int, 0600);
110
111MODULE_PARM_DESC(agpmode, "AGP Mode (-1 == PCI)");
112module_param_named(agpmode, radeon_agpmode, int, 0444);
113
114MODULE_PARM_DESC(gartsize, "Size of PCIE/IGP gart to setup in megabytes (32,64, etc)\n");
115module_param_named(gartsize, radeon_gart_size, int, 0600);
116
117MODULE_PARM_DESC(benchmark, "Run benchmark");
118module_param_named(benchmark, radeon_benchmarking, int, 0444);
119
120MODULE_PARM_DESC(connector_table, "Force connector table");
121module_param_named(connector_table, radeon_connector_table, int, 0444);
122#endif
123
44static int radeon_suspend(struct drm_device *dev, pm_message_t state) 124static int radeon_suspend(struct drm_device *dev, pm_message_t state)
45{ 125{
46 drm_radeon_private_t *dev_priv = dev->dev_private; 126 drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -73,7 +153,11 @@ static struct pci_device_id pciidlist[] = {
73 radeon_PCI_IDS 153 radeon_PCI_IDS
74}; 154};
75 155
76static struct drm_driver driver = { 156#if defined(CONFIG_DRM_RADEON_KMS)
157MODULE_DEVICE_TABLE(pci, pciidlist);
158#endif
159
160static struct drm_driver driver_old = {
77 .driver_features = 161 .driver_features =
78 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | 162 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG |
79 DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED, 163 DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED,
@@ -127,15 +211,138 @@ static struct drm_driver driver = {
127 .patchlevel = DRIVER_PATCHLEVEL, 211 .patchlevel = DRIVER_PATCHLEVEL,
128}; 212};
129 213
214#if defined(CONFIG_DRM_RADEON_KMS)
215static struct drm_driver kms_driver;
216
217static int __devinit
218radeon_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
219{
220 return drm_get_dev(pdev, ent, &kms_driver);
221}
222
223static void
224radeon_pci_remove(struct pci_dev *pdev)
225{
226 struct drm_device *dev = pci_get_drvdata(pdev);
227
228 drm_put_dev(dev);
229}
230
231static int
232radeon_pci_suspend(struct pci_dev *pdev, pm_message_t state)
233{
234 struct drm_device *dev = pci_get_drvdata(pdev);
235 return radeon_suspend_kms(dev, state);
236}
237
238static int
239radeon_pci_resume(struct pci_dev *pdev)
240{
241 struct drm_device *dev = pci_get_drvdata(pdev);
242 return radeon_resume_kms(dev);
243}
244
245static struct drm_driver kms_driver = {
246 .driver_features =
247 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG |
248 DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | DRIVER_GEM,
249 .dev_priv_size = 0,
250 .load = radeon_driver_load_kms,
251 .firstopen = radeon_driver_firstopen_kms,
252 .open = radeon_driver_open_kms,
253 .preclose = radeon_driver_preclose_kms,
254 .postclose = radeon_driver_postclose_kms,
255 .lastclose = radeon_driver_lastclose_kms,
256 .unload = radeon_driver_unload_kms,
257 .suspend = radeon_suspend_kms,
258 .resume = radeon_resume_kms,
259 .get_vblank_counter = radeon_get_vblank_counter_kms,
260 .enable_vblank = radeon_enable_vblank_kms,
261 .disable_vblank = radeon_disable_vblank_kms,
262 .master_create = radeon_master_create_kms,
263 .master_destroy = radeon_master_destroy_kms,
264#if defined(CONFIG_DEBUG_FS)
265 .debugfs_init = radeon_debugfs_init,
266 .debugfs_cleanup = radeon_debugfs_cleanup,
267#endif
268 .irq_preinstall = radeon_driver_irq_preinstall_kms,
269 .irq_postinstall = radeon_driver_irq_postinstall_kms,
270 .irq_uninstall = radeon_driver_irq_uninstall_kms,
271 .irq_handler = radeon_driver_irq_handler_kms,
272 .reclaim_buffers = drm_core_reclaim_buffers,
273 .get_map_ofs = drm_core_get_map_ofs,
274 .get_reg_ofs = drm_core_get_reg_ofs,
275 .ioctls = radeon_ioctls_kms,
276 .gem_init_object = radeon_gem_object_init,
277 .gem_free_object = radeon_gem_object_free,
278 .dma_ioctl = radeon_dma_ioctl_kms,
279 .fops = {
280 .owner = THIS_MODULE,
281 .open = drm_open,
282 .release = drm_release,
283 .ioctl = drm_ioctl,
284 .mmap = radeon_mmap,
285 .poll = drm_poll,
286 .fasync = drm_fasync,
287#ifdef CONFIG_COMPAT
288 .compat_ioctl = NULL,
289#endif
290 },
291
292 .pci_driver = {
293 .name = DRIVER_NAME,
294 .id_table = pciidlist,
295 .probe = radeon_pci_probe,
296 .remove = radeon_pci_remove,
297 .suspend = radeon_pci_suspend,
298 .resume = radeon_pci_resume,
299 },
300
301 .name = DRIVER_NAME,
302 .desc = DRIVER_DESC,
303 .date = DRIVER_DATE,
304 .major = KMS_DRIVER_MAJOR,
305 .minor = KMS_DRIVER_MINOR,
306 .patchlevel = KMS_DRIVER_PATCHLEVEL,
307};
308#endif
309
310static struct drm_driver *driver;
311
130static int __init radeon_init(void) 312static int __init radeon_init(void)
131{ 313{
132 driver.num_ioctls = radeon_max_ioctl; 314 driver = &driver_old;
133 return drm_init(&driver); 315 driver->num_ioctls = radeon_max_ioctl;
316#if defined(CONFIG_DRM_RADEON_KMS) && defined(CONFIG_X86)
317 /* if enabled by default */
318 if (radeon_modeset == -1) {
319 DRM_INFO("radeon default to kernel modesetting.\n");
320 radeon_modeset = 1;
321 }
322 if (radeon_modeset == 1) {
323 DRM_INFO("radeon kernel modesetting enabled.\n");
324 driver = &kms_driver;
325 driver->driver_features |= DRIVER_MODESET;
326 driver->num_ioctls = radeon_max_kms_ioctl;
327 }
328
329 /* if the vga console setting is enabled still
330 * let modprobe override it */
331#ifdef CONFIG_VGA_CONSOLE
332 if (vgacon_text_force() && radeon_modeset == -1) {
333 DRM_INFO("VGACON disable radeon kernel modesetting.\n");
334 driver = &driver_old;
335 driver->driver_features &= ~DRIVER_MODESET;
336 radeon_modeset = 0;
337 }
338#endif
339#endif
340 return drm_init(driver);
134} 341}
135 342
136static void __exit radeon_exit(void) 343static void __exit radeon_exit(void)
137{ 344{
138 drm_exit(&driver); 345 drm_exit(driver);
139} 346}
140 347
141module_init(radeon_init); 348module_init(radeon_init);