aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/rv770.c
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2009-12-01 13:43:46 -0500
committerDave Airlie <airlied@redhat.com>2009-12-01 23:00:06 -0500
commitd8f60cfc93452d0554f6a701aa8e3236cbee4636 (patch)
treed6048658b42bdd9443f424755cd85f855e1477ba /drivers/gpu/drm/radeon/rv770.c
parent50dafba685c0f12c23d315820370b32d9ba64db7 (diff)
drm/radeon/kms: Add support for interrupts on r6xx/r7xx chips (v3)
This enables the use of interrupts on r6xx/r7xx hardware. Interrupts are implemented via a ring buffer. The GPU adds interrupts vectors to the ring and the host reads them off in the interrupt handler. The interrupt controller requires firmware like the CP. This firmware must be installed and accessble to the firmware loader for interrupts to function. MSIs don't seem to work on my RS780. They work fine on all my discrete cards. I'm not sure about other RS780s or RS880s. I've disabled MSIs on RS780 and RS880, but it would probably be worth checking on some other systems. v2 - fix some checkpatch.pl problems; re-read the disp int status reg if we restart the ih; v3 - remove the irq handler if r600_irq_init() fails; remove spinlock in r600_ih_ring_fini(); move ih rb overflow check to r600_get_ih_wptr(); move irq ack to separate function; Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/rv770.c')
-rw-r--r--drivers/gpu/drm/radeon/rv770.c24
1 files changed, 22 insertions, 2 deletions
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index f54628475456..479684bda7e2 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -887,6 +887,16 @@ static int rv770_startup(struct radeon_device *rdev)
887 return r; 887 return r;
888 } 888 }
889 889
890 /* Enable IRQ */
891 rdev->irq.sw_int = true;
892 r = r600_irq_init(rdev);
893 if (r) {
894 DRM_ERROR("radeon: IH init failed (%d).\n", r);
895 radeon_irq_kms_fini(rdev);
896 return r;
897 }
898 r600_irq_set(rdev);
899
890 r = radeon_ring_init(rdev, rdev->cp.ring_size); 900 r = radeon_ring_init(rdev, rdev->cp.ring_size);
891 if (r) 901 if (r)
892 return r; 902 return r;
@@ -1005,11 +1015,19 @@ int rv770_init(struct radeon_device *rdev)
1005 r = radeon_object_init(rdev); 1015 r = radeon_object_init(rdev);
1006 if (r) 1016 if (r)
1007 return r; 1017 return r;
1018
1019 r = radeon_irq_kms_init(rdev);
1020 if (r)
1021 return r;
1022
1008 rdev->cp.ring_obj = NULL; 1023 rdev->cp.ring_obj = NULL;
1009 r600_ring_init(rdev, 1024 * 1024); 1024 r600_ring_init(rdev, 1024 * 1024);
1010 1025
1011 if (!rdev->me_fw || !rdev->pfp_fw) { 1026 rdev->ih.ring_obj = NULL;
1012 r = r600_cp_init_microcode(rdev); 1027 r600_ih_ring_init(rdev, 64 * 1024);
1028
1029 if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
1030 r = r600_init_microcode(rdev);
1013 if (r) { 1031 if (r) {
1014 DRM_ERROR("Failed to load firmware!\n"); 1032 DRM_ERROR("Failed to load firmware!\n");
1015 return r; 1033 return r;
@@ -1055,6 +1073,8 @@ void rv770_fini(struct radeon_device *rdev)
1055 rv770_suspend(rdev); 1073 rv770_suspend(rdev);
1056 1074
1057 r600_blit_fini(rdev); 1075 r600_blit_fini(rdev);
1076 r600_irq_fini(rdev);
1077 radeon_irq_kms_fini(rdev);
1058 radeon_ring_fini(rdev); 1078 radeon_ring_fini(rdev);
1059 r600_wb_fini(rdev); 1079 r600_wb_fini(rdev);
1060 rv770_pcie_gart_fini(rdev); 1080 rv770_pcie_gart_fini(rdev);