Skip to content

Commit

Permalink
drm/radeon/kms: r600/r700 disable irq at suspend
Browse files Browse the repository at this point in the history
To avoid hw doing anythings after we disabled PCIE GART, fully
disable IRQ at suspend. Also cleanup a bit the ih structure
and process function.

Signed-off-by: Jerome Glisse <jglisse@redhat.com>
Reviewed-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@linux.ie>
  • Loading branch information
Jerome Glisse authored and Dave Airlie committed Jan 20, 2010
1 parent 615e0cb commit 0c45249
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 18 deletions.
30 changes: 14 additions & 16 deletions drivers/gpu/drm/radeon/r600.c
Original file line number Diff line number Diff line change
Expand Up @@ -1954,6 +1954,7 @@ int r600_suspend(struct radeon_device *rdev)
/* FIXME: we should wait for ring to be empty */
r600_cp_stop(rdev);
rdev->cp.ready = false;
r600_irq_suspend(rdev);
r600_wb_disable(rdev);
r600_pcie_gart_disable(rdev);
/* unpin shaders bo */
Expand Down Expand Up @@ -2200,14 +2201,14 @@ void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size)
rb_bufsz = drm_order(ring_size / 4);
ring_size = (1 << rb_bufsz) * 4;
rdev->ih.ring_size = ring_size;
rdev->ih.align_mask = 4 - 1;
rdev->ih.ptr_mask = rdev->ih.ring_size - 1;
rdev->ih.rptr = 0;
}

static int r600_ih_ring_alloc(struct radeon_device *rdev, unsigned ring_size)
static int r600_ih_ring_alloc(struct radeon_device *rdev)
{
int r;

rdev->ih.ring_size = ring_size;
/* Allocate ring buffer */
if (rdev->ih.ring_obj == NULL) {
r = radeon_bo_create(rdev, NULL, rdev->ih.ring_size,
Expand Down Expand Up @@ -2237,9 +2238,6 @@ static int r600_ih_ring_alloc(struct radeon_device *rdev, unsigned ring_size)
return r;
}
}
rdev->ih.ptr_mask = (rdev->cp.ring_size / 4) - 1;
rdev->ih.rptr = 0;

return 0;
}

Expand Down Expand Up @@ -2389,7 +2387,7 @@ int r600_irq_init(struct radeon_device *rdev)
u32 interrupt_cntl, ih_cntl, ih_rb_cntl;

/* allocate ring */
ret = r600_ih_ring_alloc(rdev, rdev->ih.ring_size);
ret = r600_ih_ring_alloc(rdev);
if (ret)
return ret;

Expand Down Expand Up @@ -2452,10 +2450,15 @@ int r600_irq_init(struct radeon_device *rdev)
return ret;
}

void r600_irq_fini(struct radeon_device *rdev)
void r600_irq_suspend(struct radeon_device *rdev)
{
r600_disable_interrupts(rdev);
r600_rlc_stop(rdev);
}

void r600_irq_fini(struct radeon_device *rdev)
{
r600_irq_suspend(rdev);
r600_ih_ring_fini(rdev);
}

Expand Down Expand Up @@ -2648,9 +2651,7 @@ static inline u32 r600_get_ih_wptr(struct radeon_device *rdev)
tmp |= IH_WPTR_OVERFLOW_CLEAR;
WREG32(IH_RB_CNTL, tmp);
}
wptr = wptr & WPTR_OFFSET_MASK;

return wptr;
return (wptr & rdev->ih.ptr_mask);
}

/* r600 IV Ring
Expand Down Expand Up @@ -2686,7 +2687,6 @@ int r600_irq_process(struct radeon_device *rdev)
u32 wptr = r600_get_ih_wptr(rdev);
u32 rptr = rdev->ih.rptr;
u32 src_id, src_data;
u32 last_entry = rdev->ih.ring_size - 16;
u32 ring_index, disp_int, disp_int_cont, disp_int_cont2;
unsigned long flags;
bool queue_hotplug = false;
Expand Down Expand Up @@ -2820,10 +2820,8 @@ int r600_irq_process(struct radeon_device *rdev)
}

/* wptr/rptr are in bytes! */
if (rptr == last_entry)
rptr = 0;
else
rptr += 16;
rptr += 16;
rptr &= rdev->ih.ptr_mask;
}
/* make sure wptr hasn't changed while processing */
wptr = r600_get_ih_wptr(rdev);
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/radeon/radeon.h
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,6 @@ struct r600_ih {
unsigned wptr_old;
unsigned ring_size;
uint64_t gpu_addr;
uint32_t align_mask;
uint32_t ptr_mask;
spinlock_t lock;
bool enabled;
Expand Down Expand Up @@ -1162,7 +1161,8 @@ extern int r600_irq_init(struct radeon_device *rdev);
extern void r600_irq_fini(struct radeon_device *rdev);
extern void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size);
extern int r600_irq_set(struct radeon_device *rdev);

extern void r600_irq_suspend(struct radeon_device *rdev);
/* r600 audio */
extern int r600_audio_init(struct radeon_device *rdev);
extern int r600_audio_tmds_index(struct drm_encoder *encoder);
extern void r600_audio_set_clock(struct drm_encoder *encoder, int clock);
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/radeon/rv770.c
Original file line number Diff line number Diff line change
Expand Up @@ -968,6 +968,7 @@ int rv770_suspend(struct radeon_device *rdev)
/* FIXME: we should wait for ring to be empty */
r700_cp_stop(rdev);
rdev->cp.ready = false;
r600_irq_suspend(rdev);
r600_wb_disable(rdev);
rv770_pcie_gart_disable(rdev);
/* unpin shaders bo */
Expand Down

0 comments on commit 0c45249

Please sign in to comment.