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 16irqreturn_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 43void 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 55int loongson_irq_postinstall(struct drm_device *dev) 56{ 57 return 0; 58} 59 60void 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