diff options
| -rw-r--r-- | board/davinci/ea20/ea20.c | 26 | ||||
| -rw-r--r-- | drivers/video/da8xx-fb.c | 335 | ||||
| -rw-r--r-- | drivers/video/da8xx-fb.h | 4 | 
3 files changed, 307 insertions, 58 deletions
| diff --git a/board/davinci/ea20/ea20.c b/board/davinci/ea20/ea20.c index 89ee079ea..c4444c7c7 100644 --- a/board/davinci/ea20/ea20.c +++ b/board/davinci/ea20/ea20.c @@ -43,6 +43,30 @@ static const struct da8xx_panel lcd_panel = {  	.invert_pxl_clk = 0,  }; +static const struct display_panel disp_panel = { +	QVGA, +	16, +	16, +	COLOR_ACTIVE, +}; + +static const struct lcd_ctrl_config lcd_cfg = { +	&disp_panel, +	.ac_bias		= 255, +	.ac_bias_intrpt		= 0, +	.dma_burst_sz		= 16, +	.bpp			= 16, +	.fdd			= 255, +	.tft_alt_mode		= 0, +	.stn_565_mode		= 0, +	.mono_8bit_mode		= 0, +	.invert_line_clock	= 1, +	.invert_frm_clock	= 1, +	.sync_edge		= 0, +	.sync_ctrl		= 1, +	.raster_order		= 0, +}; +  /* SPI0 pin muxer settings */  static const struct pinmux_config spi1_pins[] = {  	{ pinmux(5), 1, 1 }, @@ -259,7 +283,7 @@ int board_init(void)  	/* address of boot parameters */  	gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR; -	da8xx_video_init(&lcd_panel, 16); +	da8xx_video_init(&lcd_panel, &lcd_cfg, 16);  	return 0;  } diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index dd7ce3606..b0bde2d7a 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -26,8 +26,15 @@  #include "videomodes.h"  #include "da8xx-fb.h" +#if !defined(DA8XX_LCD_CNTL_BASE) +#define DA8XX_LCD_CNTL_BASE	DAVINCI_LCD_CNTL_BASE +#endif +  #define DRIVER_NAME "da8xx_lcdc" +#define LCD_VERSION_1	1 +#define LCD_VERSION_2	2 +  /* LCD Status Register */  #define LCD_END_OF_FRAME1		(1 << 9)  #define LCD_END_OF_FRAME0		(1 << 8) @@ -42,9 +49,14 @@  #define LCD_DMA_BURST_4			0x2  #define LCD_DMA_BURST_8			0x3  #define LCD_DMA_BURST_16		0x4 -#define LCD_END_OF_FRAME_INT_ENA	(1 << 2) +#define LCD_V1_END_OF_FRAME_INT_ENA	(1 << 2) +#define LCD_V2_END_OF_FRAME0_INT_ENA	(1 << 8) +#define LCD_V2_END_OF_FRAME1_INT_ENA	(1 << 9)  #define LCD_DUAL_FRAME_BUFFER_ENABLE	(1 << 0) +#define LCD_V2_TFT_24BPP_MODE		(1 << 25) +#define LCD_V2_TFT_24BPP_UNPACK		(1 << 26) +  /* LCD Control Register */  #define LCD_CLK_DIVISOR(x)		((x) << 8)  #define LCD_RASTER_MODE			0x01 @@ -58,12 +70,20 @@  #define LCD_MONO_8BIT_MODE		(1 << 9)  #define LCD_RASTER_ORDER		(1 << 8)  #define LCD_TFT_MODE			(1 << 7) -#define LCD_UNDERFLOW_INT_ENA		(1 << 6) -#define LCD_PL_ENABLE			(1 << 4) +#define LCD_V1_UNDERFLOW_INT_ENA	(1 << 6) +#define LCD_V2_UNDERFLOW_INT_ENA	(1 << 5) +#define LCD_V1_PL_INT_ENA		(1 << 4) +#define LCD_V2_PL_INT_ENA		(1 << 6)  #define LCD_MONOCHROME_MODE		(1 << 1)  #define LCD_RASTER_ENABLE		(1 << 0)  #define LCD_TFT_ALT_ENABLE		(1 << 23)  #define LCD_STN_565_ENABLE		(1 << 24) +#define LCD_V2_DMA_CLK_EN		(1 << 2) +#define LCD_V2_LIDD_CLK_EN		(1 << 1) +#define LCD_V2_CORE_CLK_EN		(1 << 0) +#define LCD_V2_LPP_B10			26 +#define LCD_V2_TFT_24BPP_MODE		(1 << 25) +#define LCD_V2_TFT_24BPP_UNPACK		(1 << 26)  /* LCD Raster Timing 2 Register */  #define LCD_AC_BIAS_TRANSITIONS_PER_INT(x)	((x) << 16) @@ -74,6 +94,8 @@  #define LCD_INVERT_LINE_CLOCK			(1 << 21)  #define LCD_INVERT_FRAME_CLOCK			(1 << 20) +/* Clock registers available only on Version 2 */ +#define  LCD_CLK_MAIN_RESET			(1 << 3)  /* LCD Block */  struct da8xx_lcd_regs {  	u32	revid; @@ -97,6 +119,15 @@ struct da8xx_lcd_regs {  	u32	dma_frm_buf_ceiling_addr_0;  	u32	dma_frm_buf_base_addr_1;  	u32	dma_frm_buf_ceiling_addr_1; +	u32	resv1; +	u32	raw_stat; +	u32	masked_stat; +	u32	int_ena_set; +	u32	int_ena_clr; +	u32	end_of_int_ind; +	/* Clock registers available only on Version 2 */ +	u32	clk_ena; +	u32	clk_reset;  };  #define LCD_NUM_BUFFERS	1 @@ -107,6 +138,8 @@ struct da8xx_lcd_regs {  #define RIGHT_MARGIN	64  #define UPPER_MARGIN	32  #define LOWER_MARGIN	32 +#define WAIT_FOR_FRAME_DONE	true +#define NO_WAIT_FOR_FRAME_DONE	false  #define calc_fbsize() (panel.plnSizeX * panel.plnSizeY * panel.gdfBytesPP) @@ -119,6 +152,8 @@ static GraphicDevice gpanel;  static const struct da8xx_panel *lcd_panel;  static struct fb_info *da8xx_fb_info;  static int bits_x_pixel; +static unsigned int lcd_revision; +const struct lcd_ctrl_config *da8xx_lcd_cfg;  static inline unsigned int lcdc_read(u32 *addr)  { @@ -179,35 +214,24 @@ static struct fb_fix_screeninfo da8xx_fb_fix = {  	.accel = FB_ACCEL_NONE  }; -static const struct display_panel disp_panel = { -	QVGA, -	16, -	16, -	COLOR_ACTIVE, -}; - -static const struct lcd_ctrl_config lcd_cfg = { -	&disp_panel, -	.ac_bias		= 255, -	.ac_bias_intrpt		= 0, -	.dma_burst_sz		= 16, -	.bpp			= 16, -	.fdd			= 255, -	.tft_alt_mode		= 0, -	.stn_565_mode		= 0, -	.mono_8bit_mode		= 0, -	.invert_line_clock	= 1, -	.invert_frm_clock	= 1, -	.sync_edge		= 0, -	.sync_ctrl		= 1, -	.raster_order		= 0, -}; -  /* Enable the Raster Engine of the LCD Controller */  static inline void lcd_enable_raster(void)  {  	u32 reg; +	/* Put LCDC in reset for several cycles */ +	if (lcd_revision == LCD_VERSION_2) +		lcdc_write(LCD_CLK_MAIN_RESET, +			   &da8xx_fb_reg_base->clk_reset); + +	udelay(1000); +	/* Bring LCDC out of reset */ +	if (lcd_revision == LCD_VERSION_2) +		lcdc_write(0, +			   &da8xx_fb_reg_base->clk_reset); + +	udelay(1000); +  	reg = lcdc_read(&da8xx_fb_reg_base->raster_ctrl);  	if (!(reg & LCD_RASTER_ENABLE))  		lcdc_write(reg | LCD_RASTER_ENABLE, @@ -215,14 +239,40 @@ static inline void lcd_enable_raster(void)  }  /* Disable the Raster Engine of the LCD Controller */ -static inline void lcd_disable_raster(void) +static inline void lcd_disable_raster(bool wait_for_frame_done)  {  	u32 reg; +	u32 loop_cnt = 0; +	u32 stat; +	u32 i = 0; + +	if (wait_for_frame_done) +		loop_cnt = 5000;  	reg = lcdc_read(&da8xx_fb_reg_base->raster_ctrl);  	if (reg & LCD_RASTER_ENABLE)  		lcdc_write(reg & ~LCD_RASTER_ENABLE,  			&da8xx_fb_reg_base->raster_ctrl); + +	/* Wait for the current frame to complete */ +	do { +		if (lcd_revision == LCD_VERSION_1) +			stat = lcdc_read(&da8xx_fb_reg_base->stat); +		else +			stat = lcdc_read(&da8xx_fb_reg_base->raw_stat); + +		mdelay(1); +	} while (!(stat & 0x01) && (i++ < loop_cnt)); + +	if (lcd_revision == LCD_VERSION_1) +		lcdc_write(stat, &da8xx_fb_reg_base->stat); +	else +		lcdc_write(stat, &da8xx_fb_reg_base->raw_stat); + +	if ((loop_cnt != 0) && (i >= loop_cnt)) { +		printf("LCD Controller timed out\n"); +		return; +	}  }  static void lcd_blit(int load_mode, struct da8xx_fb_par *par) @@ -231,6 +281,7 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)  	u32 end;  	u32 reg_ras;  	u32 reg_dma; +	u32 reg_int;  	/* init reg to clear PLM (loading mode) fields */  	reg_ras = lcdc_read(&da8xx_fb_reg_base->raster_ctrl); @@ -243,7 +294,15 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)  		end      = par->dma_end;  		reg_ras |= LCD_PALETTE_LOAD_MODE(DATA_ONLY); -		reg_dma |= LCD_END_OF_FRAME_INT_ENA; +		if (lcd_revision == LCD_VERSION_1) { +			reg_dma |= LCD_V1_END_OF_FRAME_INT_ENA; +		} else { +			reg_int = lcdc_read(&da8xx_fb_reg_base->int_ena_set) | +				LCD_V2_END_OF_FRAME0_INT_ENA | +				LCD_V2_END_OF_FRAME1_INT_ENA | +				LCD_V2_UNDERFLOW_INT_ENA | LCD_SYNC_LOST; +			lcdc_write(reg_int, &da8xx_fb_reg_base->int_ena_set); +		}  #if (LCD_NUM_BUFFERS == 2)  		reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE; @@ -264,7 +323,13 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)  		end      = start + par->palette_sz - 1;  		reg_ras |= LCD_PALETTE_LOAD_MODE(PALETTE_ONLY); -		reg_ras |= LCD_PL_ENABLE; +		if (lcd_revision == LCD_VERSION_1) { +			reg_ras |= LCD_V1_PL_INT_ENA; +		} else { +			reg_int = lcdc_read(&da8xx_fb_reg_base->int_ena_set) | +				LCD_V2_PL_INT_ENA; +			lcdc_write(reg_int, &da8xx_fb_reg_base->int_ena_set); +		}  		lcdc_write(start, &da8xx_fb_reg_base->dma_frm_buf_base_addr_0);  		lcdc_write(end, &da8xx_fb_reg_base->dma_frm_buf_ceiling_addr_0); @@ -348,6 +413,7 @@ static void lcd_cfg_vertical_sync(int back_porch, int pulse_width,  static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)  {  	u32 reg; +	u32 reg_int;  	reg = lcdc_read(&da8xx_fb_reg_base->raster_ctrl) & ~(LCD_TFT_MODE |  						LCD_MONO_8BIT_MODE | @@ -375,7 +441,13 @@ static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)  	}  	/* enable additional interrupts here */ -	reg |= LCD_UNDERFLOW_INT_ENA; +	if (lcd_revision == LCD_VERSION_1) { +		reg |= LCD_V1_UNDERFLOW_INT_ENA; +	} else { +		reg_int = lcdc_read(&da8xx_fb_reg_base->int_ena_set) | +			LCD_V2_UNDERFLOW_INT_ENA; +		lcdc_write(reg_int, &da8xx_fb_reg_base->int_ena_set); +	}  	lcdc_write(reg, &da8xx_fb_reg_base->raster_ctrl); @@ -413,22 +485,53 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,  	/* Set the Panel Width */  	/* Pixels per line = (PPL + 1)*16 */ -	/*0x3F in bits 4..9 gives max horisontal resolution = 1024 pixels*/ -	width &= 0x3f0; +	if (lcd_revision == LCD_VERSION_1) { +		/* +		 * 0x3F in bits 4..9 gives max horisontal resolution = 1024 +		 * pixels +		 */ +		width &= 0x3f0; +	} else { +		/* +		 * 0x7F in bits 4..10 gives max horizontal resolution = 2048 +		 * pixels. +		 */ +		width &= 0x7f0; +	}  	reg = lcdc_read(&da8xx_fb_reg_base->raster_timing_0);  	reg &= 0xfffffc00; -	reg |= ((width >> 4) - 1) << 4; +	if (lcd_revision == LCD_VERSION_1) { +		reg |= ((width >> 4) - 1) << 4; +	} else { +		width = (width >> 4) - 1; +		reg |= ((width & 0x3f) << 4) | ((width & 0x40) >> 3); +	}  	lcdc_write(reg, &da8xx_fb_reg_base->raster_timing_0);  	/* Set the Panel Height */ +	/* Set bits 9:0 of Lines Per Pixel */  	reg = lcdc_read(&da8xx_fb_reg_base->raster_timing_1);  	reg = ((height - 1) & 0x3ff) | (reg & 0xfffffc00);  	lcdc_write(reg, &da8xx_fb_reg_base->raster_timing_1); +	/* Set bit 10 of Lines Per Pixel */ +	if (lcd_revision == LCD_VERSION_2) { +		reg = lcdc_read(&da8xx_fb_reg_base->raster_timing_2); +		reg |= ((height - 1) & 0x400) << 16; +		lcdc_write(reg, &da8xx_fb_reg_base->raster_timing_2); +	} +  	/* Set the Raster Order of the Frame Buffer */  	reg = lcdc_read(&da8xx_fb_reg_base->raster_ctrl) & ~(1 << 8);  	if (raster_order)  		reg |= LCD_RASTER_ORDER; + +	if (bpp == 24) +		reg |= (LCD_TFT_MODE | LCD_V2_TFT_24BPP_MODE); +	else if (bpp == 32) +		reg |= (LCD_TFT_MODE | LCD_V2_TFT_24BPP_MODE +				| LCD_V2_TFT_24BPP_UNPACK); +  	lcdc_write(reg, &da8xx_fb_reg_base->raster_ctrl);  	switch (bpp) { @@ -436,6 +539,8 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,  	case 2:  	case 4:  	case 16: +	case 24: +	case 32:  		par->palette_sz = 16 * 2;  		break; @@ -494,6 +599,23 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,  			update_hw = 1;  			palette[0] = 0x4000;  		} +	} else if (((info->var.bits_per_pixel == 32) && regno < 32) || +		   ((info->var.bits_per_pixel == 24) && regno < 24)) { +		red >>= (24 - info->var.red.length); +		red <<= info->var.red.offset; + +		green >>= (24 - info->var.green.length); +		green <<= info->var.green.offset; + +		blue >>= (24 - info->var.blue.length); +		blue <<= info->var.blue.offset; + +		par->pseudo_palette[regno] = red | green | blue; + +		if (palette[0] != 0x4000) { +			update_hw = 1; +			palette[0] = 0x4000; +		}  	}  	/* Update the palette in the h/w as needed. */ @@ -506,11 +628,18 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,  static void lcd_reset(struct da8xx_fb_par *par)  {  	/* Disable the Raster if previously Enabled */ -	lcd_disable_raster(); +	lcd_disable_raster(NO_WAIT_FOR_FRAME_DONE);  	/* DMA has to be disabled */  	lcdc_write(0, &da8xx_fb_reg_base->dma_ctrl);  	lcdc_write(0, &da8xx_fb_reg_base->raster_ctrl); + +	if (lcd_revision == LCD_VERSION_2) { +		lcdc_write(0, &da8xx_fb_reg_base->int_ena_set); +		/* Write 1 to reset */ +		lcdc_write(LCD_CLK_MAIN_RESET, &da8xx_fb_reg_base->clk_reset); +		lcdc_write(0, &da8xx_fb_reg_base->clk_reset); +	}  }  static void lcd_calc_clk_divider(struct da8xx_fb_par *par) @@ -521,12 +650,17 @@ static void lcd_calc_clk_divider(struct da8xx_fb_par *par)  	lcd_clk = clk_get(2);  	div = lcd_clk / par->pxl_clk; -	debug("LCD Clock: 0x%x Divider: 0x%x PixClk: 0x%x\n", -		lcd_clk, div, par->pxl_clk); +	debug("LCD Clock: %d Divider: %d PixClk: %d\n", +	      lcd_clk, div, par->pxl_clk);  	/* Configure the LCD clock divisor. */  	lcdc_write(LCD_CLK_DIVISOR(div) |  			(LCD_RASTER_MODE & 0x1), &da8xx_fb_reg_base->ctrl); + +	if (lcd_revision == LCD_VERSION_2) +		lcdc_write(LCD_V2_DMA_CLK_EN | LCD_V2_LIDD_CLK_EN | +				LCD_V2_CORE_CLK_EN, +				&da8xx_fb_reg_base->clk_ena);  }  static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg, @@ -566,7 +700,8 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,  	if (ret < 0)  		return ret; -	if (QVGA != cfg->p_disp_panel->panel_type) +	if ((QVGA != cfg->p_disp_panel->panel_type) && +	    (WVGA != cfg->p_disp_panel->panel_type))  		return -EINVAL;  	if (cfg->bpp <= cfg->p_disp_panel->max_bpp && @@ -602,7 +737,7 @@ static void lcdc_dma_start(void)  		&da8xx_fb_reg_base->dma_frm_buf_ceiling_addr_1);  } -static u32 lcdc_irq_handler(void) +static u32 lcdc_irq_handler_rev01(void)  {  	struct da8xx_fb_par *par = da8xx_fb_info->par;  	u32 stat = lcdc_read(&da8xx_fb_reg_base->stat); @@ -610,7 +745,7 @@ static u32 lcdc_irq_handler(void)  	if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {  		debug("LCD_SYNC_LOST\n"); -		lcd_disable_raster(); +		lcd_disable_raster(NO_WAIT_FOR_FRAME_DONE);  		lcdc_write(stat, &da8xx_fb_reg_base->stat);  		lcd_enable_raster();  		return LCD_SYNC_LOST; @@ -622,13 +757,13 @@ static u32 lcdc_irq_handler(void)  		 * interrupt via the following write to the status register. If  		 * this is done after then one gets multiple PL done interrupts.  		 */ -		lcd_disable_raster(); +		lcd_disable_raster(NO_WAIT_FOR_FRAME_DONE);  		lcdc_write(stat, &da8xx_fb_reg_base->stat);  		/* Disable PL completion inerrupt */  		reg_ras  = lcdc_read(&da8xx_fb_reg_base->raster_ctrl); -		reg_ras &= ~LCD_PL_ENABLE; +		reg_ras &= ~LCD_V1_PL_INT_ENA;  		lcdc_write(reg_ras, &da8xx_fb_reg_base->raster_ctrl);  		/* Setup and start data loading mode */ @@ -650,6 +785,66 @@ static u32 lcdc_irq_handler(void)  	return stat;  } +static u32 lcdc_irq_handler_rev02(void) +{ +	struct da8xx_fb_par *par = da8xx_fb_info->par; +	u32 stat = lcdc_read(&da8xx_fb_reg_base->masked_stat); +	u32 reg_int; + +	if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) { +		debug("LCD_SYNC_LOST\n"); +		lcd_disable_raster(NO_WAIT_FOR_FRAME_DONE); +		lcdc_write(stat, &da8xx_fb_reg_base->masked_stat); +		lcd_enable_raster(); +		lcdc_write(0, &da8xx_fb_reg_base->end_of_int_ind); +		return LCD_SYNC_LOST; +	} else if (stat & LCD_PL_LOAD_DONE) { +		debug("LCD_PL_LOAD_DONE\n"); +		/* +		 * Must disable raster before changing state of any control bit. +		 * And also must be disabled before clearing the PL loading +		 * interrupt via the following write to the status register. If +		 * this is done after then one gets multiple PL done interrupts. +		 */ +		lcd_disable_raster(NO_WAIT_FOR_FRAME_DONE); + +		lcdc_write(stat, &da8xx_fb_reg_base->masked_stat); + +		/* Disable PL completion inerrupt */ +		reg_int  = lcdc_read(&da8xx_fb_reg_base->int_ena_clr) | +			(LCD_V2_PL_INT_ENA); +		lcdc_write(reg_int, &da8xx_fb_reg_base->int_ena_clr); + +		/* Setup and start data loading mode */ +		lcd_blit(LOAD_DATA, par); +		lcdc_write(0, &da8xx_fb_reg_base->end_of_int_ind); +		return LCD_PL_LOAD_DONE; +	} else { +		lcdc_write(stat, &da8xx_fb_reg_base->masked_stat); + +		if (stat & LCD_END_OF_FRAME0) +			debug("LCD_END_OF_FRAME0\n"); + +		lcdc_write(par->dma_start, +			   &da8xx_fb_reg_base->dma_frm_buf_base_addr_0); +		lcdc_write(par->dma_end, +			   &da8xx_fb_reg_base->dma_frm_buf_ceiling_addr_0); +		par->vsync_flag = 1; +		lcdc_write(0, &da8xx_fb_reg_base->end_of_int_ind); +		return LCD_END_OF_FRAME0; +	} +	lcdc_write(0, &da8xx_fb_reg_base->end_of_int_ind); +	return stat; +} + +static u32 lcdc_irq_handler(void) +{ +	if (lcd_revision == LCD_VERSION_1) +		return lcdc_irq_handler_rev01(); +	else +		return lcdc_irq_handler_rev02(); +} +  static u32 wait_for_event(u32 event)  {  	u32 timeout = 50000; @@ -673,6 +868,7 @@ void *video_hw_init(void)  {  	struct da8xx_fb_par *par;  	u32 size; +	u32 rev;  	char *p;  	if (!lcd_panel) { @@ -685,6 +881,10 @@ void *video_hw_init(void)  	gpanel.plnSizeY = lcd_panel->height;  	switch (bits_x_pixel) { +	case 32: +		gpanel.gdfBytesPP = 4; +		gpanel.gdfIndex = GDF_32BIT_X888RGB; +		break;  	case 24:  		gpanel.gdfBytesPP = 4;  		gpanel.gdfIndex = GDF_32BIT_X888RGB; @@ -699,12 +899,29 @@ void *video_hw_init(void)  		break;  	} -	da8xx_fb_reg_base = (struct da8xx_lcd_regs *)DAVINCI_LCD_CNTL_BASE; +	da8xx_fb_reg_base = (struct da8xx_lcd_regs *)DA8XX_LCD_CNTL_BASE; + +	/* Determine LCD IP Version */ +	rev = lcdc_read(&da8xx_fb_reg_base->revid); +	switch (rev) { +	case 0x4C100102: +		lcd_revision = LCD_VERSION_1; +		break; +	case 0x4F200800: +	case 0x4F201000: +		lcd_revision = LCD_VERSION_2; +		break; +	default: +		printf("Unknown PID Reg value 0x%x, defaulting to LCD revision 1\n", +		       rev); +		lcd_revision = LCD_VERSION_1; +		break; +	} -	debug("Resolution: %dx%d %x\n", -		gpanel.winSizeX, -		gpanel.winSizeY, -		lcd_cfg.bpp); +	debug("rev: 0x%x Resolution: %dx%d %d\n", rev, +	      gpanel.winSizeX, +	      gpanel.winSizeY, +	      da8xx_lcd_cfg->bpp);  	size = sizeof(struct fb_info) + sizeof(struct da8xx_fb_par);  	da8xx_fb_info = malloc(size); @@ -722,13 +939,14 @@ void *video_hw_init(void)  	par = da8xx_fb_info->par;  	par->pxl_clk = lcd_panel->pxl_clk; -	if (lcd_init(par, &lcd_cfg, lcd_panel) < 0) { +	if (lcd_init(par, da8xx_lcd_cfg, lcd_panel) < 0) {  		printf("lcd_init failed\n");  		goto err_release_fb;  	}  	/* allocate frame buffer */ -	par->vram_size = lcd_panel->width * lcd_panel->height * lcd_cfg.bpp; +	par->vram_size = lcd_panel->width * lcd_panel->height * +			da8xx_lcd_cfg->bpp;  	par->vram_size = par->vram_size * LCD_NUM_BUFFERS / 8;  	par->vram_virt = malloc(par->vram_size); @@ -746,7 +964,7 @@ void *video_hw_init(void)  	da8xx_fb_info->screen_base = (char *) par->vram_virt;  	da8xx_fb_fix.smem_start	= gpanel.frameAdrs;  	da8xx_fb_fix.smem_len = par->vram_size; -	da8xx_fb_fix.line_length = (lcd_panel->width * lcd_cfg.bpp) / 8; +	da8xx_fb_fix.line_length = (lcd_panel->width * da8xx_lcd_cfg->bpp) / 8;  	par->dma_start = par->vram_phys;  	par->dma_end   = par->dma_start + lcd_panel->height * @@ -762,7 +980,7 @@ void *video_hw_init(void)  	par->p_palette_base = (unsigned int)par->v_palette_base;  	/* Initialize par */ -	da8xx_fb_info->var.bits_per_pixel = lcd_cfg.bpp; +	da8xx_fb_info->var.bits_per_pixel = da8xx_lcd_cfg->bpp;  	da8xx_fb_var.xres = lcd_panel->width;  	da8xx_fb_var.xres_virtual = lcd_panel->width; @@ -771,8 +989,8 @@ void *video_hw_init(void)  	da8xx_fb_var.yres_virtual = lcd_panel->height * LCD_NUM_BUFFERS;  	da8xx_fb_var.grayscale = -	    lcd_cfg.p_disp_panel->panel_shade == MONOCHROME ? 1 : 0; -	da8xx_fb_var.bits_per_pixel = lcd_cfg.bpp; +	    da8xx_lcd_cfg->p_disp_panel->panel_shade == MONOCHROME ? 1 : 0; +	da8xx_fb_var.bits_per_pixel = da8xx_lcd_cfg->bpp;  	da8xx_fb_var.hsync_len = lcd_panel->hsw;  	da8xx_fb_var.vsync_len = lcd_panel->vsw; @@ -787,8 +1005,11 @@ void *video_hw_init(void)  	/* Clear interrupt */  	memset((void *)par->vram_virt, 0, par->vram_size); -	lcd_disable_raster(); -	lcdc_write(0xFFFF, &da8xx_fb_reg_base->stat); +	lcd_disable_raster(NO_WAIT_FOR_FRAME_DONE); +	if (lcd_revision == LCD_VERSION_1) +		lcdc_write(0xFFFF, &da8xx_fb_reg_base->stat); +	else +		lcdc_write(0xFFFF, &da8xx_fb_reg_base->masked_stat);  	debug("Palette at 0x%x size %d\n", par->p_palette_base,  		par->palette_sz);  	lcdc_dma_start(); @@ -823,8 +1044,10 @@ void video_set_lut(unsigned int index,	/* color number */  	return;  } -void da8xx_video_init(const struct da8xx_panel *panel, int bits_pixel) +void da8xx_video_init(const struct da8xx_panel *panel, +		      const struct lcd_ctrl_config *lcd_cfg, int bits_pixel)  {  	lcd_panel = panel; +	da8xx_lcd_cfg = lcd_cfg;  	bits_x_pixel = bits_pixel;  } diff --git a/drivers/video/da8xx-fb.h b/drivers/video/da8xx-fb.h index f48fdfdc4..6447a4047 100644 --- a/drivers/video/da8xx-fb.h +++ b/drivers/video/da8xx-fb.h @@ -109,6 +109,8 @@ struct lcd_sync_arg {  	int pulse_width;  }; -void da8xx_video_init(const struct da8xx_panel *panel, int bits_pixel); +void da8xx_video_init(const struct da8xx_panel *panel, +		      const struct lcd_ctrl_config *lcd_cfg, +		      int bits_pixel);  #endif  /* ifndef DA8XX_FB_H */ |