Commit 1a2b750c authored by Manjunathappa, Prakash's avatar Manjunathappa, Prakash Committed by Florian Tobias Schandinat

da8xx-fb: add 24bpp LCD configuration support

LCD controller on am335x supports 24bpp raster configuration in addition
to ones on da850. LCDC also supports 24bpp in unpacked format having
ARGB:8888 32bpp format data in DDR, but it doesn't interpret alpha
component of the data.
Signed-off-by: default avatarManjunathappa, Prakash <prakash.pm@ti.com>
Cc: Anatolij Gustschin <agust@denx.de>
Signed-off-by: default avatarFlorian Tobias Schandinat <FlorianSchandinat@gmx.de>
parent 7ed25867
...@@ -86,6 +86,8 @@ ...@@ -86,6 +86,8 @@
#define LCD_V2_LIDD_CLK_EN BIT(1) #define LCD_V2_LIDD_CLK_EN BIT(1)
#define LCD_V2_CORE_CLK_EN BIT(0) #define LCD_V2_CORE_CLK_EN BIT(0)
#define LCD_V2_LPP_B10 26 #define LCD_V2_LPP_B10 26
#define LCD_V2_TFT_24BPP_MODE BIT(25)
#define LCD_V2_TFT_24BPP_UNPACK BIT(26)
/* LCD Raster Timing 2 Register */ /* LCD Raster Timing 2 Register */
#define LCD_AC_BIAS_TRANSITIONS_PER_INT(x) ((x) << 16) #define LCD_AC_BIAS_TRANSITIONS_PER_INT(x) ((x) << 16)
...@@ -156,7 +158,6 @@ struct da8xx_fb_par { ...@@ -156,7 +158,6 @@ struct da8xx_fb_par {
unsigned int dma_end; unsigned int dma_end;
struct clk *lcdc_clk; struct clk *lcdc_clk;
int irq; int irq;
unsigned short pseudo_palette[16];
unsigned int palette_sz; unsigned int palette_sz;
unsigned int pxl_clk; unsigned int pxl_clk;
int blank; int blank;
...@@ -175,6 +176,7 @@ struct da8xx_fb_par { ...@@ -175,6 +176,7 @@ struct da8xx_fb_par {
unsigned int lcd_fck_rate; unsigned int lcd_fck_rate;
#endif #endif
void (*panel_power_ctrl)(int); void (*panel_power_ctrl)(int);
u32 pseudo_palette[16];
}; };
/* Variable Screen Information */ /* Variable Screen Information */
...@@ -499,6 +501,9 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height, ...@@ -499,6 +501,9 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
{ {
u32 reg; u32 reg;
if (bpp > 16 && lcd_revision == LCD_VERSION_1)
return -EINVAL;
/* Set the Panel Width */ /* Set the Panel Width */
/* Pixels per line = (PPL + 1)*16 */ /* Pixels per line = (PPL + 1)*16 */
if (lcd_revision == LCD_VERSION_1) { if (lcd_revision == LCD_VERSION_1) {
...@@ -542,14 +547,19 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height, ...@@ -542,14 +547,19 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(1 << 8); reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(1 << 8);
if (raster_order) if (raster_order)
reg |= LCD_RASTER_ORDER; reg |= LCD_RASTER_ORDER;
lcdc_write(reg, LCD_RASTER_CTRL_REG);
par->palette_sz = 16 * 2;
switch (bpp) { switch (bpp) {
case 1: case 1:
case 2: case 2:
case 4: case 4:
case 16: case 16:
par->palette_sz = 16 * 2; break;
case 24:
reg |= LCD_V2_TFT_24BPP_MODE;
case 32:
reg |= LCD_V2_TFT_24BPP_UNPACK;
break; break;
case 8: case 8:
...@@ -560,9 +570,12 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height, ...@@ -560,9 +570,12 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
return -EINVAL; return -EINVAL;
} }
lcdc_write(reg, LCD_RASTER_CTRL_REG);
return 0; return 0;
} }
#define CNVT_TOHW(val, width) ((((val) << (width)) + 0x7FFF - (val)) >> 16)
static int fb_setcolreg(unsigned regno, unsigned red, unsigned green, static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
unsigned blue, unsigned transp, unsigned blue, unsigned transp,
struct fb_info *info) struct fb_info *info)
...@@ -578,13 +591,38 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green, ...@@ -578,13 +591,38 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) if (info->fix.visual == FB_VISUAL_DIRECTCOLOR)
return 1; return 1;
if (info->var.bits_per_pixel == 4) { if (info->var.bits_per_pixel > 16 && lcd_revision == LCD_VERSION_1)
if (regno > 15) return -EINVAL;
return 1;
if (info->var.grayscale) { switch (info->fix.visual) {
pal = regno; case FB_VISUAL_TRUECOLOR:
} else { red = CNVT_TOHW(red, info->var.red.length);
green = CNVT_TOHW(green, info->var.green.length);
blue = CNVT_TOHW(blue, info->var.blue.length);
break;
case FB_VISUAL_PSEUDOCOLOR:
switch (info->var.bits_per_pixel) {
case 4:
if (regno > 15)
return -EINVAL;
if (info->var.grayscale) {
pal = regno;
} else {
red >>= 4;
green >>= 8;
blue >>= 12;
pal = red & 0x0f00;
pal |= green & 0x00f0;
pal |= blue & 0x000f;
}
if (regno == 0)
pal |= 0x2000;
palette[regno] = pal;
break;
case 8:
red >>= 4; red >>= 4;
green >>= 8; green >>= 8;
blue >>= 12; blue >>= 12;
...@@ -592,36 +630,36 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green, ...@@ -592,36 +630,36 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
pal = (red & 0x0f00); pal = (red & 0x0f00);
pal |= (green & 0x00f0); pal |= (green & 0x00f0);
pal |= (blue & 0x000f); pal |= (blue & 0x000f);
}
if (regno == 0)
pal |= 0x2000;
palette[regno] = pal;
} else if (info->var.bits_per_pixel == 8) { if (palette[regno] != pal) {
red >>= 4; update_hw = 1;
green >>= 8; palette[regno] = pal;
blue >>= 12; }
break;
pal = (red & 0x0f00);
pal |= (green & 0x00f0);
pal |= (blue & 0x000f);
if (palette[regno] != pal) {
update_hw = 1;
palette[regno] = pal;
} }
} else if ((info->var.bits_per_pixel == 16) && regno < 16) { break;
red >>= (16 - info->var.red.length); }
red <<= info->var.red.offset;
green >>= (16 - info->var.green.length); /* Truecolor has hardware independent palette */
green <<= info->var.green.offset; if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
u32 v;
blue >>= (16 - info->var.blue.length); if (regno > 15)
blue <<= info->var.blue.offset; return -EINVAL;
par->pseudo_palette[regno] = red | green | blue; v = (red << info->var.red.offset) |
(green << info->var.green.offset) |
(blue << info->var.blue.offset);
switch (info->var.bits_per_pixel) {
case 16:
((u16 *) (info->pseudo_palette))[regno] = v;
break;
case 24:
case 32:
((u32 *) (info->pseudo_palette))[regno] = v;
break;
}
if (palette[0] != 0x4000) { if (palette[0] != 0x4000) {
update_hw = 1; update_hw = 1;
palette[0] = 0x4000; palette[0] = 0x4000;
...@@ -634,6 +672,7 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green, ...@@ -634,6 +672,7 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
return 0; return 0;
} }
#undef CNVT_TOHW
static void lcd_reset(struct da8xx_fb_par *par) static void lcd_reset(struct da8xx_fb_par *par)
{ {
...@@ -842,6 +881,9 @@ static int fb_check_var(struct fb_var_screeninfo *var, ...@@ -842,6 +881,9 @@ static int fb_check_var(struct fb_var_screeninfo *var,
{ {
int err = 0; int err = 0;
if (var->bits_per_pixel > 16 && lcd_revision == LCD_VERSION_1)
return -EINVAL;
switch (var->bits_per_pixel) { switch (var->bits_per_pixel) {
case 1: case 1:
case 8: case 8:
...@@ -877,6 +919,26 @@ static int fb_check_var(struct fb_var_screeninfo *var, ...@@ -877,6 +919,26 @@ static int fb_check_var(struct fb_var_screeninfo *var,
var->transp.length = 0; var->transp.length = 0;
var->nonstd = 0; var->nonstd = 0;
break; break;
case 24:
var->red.offset = 16;
var->red.length = 8;
var->green.offset = 8;
var->green.length = 8;
var->blue.offset = 0;
var->blue.length = 8;
var->nonstd = 0;
break;
case 32:
var->transp.offset = 24;
var->transp.length = 8;
var->red.offset = 16;
var->red.length = 8;
var->green.offset = 8;
var->green.length = 8;
var->blue.offset = 0;
var->blue.length = 8;
var->nonstd = 0;
break;
default: default:
err = -EINVAL; err = -EINVAL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment