diff --git a/firmware/target/arm/rk27xx/lcd-hifiman.c b/firmware/target/arm/rk27xx/lcd-hifiman.c
index d98ed5a..6af9132 100644
--- a/firmware/target/arm/rk27xx/lcd-hifiman.c
+++ b/firmware/target/arm/rk27xx/lcd-hifiman.c
@@ -84,7 +84,7 @@ static void lcd_display_init(void)
udelay(40);

/* Memmory access setting */
- lcd_write_reg(0x16, 0x48);
+ lcd_write_reg(0x16, 0x68);
/* Setup 16bit mode */
lcd_write_reg(0x17, 0x05);

@@ -92,11 +92,11 @@ static void lcd_display_init(void)
lcd_write_reg(0x02, 0x00);
lcd_write_reg(0x03, 0x00);
lcd_write_reg(0x04, 0x00);
- lcd_write_reg(0x05, LCD_HEIGHT - 1);
+ lcd_write_reg(0x05, LCD_WIDTH - 1);
lcd_write_reg(0x06, 0x00);
lcd_write_reg(0x07, 0x00);
lcd_write_reg(0x08, 0x00);
- lcd_write_reg(0x09, LCD_WIDTH - 1);
+ lcd_write_reg(0x09, LCD_HEIGHT - 1);

/* Start GRAM write */
lcd_cmd(0x22);
@@ -116,6 +116,8 @@ void lcd_init_device(void)

void lcd_enable (bool on)
{
+ lcdctrl_bypass(1);
+
if (on)
{
lcd_write_reg(0x18, 0x44);
@@ -158,6 +160,8 @@ void lcd_update_rect(int x, int y, int width, int height)
{
int px = x, py = y;
int pxmax = x + width, pymax = y + height;
+ lcd_update();
+ return ;

lcd_write_reg(0x03, y);
lcd_write_reg(0x05, pymax-1);
diff --git a/firmware/target/arm/rk27xx/lcdif-rk27xx.c b/firmware/target/arm/rk27xx/lcdif-rk27xx.c
index affc49b..4ac22f1 100644
--- a/firmware/target/arm/rk27xx/lcdif-rk27xx.c
+++ b/firmware/target/arm/rk27xx/lcdif-rk27xx.c
@@ -65,7 +65,7 @@ void lcd_write_reg(unsigned int reg, unsigned int val)
lcd_data(val);
}

-static void lcdctrl_bypass(unsigned int on_off)
+void lcdctrl_bypass(unsigned int on_off)
{
while (!(LCDC_STA & LCDC_MCU_IDLE));

@@ -89,37 +89,21 @@ static void lcdctrl_init(void)
LCDC_CTRL = ALPHA(7) | LCDC_STOP | LCDC_MCU | RGB24B;
MCU_CTRL = ALPHA_BASE(0x3f) | MCU_CTRL_BYPASS;

- HOR_ACT = LCD_WIDTH + 3; /* define horizonatal active region */
- VERT_ACT = LCD_HEIGHT; /* define vertical active region */
- VERT_PERIOD = 0xfff; /* CSn/WEn/RDn signal timings */
+ HOR_BP = LCD_WIDTH + 3; /* define horizonatal active region */
+ VERT_BP = LCD_HEIGHT; /* define vertical active region */
+ VERT_PERIOD = (1<<7)|(1<<6)|1;//0xfff; /* CSn/WEn/RDn signal timings */

- LINE0_YADDR = LINE_ALPHA_EN | 0x7fe;
- LINE1_YADDR = LINE_ALPHA_EN | ((1 * LCD_WIDTH) - 2);
- LINE2_YADDR = LINE_ALPHA_EN | ((2 * LCD_WIDTH) - 2);
- LINE3_YADDR = LINE_ALPHA_EN | ((3 * LCD_WIDTH) - 2);
-
- LINE0_UVADDR = 0x7fe + 1;
- LINE1_UVADDR = ((1 * LCD_WIDTH) - 2 + 1);
- LINE2_UVADDR = ((2 * LCD_WIDTH) - 2 + 1);
- LINE3_UVADDR = ((3 * LCD_WIDTH) - 2 + 1);
-
-#if 0
LINE0_YADDR = 0;
- LINE1_YADDR = (1 * LCD_WIDTH);
- LINE2_YADDR = (2 * LCD_WIDTH);
- LINE3_YADDR = (3 * LCD_WIDTH);
+ 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) + 1;
- LINE2_UVADDR = (2 * LCD_WIDTH) + 1;
- LINE3_UVADDR = (3 * LCD_WIDTH) + 1;
-
- START_X = 0;
- START_Y = 0;
- DELTA_X = 0x200; /* no scaling */
- DELTA_Y = 0x200; /* no scaling */
-#endif
- LCDC_INTR_MASK = INTR_MASK_LINE; /* INTR_MASK_EVENLINE; */
+ LINE1_UVADDR = (1 * LCD_WIDTH/2) + 1;
+ LINE2_UVADDR = (2 * LCD_WIDTH/2) + 1;
+ LINE3_UVADDR = (3 * LCD_WIDTH/2) + 1;
+
+ LCDC_INTR_MASK = 0; /*INTR_MASK_LINE; INTR_MASK_EVENLINE; */
}

/* configure pins to drive lcd in 18bit mode (16bit mode for HiFiMAN's) */
@@ -138,11 +122,11 @@ static void iomux_lcd(enum lcdif_mode_t mode)
SCU_IOMUXB_CON |= IOMUX_LCD_D815;
}

