18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright (c) 2018 Loongson Technology Co., Ltd. 38c2ecf20Sopenharmony_ci * Authors: 48c2ecf20Sopenharmony_ci * Chen Zhu <zhuchen@loongson.cn> 58c2ecf20Sopenharmony_ci * Yaling Fang <fangyaling@loongson.cn> 68c2ecf20Sopenharmony_ci * Dandan Zhang <zhangdandan@loongson.cn> 78c2ecf20Sopenharmony_ci * Huacai Chen <chenhc@lemote.com> 88c2ecf20Sopenharmony_ci * This program is free software; you can redistribute it and/or modify it 98c2ecf20Sopenharmony_ci * under the terms of the GNU General Public License as published by the 108c2ecf20Sopenharmony_ci * Free Software Foundation; either version 2 of the License, or (at your 118c2ecf20Sopenharmony_ci * option) any later version. 128c2ecf20Sopenharmony_ci */ 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#include "loongson_drv.h" 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ciirqreturn_t loongson_irq_handler(int irq, void *arg) 178c2ecf20Sopenharmony_ci{ 188c2ecf20Sopenharmony_ci unsigned int val; 198c2ecf20Sopenharmony_ci struct drm_device *dev = (struct drm_device *) arg; 208c2ecf20Sopenharmony_ci struct loongson_drm_device *ldev = dev->dev_private; 218c2ecf20Sopenharmony_ci volatile void __iomem *base = ldev->mmio; 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci val = readl(base + FB_INT_REG); 248c2ecf20Sopenharmony_ci spin_lock(&loongson_reglock); 258c2ecf20Sopenharmony_ci writel(val, base + FB_INT_REG); 268c2ecf20Sopenharmony_ci spin_unlock(&loongson_reglock); 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci if (val & BIT(INT_DVO0_FB_END)){ 298c2ecf20Sopenharmony_ci drm_crtc_handle_vblank(&ldev->lcrtc[0].base); 308c2ecf20Sopenharmony_ci } 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci if (val & BIT(INT_DVO1_FB_END)){ 338c2ecf20Sopenharmony_ci drm_crtc_handle_vblank(&ldev->lcrtc[1].base); 348c2ecf20Sopenharmony_ci } 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci spin_lock(&loongson_reglock); 378c2ecf20Sopenharmony_ci writel(ldev->int_reg, base + FB_INT_REG); 388c2ecf20Sopenharmony_ci spin_unlock(&loongson_reglock); 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci return IRQ_HANDLED; 418c2ecf20Sopenharmony_ci} 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_civoid loongson_irq_preinstall(struct drm_device *dev) 448c2ecf20Sopenharmony_ci{ 458c2ecf20Sopenharmony_ci unsigned long flags; 468c2ecf20Sopenharmony_ci struct loongson_drm_device *ldev = dev->dev_private; 478c2ecf20Sopenharmony_ci volatile void __iomem *base = ldev->mmio; 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci /* disable interupt */ 508c2ecf20Sopenharmony_ci spin_lock_irqsave(&loongson_reglock, flags); 518c2ecf20Sopenharmony_ci writel(0x0000 << 16, base + FB_INT_REG); 528c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&loongson_reglock, flags); 538c2ecf20Sopenharmony_ci} 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ciint loongson_irq_postinstall(struct drm_device *dev) 568c2ecf20Sopenharmony_ci{ 578c2ecf20Sopenharmony_ci return 0; 588c2ecf20Sopenharmony_ci} 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_civoid loongson_irq_uninstall(struct drm_device *dev) 618c2ecf20Sopenharmony_ci{ 628c2ecf20Sopenharmony_ci unsigned long flags; 638c2ecf20Sopenharmony_ci struct loongson_drm_device *ldev = dev->dev_private; 648c2ecf20Sopenharmony_ci volatile void __iomem *base = ldev->mmio; 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci /* disable interupt */ 678c2ecf20Sopenharmony_ci spin_lock_irqsave(&loongson_reglock, flags); 688c2ecf20Sopenharmony_ci writel(0x0000 << 16, base + FB_INT_REG); 698c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&loongson_reglock, flags); 708c2ecf20Sopenharmony_ci} 71