static int32_t sprdfb_dispc_init(struct sprdfb_device *dev)
{
	pr_debug(KERN_INFO "sprdfb:[%s]\n",__FUNCTION__);
	/*set bg color*/
	dispc_set_bg_color(0xFFFFFFFF);
	/*enable dithering*/
	dispc_dithering_enable(true);
	/*use MSBs as img exp mode*/
	dispc_set_exp_mode(0x0);

	if(dispc_ctx.is_first_frame){
		dispc_layer_init(&(dev->fb->var));
	}else{
		dispc_layer_update(&(dev->fb->var));
	}

	if(SPRDFB_PANEL_IF_DPI == dev->panel_if_type){
		if(dispc_ctx.is_first_frame){
			/*set dpi register update only with SW*/
			dispc_set_bits(BIT(4), DISPC_DPI_CTRL);
		}else{
			/*set dpi register update with SW & VSYNC*/
			dispc_clear_bits(BIT(4), DISPC_DPI_CTRL);
		}
		/*enable dispc update done INT*/
		dispc_write((1<<4), DISPC_INT_EN);
	}else{
		/* enable dispc DONE  INT*/
		dispc_write((1<<0), DISPC_INT_EN);
	}
	dispc_set_bits(BIT(2), DISPC_INT_EN);
	dev->enable = 1;
	return 0;
}
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 int32_t sprdfb_dispc_init(struct sprdfb_device *dev)
{
	FB_PRINT("sprdfb:[%s]\n",__FUNCTION__);

	/*set bg color*/
	dispc_set_bg_color(0xFFFFFFFF);
	/*enable dithering*/
	dispc_dithering_enable(1);
	/*use MSBs as img exp mode*/
	dispc_set_exp_mode(0x0);

	dispc_layer_init(dev);

	if(SPRDFB_PANEL_IF_DPI == dev->panel_if_type){
		if(is_first_frame){
			/*set dpi register update only with SW*/
			dispc_set_bits((1<<4), DISPC_DPI_CTRL);
		}else{
			/*set dpi register update with SW & VSYNC*/
			dispc_clear_bits((1<<4), DISPC_DPI_CTRL);
		}
		/*enable dispc update done INT*/
//		dispc_write((1<<4), DISPC_INT_EN);
	}else{
		/* enable dispc DONE  INT*/
//		dispc_write((1<<0), DISPC_INT_EN);
	}
	return 0;
}
Beispiel #4
0
static void dispc_pwr_enable(bool enable)
{
	if(enable){
		dispc_set_bits(BIT(7), DISPC_CTRL);
	}else{
		dispc_clear_bits(BIT(7), DISPC_CTRL);
	}
}
Beispiel #5
0
static void dispc_dithering_enable(bool enable)
{
	if(enable){
		dispc_set_bits(BIT(6), DISPC_CTRL);
	}else{
		dispc_clear_bits(BIT(6), DISPC_CTRL);
	}
}
static int32_t sprdfb_lcdc_early_init(struct sprdfb_device *dev)
{
	int ret = 0;

	pr_debug(KERN_INFO "sprdfb:[%s]\n", __FUNCTION__);

	if(lcdc_ctx.is_inited){
		printk(KERN_WARNING "sprdfb: lcdc early init warning!(has been inited)");
		return 0;
	}

	lcdc_ctx.clk_lcdc = clk_get(NULL, "clk_lcd");
	if (IS_ERR(lcdc_ctx.clk_lcdc)) {
		printk(KERN_WARNING "sprdfb: get clk_lcd fail!\n");
		return 0;
	} else {
		pr_debug(KERN_INFO "sprdfb: get clk_lcd ok!\n");
	}

	/*usesd to open dipsc matix clock*/
	sci_glb_set(REG_AHB_MATRIX_CLOCK, (1<<LCDC_CORE_CLK_EN));

	if(!dev->panel_ready){
		ret = clk_enable(lcdc_ctx.clk_lcdc);
		if (ret) {
			printk(KERN_WARNING "sprdfb: enable clk_lcdc fail!\n");
			return 0;
		} else {
			pr_debug(KERN_INFO "sprdfb: get clk_lcdc ok!\n");
		}

		/*dispc must be enbale before lcdc enable*/
		sprdfb_dispc_ctrl.early_init(dev);
		dispc_set_bits(BIT(3), DISPC_CTRL);

		lcdc_reset();
		lcdc_module_enable();
		lcdc_ctx.is_first_frame = true;
	}else{
		lcdc_ctx.is_first_frame = false;
	}

	lcdc_ctx.vsync_done = 1;
	lcdc_ctx.vsync_waiter = 0;
	init_waitqueue_head(&(lcdc_ctx.vsync_queue));

	lcdc_ctx.is_inited = true;

	ret = request_irq(IRQ_LCDC_INT, lcdc_isr, IRQF_DISABLED, "LCDC", &lcdc_ctx);
	if (ret) {
		printk(KERN_ERR "sprdfb: lcdc failed to request irq!\n");
		clk_disable(lcdc_ctx.clk_lcdc);
		lcdc_ctx.is_inited = false;
		return -1;
	}

	return 0;
}
Beispiel #7
0
static void dispc_run(void)
{
	if(DISPC_IF_DPI == autotst_dispc_ctx.dispc_if){
		/*dpi register update*/
		dispc_set_bits(BIT(5), DISPC_DPI_CTRL);
		udelay(30);

		/*dpi register update with SW and VSync*/
		dispc_clear_bits(BIT(4), DISPC_DPI_CTRL);

		/* start refresh */
		dispc_set_bits((1 << 4), DISPC_CTRL);

	}else{
		/* start refresh */
		dispc_set_bits((1 << 4), DISPC_CTRL);
	}
}
Beispiel #8
0
static void dispc_stop(void)
{
	if(DISPC_IF_DPI == autotst_dispc_ctx.dispc_if){
		/*dpi register update with SW only*/
		dispc_set_bits(BIT(4), DISPC_DPI_CTRL);

		/* stop refresh */
		dispc_clear_bits((1 << 4), DISPC_CTRL);
	}
}
static void dispc_dithering_enable(uint16_t enable)
{
	FB_PRINT("sprdfb:[%s]\n",__FUNCTION__);

	if(enable){
		dispc_set_bits((1<<6), DISPC_CTRL);
	}else{
		dispc_clear_bits((1<<6), DISPC_CTRL);
	}
}
static void dispc_run(struct sprdfb_device *dev)
{
	if(0 == dev->enable){
		return;
	}

#ifdef CONFIG_FB_ESD_SUPPORT
	down(&dev->ESD_lock);
#endif

	if(SPRDFB_PANEL_IF_DPI == dev->panel_if_type){
		if(!dispc_ctx.is_first_frame){
			dispc_ctx.vsync_done = 0;
			dispc_ctx.vsync_waiter ++;
		}

		/*dpi register update*/
		dispc_set_bits(BIT(5), DISPC_DPI_CTRL);

		udelay(30);

		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;
		}else{
			dispc_sync(dev);
		}
	}else{
		dispc_ctx.vsync_done = 0;
		/* start refresh */
		dispc_set_bits((1 << 4), DISPC_CTRL);
	}

