Esempio n. 1
0
static int32_t sprdfb_mcu_panel_check(struct panel_spec *panel)
{
	struct info_mcu* mcu_info = NULL;
	uint16_t rval = 1;

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

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

	mcu_info = panel->info.mcu;

	FB_PRINT("sprdfb: [%s]: bus width= %d, bpp = %d\n",__FUNCTION__, mcu_info->bus_width, mcu_info->bpp);

	switch(mcu_info->bus_width){
	case 8:
		if((16 != mcu_info->bpp) && (24 != mcu_info->bpp)){
			rval = 0;
		}
		break;
	case 9:
		if(18 != mcu_info->bpp) {
			rval = 0;
		}
		break;
	case 16:
		if((16 != mcu_info->bpp) && (18 != mcu_info->bpp) &&
			(24 != mcu_info->bpp)){
			rval = 0;
		}
		break;
	case 18:
		if(18 != mcu_info->bpp){
			rval = 0;
		}
		break;
	case 24:
		if(24 != mcu_info->bpp){
			rval = 0;
		}
		break;
	default:
		rval = 0;
		break;
	}

	if(!rval){
		FB_PRINT("sprdfb: mcu_panel_check return false!\n");
	}

	return rval;
}
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;
}
/* dispc soft reset */
static void dispc_reset(void)
{
	FB_PRINT("sprdfb:[%s]\n",__FUNCTION__);

	__raw_writel(__raw_readl(AHB_SOFT_RST) | (1<<DISPC_SOFT_RST), AHB_SOFT_RST);
	udelay(10);
	__raw_writel(__raw_readl(AHB_SOFT_RST) & (~(1<<DISPC_SOFT_RST)), AHB_SOFT_RST);
}
static int32_t sprdfb_dispc_uninit(struct sprdfb_device *dev)
{
	FB_PRINT("sprdfb:[%s]\n",__FUNCTION__);

	//disable DISPC clock
	__raw_bits_and(~(1<<22), AHB_CTL0);
	return 0;
}
int32_t dsi_early_int(void)
{
	FB_PRINT("sprdfb:[%s]\n", __FUNCTION__);

	if(dsi_ctx.is_inited){
		FB_PRINT("sprdfb: dispc early init warning!(has been inited)");
		return 0;
	}

	//TODO:Enable DSI clock

	dsi_reset();

	memset(&(dsi_ctx.dsi_inst), 0, sizeof(dsi_ctx.dsi_inst));

	dsi_ctx.is_inited = 1;
	return 0;
}
static int32_t sprdfb_dsi_dcs_write(uint8_t *param, uint16_t param_length)
{
	dsih_error_t result;
	result = mipi_dsih_dcs_wr_cmd(&(dsi_ctx.dsi_inst), 0, param, param_length);
	if(OK != result){
		FB_PRINT("sprdfb: [%s] error (%d)\n", __FUNCTION__, result);
		return -1;
	}
	return 0;
}
static void dispc_set_exp_mode(uint16_t exp_mode)
{
	uint32_t reg_val = dispc_read(DISPC_CTRL);

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

	reg_val &= ~(0x3 << 16);
	reg_val |= (exp_mode << 16);
	dispc_write(reg_val, 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 int32_t sprdfb_dsi_dcs_read(uint8_t command, uint8_t bytes_to_read, uint8_t *read_buffer)
{
	uint16_t result;
	result = mipi_dsih_dcs_rd_cmd(&(dsi_ctx.dsi_inst), 0, command, bytes_to_read, read_buffer);
	if(0 == result){
		FB_PRINT("sprdfb: [%s] error (%d)\n", __FUNCTION__, result);
		return -1;
	}
	return 0;
}
static void dispc_layer_init(struct sprdfb_device *dev)
{
	uint32_t reg_val = 0;

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

	dispc_clear_bits((1<<0),DISPC_IMG_CTRL);
	dispc_clear_bits((1<<0),DISPC_OSD_CTRL);

	/******************* OSD layer setting **********************/

	/*enable OSD layer*/
	reg_val |= (1 << 0);

	/*disable  color key */

	/* alpha mode select  - block alpha*/
	reg_val |= (1 << 2);

	/* data format */
	/* RGB565 */
	reg_val |= (5 << 4);
	/* B2B3B0B1 */
	reg_val |= (2 << 8);

	dispc_write(reg_val, DISPC_OSD_CTRL);

	/* OSD layer alpha value */
	dispc_write(0xff, DISPC_OSD_ALPHA);

	/* OSD layer size */
	reg_val = ( dev->panel->width& 0xfff) | ((dev->panel->height & 0xfff ) << 16);
	dispc_write(reg_val, DISPC_OSD_SIZE_XY);

	/* OSD layer start position */
	dispc_write(0, DISPC_OSD_DISP_XY);

	/* OSD layer pitch */
	reg_val = ( dev->panel->width & 0xfff) ;
	dispc_write(reg_val, DISPC_OSD_PITCH);

	/*OSD base address*/
	dispc_write(dev->smem_start, DISPC_OSD_BASE_ADDR);

	/* OSD color_key value */
	dispc_set_osd_ck(0x0);

	/* DISPC workplane size */
	dispc_set_disp_size(dev);

	FB_PRINT("DISPC_OSD_CTRL: 0x%x\n", dispc_read(DISPC_OSD_CTRL));
	FB_PRINT("DISPC_OSD_ALPHA: 0x%x\n", dispc_read(DISPC_OSD_ALPHA));
	FB_PRINT("DISPC_OSD_SIZE_XY: 0x%x\n", dispc_read(DISPC_OSD_SIZE_XY));
	FB_PRINT("DISPC_OSD_DISP_XY: 0x%x\n", dispc_read(DISPC_OSD_DISP_XY));
	FB_PRINT("DISPC_OSD_PITCH: 0x%x\n", dispc_read(DISPC_OSD_PITCH));
	FB_PRINT("DISPC_OSD_BASE_ADDR: 0x%x\n", dispc_read(DISPC_OSD_BASE_ADDR));
}
static inline int32_t  dispc_set_disp_size(struct sprdfb_device *dev)
{
	uint32_t reg_val;

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

	reg_val = (dev->panel->width& 0xfff) | ((dev->panel->height & 0xfff ) << 16);
	dispc_write(reg_val, DISPC_SIZE_XY);

	return 0;
}
static int32_t sprdfb_dispc_early_init(struct sprdfb_device *dev)
{
	FB_PRINT("sprdfb:[%s]\n", __FUNCTION__);

	//select DISPC clock source
	__raw_bits_and(~(1<<1), AHB_DISPC_CLK);    //pll_src=256M
	__raw_bits_and(~(1<<2), AHB_DISPC_CLK);

	//set DISPC divdior
	__raw_bits_and(~(1<<3), AHB_DISPC_CLK);  //div=0
	__raw_bits_and(~(1<<4), AHB_DISPC_CLK);
	__raw_bits_and(~(1<<5), AHB_DISPC_CLK);

	//select DBI clock source
	__raw_bits_and(~(1<<9), AHB_DISPC_CLK);    //pll_src=256M
	__raw_bits_and(~(1<<10), AHB_DISPC_CLK);

	//set DBI divdior
	__raw_bits_and(~(1<<11), AHB_DISPC_CLK);  //div=0
	__raw_bits_and(~(1<<12), AHB_DISPC_CLK);
	__raw_bits_and(~(1<<13), AHB_DISPC_CLK);

	//select DPI clock source
	__raw_bits_and(~(1<<17), AHB_DISPC_CLK);    //pll_src=384M
	__raw_bits_and(~(1<<18), AHB_DISPC_CLK);

	//set DPI divdior
	__raw_bits_and(~(1<<19), AHB_DISPC_CLK);  //div=10, dpi_clk = pll_src/(10+1)
	__raw_bits_or((1<<20), AHB_DISPC_CLK);
	__raw_bits_and(~(1<<21), AHB_DISPC_CLK);
	__raw_bits_or((1<<22), AHB_DISPC_CLK);
	__raw_bits_and(~(1<<23), AHB_DISPC_CLK);
	__raw_bits_and(~(1<<24), AHB_DISPC_CLK);
	__raw_bits_and(~(1<<25), AHB_DISPC_CLK);
	__raw_bits_and(~(1<<26), AHB_DISPC_CLK);

	//enable dispc matric clock
	__raw_bits_or((1<<9), AHB_CTL2);  //core_clock_en
	__raw_bits_or((1<<11), AHB_CTL2);  //matrix clock en

	//enable DISPC clock
	__raw_bits_or(1<<22, AHB_CTL0);

	printf("0x20900200 = 0x%x\n", __raw_readl(0x20900200));
	printf("0x20900208 = 0x%x\n", __raw_readl(0x20900208));
	printf("0x20900220 = 0x%x\n", __raw_readl(0x20900220));

	dispc_reset();
	dispc_module_enable();
	is_first_frame = 1;

	return 0;
}
static void dispc_module_enable(void)
{
	FB_PRINT("sprdfb:[%s]\n",__FUNCTION__);

	/*dispc module enable */
	dispc_write((1<<0), DISPC_CTRL);

	/*disable dispc INT*/
	dispc_write(0x0, DISPC_INT_EN);

	/* clear dispc INT */
	dispc_write(0x1F, DISPC_INT_CLR);
}
Esempio n. 14
0
int32_t sprdfb_dsi_uninit(struct sprdfb_device *dev)
{
	dsih_error_t result;
	result = mipi_dsih_close(&(dsi_ctx.dsi_inst));
	if(OK != result){
		FB_PRINT("sprdfb: [%s]: sprdfb_dsi_uninit fail (%d)!\n", __FUNCTION__, result);
		return -1;
	} else {
		dsi_ctx.is_inited = 0;
	}

	dsi_core_write_function(DSI_CTL_BEGIN, R_DSI_HOST_PHY_IF_CTRL, 0);
	mdelay(3);

	return 0;
}
Esempio n. 15
0
void mcu_dispc_set_timing(struct sprdfb_device *dev, uint32_t type)
{
	FB_PRINT("sprdfb: [%s] for cs0, type = %d\n", __FUNCTION__, type);

	switch (type)
	{
	case MCU_LCD_REGISTER_TIMING:
		dispc_write(dev->panel_timing.mcu_timing[MCU_LCD_REGISTER_TIMING],DISPC_DBI_TIMING0);
		break;

	case MCU_LCD_GRAM_TIMING:
		dispc_write(dev->panel_timing.mcu_timing[MCU_LCD_GRAM_TIMING],DISPC_DBI_TIMING0);
		break;
	default:
		break;
	}
}
Esempio n. 16
0
static int32_t dsi_edpi_setbuswidth(struct info_mipi * mipi)
{
	dsih_color_coding_t color_coding = 0;

	switch(mipi->video_bus_width){
	case 16:
		color_coding = COLOR_CODE_16BIT_CONFIG1;
		break;
	case 18:
		color_coding = COLOR_CODE_18BIT_CONFIG1;
		break;
	case 24:
		color_coding = COLOR_CODE_24BIT;
		break;
	default:
		FB_PRINT("sprdfb:[%s] fail, invalid video_bus_width\n", __FUNCTION__);
		break;
	}

	dsi_core_write_function(DSI_CTL_BEGIN,  R_DSI_HOST_DPI_CFG, (uint32_t)(color_coding<<2));
	return 0;
}
Esempio n. 17
0
static void sprdfb_mcu_panel_mount(struct sprdfb_device *dev)
{
	struct timing_mcu* timing = NULL;

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

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

	dev->panel_if_type = SPRDFB_PANEL_IF_DBI;

	dev->panel->info.mcu->ops =  &dispc_mcu_ops;

	if(NULL == dev->panel->ops->panel_readid){
		dev->panel->ops->panel_readid = mcu_readid;
	}

	timing = dev->panel->info.mcu->timing;
	dev->panel_timing.mcu_timing[MCU_LCD_REGISTER_TIMING] = mcu_calc_timing(timing);
	timing++;
	dev->panel_timing.mcu_timing[MCU_LCD_GRAM_TIMING] = mcu_calc_timing(timing);
}
Esempio n. 18
0
/*cs0*/
void mcu_dispc_init_config(struct panel_spec *panel)
{
	uint32_t reg_val = 0;

	FB_PRINT("sprdfb: [%s] for cs0\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);

	/* 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);

	FB_PRINT("sprdfb: [%s] DISPC_DBI_CTRL = %d\n", __FUNCTION__, dispc_read(DISPC_DBI_CTRL));
}
static inline void dispc_set_bg_color(uint32_t bg_color)
{
	FB_PRINT("sprdfb:[%s]\n",__FUNCTION__);

	dispc_write(bg_color, DISPC_BG_COLOR);
}
static inline void dispc_set_osd_ck(uint32_t ck_color)
{
	FB_PRINT("sprdfb:[%s]\n",__FUNCTION__);

	dispc_write(ck_color, DISPC_OSD_CK);
}
Esempio n. 21
0
static uint32_t mcu_calc_timing(struct timing_mcu *timing)
{
	uint32_t  clk_rate;
	uint32_t  rcss, rlpw, rhpw, wcss, wlpw, whpw;
//	struct clk * clk = NULL;

	if(NULL == timing){
		FB_PRINT("sprdfb: [%s]: Invalid Param\n", __FUNCTION__);
		return 0;
	}

//	clk_get(NULL,"clk_dispc_dbi");
//	clk_rate = clk_get_rate(clk) / 1000000;
	clk_rate = 250; // 250 MHz

	FB_PRINT("sprdfb: [%s] clk_rate: 0x%x\n", __FUNCTION__, clk_rate);

	/********************************************************
	* we assume : t = ? ns, dispc_dbi = ? MHz   so
	*      1ns need cycle  :  dispc_dbi /1000
	*      tns need cycles :  t * dispc_dbi / 1000
	*
	********************************************************/
#define MAX_DBI_RWCSS_TIMING_VALUE	15
#define MAX_DBI_RWLPW_TIMING_VALUE	63
#define MAX_DBI_RWHPW_TIMING_VALUE	63
#define DBI_CYCLES(ns) (( (ns) * clk_rate + 1000 - 1)/ 1000)

	/* ceiling*/
	rcss = DBI_CYCLES(timing->rcss);
	if (rcss > MAX_DBI_RWCSS_TIMING_VALUE) {
		rcss = MAX_DBI_RWCSS_TIMING_VALUE ;
	}

	rlpw = DBI_CYCLES(timing->rlpw);
	if (rlpw > MAX_DBI_RWLPW_TIMING_VALUE) {
		rlpw = MAX_DBI_RWLPW_TIMING_VALUE ;
	}

	rhpw = DBI_CYCLES (timing->rhpw);
	if (rhpw > MAX_DBI_RWHPW_TIMING_VALUE) {
		rhpw = MAX_DBI_RWHPW_TIMING_VALUE ;
	}

	wcss = DBI_CYCLES(timing->wcss);
	if (wcss > MAX_DBI_RWCSS_TIMING_VALUE) {
		wcss = MAX_DBI_RWCSS_TIMING_VALUE ;
	}

	wlpw = DBI_CYCLES(timing->wlpw);
	if (wlpw > MAX_DBI_RWLPW_TIMING_VALUE) {
		wlpw = MAX_DBI_RWLPW_TIMING_VALUE ;
	}

#ifndef CONFIG_LCD_CS_ALWAYS_LOW
	 /* dispc/lcdc will waste one cycle because CS pulse will use one cycle*/
	whpw = DBI_CYCLES (timing->whpw) - 1;
#else
	whpw = DBI_CYCLES (timing->whpw) ;
#endif
	if (whpw > MAX_DBI_RWHPW_TIMING_VALUE) {
		whpw = MAX_DBI_RWHPW_TIMING_VALUE ;
	}

	return (whpw | (wlpw << 6) | (wcss << 12)
			| (rhpw << 16) |(rlpw << 22) | (rcss << 28));
}
Esempio n. 22
0
int32_t sprdfb_dsi_init(struct sprdfb_device *dev)
{
	dsih_error_t result = OK;
	dsih_ctrl_t* dsi_instance = &(dsi_ctx.dsi_inst);
	dphy_t *phy = &(dsi_instance->phy_instance);
	struct info_mipi * mipi = dev->panel->info.mipi;

	__raw_bits_or((1<<0), 0x2090021c);  //enable dphy

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

	dsi_early_int();

	phy->address = DSI_CTL_BEGIN;
	phy->core_read_function = dsi_core_read_function;
	phy->core_write_function = dsi_core_write_function;
	phy->log_error = dsi_log_error;
	phy->log_info = NULL;
	phy->reference_freq = DSI_PHY_REF_CLOCK;

	dsi_instance->address = DSI_CTL_BEGIN;
	dsi_instance->color_mode_polarity =mipi->color_mode_pol;
	dsi_instance->shut_down_polarity = mipi->shut_down_pol;
	dsi_instance->core_read_function = dsi_core_read_function;
	dsi_instance->core_write_function = dsi_core_write_function;
	dsi_instance->log_error = dsi_log_error;
	dsi_instance->log_info = NULL;
	/*in our rtl implementation, this is max rd time, not bta time and use 15bits*/
	dsi_instance->max_bta_cycles = 0x6000;//10;
	dsi_instance->max_hs_to_lp_cycles = 4;//110;
	dsi_instance->max_lp_to_hs_cycles = 15;//10;
	dsi_instance->max_lanes = mipi->lan_number;

	if(SPRDFB_MIPI_MODE_CMD == mipi->work_mode){
		dsi_edpi_init();
	}/*else{
		dsi_dpi_init(dev->panel);
	}*/

/*
	result = mipi_dsih_unregister_all_events(dsi_instance);
	if(OK != result){
		FB_PRINT("sprdfb: [%s]: mipi_dsih_unregister_all_events fail (%d)!\n", __FUNCTION__, result);
		return -1;
	}
*/
	dsi_core_write_function(DSI_CTL_BEGIN,  R_DSI_HOST_ERROR_MSK0, 0x1fffff);
	dsi_core_write_function(DSI_CTL_BEGIN,  R_DSI_HOST_ERROR_MSK1, 0x3ffff);

	result = mipi_dsih_open(dsi_instance);
	if(OK != result){
		FB_PRINT("sprdfb: [%s]: mipi_dsih_open fail (%d)!\n", __FUNCTION__, result);
		return -1;
	}

	result = mipi_dsih_dphy_configure(phy,  mipi->lan_number, mipi->phy_feq);
	if(OK != result){
		FB_PRINT("sprdfb: [%s]: mipi_dsih_dphy_configure fail (%d)!\n", __FUNCTION__, result);
		return -1;
	}

	while(5 != (dsi_core_read_function(DSI_CTL_BEGIN, R_DSI_HOST_PHY_STATUS) & 5));

	if(SPRDFB_MIPI_MODE_CMD == mipi->work_mode){
		dsi_edpi_setbuswidth(mipi);
	}

	result = mipi_dsih_enable_rx(dsi_instance, 1);
	if(OK != result){
		FB_PRINT("sprdfb: [%s]: mipi_dsih_enable_rx fail (%d)!\n", __FUNCTION__, result);
		return -1;
	}

	result = mipi_dsih_ecc_rx(dsi_instance, 1);
	if(OK != result){
		FB_PRINT("sprdfb: [%s]: mipi_dsih_ecc_rx fail (%d)!\n", __FUNCTION__, result);
		return -1;
	}

	result = mipi_dsih_eotp_rx(dsi_instance, 1);
	if(OK != result){
		FB_PRINT("sprdfb: [%s]: mipi_dsih_eotp_rx fail (%d)!\n", __FUNCTION__, result);
		return -1;
	}

	result = mipi_dsih_eotp_tx(dsi_instance, 1);
	if(OK != result){
		FB_PRINT("sprdfb: [%s]: mipi_dsih_eotp_tx fail (%d)!\n", __FUNCTION__, result);
		return -1;
	}

	if(SPRDFB_MIPI_MODE_VIDEO == mipi->work_mode){
		dsi_dpi_init(dev->panel);
	}

	return 0;
}
Esempio n. 23
0
static void dsi_log_error(const char * string)
{
	FB_PRINT(string);
}