diff options
| -rw-r--r-- | drivers/gpu/drm/armada/armada_crtc.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index 03eeee11dd5b..42a40daff132 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c | |||
| @@ -519,8 +519,9 @@ static irqreturn_t armada_drm_irq(int irq, void *arg) | |||
| 519 | u32 v, stat = readl_relaxed(dcrtc->base + LCD_SPU_IRQ_ISR); | 519 | u32 v, stat = readl_relaxed(dcrtc->base + LCD_SPU_IRQ_ISR); |
| 520 | 520 | ||
| 521 | /* | 521 | /* |
| 522 | * This is rediculous - rather than writing bits to clear, we | 522 | * Reading the ISR appears to clear bits provided CLEAN_SPU_IRQ_ISR |
| 523 | * have to set the actual status register value. This is racy. | 523 | * is set. Writing has some other effect to acknowledge the IRQ - |
| 524 | * without this, we only get a single IRQ. | ||
| 524 | */ | 525 | */ |
| 525 | writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ISR); | 526 | writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ISR); |
| 526 | 527 | ||
| @@ -1116,16 +1117,22 @@ armada_drm_crtc_set_property(struct drm_crtc *crtc, | |||
| 1116 | static int armada_drm_crtc_enable_vblank(struct drm_crtc *crtc) | 1117 | static int armada_drm_crtc_enable_vblank(struct drm_crtc *crtc) |
| 1117 | { | 1118 | { |
| 1118 | struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); | 1119 | struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); |
| 1120 | unsigned long flags; | ||
| 1119 | 1121 | ||
| 1122 | spin_lock_irqsave(&dcrtc->irq_lock, flags); | ||
| 1120 | armada_drm_crtc_enable_irq(dcrtc, VSYNC_IRQ_ENA); | 1123 | armada_drm_crtc_enable_irq(dcrtc, VSYNC_IRQ_ENA); |
| 1124 | spin_unlock_irqrestore(&dcrtc->irq_lock, flags); | ||
| 1121 | return 0; | 1125 | return 0; |
| 1122 | } | 1126 | } |
| 1123 | 1127 | ||
| 1124 | static void armada_drm_crtc_disable_vblank(struct drm_crtc *crtc) | 1128 | static void armada_drm_crtc_disable_vblank(struct drm_crtc *crtc) |
| 1125 | { | 1129 | { |
| 1126 | struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); | 1130 | struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); |
| 1131 | unsigned long flags; | ||
| 1127 | 1132 | ||
| 1133 | spin_lock_irqsave(&dcrtc->irq_lock, flags); | ||
| 1128 | armada_drm_crtc_disable_irq(dcrtc, VSYNC_IRQ_ENA); | 1134 | armada_drm_crtc_disable_irq(dcrtc, VSYNC_IRQ_ENA); |
| 1135 | spin_unlock_irqrestore(&dcrtc->irq_lock, flags); | ||
| 1129 | } | 1136 | } |
| 1130 | 1137 | ||
| 1131 | static const struct drm_crtc_funcs armada_crtc_funcs = { | 1138 | static const struct drm_crtc_funcs armada_crtc_funcs = { |
| @@ -1415,6 +1422,7 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev, | |||
| 1415 | CFG_PDWN64x66, dcrtc->base + LCD_SPU_SRAM_PARA1); | 1422 | CFG_PDWN64x66, dcrtc->base + LCD_SPU_SRAM_PARA1); |
| 1416 | writel_relaxed(0x2032ff81, dcrtc->base + LCD_SPU_DMA_CTRL1); | 1423 | writel_relaxed(0x2032ff81, dcrtc->base + LCD_SPU_DMA_CTRL1); |
| 1417 | writel_relaxed(dcrtc->irq_ena, dcrtc->base + LCD_SPU_IRQ_ENA); | 1424 | writel_relaxed(dcrtc->irq_ena, dcrtc->base + LCD_SPU_IRQ_ENA); |
| 1425 | readl_relaxed(dcrtc->base + LCD_SPU_IRQ_ISR); | ||
| 1418 | writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ISR); | 1426 | writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ISR); |
| 1419 | 1427 | ||
| 1420 | ret = devm_request_irq(dev, irq, armada_drm_irq, 0, "armada_drm_crtc", | 1428 | ret = devm_request_irq(dev, irq, armada_drm_irq, 0, "armada_drm_crtc", |
