1 /*
2 * Copyright (c) 2018 Loongson Technology Co., Ltd.
3 * Authors:
4 * Chen Zhu <zhuchen@loongson.cn>
5 * Yaling Fang <fangyaling@loongson.cn>
6 * Dandan Zhang <zhangdandan@loongson.cn>
7 * Huacai Chen <chenhc@lemote.com>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14 #include "loongson_drv.h"
15
loongson_irq_handler(int irq, void *arg)16 irqreturn_t loongson_irq_handler(int irq, void *arg)
17 {
18 unsigned int val;
19 struct drm_device *dev = (struct drm_device *) arg;
20 struct loongson_drm_device *ldev = dev->dev_private;
21 volatile void __iomem *base = ldev->mmio;
22
23 val = readl(base + FB_INT_REG);
24 spin_lock(&loongson_reglock);
25 writel(val, base + FB_INT_REG);
26 spin_unlock(&loongson_reglock);
27
28 if (val & BIT(INT_DVO0_FB_END)){
29 drm_crtc_handle_vblank(&ldev->lcrtc[0].base);
30 }
31
32 if (val & BIT(INT_DVO1_FB_END)){
33 drm_crtc_handle_vblank(&ldev->lcrtc[1].base);
34 }
35
36 spin_lock(&loongson_reglock);
37 writel(ldev->int_reg, base + FB_INT_REG);
38 spin_unlock(&loongson_reglock);
39
40 return IRQ_HANDLED;
41 }
42
loongson_irq_preinstall(struct drm_device *dev)43 void loongson_irq_preinstall(struct drm_device *dev)
44 {
45 unsigned long flags;
46 struct loongson_drm_device *ldev = dev->dev_private;
47 volatile void __iomem *base = ldev->mmio;
48
49 /* disable interupt */
50 spin_lock_irqsave(&loongson_reglock, flags);
51 writel(0x0000 << 16, base + FB_INT_REG);
52 spin_unlock_irqrestore(&loongson_reglock, flags);
53 }
54
loongson_irq_postinstall(struct drm_device *dev)55 int loongson_irq_postinstall(struct drm_device *dev)
56 {
57 return 0;
58 }
59
loongson_irq_uninstall(struct drm_device *dev)60 void loongson_irq_uninstall(struct drm_device *dev)
61 {
62 unsigned long flags;
63 struct loongson_drm_device *ldev = dev->dev_private;
64 volatile void __iomem *base = ldev->mmio;
65
66 /* disable interupt */
67 spin_lock_irqsave(&loongson_reglock, flags);
68 writel(0x0000 << 16, base + FB_INT_REG);
69 spin_unlock_irqrestore(&loongson_reglock, flags);
70 }
71