diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2009-12-01 13:43:46 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-12-02 14:00:06 +1000 |
commit | d8f60cfc93452d0554f6a701aa8e3236cbee4636 (patch) | |
tree | d6048658b42bdd9443f424755cd85f855e1477ba /drivers/gpu/drm/radeon/rv770.c | |
parent | 50dafba685c0f12c23d315820370b32d9ba64db7 (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.c | 24 |
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) return r; } + /* Enable IRQ */ + rdev->irq.sw_int = true; + r = r600_irq_init(rdev); + if (r) { + DRM_ERROR("radeon: IH init failed (%d).\n", r); + radeon_irq_kms_fini(rdev); + return r; + } + r600_irq_set(rdev); + r = radeon_ring_init(rdev, rdev->cp.ring_size); if (r) return r; @@ -1005,11 +1015,19 @@ int rv770_init(struct radeon_device *rdev) r = radeon_object_init(rdev); if (r) return r; + + r = radeon_irq_kms_init(rdev); + if (r) + return r; + rdev->cp.ring_obj = NULL; r600_ring_init(rdev, 1024 * 1024); - if (!rdev->me_fw || !rdev->pfp_fw) { - r = r600_cp_init_microcode(rdev); + rdev->ih.ring_obj = NULL; + r600_ih_ring_init(rdev, 64 * 1024); + + if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { + r = r600_init_microcode(rdev); if (r) { DRM_ERROR("Failed to load firmware!\n"); return r; @@ -1055,6 +1073,8 @@ void rv770_fini(struct radeon_device *rdev) rv770_suspend(rdev); r600_blit_fini(rdev); + r600_irq_fini(rdev); + radeon_irq_kms_fini(rdev); radeon_ring_fini(rdev); r600_wb_fini(rdev); rv770_pcie_gart_fini(rdev); |