diff --git a/firmware/target/arm/rk27xx/lcdif-rk27xx.c b/firmware/target/arm/rk27xx/lcdif-rk27xx.c
index d584739..300c6d8 100644
--- a/firmware/target/arm/rk27xx/lcdif-rk27xx.c
+++ b/firmware/target/arm/rk27xx/lcdif-rk27xx.c
@@ -68,6 +68,24 @@ static uint32_t lcd_data_transform(uint32_t data)
return (r | g | b);
}

+static void lcdctrl_buff_setup(int width, int height)
+{
+ HOR_ACT = width + 3; /* define horizonatal active region */
+ VERT_ACT = height; /* define vertical active region */
+
+ width = width >> 1;
+
+ LINE0_YADDR = 0;
+ LINE1_YADDR = 1 * width;
+ LINE2_YADDR = 2 * width;
+ LINE3_YADDR = 3 * width;
+
+ LINE0_UVADDR = LINE0_YADDR + 1;
+ LINE1_UVADDR = LINE1_YADDR + 1;
+ LINE2_UVADDR = LINE2_YADDR + 1;
+ LINE3_UVADDR = LINE3_YADDR + 1;
+}
+
static void lcdctrl_init(void)
{
int i;
@@ -187,18 +205,20 @@ static void dwdma_start(uint8_t ch, struct llp_t *llp, uint8_t handshake)
DWDMA_DMA_CHEN = (0x101<<ch);
}

-static void create_llp(void)
+static void create_llp(int x, int y, int width, int height)
{
int i;

+ width = width>>1;
+
/* build LLPs */
- for (i=0; i<LCD_HEIGHT; i++)
- llp_setup((void *)FBADDR(0,i),
- (void*)(LCD_BUFF+((i%4)*4*LCD_WIDTH/2)),
+ for (i=0; i<height; i++)
+ llp_setup((void *)FBADDR(x,y+i),
+ (void*)(LCD_BUFF+((i%4)*4*width)),
&(scr_llp[i]),
- LCD_WIDTH/2);
+ width);

- llp_end(&scr_llp[LCD_HEIGHT-1]);
+ llp_end(&scr_llp[height-1]);
}

/* Public functions */
@@ -243,19 +263,23 @@ void lcd_init_device(void)
{
iomux_lcd(LCD_DATABUS_WIDTH); /* setup pins for lcd interface */
dwdma_init(); /* init dwdma module */
- create_llp(); /* build LLPs for screen update dma */
lcdctrl_init(); /* basic lcdc module configuration */
}

-void lcd_update()
+void lcd_update_rect(int x, int y, int width, int height)
{
- lcd_set_gram_area(0, 0, LCD_WIDTH, LCD_HEIGHT);
+ width = (width + 1) & ~1;
+
+ lcd_set_gram_area(x, y, width, height);
+ create_llp(x, y, width, height);
lcdctrl_bypass(0);

+ /* whole framebuffer for now */
commit_discard_dcache_range(FBADDR(0,0), 2*LCD_WIDTH*LCD_HEIGHT);

while (!(LCDC_STA & LCDC_MCU_IDLE));

+ lcdctrl_buff_setup(width, height);
dwdma_start(0, scr_llp, 6);
udelay(10);

@@ -265,3 +289,8 @@ void lcd_update()
/* Wait for DMA transfer to finish */
while (DWDMA_CTL_L(0) & (1<<27));
}
+
+void lcd_update()
+{
+ lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
+}
diff --git a/firmware/target/arm/rk27xx/rk27generic/lcd-rk27generic.c b/firmware/target/arm/rk27xx/rk27generic/lcd-rk27generic.c
index 988f710..ca73a18 100644
--- a/firmware/target/arm/rk27xx/rk27generic/lcd-rk27generic.c
+++ b/firmware/target/arm/rk27xx/rk27generic/lcd-rk27generic.c
@@ -178,6 +178,7 @@ void lcd_set_gram_area(int x, int y, int width, int height)
LCDC_CTRL &= ~RGB24B;
}

+#if 0
void lcd_update_rect(int x, int y, int width, int height)
{
int px = x, py = y;
@@ -195,7 +196,7 @@ void lcd_update_rect(int x, int y, int width, int height)
/* Blit a YUV bitmap directly to the LCD
* provided by generic fallback in lcd-16bit-common.c
*/
-#if 0
+
void lcd_blit_yuv(unsigned char * const src[3],
int src_x, int src_y, int stride,
int x, int y, int width, int height)