Thank you to anyone who has already donated - your generous donations helped make three months of treatment possible.

My brother Nate continues to fight stage IV Hodgkin's lymphoma. He's just 31, with a wife and baby girl. They have no active income (since he's been unable to return to work), no insurance, and cannot afford the treatment he needs. Nate and his family need your help. Please consider a donation, every dollar helps. Thanks.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
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)