#ifdef CONFIG_FB_ESD_SUPPORT
	up(&dev->ESD_lock);
#endif
}
static void dispc_stop(struct sprdfb_device *dev)
{
	if(SPRDFB_PANEL_IF_DPI == dev->panel_if_type){
		/*dpi register update with SW only*/
		dispc_set_bits(BIT(4), DISPC_DPI_CTRL);

		/* stop refresh */
		dispc_clear_bits((1 << 4), DISPC_CTRL);

		dispc_ctx.is_first_frame = true;
	}
}
Beispiel #12
0
static void mipi_dispc_init_config(struct panel_spec *panel)
{
	uint32_t reg_val = dispc_read(DISPC_DPI_CTRL);

	pr_debug("autotst_dispc: [%s]\n", __FUNCTION__);

	if(NULL == panel){
		printk(KERN_ERR "autotst_dispc: [%s] fail.(Invalid Param)\n", __FUNCTION__);
		return;
	}

	if(SPRDFB_PANEL_TYPE_MIPI != panel->type){
		printk(KERN_ERR "autotst_dispc: [%s] fail.(not  mcu panel)\n", __FUNCTION__);
		return;
	}

	if(SPRDFB_MIPI_MODE_CMD == panel->info.mipi->work_mode){
		/*use edpi as interface*/
		dispc_set_bits((1<<1), DISPC_CTRL);
		autotst_dispc_ctx.dispc_if = DISPC_IF_EDPI;
	}else{
		/*use dpi as interface*/
		dispc_clear_bits((3<<1), DISPC_CTRL);
		autotst_dispc_ctx.dispc_if = DISPC_IF_DPI;
	}

	/*h sync pol*/
	if(SPRDFB_POLARITY_NEG == panel->info.mipi->h_sync_pol){
		reg_val |= (1<<0);
	}

	/*v sync pol*/
	if(SPRDFB_POLARITY_NEG == panel->info.mipi->v_sync_pol){
		reg_val |= (1<<1);
	}

	/*de sync pol*/
	if(SPRDFB_POLARITY_NEG == panel->info.mipi->de_pol){
		reg_val |= (1<<2);
	}

	if(SPRDFB_MIPI_MODE_VIDEO == panel->info.mipi->work_mode){
#ifdef CONFIG_DPI_SINGLE_RUN
		/*single run mode*/
		reg_val |= (1<<3);
#endif
	}else{
		if(!(panel->cap & PANEL_CAP_NOT_TEAR_SYNC)){
			printk("autotst_dispc: mipi_dispc_init_config not support TE\n");
			/*enable te*/
			reg_val |= (1<<8);
		}
		/*te pol*/
		if(SPRDFB_POLARITY_NEG == panel->info.mipi->te_pol){
			reg_val |= (1<<9);
		}
		/*use external te*/
		reg_val |= (1<<10);
	}

	/*dpi bits*/
	switch(panel->info.rgb->video_bus_width){
	case 16:
		break;
	case 18:
		reg_val |= (1 << 6);
		break;
	case 24:
		reg_val |= (2 << 6);
		break;
	default:
		break;
	}

	dispc_write(reg_val, DISPC_DPI_CTRL);

	pr_debug("autotst_dispc: [%s] DISPC_DPI_CTRL = %d\n", __FUNCTION__, dispc_read(DISPC_DPI_CTRL));
}
Beispiel #13
0
/*cs0*/
static void mcu_dispc_init_config(struct panel_spec *panel)
{
	uint32_t reg_val = 0;

	pr_debug("autotst_dispc: [%s] for cs0\n", __FUNCTION__);

	if(NULL == panel){
		printk(KERN_ERR "autotst_dispc: [%s] fail.(Invalid Param)\n", __FUNCTION__);
		return;
	}

	if(SPRDFB_PANEL_TYPE_MCU != panel->type){
		printk(KERN_ERR "autotst_dispc: [%s] fail.(not  mcu panel)\n", __FUNCTION__);
		return;
	}

	/*use dbi as interface*/
	dispc_set_bits((2<<1), DISPC_CTRL);
	autotst_dispc_ctx.dispc_if = DISPC_IF_DBI;

	/* CS0 bus mode [BIT0]: 8080/6800 */
	switch (panel->info.mcu->bus_mode) {
	case LCD_BUS_8080:
		break;
	case LCD_BUS_6800:
		reg_val |= 1;
		break;
	default:
		break;
	}
	/* CS0 bus width [BIT3:1] */
	switch (panel->info.mcu->bus_width) {
	case 8:
		break;
	case 9:
		reg_val |= (1 << 1);
		break;
	case 16:
		reg_val |= (2 << 1);
		break;
	case 18:
		reg_val |= (3 << 1) ;
		break;
	case 24:
		reg_val |= (4 << 1);
		break;
	default:
		break;
	}

	/*CS0 pixel bits [BIT5:4]*/
	switch (panel->info.mcu->bpp) {
	case 16:
		break;
	case 18:
		reg_val |= (1 << 4) ;
		break;
	case 24:
		reg_val |= (2 << 4);
		break;
	default:
		break;
	}

#ifndef CONFIG_FB_NO_FMARK
	/*TE enable*/
	reg_val |= (1 << 16);
	if(SPRDFB_POLARITY_NEG == panel->info.mcu->te_pol){
		reg_val |= (1<< 17);
	}
	dispc_write(panel->info.mcu->te_sync_delay, DISPC_TE_SYNC_DELAY);
#endif

#ifdef CONFIG_LCD_CS_ALWAYS_LOW
	/*CS alway low mode*/
	reg_val |= (1<<21);
#else
	/*CS not alway low mode*/
#endif

	/*CS0 selected*/

	dispc_write(reg_val, DISPC_DBI_CTRL);

	pr_debug("autotst_dispc: [%s] DISPC_DBI_CTRL = %d\n", __FUNCTION__, dispc_read(DISPC_DBI_CTRL));
}
Beispiel #14
0
int32_t autotst_dispc_init(int display_type)
{
	int ret = 0;

	printk(KERN_INFO "autotst_dispc:[%s]\n",__FUNCTION__);

        //autotst_dsi_dump();

        autotst_dispc_uninit(DISPLAY_TYPE_MIPI);

	ret = dispc_clk_init();
	if(ret){
		printk(KERN_WARNING "autotst_dispc: dispc_clk_init fail!\n");
		return -1;
	}

	dispc_reset();
	dispc_module_enable();

	/*set bg color*/
	dispc_set_bg_color(0xFFFFFFFF);
	/*enable dithering*/
	dispc_dithering_enable(true);
	/*use MSBs as img exp mode*/
	dispc_set_exp_mode(0x0);
	//enable DISPC Power Control
	dispc_pwr_enable(true);

	switch(display_type){
	case DISPLAY_TYPE_MCU:
		autotst_panel = &lcd_dummy_mcu_spec;
		mcu_dispc_init_config(autotst_panel);
		mcu_dispc_set_timing(autotst_panel);
		break;
	case DISPLAY_TYPE_RGB:
		autotst_panel = &lcd_dummy_rgb_spec;
		rgb_dispc_init_config(autotst_panel);
		rgb_dispc_set_timing(autotst_panel);
		autotst_dispc_ctx.dispc_if = DISPC_IF_DPI;
		break;
	case DISPLAY_TYPE_MIPI:
		autotst_panel = &lcd_dummy_mipi_spec;
		mipi_dispc_init_config(autotst_panel);
		mipi_dispc_set_timing(autotst_panel);
		autotst_dsi_init(autotst_panel);
		break;
	default:
		printk("autotst_dispc:[%s] error display type (%d)\n", __FUNCTION__, display_type);
	}

	dispc_layer_init(autotst_panel);

	if(DISPC_IF_DPI == autotst_dispc_ctx.dispc_if){
		if(1){
			/*set dpi register update only with SW*/
			dispc_set_bits(BIT(4), DISPC_DPI_CTRL);
		}else{
			/*set dpi register update with SW & VSYNC*/
			dispc_clear_bits(BIT(4), DISPC_DPI_CTRL);
		}
		/*enable dispc update done INT*/
		//dispc_write((1<<4), DISPC_INT_EN);
	}else{
		/* enable dispc DONE  INT*/
		//dispc_write((1<<0), DISPC_INT_EN);
	}
	//dispc_set_bits(BIT(2), DISPC_INT_EN);
	return 0;
}
Beispiel #15
0
/*cs1*/
void mcu_dispc_init_config(struct panel_spec *panel)
{
	uint32_t reg_val = 0;

	FB_PRINT("sprdfb: [%s] for cs1\n", __FUNCTION__);

	if(NULL == panel){
		printf("sprdfb: [%s] fail.(Invalid Param)\n", __FUNCTION__);
		return;
	}

	if(SPRDFB_PANEL_TYPE_MCU != panel->type){
		printf("sprdfb: [%s] fail.(not  mcu panel)\n", __FUNCTION__);
		return;
	}

	/*use dbi as interface*/
	dispc_set_bits((2<<1), DISPC_CTRL);

	/* CS1 bus mode [BIT8]: 8080/6800 */
	switch (panel->info.mcu->bus_mode) {
	case LCD_BUS_8080:
		break;
	case LCD_BUS_6800:
		reg_val |= (1<<8);
		break;
	default:
		break;
	}
	/* CS1 bus width [BIT11:9] */
	switch (panel->info.mcu->bus_width) {
	case 8:
		break;
	case 9:
		reg_val |= (1 << 9);
		break;
	case 16:
		reg_val |= (2 << 9);
		break;
	case 18:
		reg_val |= (3 << 9) ;
		break;
	case 24:
		reg_val |= (4 << 9);
		break;
	default:
		break;
	}

	/*CS1 pixel bits [BIT13:12]*/
	switch (panel->info.mcu->bpp) {
	case 16:
		break;
	case 18:
		reg_val |= (1 << 12) ;
		break;
	case 24:
		reg_val |= (2 << 12);
		break;
	default:
		break;
	}

#ifndef CONFIG_FB_NO_FMARK
	/*TE enable*/
	reg_val |= (1 << 16);
	if(SPRDFB_POLARITY_NEG == panel->info.mcu->te_pol){
		reg_val |= (1<< 17);
	}
	dispc_write(panel->info.mcu->te_sync_delay, DISPC_TE_SYNC_DELAY);
#endif

#ifdef CONFIG_LCD_CS_ALWAYS_LOW
	/*CS alway low mode*/
	reg_val |= (1<<21);
#else
	/*CS not alway low mode*/
#endif

	/*CS1 selected*/
	reg_val |= (1 << 20);

	dispc_write(reg_val, DISPC_DBI_CTRL);

	FB_PRINT("sprdfb: [%s] DISPC_DBI_CTRL = %d\n", __FUNCTION__, dispc_read(DISPC_DBI_CTRL));
}
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;
}