static int32_t sprdfb_dispc_refresh (struct sprdfb_device *dev) { FB_PRINT("sprdfb:[%s]\n",__FUNCTION__); uint32_t i; if(SPRDFB_PANEL_IF_DPI != dev->panel_if_type){ sprdfb_panel_invalidate(dev->panel); } sprdfb_panel_before_refresh(dev); if(SPRDFB_PANEL_IF_DPI == dev->panel_if_type){ //dispc_write(0x0, DISPC_OSD_CTRL); //dispc_write(0x0, DISPC_BG_COLOR); /*dpi register update*/ dispc_set_bits((1<<5), DISPC_DPI_CTRL); if(is_first_frame){ udelay(30); /*dpi register update with SW and VSync*/ dispc_clear_bits((1<<4), DISPC_DPI_CTRL); /* start refresh */ dispc_set_bits((1 << 4), DISPC_CTRL); is_first_frame = 0; }else{ for(i=0;i<1000;i++){ if(!(dispc_read(DISPC_INT_RAW) & (0x10))){ udelay(100); }else{ break; } } if(i >= 1000){ FB_PRINT("sprdfb:[%s] wait dispc update int time out!! (0x%x)\n", __FUNCTION__, dispc_read(DISPC_INT_RAW)); }else{ FB_PRINT("sprdfb:[%s] got dispc update int (0x%x)\n", __FUNCTION__, dispc_read(DISPC_INT_RAW)); } dispc_set_bits((1<<5), DISPC_INT_CLR); } }else{ /* start refresh */ dispc_set_bits((1 << 4), DISPC_CTRL); for(i=0;i<500;i++){ if(0x1 != (dispc_read(DISPC_INT_RAW) & (1<<0))){ udelay(1000); }else{ break; } } if(i >= 1000){ FB_PRINT("sprdfb:[%s] wait dispc done int time out!! (0x%x)\n", __FUNCTION__, dispc_read(DISPC_INT_RAW)); }else{ FB_PRINT("sprdfb:[%s] got dispc done int (0x%x)\n", __FUNCTION__, dispc_read(DISPC_INT_RAW)); } dispc_set_bits((1<<0), DISPC_INT_CLR); } sprdfb_panel_after_refresh(dev); return 0; }
static irqreturn_t lcdc_isr(int irq, void *data) { struct sprdfb_lcdc_context *lcdc_ctx = (struct sprdfb_lcdc_context *)data; uint32_t reg_val; struct sprdfb_device *dev = lcdc_ctx->dev; reg_val = lcdc_read(LCDC_INT_STATUS); if (reg_val & 1) { /* lcdc done isr */ lcdc_write(1, LCDC_INT_CLR); lcdc_ctx->vsync_done = 1; if (lcdc_ctx->vsync_waiter) { wake_up_interruptible_all(&(lcdc_ctx->vsync_queue)); lcdc_ctx->vsync_waiter = 0; } sprdfb_panel_after_refresh(dev); pr_debug(KERN_INFO "sprdfb: [%s]: Done INT !\n", __FUNCTION__); } 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; }