diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2011-11-17 20:13:28 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2011-12-20 14:52:03 -0500 |
commit | 1b37078b7ddf35cab12ac6544187e3636d50c0dc (patch) | |
tree | f1a3621a98ab8ae5ffef14ae34a5b3454f14dcf9 /drivers/gpu/drm/radeon/evergreen.c | |
parent | b40e7e1608c332767e6b94bed7af84b30418e739 (diff) |
drm/radeon/kms: add support for per-ring fence interrupts
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Christian König <deathsimple@vodafone.de>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/evergreen.c')
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen.c | 58 |
1 files changed, 51 insertions, 7 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 6ff1180c7321..266d411c6d2b 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -40,6 +40,8 @@ | |||
40 | static void evergreen_gpu_init(struct radeon_device *rdev); | 40 | static void evergreen_gpu_init(struct radeon_device *rdev); |
41 | void evergreen_fini(struct radeon_device *rdev); | 41 | void evergreen_fini(struct radeon_device *rdev); |
42 | void evergreen_pcie_gen2_enable(struct radeon_device *rdev); | 42 | void evergreen_pcie_gen2_enable(struct radeon_device *rdev); |
43 | extern void cayman_cp_int_cntl_setup(struct radeon_device *rdev, | ||
44 | int ring, u32 cp_int_cntl); | ||
43 | 45 | ||
44 | void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev) | 46 | void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev) |
45 | { | 47 | { |
@@ -2474,7 +2476,13 @@ void evergreen_disable_interrupt_state(struct radeon_device *rdev) | |||
2474 | { | 2476 | { |
2475 | u32 tmp; | 2477 | u32 tmp; |
2476 | 2478 | ||
2477 | WREG32(CP_INT_CNTL, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); | 2479 | if (rdev->family >= CHIP_CAYMAN) { |
2480 | cayman_cp_int_cntl_setup(rdev, 0, | ||
2481 | CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); | ||
2482 | cayman_cp_int_cntl_setup(rdev, 1, 0); | ||
2483 | cayman_cp_int_cntl_setup(rdev, 2, 0); | ||
2484 | } else | ||
2485 | WREG32(CP_INT_CNTL, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); | ||
2478 | WREG32(GRBM_INT_CNTL, 0); | 2486 | WREG32(GRBM_INT_CNTL, 0); |
2479 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | 2487 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); |
2480 | WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | 2488 | WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); |
@@ -2519,6 +2527,7 @@ void evergreen_disable_interrupt_state(struct radeon_device *rdev) | |||
2519 | int evergreen_irq_set(struct radeon_device *rdev) | 2527 | int evergreen_irq_set(struct radeon_device *rdev) |
2520 | { | 2528 | { |
2521 | u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE; | 2529 | u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE; |
2530 | u32 cp_int_cntl1 = 0, cp_int_cntl2 = 0; | ||
2522 | u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0; | 2531 | u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0; |
2523 | u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6; | 2532 | u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6; |
2524 | u32 grbm_int_cntl = 0; | 2533 | u32 grbm_int_cntl = 0; |
@@ -2543,11 +2552,28 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
2543 | hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN; | 2552 | hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN; |
2544 | hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN; | 2553 | hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN; |
2545 | 2554 | ||
2546 | if (rdev->irq.sw_int) { | 2555 | if (rdev->family >= CHIP_CAYMAN) { |
2547 | DRM_DEBUG("evergreen_irq_set: sw int\n"); | 2556 | /* enable CP interrupts on all rings */ |
2548 | cp_int_cntl |= RB_INT_ENABLE; | 2557 | if (rdev->irq.sw_int[RADEON_RING_TYPE_GFX_INDEX]) { |
2549 | cp_int_cntl |= TIME_STAMP_INT_ENABLE; | 2558 | DRM_DEBUG("evergreen_irq_set: sw int gfx\n"); |
2559 | cp_int_cntl |= TIME_STAMP_INT_ENABLE; | ||
2560 | } | ||
2561 | if (rdev->irq.sw_int[CAYMAN_RING_TYPE_CP1_INDEX]) { | ||
2562 | DRM_DEBUG("evergreen_irq_set: sw int cp1\n"); | ||
2563 | cp_int_cntl1 |= TIME_STAMP_INT_ENABLE; | ||
2564 | } | ||
2565 | if (rdev->irq.sw_int[CAYMAN_RING_TYPE_CP2_INDEX]) { | ||
2566 | DRM_DEBUG("evergreen_irq_set: sw int cp2\n"); | ||
2567 | cp_int_cntl2 |= TIME_STAMP_INT_ENABLE; | ||
2568 | } | ||
2569 | } else { | ||
2570 | if (rdev->irq.sw_int[RADEON_RING_TYPE_GFX_INDEX]) { | ||
2571 | DRM_DEBUG("evergreen_irq_set: sw int gfx\n"); | ||
2572 | cp_int_cntl |= RB_INT_ENABLE; | ||
2573 | cp_int_cntl |= TIME_STAMP_INT_ENABLE; | ||
2574 | } | ||
2550 | } | 2575 | } |
2576 | |||
2551 | if (rdev->irq.crtc_vblank_int[0] || | 2577 | if (rdev->irq.crtc_vblank_int[0] || |
2552 | rdev->irq.pflip[0]) { | 2578 | rdev->irq.pflip[0]) { |
2553 | DRM_DEBUG("evergreen_irq_set: vblank 0\n"); | 2579 | DRM_DEBUG("evergreen_irq_set: vblank 0\n"); |
@@ -2607,7 +2633,12 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
2607 | grbm_int_cntl |= GUI_IDLE_INT_ENABLE; | 2633 | grbm_int_cntl |= GUI_IDLE_INT_ENABLE; |
2608 | } | 2634 | } |
2609 | 2635 | ||
2610 | WREG32(CP_INT_CNTL, cp_int_cntl); | 2636 | if (rdev->family >= CHIP_CAYMAN) { |
2637 | cayman_cp_int_cntl_setup(rdev, 0, cp_int_cntl); | ||
2638 | cayman_cp_int_cntl_setup(rdev, 1, cp_int_cntl1); | ||
2639 | cayman_cp_int_cntl_setup(rdev, 2, cp_int_cntl2); | ||
2640 | } else | ||
2641 | WREG32(CP_INT_CNTL, cp_int_cntl); | ||
2611 | WREG32(GRBM_INT_CNTL, grbm_int_cntl); | 2642 | WREG32(GRBM_INT_CNTL, grbm_int_cntl); |
2612 | 2643 | ||
2613 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1); | 2644 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1); |
@@ -3026,7 +3057,20 @@ restart_ih: | |||
3026 | break; | 3057 | break; |
3027 | case 181: /* CP EOP event */ | 3058 | case 181: /* CP EOP event */ |
3028 | DRM_DEBUG("IH: CP EOP\n"); | 3059 | DRM_DEBUG("IH: CP EOP\n"); |
3029 | radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); | 3060 | if (rdev->family >= CHIP_CAYMAN) { |
3061 | switch (src_data) { | ||
3062 | case 0: | ||
3063 | radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); | ||
3064 | break; | ||
3065 | case 1: | ||
3066 | radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP1_INDEX); | ||
3067 | break; | ||
3068 | case 2: | ||
3069 | radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP2_INDEX); | ||
3070 | break; | ||
3071 | } | ||
3072 | } else | ||
3073 | radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); | ||
3030 | break; | 3074 | break; |
3031 | case 233: /* GUI IDLE */ | 3075 | case 233: /* GUI IDLE */ |
3032 | DRM_DEBUG("IH: GUI idle\n"); | 3076 | DRM_DEBUG("IH: GUI idle\n"); |