Commit 4cd096dd authored by Lyude's avatar Lyude Committed by Alex Deucher

drm/radeon: Cleanup display interrupt handling for evergreen, si

The current code here is really, really bad. A huge amount of it looks
to be copy pasted, it has some weird hatred of arrays and code sharing,
switch cases everywhere for things that really don't need them, and it
makes the file seem immensely more complex then it actually is. This is
a pain for maintanence, and is vulnerable to more weird irq handling
bugs.

So, let's start cleaning this up a bit. Modify all of the IRQ handlers
for evergreen/si so that they just use for loops. As well, we add a
helper function radeon_irq_kms_set_irq_n_enabled(), whose purpose is
just to update the state of registers that enable/disable interrupts
while printing any changes to the set of enabled interrupts to the
kernel log.

Note in this commit, since vblank/vline irq acking is intertwined with
page flip irq acking, we can't cut out all of the copy paste in
evergreen/si_irq_ack() just yet.

Changes since v1:
- Preserve order we write back all registers
Acked-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarLyude <lyude@redhat.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent e30a5223
This diff is collapsed.
...@@ -771,12 +771,7 @@ struct r600_irq_stat_regs { ...@@ -771,12 +771,7 @@ struct r600_irq_stat_regs {
}; };
struct evergreen_irq_stat_regs { struct evergreen_irq_stat_regs {
u32 disp_int; u32 disp_int[6];
u32 disp_int_cont;
u32 disp_int_cont2;
u32 disp_int_cont3;
u32 disp_int_cont4;
u32 disp_int_cont5;
u32 d1grph_int; u32 d1grph_int;
u32 d2grph_int; u32 d2grph_int;
u32 d3grph_int; u32 d3grph_int;
...@@ -2980,6 +2975,12 @@ int r600_cs_common_vline_parse(struct radeon_cs_parser *p, ...@@ -2980,6 +2975,12 @@ int r600_cs_common_vline_parse(struct radeon_cs_parser *p,
uint32_t *vline_start_end, uint32_t *vline_start_end,
uint32_t *vline_status); uint32_t *vline_status);
/* interrupt control register helpers */
void radeon_irq_kms_set_irq_n_enabled(struct radeon_device *rdev,
u32 reg, u32 mask,
bool enable, const char *name,
unsigned n);
#include "radeon_object.h" #include "radeon_object.h"
#endif #endif
...@@ -538,3 +538,38 @@ void radeon_irq_kms_disable_hpd(struct radeon_device *rdev, unsigned hpd_mask) ...@@ -538,3 +538,38 @@ void radeon_irq_kms_disable_hpd(struct radeon_device *rdev, unsigned hpd_mask)
spin_unlock_irqrestore(&rdev->irq.lock, irqflags); spin_unlock_irqrestore(&rdev->irq.lock, irqflags);
} }
/**
* radeon_irq_kms_update_int_n - helper for updating interrupt enable registers
*
* @rdev: radeon device pointer
* @reg: the register to write to enable/disable interrupts
* @mask: the mask that enables the interrupts
* @enable: whether to enable or disable the interrupt register
* @name: the name of the interrupt register to print to the kernel log
* @num: the number of the interrupt register to print to the kernel log
*
* Helper for updating the enable state of interrupt registers. Checks whether
* or not the interrupt matches the enable state we want. If it doesn't, then
* we update it and print a debugging message to the kernel log indicating the
* new state of the interrupt register.
*
* Used for updating sequences of interrupts registers like HPD1, HPD2, etc.
*/
void radeon_irq_kms_set_irq_n_enabled(struct radeon_device *rdev,
u32 reg, u32 mask,
bool enable, const char *name, unsigned n)
{
u32 tmp = RREG32(reg);
/* Interrupt state didn't change */
if (!!(tmp & mask) == enable)
return;
if (enable) {
DRM_DEBUG("%s%d interrupts enabled\n", name, n);
WREG32(reg, tmp |= mask);
} else {
DRM_DEBUG("%s%d interrupts disabled\n", name, n);
WREG32(reg, tmp & ~mask);
}
}
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment