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