xref: /linux/drivers/gpu/drm/loongson/lsdc_irq.c (revision 815e260a18a3af4dab59025ee99a7156c0e8b5e0)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2023 Loongson Technology Corporation Limited
4  */
5 
6 #include <drm/drm_print.h>
7 #include <drm/drm_vblank.h>
8 
9 #include "lsdc_irq.h"
10 
11 /*
12  * For the DC in LS7A2000, clearing interrupt status is achieved by
13  * write "1" to LSDC_INT_REG.
14  *
15  * For the DC in LS7A1000, clear interrupt status is achieved by write "0"
16  * to LSDC_INT_REG.
17  *
18  * Two different hardware engineers modify it as their will.
19  */
20 
21 irqreturn_t ls7a2000_dc_irq_handler(int irq, void *arg)
22 {
23 	struct drm_device *ddev = arg;
24 	struct lsdc_device *ldev = to_lsdc(ddev);
25 	u32 val;
26 
27 	/* Read the interrupt status */
28 	val = lsdc_rreg32(ldev, LSDC_INT_REG);
29 	if ((val & INT_STATUS_MASK) == 0) {
30 		drm_warn(ddev, "no interrupt occurs\n");
31 		return IRQ_NONE;
32 	}
33 
34 	ldev->irq_status = val;
35 
36 	/* write "1" to clear the interrupt status */
37 	lsdc_wreg32(ldev, LSDC_INT_REG, val);
38 
39 	if (ldev->irq_status & INT_CRTC0_VSYNC)
40 		drm_handle_vblank(ddev, 0);
41 
42 	if (ldev->irq_status & INT_CRTC1_VSYNC)
43 		drm_handle_vblank(ddev, 1);
44 
45 	return IRQ_HANDLED;
46 }
47 
48 /* For the DC in LS7A1000 and LS2K1000 */
49 irqreturn_t ls7a1000_dc_irq_handler(int irq, void *arg)
50 {
51 	struct drm_device *ddev = arg;
52 	struct lsdc_device *ldev = to_lsdc(ddev);
53 	u32 val;
54 
55 	/* Read the interrupt status */
56 	val = lsdc_rreg32(ldev, LSDC_INT_REG);
57 	if ((val & INT_STATUS_MASK) == 0) {
58 		drm_warn(ddev, "no interrupt occurs\n");
59 		return IRQ_NONE;
60 	}
61 
62 	ldev->irq_status = val;
63 
64 	/* write "0" to clear the interrupt status */
65 	val &= ~(INT_CRTC0_VSYNC | INT_CRTC1_VSYNC);
66 	lsdc_wreg32(ldev, LSDC_INT_REG, val);
67 
68 	if (ldev->irq_status & INT_CRTC0_VSYNC)
69 		drm_handle_vblank(ddev, 0);
70 
71 	if (ldev->irq_status & INT_CRTC1_VSYNC)
72 		drm_handle_vblank(ddev, 1);
73 
74 	return IRQ_HANDLED;
75 }
76