From patchwork Tue Aug 14 13:23:25 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Manjunathappa, Prakash" X-Patchwork-Id: 1319361 Return-Path: X-Original-To: patchwork-linux-fbdev@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 8D92CDF215 for ; Tue, 14 Aug 2012 13:38:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752194Ab2HNNi0 (ORCPT ); Tue, 14 Aug 2012 09:38:26 -0400 Received: from comal.ext.ti.com ([198.47.26.152]:55841 "EHLO comal.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752190Ab2HNNiZ (ORCPT ); Tue, 14 Aug 2012 09:38:25 -0400 Received: from dbdp20.itg.ti.com ([172.24.170.38]) by comal.ext.ti.com (8.13.7/8.13.7) with ESMTP id q7EDcMWw001188; Tue, 14 Aug 2012 08:38:23 -0500 Received: from DBDE71.ent.ti.com (localhost [127.0.0.1]) by dbdp20.itg.ti.com (8.13.8/8.13.8) with ESMTP id q7EDcKQv018399; Tue, 14 Aug 2012 19:08:20 +0530 (IST) Received: from dbdp32.itg.ti.com (172.24.170.251) by DBDE71.ent.ti.com (172.24.170.149) with Microsoft SMTP Server id 14.1.323.3; Tue, 14 Aug 2012 19:08:20 +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 q7EDcK0e021181; Tue, 14 Aug 2012 19:08:20 +0530 Received: from symphony.india.ext.ti.com (unknown [192.168.247.13]) by ucmsshproxy.india.ext.ti.com (Postfix) with ESMTP id F356D158002; Tue, 14 Aug 2012 19:08:19 +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 q7EDcJI12691; Tue, 14 Aug 2012 19:08:19 +0530 (IST) From: "Manjunathappa, Prakash" To: CC: Florian Tobias Schandinat , , "Manjunathappa, Prakash" Subject: [PATCH v3] da8xx-fb: allow frame to complete after disabling LCDC Date: Tue, 14 Aug 2012 18:53:25 +0530 Message-ID: <1344950605-18945-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 Wait for active frame transfer to complete after disabling LCDC. At the same this wait is not be required when there are sync and underflow errors. More information on disable and reset sequence can be found in section 13.4.6 of AM335x TRM @www.ti.com/am335x. Signed-off-by: Manjunathappa, Prakash --- Applies on top of fbdev-next of Florian Tobias Schandinat's tree. Since v2: Optimized the lcd_disable_raster function. Since v1: Changed the commit message, also added link to hardware specification. drivers/video/da8xx-fb.c | 49 ++++++++++++++++++++++++++++++++++++--------- 1 files changed, 39 insertions(+), 10 deletions(-) diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index 7ae9d53..cb696ff 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -48,6 +48,7 @@ #define LCD_PL_LOAD_DONE BIT(6) #define LCD_FIFO_UNDERFLOW BIT(5) #define LCD_SYNC_LOST BIT(2) +#define LCD_FRAME_DONE BIT(0) /* LCD DMA Control Register */ #define LCD_DMA_BURST_SIZE(x) ((x) << 4) @@ -288,13 +289,41 @@ 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 stat_reg = LCD_STAT_REG; + u32 loop_cnt = 0; reg = lcdc_read(LCD_RASTER_CTRL_REG); if (reg & LCD_RASTER_ENABLE) lcdc_write(reg & ~LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG); + + if (lcd_revision == LCD_VERSION_2) + stat_reg = LCD_RAW_STAT_REG; + + if (wait_for_frame_done) { + /* + * 50 milli seconds should be sufficient for a frame to + * complete + */ + loop_cnt = 50; + while (!(lcdc_read(stat_reg) & LCD_FRAME_DONE)) { + /* Handle timeout */ + if (unlikely(0 == --loop_cnt)) { + pr_err("LCD Controller timed out\n"); + break; + } + mdelay(1); + } + } + + /* clear asserted interrupts */ + reg = lcdc_read(stat_reg); + if (lcd_revision == LCD_VERSION_1) + lcdc_write(reg, LCD_STAT_REG); + else + lcdc_write(reg, LCD_MASKED_STAT_REG); } static void lcd_blit(int load_mode, struct da8xx_fb_par *par) @@ -638,7 +667,7 @@ 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(false); /* DMA has to be disabled */ lcdc_write(0, LCD_DMA_CTRL_REG); @@ -734,7 +763,7 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg) u32 stat = lcdc_read(LCD_MASKED_STAT_REG); if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) { - lcd_disable_raster(); + lcd_disable_raster(false); lcdc_write(stat, LCD_MASKED_STAT_REG); lcd_enable_raster(); } else if (stat & LCD_PL_LOAD_DONE) { @@ -744,7 +773,7 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg) * 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(false); lcdc_write(stat, LCD_MASKED_STAT_REG); @@ -789,7 +818,7 @@ static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg) u32 reg_ras; if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) { - lcd_disable_raster(); + lcd_disable_raster(false); lcdc_write(stat, LCD_STAT_REG); lcd_enable_raster(); } else if (stat & LCD_PL_LOAD_DONE) { @@ -799,7 +828,7 @@ static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg) * 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(false); lcdc_write(stat, LCD_STAT_REG); @@ -898,7 +927,7 @@ static int lcd_da8xx_cpufreq_transition(struct notifier_block *nb, if (val == CPUFREQ_POSTCHANGE) { if (par->lcd_fck_rate != clk_get_rate(par->lcdc_clk)) { par->lcd_fck_rate = clk_get_rate(par->lcdc_clk); - lcd_disable_raster(); + lcd_disable_raster(true); lcd_calc_clk_divider(par); lcd_enable_raster(); } @@ -935,7 +964,7 @@ static int __devexit fb_remove(struct platform_device *dev) if (par->panel_power_ctrl) par->panel_power_ctrl(0); - lcd_disable_raster(); + lcd_disable_raster(true); lcdc_write(0, LCD_RASTER_CTRL_REG); /* disable DMA */ @@ -1051,7 +1080,7 @@ static int cfb_blank(int blank, struct fb_info *info) if (par->panel_power_ctrl) par->panel_power_ctrl(0); - lcd_disable_raster(); + lcd_disable_raster(true); break; default: ret = -EINVAL; @@ -1411,7 +1440,7 @@ static int fb_suspend(struct platform_device *dev, pm_message_t state) par->panel_power_ctrl(0); fb_set_suspend(info, 1); - lcd_disable_raster(); + lcd_disable_raster(true); clk_disable(par->lcdc_clk); console_unlock();