From 440872bb4277c882ece20339fa4b2525c1c4ed2a Mon Sep 17 00:00:00 2001 From: Marcin Bukat Date: Sat, 11 May 2013 12:55:23 +0200 Subject: rk27xx: Use DMA for lcd_update_rect() This speeds up partial updates quite a bit but what is more important it opens up a way to efficiently implement lcd_blit_yuv() using hw colorspace conversion. Tested on rk27generic, hm60x v1 and v2 and on ma9. Benchmark for hm60x v1 (by mortalis): HEAD patched 1/1 141fps 138fps 1/4 315fps 395fps Change-Id: I4cc115786c3139000fc14c49a7290e289cfd6c42 --- firmware/target/arm/rk27xx/lcd-hifiman.c | 44 ----------- firmware/target/arm/rk27xx/lcdif-rk27xx.c | 87 ++++++++++++++-------- firmware/target/arm/rk27xx/ma/lcd-ma.c | 14 ---- .../arm/rk27xx/rk27generic/lcd-rk27generic.c | 14 ---- 4 files changed, 58 insertions(+), 101 deletions(-) (limited to 'firmware/target') diff --git a/firmware/target/arm/rk27xx/lcd-hifiman.c b/firmware/target/arm/rk27xx/lcd-hifiman.c index 1adc6e36ed..bde1d3546f 100644 --- a/firmware/target/arm/rk27xx/lcd-hifiman.c +++ b/firmware/target/arm/rk27xx/lcd-hifiman.c @@ -175,19 +175,6 @@ static void lcd_v1_set_gram_area(int x_start, int y_start, LCDC_CTRL &= ~RGB24B; } -static void lcd_v1_update_rect(int x, int y, int width, int height) -{ - int px = x, py = y; - int pxmax = x + width, pymax = y + height; - - lcd_v1_set_gram_area(x, y, pxmax-1, pymax-1); - - for (py=y; py> 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; @@ -80,31 +107,11 @@ static void lcdctrl_init(void) LCDC_CTRL = ALPHA(7) | LCDC_STOP | LCDC_MCU | RGB24B; MCU_CTRL = ALPHA_BASE(0x3f) | MCU_CTRL_BYPASS; - /* Warning: datasheet addresses and OF addresses - * don't match for HOR_ACT and VERT_ACT - */ - HOR_ACT = LCD_WIDTH + 3; /* define horizonatal active region */ - VERT_ACT = LCD_HEIGHT; /* define vertical active region */ VERT_PERIOD = (1<<7)|(1<<5)|1; /* CSn/WEn/RDn signal timings */ lcd_display_init(); lcdctrl_bypass(0); - - /* This lines define layout of data in lcdif internal buffer - * LINEx_UVADDR = LINEx_YADDR + 1 - * buffer is organized as 2048 x 32bit - * we use RGB565 (16 bits per pixel) so we pack 2 pixels - * in every lcdbuffer mem cell - */ - LINE0_YADDR = 0; - LINE1_YADDR = 1 * LCD_WIDTH/2; - LINE2_YADDR = 2 * LCD_WIDTH/2; - LINE3_YADDR = 3 * LCD_WIDTH/2; - - LINE0_UVADDR = 1; - LINE1_UVADDR = (1 * LCD_WIDTH/2) + 1; - LINE2_UVADDR = (2 * LCD_WIDTH/2) + 1; - LINE3_UVADDR = (3 * LCD_WIDTH/2) + 1; + lcdctrl_buff_setup(LCD_WIDTH, LCD_HEIGHT); LCDC_INTR_MASK = INTR_MASK_EVENLINE; @@ -185,18 +192,20 @@ static void dwdma_start(uint8_t ch, struct llp_t *llp, uint8_t handshake) DWDMA_DMA_CHEN = (0x101<>1; + /* build LLPs */ - for (i=0; i