diff options
author | Marek Vasut <marex@denx.de> | 2013-07-30 21:37:54 (GMT) |
---|---|---|
committer | Anatolij Gustschin <agust@denx.de> | 2013-08-09 19:48:57 (GMT) |
commit | 84f957f80b32b25df64316b6931d6924b83d4b72 (patch) | |
tree | cd9a31459c98ae902996bfcad3d42750d6fab4b6 | |
parent | 9de4b729eb42dab9ed35ab7079d7d2a9241b0d07 (diff) | |
download | u-boot-84f957f80b32b25df64316b6931d6924b83d4b72.tar.xz |
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>
-rw-r--r-- | drivers/video/mxsfb.c | 26 |
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(®s->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; } |