From patchwork Thu Jul 19 15:37:46 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Manjunathappa, Prakash" X-Patchwork-Id: 1217871 Return-Path: X-Original-To: patchwork-linux-fbdev@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id 0DE443FD4F for ; Thu, 19 Jul 2012 15:54:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751728Ab2GSPy2 (ORCPT ); Thu, 19 Jul 2012 11:54:28 -0400 Received: from devils.ext.ti.com ([198.47.26.153]:44187 "EHLO devils.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751653Ab2GSPy1 (ORCPT ); Thu, 19 Jul 2012 11:54:27 -0400 Received: from dbdp20.itg.ti.com ([172.24.170.38]) by devils.ext.ti.com (8.13.7/8.13.7) with ESMTP id q6JFsKrU026628; Thu, 19 Jul 2012 10:54:21 -0500 Received: from DBDE70.ent.ti.com (localhost [127.0.0.1]) by dbdp20.itg.ti.com (8.13.8/8.13.8) with ESMTP id q6JFsHoZ021152; Thu, 19 Jul 2012 21:24:17 +0530 (IST) Received: from dbdp32.itg.ti.com (172.24.170.251) by dbde70.ent.ti.com (172.24.170.148) with Microsoft SMTP Server id 14.1.323.3; Thu, 19 Jul 2012 21:24:16 +0530 Received: from ucmsshproxy.india.ext.ti.com (dbdp20.itg.ti.com [172.24.170.38]) by dbdp32.itg.ti.com (8.13.8/8.13.8) with SMTP id q6JFsCSd005528; Thu, 19 Jul 2012 21:24:13 +0530 Received: from symphony.india.ext.ti.com (unknown [192.168.247.13]) by ucmsshproxy.india.ext.ti.com (Postfix) with ESMTP id 3CDFF158002; Thu, 19 Jul 2012 21:24:12 +0530 (IST) Received: from linux-psp-server.india.ext.ti.com (linux-psp-server [192.168.247.76]) by symphony.india.ext.ti.com (8.11.7p1+Sun/8.11.7) with ESMTP id q6JFsAI27368; Thu, 19 Jul 2012 21:24:10 +0530 (IST) From: "Manjunathappa, Prakash" To: CC: Florian Tobias Schandinat , , "Manjunathappa, Prakash" , Anatolij Gustschin Subject: [PATCH v3] video: da8xx-fb: add 24bpp LCD configuration support Date: Thu, 19 Jul 2012 21:07:46 +0530 Message-ID: <1342712266-4381-1-git-send-email-prakash.pm@ti.com> X-Mailer: git-send-email 1.7.1 MIME-Version: 1.0 Sender: linux-fbdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fbdev@vger.kernel.org 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: Manjunathappa, Prakash Cc: Anatolij Gustschin --- Since v2: Fixed additional configurations for 24bpp support. Since v1: Simplified calculation of pseudopalette for FB_VISUAL_TRUECOLOR type. drivers/video/da8xx-fb.c | 127 ++++++++++++++++++++++++++++++++++------------ 1 files changed, 94 insertions(+), 33 deletions(-) diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index 47118c7..3d2d0d1 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -83,6 +83,8 @@ #define LCD_V2_LIDD_CLK_EN BIT(1) #define LCD_V2_CORE_CLK_EN BIT(0) #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 */ #define LCD_AC_BIAS_TRANSITIONS_PER_INT(x) ((x) << 16) @@ -153,7 +155,7 @@ struct da8xx_fb_par { unsigned int dma_end; struct clk *lcdc_clk; int irq; - unsigned short pseudo_palette[16]; + unsigned long pseudo_palette[16]; unsigned int palette_sz; unsigned int pxl_clk; int blank; @@ -482,6 +484,9 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height, { u32 reg; + if ((bpp > 16) && (lcd_revision == LCD_VERSION_1)) + return -EINVAL; + /* Set the Panel Width */ /* Pixels per line = (PPL + 1)*16 */ if (lcd_revision == LCD_VERSION_1) { @@ -525,6 +530,12 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height, reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(1 << 8); if (raster_order) reg |= LCD_RASTER_ORDER; + + if (bpp == 24) + reg |= LCD_V2_TFT_24BPP_MODE; + else if (bpp == 32) + reg |= (LCD_V2_TFT_24BPP_MODE | LCD_V2_TFT_24BPP_UNPACK); + lcdc_write(reg, LCD_RASTER_CTRL_REG); switch (bpp) { @@ -532,6 +543,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; @@ -546,6 +559,8 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height, return 0; } + +#define CNVT_TOHW(val, width) ((((val)<<(width))+0x7FFF-(val))>>16) static int fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info) @@ -561,13 +576,36 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green, if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) return 1; - if (info->var.bits_per_pixel == 4) { - if (regno > 15) - return 1; + if ((info->var.bits_per_pixel > 16) && (lcd_revision == LCD_VERSION_1)) + return 1; - if (info->var.grayscale) { - pal = regno; - } else { + switch (info->fix.visual) { + case FB_VISUAL_TRUECOLOR: + 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: + if (info->var.bits_per_pixel == 4) { + if (regno > 15) + return 1; + + 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; + + } else if (info->var.bits_per_pixel == 8) { red >>= 4; green >>= 8; blue >>= 12; @@ -575,36 +613,35 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green, pal = (red & 0x0f00); pal |= (green & 0x00f0); pal |= (blue & 0x000f); - } - if (regno == 0) - pal |= 0x2000; - palette[regno] = pal; - - } else if (info->var.bits_per_pixel == 8) { - red >>= 4; - green >>= 8; - blue >>= 12; - - pal = (red & 0x0f00); - pal |= (green & 0x00f0); - pal |= (blue & 0x000f); - if (palette[regno] != pal) { - update_hw = 1; - palette[regno] = pal; + if (palette[regno] != pal) { + update_hw = 1; + palette[regno] = pal; + } } - } else if ((info->var.bits_per_pixel == 16) && regno < 16) { - red >>= (16 - info->var.red.length); - red <<= info->var.red.offset; + break; + } - green >>= (16 - info->var.green.length); - green <<= info->var.green.offset; + /* Truecolor has hardware independent palette */ + if (info->fix.visual == FB_VISUAL_TRUECOLOR) { + u32 v; - blue >>= (16 - info->var.blue.length); - blue <<= info->var.blue.offset; + if (regno > 15) + 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) { update_hw = 1; palette[0] = 0x4000; @@ -617,6 +654,7 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green, return 0; } +#undef CNVT_TOHW static void lcd_reset(struct da8xx_fb_par *par) { @@ -824,6 +862,9 @@ static int fb_check_var(struct fb_var_screeninfo *var, { int err = 0; + if ((var->bits_per_pixel > 16) && (lcd_revision == LCD_VERSION_1)) + return -EINVAL; + switch (var->bits_per_pixel) { case 1: case 8: @@ -859,6 +900,26 @@ static int fb_check_var(struct fb_var_screeninfo *var, var->transp.length = 0; var->nonstd = 0; 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: err = -EINVAL; }