summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorMarek Vasut <marex@denx.de>2013-07-30 23:37:54 +0200
committerAnatolij Gustschin <agust@denx.de>2013-08-09 21:48:57 +0200
commit84f957f80b32b25df64316b6931d6924b83d4b72 (patch)
treecd9a31459c98ae902996bfcad3d42750d6fab4b6 /drivers
parent9de4b729eb42dab9ed35ab7079d7d2a9241b0d07 (diff)
downloadu-boot-imx-84f957f80b32b25df64316b6931d6924b83d4b72.zip
u-boot-imx-84f957f80b32b25df64316b6931d6924b83d4b72.tar.gz
u-boot-imx-84f957f80b32b25df64316b6931d6924b83d4b72.tar.bz2
video: Implement continuous screen refresh for SmartLCD into mxsfb
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/mxsfb.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c
index c55cb44..03b0f88 100644
--- a/drivers/video/mxsfb.c
+++ b/drivers/video/mxsfb.c
@@ -15,11 +15,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
@@ -194,5 +197,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;
}