aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_device.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_device.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_device.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c813
1 files changed, 813 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
new file mode 100644
index 000000000000..5fd2b639bf66
--- /dev/null
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -0,0 +1,813 @@
1/*
2 * Copyright 2008 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 * Copyright 2009 Jerome Glisse.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Dave Airlie
25 * Alex Deucher
26 * Jerome Glisse
27 */
28#include <linux/console.h>
29#include <drm/drmP.h>
30#include <drm/drm_crtc_helper.h>
31#include <drm/radeon_drm.h>
32#include "radeon_reg.h"
33#include "radeon.h"
34#include "radeon_asic.h"
35#include "atom.h"
36
37/*
38 * GPU scratch registers helpers function.
39 */
40static void radeon_scratch_init(struct radeon_device *rdev)
41{
42 int i;
43
44 /* FIXME: check this out */
45 if (rdev->family < CHIP_R300) {
46 rdev->scratch.num_reg = 5;
47 } else {
48 rdev->scratch.num_reg = 7;
49 }
50 for (i = 0; i < rdev->scratch.num_reg; i++) {
51 rdev->scratch.free[i] = true;
52 rdev->scratch.reg[i] = RADEON_SCRATCH_REG0 + (i * 4);
53 }
54}
55
56int radeon_scratch_get(struct radeon_device *rdev, uint32_t *reg)
57{
58 int i;
59
60 for (i = 0; i < rdev->scratch.num_reg; i++) {
61 if (rdev->scratch.free[i]) {
62 rdev->scratch.free[i] = false;
63 *reg = rdev->scratch.reg[i];
64 return 0;
65 }
66 }
67 return -EINVAL;
68}
69
70void radeon_scratch_free(struct radeon_device *rdev, uint32_t reg)
71{
72 int i;
73
74 for (i = 0; i < rdev->scratch.num_reg; i++) {
75 if (rdev->scratch.reg[i] == reg) {
76 rdev->scratch.free[i] = true;
77 return;
78 }
79 }
80}
81
82/*
83 * MC common functions
84 */
85int radeon_mc_setup(struct radeon_device *rdev)
86{
87 uint32_t tmp;
88
89 /* Some chips have an "issue" with the memory controller, the
90 * location must be aligned to the size. We just align it down,
91 * too bad if we walk over the top of system memory, we don't
92 * use DMA without a remapped anyway.
93 * Affected chips are rv280, all r3xx, and all r4xx, but not IGP
94 */
95 /* FGLRX seems to setup like this, VRAM a 0, then GART.
96 */
97 /*
98 * Note: from R6xx the address space is 40bits but here we only
99 * use 32bits (still have to see a card which would exhaust 4G
100 * address space).
101 */
102 if (rdev->mc.vram_location != 0xFFFFFFFFUL) {
103 /* vram location was already setup try to put gtt after
104 * if it fits */
105 tmp = rdev->mc.vram_location + rdev->mc.vram_size;
106 tmp = (tmp + rdev->mc.gtt_size - 1) & ~(rdev->mc.gtt_size - 1);
107 if ((0xFFFFFFFFUL - tmp) >= rdev->mc.gtt_size) {
108 rdev->mc.gtt_location = tmp;
109 } else {
110 if (rdev->mc.gtt_size >= rdev->mc.vram_location) {
111 printk(KERN_ERR "[drm] GTT too big to fit "
112 "before or after vram location.\n");
113 return -EINVAL;
114 }
115 rdev->mc.gtt_location = 0;
116 }
117 } else if (rdev->mc.gtt_location != 0xFFFFFFFFUL) {
118 /* gtt location was already setup try to put vram before
119 * if it fits */
120 if (rdev->mc.vram_size < rdev->mc.gtt_location) {
121 rdev->mc.vram_location = 0;
122 } else {
123 tmp = rdev->mc.gtt_location + rdev->mc.gtt_size;
124 tmp += (rdev->mc.vram_size - 1);
125 tmp &= ~(rdev->mc.vram_size - 1);
126 if ((0xFFFFFFFFUL - tmp) >= rdev->mc.vram_size) {
127 rdev->mc.vram_location = tmp;
128 } else {
129 printk(KERN_ERR "[drm] vram too big to fit "
130 "before or after GTT location.\n");
131 return -EINVAL;
132 }
133 }
134 } else {
135 rdev->mc.vram_location = 0;
136 rdev->mc.gtt_location = rdev->mc.vram_size;
137 }
138 DRM_INFO("radeon: VRAM %uM\n", rdev->mc.vram_size >> 20);
139 DRM_INFO("radeon: VRAM from 0x%08X to 0x%08X\n",
140 rdev->mc.vram_location,
141 rdev->mc.vram_location + rdev->mc.vram_size - 1);
142 DRM_INFO("radeon: GTT %uM\n", rdev->mc.gtt_size >> 20);
143 DRM_INFO("radeon: GTT from 0x%08X to 0x%08X\n",
144 rdev->mc.gtt_location,
145 rdev->mc.gtt_location + rdev->mc.gtt_size - 1);
146 return 0;
147}
148
149
150/*
151 * GPU helpers function.
152 */
153static bool radeon_card_posted(struct radeon_device *rdev)
154{
155 uint32_t reg;
156
157 /* first check CRTCs */
158 if (ASIC_IS_AVIVO(rdev)) {
159 reg = RREG32(AVIVO_D1CRTC_CONTROL) |
160 RREG32(AVIVO_D2CRTC_CONTROL);
161 if (reg & AVIVO_CRTC_EN) {
162 return true;
163 }
164 } else {
165 reg = RREG32(RADEON_CRTC_GEN_CNTL) |
166 RREG32(RADEON_CRTC2_GEN_CNTL);
167 if (reg & RADEON_CRTC_EN) {
168 return true;
169 }
170 }
171
172 /* then check MEM_SIZE, in case the crtcs are off */
173 if (rdev->family >= CHIP_R600)
174 reg = RREG32(R600_CONFIG_MEMSIZE);
175 else
176 reg = RREG32(RADEON_CONFIG_MEMSIZE);
177
178 if (reg)
179 return true;
180
181 return false;
182
183}
184
185
186/*
187 * Registers accessors functions.
188 */
189uint32_t radeon_invalid_rreg(struct radeon_device *rdev, uint32_t reg)
190{
191 DRM_ERROR("Invalid callback to read register 0x%04X\n", reg);
192 BUG_ON(1);
193 return 0;
194}
195
196void radeon_invalid_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
197{
198 DRM_ERROR("Invalid callback to write register 0x%04X with 0x%08X\n",
199 reg, v);
200 BUG_ON(1);
201}
202
203void radeon_register_accessor_init(struct radeon_device *rdev)
204{
205 rdev->mm_rreg = &r100_mm_rreg;
206 rdev->mm_wreg = &r100_mm_wreg;
207 rdev->mc_rreg = &radeon_invalid_rreg;
208 rdev->mc_wreg = &radeon_invalid_wreg;
209 rdev->pll_rreg = &radeon_invalid_rreg;
210 rdev->pll_wreg = &radeon_invalid_wreg;
211 rdev->pcie_rreg = &radeon_invalid_rreg;
212 rdev->pcie_wreg = &radeon_invalid_wreg;
213 rdev->pciep_rreg = &radeon_invalid_rreg;
214 rdev->pciep_wreg = &radeon_invalid_wreg;
215
216 /* Don't change order as we are overridding accessor. */
217 if (rdev->family < CHIP_RV515) {
218 rdev->pcie_rreg = &rv370_pcie_rreg;
219 rdev->pcie_wreg = &rv370_pcie_wreg;
220 }
221 if (rdev->family >= CHIP_RV515) {
222 rdev->pcie_rreg = &rv515_pcie_rreg;
223 rdev->pcie_wreg = &rv515_pcie_wreg;
224 }
225 /* FIXME: not sure here */
226 if (rdev->family <= CHIP_R580) {
227 rdev->pll_rreg = &r100_pll_rreg;
228 rdev->pll_wreg = &r100_pll_wreg;
229 }
230 if (rdev->family >= CHIP_RV515) {
231 rdev->mc_rreg = &rv515_mc_rreg;
232 rdev->mc_wreg = &rv515_mc_wreg;
233 }
234 if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480) {
235 rdev->mc_rreg = &rs400_mc_rreg;
236 rdev->mc_wreg = &rs400_mc_wreg;
237 }
238 if (rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) {
239 rdev->mc_rreg = &rs690_mc_rreg;
240 rdev->mc_wreg = &rs690_mc_wreg;
241 }
242 if (rdev->family == CHIP_RS600) {
243 rdev->mc_rreg = &rs600_mc_rreg;
244 rdev->mc_wreg = &rs600_mc_wreg;
245 }
246 if (rdev->family >= CHIP_R600) {
247 rdev->pciep_rreg = &r600_pciep_rreg;
248 rdev->pciep_wreg = &r600_pciep_wreg;
249 }
250}
251
252
253/*
254 * ASIC
255 */
256int radeon_asic_init(struct radeon_device *rdev)
257{
258 radeon_register_accessor_init(rdev);
259 switch (rdev->family) {
260 case CHIP_R100:
261 case CHIP_RV100:
262 case CHIP_RS100:
263 case CHIP_RV200:
264 case CHIP_RS200:
265 case CHIP_R200:
266 case CHIP_RV250:
267 case CHIP_RS300:
268 case CHIP_RV280:
269 rdev->asic = &r100_asic;
270 break;
271 case CHIP_R300:
272 case CHIP_R350:
273 case CHIP_RV350:
274 case CHIP_RV380:
275 rdev->asic = &r300_asic;
276 break;
277 case CHIP_R420:
278 case CHIP_R423:
279 case CHIP_RV410:
280 rdev->asic = &r420_asic;
281 break;
282 case CHIP_RS400:
283 case CHIP_RS480:
284 rdev->asic = &rs400_asic;
285 break;
286 case CHIP_RS600:
287 rdev->asic = &rs600_asic;
288 break;
289 case CHIP_RS690:
290 case CHIP_RS740:
291 rdev->asic = &rs690_asic;
292 break;
293 case CHIP_RV515:
294 rdev->asic = &rv515_asic;
295 break;
296 case CHIP_R520:
297 case CHIP_RV530:
298 case CHIP_RV560:
299 case CHIP_RV570:
300 case CHIP_R580:
301 rdev->asic = &r520_asic;
302 break;
303 case CHIP_R600:
304 case CHIP_RV610:
305 case CHIP_RV630:
306 case CHIP_RV620:
307 case CHIP_RV635:
308 case CHIP_RV670:
309 case CHIP_RS780:
310 case CHIP_RV770:
311 case CHIP_RV730:
312 case CHIP_RV710:
313 default:
314 /* FIXME: not supported yet */
315 return -EINVAL;
316 }
317 return 0;
318}
319
320
321/*
322 * Wrapper around modesetting bits.
323 */
324int radeon_clocks_init(struct radeon_device *rdev)
325{
326 int r;
327
328 radeon_get_clock_info(rdev->ddev);
329 r = radeon_static_clocks_init(rdev->ddev);
330 if (r) {
331 return r;
332 }
333 DRM_INFO("Clocks initialized !\n");
334 return 0;
335}
336
337void radeon_clocks_fini(struct radeon_device *rdev)
338{
339}
340
341/* ATOM accessor methods */
342static uint32_t cail_pll_read(struct card_info *info, uint32_t reg)
343{
344 struct radeon_device *rdev = info->dev->dev_private;
345 uint32_t r;
346
347 r = rdev->pll_rreg(rdev, reg);
348 return r;
349}
350
351static void cail_pll_write(struct card_info *info, uint32_t reg, uint32_t val)
352{
353 struct radeon_device *rdev = info->dev->dev_private;
354
355 rdev->pll_wreg(rdev, reg, val);
356}
357
358static uint32_t cail_mc_read(struct card_info *info, uint32_t reg)
359{
360 struct radeon_device *rdev = info->dev->dev_private;
361 uint32_t r;
362
363 r = rdev->mc_rreg(rdev, reg);
364 return r;
365}
366
367static void cail_mc_write(struct card_info *info, uint32_t reg, uint32_t val)
368{
369 struct radeon_device *rdev = info->dev->dev_private;
370
371 rdev->mc_wreg(rdev, reg, val);
372}
373
374static void cail_reg_write(struct card_info *info, uint32_t reg, uint32_t val)
375{
376 struct radeon_device *rdev = info->dev->dev_private;
377
378 WREG32(reg*4, val);
379}
380
381static uint32_t cail_reg_read(struct card_info *info, uint32_t reg)
382{
383 struct radeon_device *rdev = info->dev->dev_private;
384 uint32_t r;
385
386 r = RREG32(reg*4);
387 return r;
388}
389
390static struct card_info atom_card_info = {
391 .dev = NULL,
392 .reg_read = cail_reg_read,
393 .reg_write = cail_reg_write,
394 .mc_read = cail_mc_read,
395 .mc_write = cail_mc_write,
396 .pll_read = cail_pll_read,
397 .pll_write = cail_pll_write,
398};
399
400int radeon_atombios_init(struct radeon_device *rdev)
401{
402 atom_card_info.dev = rdev->ddev;
403 rdev->mode_info.atom_context = atom_parse(&atom_card_info, rdev->bios);
404 radeon_atom_initialize_bios_scratch_regs(rdev->ddev);
405 return 0;
406}
407
408void radeon_atombios_fini(struct radeon_device *rdev)
409{
410 kfree(rdev->mode_info.atom_context);
411}
412
413int radeon_combios_init(struct radeon_device *rdev)
414{
415 radeon_combios_initialize_bios_scratch_regs(rdev->ddev);
416 return 0;
417}
418
419void radeon_combios_fini(struct radeon_device *rdev)
420{
421}
422
423int radeon_modeset_init(struct radeon_device *rdev);
424void radeon_modeset_fini(struct radeon_device *rdev);
425
426
427/*
428 * Radeon device.
429 */
430int radeon_device_init(struct radeon_device *rdev,
431 struct drm_device *ddev,
432 struct pci_dev *pdev,
433 uint32_t flags)
434{
435 int r, ret;
436
437 DRM_INFO("radeon: Initializing kernel modesetting.\n");
438 rdev->shutdown = false;
439 rdev->ddev = ddev;
440 rdev->pdev = pdev;
441 rdev->flags = flags;
442 rdev->family = flags & RADEON_FAMILY_MASK;
443 rdev->is_atom_bios = false;
444 rdev->usec_timeout = RADEON_MAX_USEC_TIMEOUT;
445 rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
446 rdev->gpu_lockup = false;
447 /* mutex initialization are all done here so we
448 * can recall function without having locking issues */
449 mutex_init(&rdev->cs_mutex);
450 mutex_init(&rdev->ib_pool.mutex);
451 mutex_init(&rdev->cp.mutex);
452 rwlock_init(&rdev->fence_drv.lock);
453
454 if (radeon_agpmode == -1) {
455 rdev->flags &= ~RADEON_IS_AGP;
456 if (rdev->family > CHIP_RV515 ||
457 rdev->family == CHIP_RV380 ||
458 rdev->family == CHIP_RV410 ||
459 rdev->family == CHIP_R423) {
460 DRM_INFO("Forcing AGP to PCIE mode\n");
461 rdev->flags |= RADEON_IS_PCIE;
462 } else {
463 DRM_INFO("Forcing AGP to PCI mode\n");
464 rdev->flags |= RADEON_IS_PCI;
465 }
466 }
467
468 /* Set asic functions */
469 r = radeon_asic_init(rdev);
470 if (r) {
471 return r;
472 }
473
474 /* Report DMA addressing limitation */
475 r = pci_set_dma_mask(rdev->pdev, DMA_BIT_MASK(32));
476 if (r) {
477 printk(KERN_WARNING "radeon: No suitable DMA available.\n");
478 }
479
480 /* Registers mapping */
481 /* TODO: block userspace mapping of io register */
482 rdev->rmmio_base = drm_get_resource_start(rdev->ddev, 2);
483 rdev->rmmio_size = drm_get_resource_len(rdev->ddev, 2);
484 rdev->rmmio = ioremap(rdev->rmmio_base, rdev->rmmio_size);
485 if (rdev->rmmio == NULL) {
486 return -ENOMEM;
487 }
488 DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)rdev->rmmio_base);
489 DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size);
490
491 /* Setup errata flags */
492 radeon_errata(rdev);
493 /* Initialize scratch registers */
494 radeon_scratch_init(rdev);
495
496 /* TODO: disable VGA need to use VGA request */
497 /* BIOS*/
498 if (!radeon_get_bios(rdev)) {
499 if (ASIC_IS_AVIVO(rdev))
500 return -EINVAL;
501 }
502 if (rdev->is_atom_bios) {
503 r = radeon_atombios_init(rdev);
504 if (r) {
505 return r;
506 }
507 } else {
508 r = radeon_combios_init(rdev);
509 if (r) {
510 return r;
511 }
512 }
513 /* Reset gpu before posting otherwise ATOM will enter infinite loop */
514 if (radeon_gpu_reset(rdev)) {
515 /* FIXME: what do we want to do here ? */
516 }
517 /* check if cards are posted or not */
518 if (!radeon_card_posted(rdev) && rdev->bios) {
519 DRM_INFO("GPU not posted. posting now...\n");
520 if (rdev->is_atom_bios) {
521 atom_asic_init(rdev->mode_info.atom_context);
522 } else {
523 radeon_combios_asic_init(rdev->ddev);
524 }
525 }
526 /* Get vram informations */
527 radeon_vram_info(rdev);
528 /* Device is severly broken if aper size > vram size.
529 * for RN50/M6/M7 - Novell bug 204882 ?
530 */
531 if (rdev->mc.vram_size < rdev->mc.aper_size) {
532 rdev->mc.aper_size = rdev->mc.vram_size;
533 }
534 /* Add an MTRR for the VRAM */
535 rdev->mc.vram_mtrr = mtrr_add(rdev->mc.aper_base, rdev->mc.aper_size,
536 MTRR_TYPE_WRCOMB, 1);
537 DRM_INFO("Detected VRAM RAM=%uM, BAR=%uM\n",
538 rdev->mc.vram_size >> 20,
539 (unsigned)rdev->mc.aper_size >> 20);
540 DRM_INFO("RAM width %dbits %cDR\n",
541 rdev->mc.vram_width, rdev->mc.vram_is_ddr ? 'D' : 'S');
542 /* Initialize clocks */
543 r = radeon_clocks_init(rdev);
544 if (r) {
545 return r;
546 }
547 /* Initialize memory controller (also test AGP) */
548 r = radeon_mc_init(rdev);
549 if (r) {
550 return r;
551 }
552 /* Fence driver */
553 r = radeon_fence_driver_init(rdev);
554 if (r) {
555 return r;
556 }
557 r = radeon_irq_kms_init(rdev);
558 if (r) {
559 return r;
560 }
561 /* Memory manager */
562 r = radeon_object_init(rdev);
563 if (r) {
564 return r;
565 }
566 /* Initialize GART (initialize after TTM so we can allocate
567 * memory through TTM but finalize after TTM) */
568 r = radeon_gart_enable(rdev);
569 if (!r) {
570 r = radeon_gem_init(rdev);
571 }
572
573 /* 1M ring buffer */
574 if (!r) {
575 r = radeon_cp_init(rdev, 1024 * 1024);
576 }
577 if (!r) {
578 r = radeon_wb_init(rdev);
579 if (r) {
580 DRM_ERROR("radeon: failled initializing WB (%d).\n", r);
581 return r;
582 }
583 }
584 if (!r) {
585 r = radeon_ib_pool_init(rdev);
586 if (r) {
587 DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r);
588 return r;
589 }
590 }
591 if (!r) {
592 r = radeon_ib_test(rdev);
593 if (r) {
594 DRM_ERROR("radeon: failled testing IB (%d).\n", r);
595 return r;
596 }
597 }
598 ret = r;
599 r = radeon_modeset_init(rdev);
600 if (r) {
601 return r;
602 }
603 if (rdev->fbdev_rfb && rdev->fbdev_rfb->obj) {
604 rdev->fbdev_robj = rdev->fbdev_rfb->obj->driver_private;
605 }
606 if (!ret) {
607 DRM_INFO("radeon: kernel modesetting successfully initialized.\n");
608 }
609 if (radeon_benchmarking) {
610 radeon_benchmark(rdev);
611 }
612 return ret;
613}
614
615void radeon_device_fini(struct radeon_device *rdev)
616{
617 if (rdev == NULL || rdev->rmmio == NULL) {
618 return;
619 }
620 DRM_INFO("radeon: finishing device.\n");
621 rdev->shutdown = true;
622 /* Order matter so becarefull if you rearrange anythings */
623 radeon_modeset_fini(rdev);
624 radeon_ib_pool_fini(rdev);
625 radeon_cp_fini(rdev);
626 radeon_wb_fini(rdev);
627 radeon_gem_fini(rdev);
628 radeon_object_fini(rdev);
629 /* mc_fini must be after object_fini */
630 radeon_mc_fini(rdev);
631#if __OS_HAS_AGP
632 radeon_agp_fini(rdev);
633#endif
634 radeon_irq_kms_fini(rdev);
635 radeon_fence_driver_fini(rdev);
636 radeon_clocks_fini(rdev);
637 if (rdev->is_atom_bios) {
638 radeon_atombios_fini(rdev);
639 } else {
640 radeon_combios_fini(rdev);
641 }
642 kfree(rdev->bios);
643 rdev->bios = NULL;
644 iounmap(rdev->rmmio);
645 rdev->rmmio = NULL;
646}
647
648
649/*
650 * Suspend & resume.
651 */
652int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
653{
654 struct radeon_device *rdev = dev->dev_private;
655 struct drm_crtc *crtc;
656
657 if (dev == NULL || rdev == NULL) {
658 return -ENODEV;
659 }
660 if (state.event == PM_EVENT_PRETHAW) {
661 return 0;
662 }
663 /* unpin the front buffers */
664 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
665 struct radeon_framebuffer *rfb = to_radeon_framebuffer(crtc->fb);
666 struct radeon_object *robj;
667
668 if (rfb == NULL || rfb->obj == NULL) {
669 continue;
670 }
671 robj = rfb->obj->driver_private;
672 if (robj != rdev->fbdev_robj) {
673 radeon_object_unpin(robj);
674 }
675 }
676 /* evict vram memory */
677 radeon_object_evict_vram(rdev);
678 /* wait for gpu to finish processing current batch */
679 radeon_fence_wait_last(rdev);
680
681 radeon_cp_disable(rdev);
682 radeon_gart_disable(rdev);
683
684 /* evict remaining vram memory */
685 radeon_object_evict_vram(rdev);
686
687 rdev->irq.sw_int = false;
688 radeon_irq_set(rdev);
689
690 pci_save_state(dev->pdev);
691 if (state.event == PM_EVENT_SUSPEND) {
692 /* Shut down the device */
693 pci_disable_device(dev->pdev);
694 pci_set_power_state(dev->pdev, PCI_D3hot);
695 }
696 acquire_console_sem();
697 fb_set_suspend(rdev->fbdev_info, 1);
698 release_console_sem();
699 return 0;
700}
701
702int radeon_resume_kms(struct drm_device *dev)
703{
704 struct radeon_device *rdev = dev->dev_private;
705 int r;
706
707 acquire_console_sem();
708 pci_set_power_state(dev->pdev, PCI_D0);
709 pci_restore_state(dev->pdev);
710 if (pci_enable_device(dev->pdev)) {
711 release_console_sem();
712 return -1;
713 }
714 pci_set_master(dev->pdev);
715 /* Reset gpu before posting otherwise ATOM will enter infinite loop */
716 if (radeon_gpu_reset(rdev)) {
717 /* FIXME: what do we want to do here ? */
718 }
719 /* post card */
720 if (rdev->is_atom_bios) {
721 atom_asic_init(rdev->mode_info.atom_context);
722 } else {
723 radeon_combios_asic_init(rdev->ddev);
724 }
725 /* Initialize clocks */
726 r = radeon_clocks_init(rdev);
727 if (r) {
728 release_console_sem();
729 return r;
730 }
731 /* Enable IRQ */
732 rdev->irq.sw_int = true;
733 radeon_irq_set(rdev);
734 /* Initialize GPU Memory Controller */
735 r = radeon_mc_init(rdev);
736 if (r) {
737 goto out;
738 }
739 r = radeon_gart_enable(rdev);
740 if (r) {
741 goto out;
742 }
743 r = radeon_cp_init(rdev, rdev->cp.ring_size);
744 if (r) {
745 goto out;
746 }
747out:
748 fb_set_suspend(rdev->fbdev_info, 0);
749 release_console_sem();
750
751 /* blat the mode back in */
752 drm_helper_resume_force_mode(dev);
753 return 0;
754}
755
756
757/*
758 * Debugfs
759 */
760struct radeon_debugfs {
761 struct drm_info_list *files;
762 unsigned num_files;
763};
764static struct radeon_debugfs _radeon_debugfs[RADEON_DEBUGFS_MAX_NUM_FILES];
765static unsigned _radeon_debugfs_count = 0;
766
767int radeon_debugfs_add_files(struct radeon_device *rdev,
768 struct drm_info_list *files,
769 unsigned nfiles)
770{
771 unsigned i;
772
773 for (i = 0; i < _radeon_debugfs_count; i++) {
774 if (_radeon_debugfs[i].files == files) {
775 /* Already registered */
776 return 0;
777 }
778 }
779 if ((_radeon_debugfs_count + nfiles) > RADEON_DEBUGFS_MAX_NUM_FILES) {
780 DRM_ERROR("Reached maximum number of debugfs files.\n");
781 DRM_ERROR("Report so we increase RADEON_DEBUGFS_MAX_NUM_FILES.\n");
782 return -EINVAL;
783 }
784 _radeon_debugfs[_radeon_debugfs_count].files = files;
785 _radeon_debugfs[_radeon_debugfs_count].num_files = nfiles;
786 _radeon_debugfs_count++;
787#if defined(CONFIG_DEBUG_FS)
788 drm_debugfs_create_files(files, nfiles,
789 rdev->ddev->control->debugfs_root,
790 rdev->ddev->control);
791 drm_debugfs_create_files(files, nfiles,
792 rdev->ddev->primary->debugfs_root,
793 rdev->ddev->primary);
794#endif
795 return 0;
796}
797
798#if defined(CONFIG_DEBUG_FS)
799int radeon_debugfs_init(struct drm_minor *minor)
800{
801 return 0;
802}
803
804void radeon_debugfs_cleanup(struct drm_minor *minor)
805{
806 unsigned i;
807
808 for (i = 0; i < _radeon_debugfs_count; i++) {
809 drm_debugfs_remove_files(_radeon_debugfs[i].files,
810 _radeon_debugfs[i].num_files, minor);
811 }
812}
813#endif