static irqreturn_t lcdc_isr(int irq, void *data) { uint32_t val; struct sprd_lcd_controller *lcdc = (struct sprd_lcd_controller *)data; struct sprdfb_device *dev = lcdc->dev; val = lcdc_read(LCDC_IRQ_STATUS); if (val & 1) { /* lcdc done isr */ lcdc_write(1, LCDC_IRQ_CLR); #ifdef CONFIG_FB_LCD_OVERLAY_SUPPORT if(SPRD_OVERLAY_STATUS_STARTED == lcdc->overlay_state){ overlay_close(dev); } #endif if (dev->ctrl->set_timing) { dev->ctrl->set_timing(dev,LCD_REGISTER_TIMING); } lcdc->vsync_done = 1; if (dev->vsync_waiter) { wake_up_interruptible_all(&(lcdc->vsync_queue)); dev->vsync_waiter = 0; } pr_debug(KERN_INFO "lcdc_done_isr !\n"); } return IRQ_HANDLED; }
static irqreturn_t dispc_isr(int irq, void *data) { struct sprdfb_dispc_context *dispc_ctx = (struct sprdfb_dispc_context *)data; uint32_t reg_val; struct sprdfb_device *dev = dispc_ctx->dev; bool done = false; reg_val = dispc_read(DISPC_INT_STATUS); pr_debug("dispc_isr (0x%x)\n",reg_val ); if(reg_val & 0x04){ printk("Warning: dispc underflow (0x%x)!\n",reg_val); dispc_write(0x04, DISPC_INT_CLR); } if(NULL == dev){ return IRQ_HANDLED; } if((reg_val & 0x10) && (SPRDFB_PANEL_IF_DPI == dev->panel_if_type)){/*dispc update done isr*/ #if 0 if(dispc_ctx->is_first_frame){ /*dpi register update with SW and VSync*/ dispc_clear_bits(BIT(4), DISPC_DPI_CTRL); /* start refresh */ dispc_set_bits((1 << 4), DISPC_CTRL); dispc_ctx->is_first_frame = false; } #endif dispc_write(0x10, DISPC_INT_CLR); done = true; }else if ((reg_val & 0x1) && (SPRDFB_PANEL_IF_DPI != dev->panel_if_type)){ /* dispc done isr */ dispc_write(1, DISPC_INT_CLR); dispc_ctx->is_first_frame = false; done = true; } if(done){ dispc_ctx->vsync_done = 1; #ifdef CONFIG_FB_LCD_OVERLAY_SUPPORT if(SPRD_OVERLAY_STATUS_STARTED == dispc_ctx->overlay_state){ overlay_close(dev); } #endif #ifdef CONFIG_FB_DYNAMIC_CLK_SUPPORT if(SPRDFB_PANEL_IF_DPI != dev->panel_if_type){ clk_disable(dispc_ctx->clk_dispc); clk_disable(dispc_ctx->clk_dispc_dpi); clk_disable(dispc_ctx->clk_dispc_dbi); dispc_ctx->clk_open = false; } #endif if (dispc_ctx->vsync_waiter) { wake_up_interruptible_all(&(dispc_ctx->vsync_queue)); dispc_ctx->vsync_waiter = 0; } sprdfb_panel_after_refresh(dev); pr_debug(KERN_INFO "sprdfb: [%s]: Done INT, reg_val = %d !\n", __FUNCTION__, reg_val); } return IRQ_HANDLED; }