static void hdlcd_crtc_disable_vblank(struct drm_crtc *crtc) { struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); unsigned int mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK); hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, mask & ~HDLCD_INTERRUPT_VSYNC); }
static void hdlcd_disable_vblank(struct drm_device *drm, unsigned int crtc) { struct hdlcd_drm_private *hdlcd = drm->dev_private; unsigned int mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK); hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, mask & ~HDLCD_INTERRUPT_VSYNC); }
static irqreturn_t hdlcd_irq(int irq, void *arg) { struct drm_device *drm = arg; struct hdlcd_drm_private *hdlcd = drm->dev_private; unsigned long irq_status; irq_status = hdlcd_read(hdlcd, HDLCD_REG_INT_STATUS); #ifdef CONFIG_DEBUG_FS if (irq_status & HDLCD_INTERRUPT_UNDERRUN) atomic_inc(&hdlcd->buffer_underrun_count); if (irq_status & HDLCD_INTERRUPT_DMA_END) atomic_inc(&hdlcd->dma_end_count); if (irq_status & HDLCD_INTERRUPT_BUS_ERROR) atomic_inc(&hdlcd->bus_error_count); if (irq_status & HDLCD_INTERRUPT_VSYNC) atomic_inc(&hdlcd->vsync_count); #endif if (irq_status & HDLCD_INTERRUPT_VSYNC) drm_crtc_handle_vblank(&hdlcd->crtc); /* acknowledge interrupt(s) */ hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, irq_status); return IRQ_HANDLED; }
static int hdlcd_irq_postinstall(struct drm_device *drm) { #ifdef CONFIG_DEBUG_FS struct hdlcd_drm_private *hdlcd = drm->dev_private; unsigned long irq_mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK); /* enable debug interrupts */ irq_mask |= HDLCD_DEBUG_INT_MASK; hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, irq_mask); #endif return 0; }
static void hdlcd_irq_uninstall(struct drm_device *drm) { struct hdlcd_drm_private *hdlcd = drm->dev_private; /* disable all the interrupts that we might have enabled */ unsigned long irq_mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK); #ifdef CONFIG_DEBUG_FS /* disable debug interrupts */ irq_mask &= ~HDLCD_DEBUG_INT_MASK; #endif /* disable vsync interrupts */ irq_mask &= ~HDLCD_INTERRUPT_VSYNC; hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, irq_mask); }
static int hdlcd_load(struct drm_device *drm, unsigned long flags) { struct hdlcd_drm_private *hdlcd = drm->dev_private; struct platform_device *pdev = to_platform_device(drm->dev); struct resource *res; u32 version; int ret; hdlcd->clk = devm_clk_get(drm->dev, "pxlclk"); if (IS_ERR(hdlcd->clk)) return PTR_ERR(hdlcd->clk); #ifdef CONFIG_DEBUG_FS atomic_set(&hdlcd->buffer_underrun_count, 0); atomic_set(&hdlcd->bus_error_count, 0); atomic_set(&hdlcd->vsync_count, 0); atomic_set(&hdlcd->dma_end_count, 0); #endif res = platform_get_resource(pdev, IORESOURCE_MEM, 0); hdlcd->mmio = devm_ioremap_resource(drm->dev, res); if (IS_ERR(hdlcd->mmio)) { DRM_ERROR("failed to map control registers area\n"); ret = PTR_ERR(hdlcd->mmio); hdlcd->mmio = NULL; return ret; } version = hdlcd_read(hdlcd, HDLCD_REG_VERSION); if ((version & HDLCD_PRODUCT_MASK) != HDLCD_PRODUCT_ID) { DRM_ERROR("unknown product id: 0x%x\n", version); return -EINVAL; } DRM_INFO("found ARM HDLCD version r%dp%d\n", (version & HDLCD_VERSION_MAJOR_MASK) >> 8, version & HDLCD_VERSION_MINOR_MASK); /* Get the optional framebuffer memory resource */ ret = of_reserved_mem_device_init(drm->dev); if (ret && ret != -ENODEV) return ret; ret = dma_set_mask_and_coherent(drm->dev, DMA_BIT_MASK(32)); if (ret) goto setup_fail; ret = hdlcd_setup_crtc(drm); if (ret < 0) { DRM_ERROR("failed to create crtc\n"); goto setup_fail; } ret = drm_irq_install(drm, platform_get_irq(pdev, 0)); if (ret < 0) { DRM_ERROR("failed to install IRQ handler\n"); goto irq_fail; } return 0; irq_fail: drm_crtc_cleanup(&hdlcd->crtc); setup_fail: of_reserved_mem_device_release(drm->dev); return ret; }