-void lcdif_init(enum lcdif_mode_t mode)
+static void dwdma_init(void)
{
- iomux_lcd(mode); /* setup pins for lcd interface */
- lcdctrl_init(); /* basic lcdc module configuration */
- lcdctrl_bypass(1); /* run in bypass mode - all writes goes directly to lcd controller */
+ DWDMA_DMA_CHEN = 0xf00;
+ DWDMA_CLEAR_BLOCK = 0x0f;
+ DWDMA_DMA_CFG = 1; /* global enable */
}

/* This is ugly hack. We drive lcd in bypass mode
@@ -157,7 +141,115 @@ void lcdif_init(enum lcdif_mode_t mode)
* Moreover OF sets some bits in IF module registers
* which are referred as reseved in datasheet.
*/
+
+/* dwdma linked list struct */
+struct llp_t {
+ uint32_t sar;
+ uint32_t dar;
+ struct llp_t *llp;
+ uint32_t ctl_l;
+ uint32_t ctl_h;
+ uint32_t dstat;
+};
+
+
+/* structs which describe full screen update */
+struct llp_t scr_llp[LCD_HEIGHT];
+
+
+static void llp_setup(void *src, void *dst, struct llp_t *llp, uint32_t size)
+{
+ llp->sar = (uint32_t)src;
+ llp->dar = (uint32_t)dst;
+ llp->llp = llp + 1;
+ llp->ctl_h = size;
+ llp->ctl_l = (1<<20) |
+ (1<<23) |
+ (1<<17) |
+ (2<<1) |
+ (2<<4) |
+ (3<<11) |
+ (3<<14) |
+ (1<<27) |
+ (1<<28);
+}
+
+static void llp_end(struct llp_t *llp)
+{
+ llp->ctl_l &= ~((1<<27)|(1<<28));
+}
+
+
+static void dwdma_start(uint8_t ch, struct llp_t *llp, uint8_t handshake)
+{
+ DWDMA_SAR(ch) = 0;
+ DWDMA_DAR(ch) = 0;
+ DWDMA_LLP(ch) = (uint32_t)llp;
+ DWDMA_CTL_L(ch) = (1<<20) |
+ (1<<23) |
+ (1<<17) |
+ (2<<1) |
+ (2<<4) |
+ (3<<11) |
+ (3<<14) |
+ (1<<27) |
+ (1<<28);
+
+ DWDMA_CTL_H(ch) = 1;
+ DWDMA_CFG_L(ch) = (7<<5);
+ DWDMA_CFG_H(ch) = (handshake<<11)|(1<<2);
+ DWDMA_SGR(ch) = (13<<20);
+ DWDMA_DMA_CHEN = (0x101<<ch);
+
+}
+
+
+void create_llp(void)
+{
+ int i = 0;
+
+ /* build LLPs */
+ for (i=0; i<LCD_HEIGHT; i++)
+ llp_setup(FBADDR(0,i), (void*)(&LCD_BUFF+(i%4)*LCD_WIDTH), &scr_llp[i], LCD_WIDTH/2);
+ llp_end(&scr_llp[LCD_HEIGHT-1]);
+}
+void lcdif_init(enum lcdif_mode_t mode)
+{
+ iomux_lcd(mode); /* setup pins for lcd interface */
+ dwdma_init();
+ create_llp();
+ lcdctrl_init(); /* basic lcdc module configuration */
+ lcdctrl_bypass(1); /* run in bypass mode - all writes goes directly to lcd controller */
+}
+struct mutex lcd_mtx;
void lcd_update()
{
- lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
+ mutex_lock(&lcd_mtx);
+//#if 0
+ LCDC_CTRL = ALPHA(7) | LCDC_STOP | LCDC_MCU | RGB24B;
+ lcdctrl_bypass(1);
+ lcd_write_reg(0x210, 0x0000);
+ lcd_write_reg(0x211, 0x00EF); /* 239 */
+ lcd_write_reg(0x212, 0x0000);
+ lcd_write_reg(0x213, 0x018F); /* 399 */
+ lcd_write_reg(0x200, 0x0000);
+ lcd_write_reg(0x201, 0x0000);
+
+ lcd_cmd(0x202);
+ LCDC_CTRL = ALPHA(7) | LCDC_STOP | LCDC_MCU;
+ lcdctrl_bypass(0);
+
+ while (!(LCDC_STA & LCDC_MCU_IDLE));
+ commit_discard_dcache_range(FBADDR(0,0), 2*LCD_WIDTH*LCD_HEIGHT);
+ dwdma_start(0, scr_llp, 6);
+ udelay(100);
+
+ MCU_CTRL=(1<<1)|(1<<2)|(1<<5);
+
+
+// while (DWDMA_CTL_L(0) & (1<<27))
+// yield();
+//#endif
+// lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
+ mutex_unlock(&lcd_mtx);
}
diff --git a/firmware/target/arm/rk27xx/rk27generic/lcd-rk27generic.c b/firmware/target/arm/rk27xx/rk27generic/lcd-rk27generic.c
index 5eca87c..9c1d7a0 100644
--- a/firmware/target/arm/rk27xx/rk27generic/lcd-rk27generic.c
+++ b/firmware/target/arm/rk27xx/rk27generic/lcd-rk27generic.c
@@ -181,9 +181,10 @@ void lcd_init_device(void)

void lcd_update_rect(int x, int y, int width, int height)
{
+#if 0
int px = x, py = y;
int pxmax = x + width, pymax = y + height;
-
+LCDC_CTRL = ALPHA(7) | LCDC_STOP | LCDC_MCU | RGB24B;
/* addresses setup */
lcd_write_reg(WINDOW_H_START, y);
lcd_write_reg(WINDOW_H_END, pymax-1);
@@ -193,12 +194,14 @@ void lcd_update_rect(int x, int y, int width, int height)
lcd_write_reg(GRAM_V_ADDR, x);

lcd_cmd(GRAM_WRITE);
-
+LCDC_CTRL = ALPHA(7) | LCDC_STOP | LCDC_MCU;
for (py=y; py<pymax; py++)
{
for (px=x; px<pxmax; px++)
- LCD_DATA = lcd_pixel_transform(*FBADDR(px,py));
+ LCD_DATA = *FBADDR(px,py);
}
+#endif
+lcd_update();
}

/* Blit a YUV bitmap directly to the LCD */
@@ -213,5 +216,4 @@ void lcd_blit_yuv(unsigned char * const src[3],
(void)x;
(void)y;
(void)width;
- (void)height;
}