Patchwork [U-Boot,04/11] video: Implement continuous screen refresh for SmartLCD into mxsfb

login
register
mail settings
Submitter Marek Vasut
Date July 30, 2013, 9:37 p.m.
Message ID <1375220281-11132-5-git-send-email-marex@denx.de>
Download mbox | patch
Permalink /patch/263527/
State Accepted
Delegated to: Anatolij Gustschin
Headers show

Comments

Marek Vasut - July 30, 2013, 9:37 p.m.
The LCDIF interface doesn't give us any means to do continuous refresh
when driving a SmartLCD. To work this around, we produce a special
circular DMA descriptor, which only writes the HW_LCDIF_CTRL0 register
and sets the RUN bit.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Anatolij Gustschin <agust@denx.de>
Cc: Fabio Estevam <fabio.estevam@freescale.com>
Cc: Otavio Salvador <otavio@ossystems.com.br>
Cc: Stefano Babic <sbabic@denx.de>
---
 drivers/video/mxsfb.c |   26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)
Anatolij Gustschin - Aug. 9, 2013, 7:51 p.m.
On Tue, 30 Jul 2013 23:37:54 +0200
Marek Vasut <marex@denx.de> wrote:

> The LCDIF interface doesn't give us any means to do continuous refresh
> when driving a SmartLCD. To work this around, we produce a special
> circular DMA descriptor, which only writes the HW_LCDIF_CTRL0 register
> and sets the RUN bit.
> 
> Signed-off-by: Marek Vasut <marex@denx.de>
> Cc: Anatolij Gustschin <agust@denx.de>
> Cc: Fabio Estevam <fabio.estevam@freescale.com>
> Cc: Otavio Salvador <otavio@ossystems.com.br>
> Cc: Stefano Babic <sbabic@denx.de>
> ---
>  drivers/video/mxsfb.c |   26 ++++++++++++++++++++++++++
>  1 file changed, 26 insertions(+)

Applied to u-boot-video/master. Thanks!

Anatolij

Patch

diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c
index 78709dd..98d5264 100644
--- a/drivers/video/mxsfb.c
+++ b/drivers/video/mxsfb.c
@@ -28,11 +28,14 @@ 
 #include <asm/errno.h>
 #include <asm/io.h>
 
+#include <asm/imx-common/dma.h>
+
 #include "videomodes.h"
 
 #define	PS2KHZ(ps)	(1000000000UL / (ps))
 
 static GraphicDevice panel;
+struct mxs_dma_desc desc;
 
 /**
  * mxsfb_system_setup() - Fine-tune LCDIF configuration
@@ -207,5 +210,28 @@  void *video_hw_init(void)
 	/* Start framebuffer */
 	mxs_lcd_init(&panel, &mode, bpp);
 
+#ifdef CONFIG_VIDEO_MXS_MODE_SYSTEM
+	/*
+	 * If the LCD runs in system mode, the LCD refresh has to be triggered
+	 * manually by setting the RUN bit in HW_LCDIF_CTRL register. To avoid
+	 * having to set this bit manually after every single change in the
+	 * framebuffer memory, we set up specially crafted circular DMA, which
+	 * sets the RUN bit, then waits until it gets cleared and repeats this
+	 * infinitelly. This way, we get smooth continuous updates of the LCD.
+	 */
+	struct mxs_lcdif_regs *regs = (struct mxs_lcdif_regs *)MXS_LCDIF_BASE;
+
+	memset(&desc, 0, sizeof(struct mxs_dma_desc));
+	desc.address = (dma_addr_t)&desc;
+	desc.cmd.data = MXS_DMA_DESC_COMMAND_NO_DMAXFER | MXS_DMA_DESC_CHAIN |
+			MXS_DMA_DESC_WAIT4END |
+			(1 << MXS_DMA_DESC_PIO_WORDS_OFFSET);
+	desc.cmd.pio_words[0] = readl(&regs->hw_lcdif_ctrl) | LCDIF_CTRL_RUN;
+	desc.cmd.next = (uint32_t)&desc.cmd;
+
+	/* Execute the DMA chain. */
+	mxs_dma_circ_start(MXS_DMA_CHANNEL_AHB_APBH_LCDIF, &desc);
+#endif
+
 	return (void *)&panel;
 }