From 3fa27091f3144ba7bcc9851279e5a33cfcad1870 Mon Sep 17 00:00:00 2001 From: Marcin Bukat Date: Fri, 2 Oct 2026 10:30:58 +0200 Subject: [PATCH] rk27xx: wait for the LCD DMA transfer to end lcd_update_rect() waited on the channel's CTL_L LLP_DST_EN bit, which the last descriptor has clear: it clears when the last block is loaded, not when it is done. The update returned with that line still being read, and the next one reprogrammed the window and the channel under it. Wait for the channel to disable itself, which it does after its last block. Co-Authored-By: Claude Opus 5.5 Change-Id: Icf9314fbe40b8ea53a7f5f24ea11513e87a54cf6 --- firmware/target/arm/rk27xx/lcdif-rk27xx.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/firmware/target/arm/rk27xx/lcdif-rk27xx.c b/firmware/target/arm/rk27xx/lcdif-rk27xx.c index c023482679..bb3500d866 100644 --- a/firmware/target/arm/rk27xx/lcdif-rk27xx.c +++ b/firmware/target/arm/rk27xx/lcdif-rk27xx.c @@ -305,8 +305,11 @@ void lcd_update_rect(int x, int y, int width, int height) /* Setup buffered writes to lcd controler */ MCU_CTRL = MCU_CTRL_RS_HIGH|MCU_CTRL_BUFF_WRITE|MCU_CTRL_BUFF_START; - /* Wait for DMA transfer to finish */ - while (DWDMA_CTL_L(0) & (1<<27)); + /* Wait for the DMA transfer to finish: the channel disables itself + * after its last block. CTL_L's LLP_DST_EN (bit 27) is no measure - + * it clears as soon as the last block is loaded, while that block + * still runs. */ + while (DWDMA_DMA_CHEN & (1<<0)); } void lcd_update()