diff options
author | Jens Arnold <amiconn@rockbox.org> | 2007-10-14 23:05:56 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2007-10-14 23:05:56 +0000 |
commit | 99f955088149d5938ce4c9ca5624377f464b1380 (patch) | |
tree | 403178f0198f8ef0b57c49be3b25f085be52aa8a /firmware | |
parent | 57418b2192f4eb4decab716d50e09232ba22f7f4 (diff) | |
download | rockbox-99f955088149d5938ce4c9ca5624377f464b1380.tar.gz rockbox-99f955088149d5938ce4c9ca5624377f464b1380.zip |
H300, X5: Optimised lcd_yuv_blit(), using line-pair zig-zag writing to the LCD controller. ~7% speedup on H300, ~5% speedup on X5.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15111 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/target/coldfire/iaudio/x5/lcd-as-x5.S | 131 | ||||
-rw-r--r-- | firmware/target/coldfire/iaudio/x5/lcd-x5.c | 77 | ||||
-rw-r--r-- | firmware/target/coldfire/iriver/h300/lcd-as-h300.S | 129 | ||||
-rw-r--r-- | firmware/target/coldfire/iriver/h300/lcd-h300.c | 45 |
4 files changed, 255 insertions, 127 deletions
diff --git a/firmware/target/coldfire/iaudio/x5/lcd-as-x5.S b/firmware/target/coldfire/iaudio/x5/lcd-as-x5.S index 11150203af..879235ebf2 100644 --- a/firmware/target/coldfire/iaudio/x5/lcd-as-x5.S +++ b/firmware/target/coldfire/iaudio/x5/lcd-as-x5.S | |||
@@ -45,6 +45,23 @@ | |||
45 | * |B| |19611723 33976259 0| |Cr - 128| >> 26 | 45 | * |B| |19611723 33976259 0| |Cr - 128| >> 26 |
46 | * | 46 | * |
47 | * Needs EMAC set to saturated, signed integer mode. | 47 | * Needs EMAC set to saturated, signed integer mode. |
48 | * | ||
49 | * register usage: | ||
50 | * %a0 - LCD data port | ||
51 | * %a1 - Y pointer | ||
52 | * %a2 - C pointer | ||
53 | * %a3 - C width | ||
54 | * %a4 - Y end address | ||
55 | * %a5 - Y factor | ||
56 | * %a6 - BU factor | ||
57 | * %d0 - scratch | ||
58 | * %d1 - B, previous Y \ alternating | ||
59 | * %d2 - U / B, previous Y / | ||
60 | * %d3 - V / G | ||
61 | * %d4 - R / output pixel | ||
62 | * %d5 - GU factor | ||
63 | * %d6 - GV factor | ||
64 | * %d7 - RGB signed -> unsigned conversion mask | ||
48 | */ | 65 | */ |
49 | .align 2 | 66 | .align 2 |
50 | .global lcd_write_yuv420_lines | 67 | .global lcd_write_yuv420_lines |
@@ -55,8 +72,8 @@ lcd_write_yuv420_lines: | |||
55 | movem.l %d2-%d7/%a2-%a6, (%sp) | 72 | movem.l %d2-%d7/%a2-%a6, (%sp) |
56 | 73 | ||
57 | lea.l 0xf0008002, %a0 /* LCD data port */ | 74 | lea.l 0xf0008002, %a0 /* LCD data port */ |
58 | movem.l (44+4, %sp), %a1-%a4 /* Y data, Cb data, Cr data, width */ | 75 | movem.l (44+4, %sp), %a1-%a3 /* Y data, C data, C width */ |
59 | lea.l (%a1, %a4), %a4 /* end address */ | 76 | lea.l (%a1, %a3*2), %a4 /* Y end address */ |
60 | 77 | ||
61 | move.l #19611723, %a5 /* y factor */ | 78 | move.l #19611723, %a5 /* y factor */ |
62 | move.l #33976259, %a6 /* bu factor */ | 79 | move.l #33976259, %a6 /* bu factor */ |
@@ -65,11 +82,11 @@ lcd_write_yuv420_lines: | |||
65 | move.l #0x01040820, %d7 /* bitmask for signed->unsigned conversion | 82 | move.l #0x01040820, %d7 /* bitmask for signed->unsigned conversion |
66 | * of R, G and B within RGGB6666 at once */ | 83 | * of R, G and B within RGGB6666 at once */ |
67 | 84 | ||
68 | /* chroma for (very) first & second pixel */ | 85 | /* chroma for first 2x2 block */ |
86 | clr.l %d3 /* load v component */ | ||
87 | move.b (%a2, %a3), %d3 | ||
69 | clr.l %d2 /* load u component */ | 88 | clr.l %d2 /* load u component */ |
70 | move.b (%a2)+, %d2 | 89 | move.b (%a2)+, %d2 |
71 | clr.l %d3 /* load v component */ | ||
72 | move.b (%a3)+, %d3 | ||
73 | moveq.l #-128, %d0 | 90 | moveq.l #-128, %d0 |
74 | add.l %d0, %d2 | 91 | add.l %d0, %d2 |
75 | add.l %d0, %d3 | 92 | add.l %d0, %d3 |
@@ -80,9 +97,9 @@ lcd_write_yuv420_lines: | |||
80 | move.l #26881894, %d0 /* rv factor */ | 97 | move.l #26881894, %d0 /* rv factor */ |
81 | mac.l %d0, %d3, %acc2 /* rv */ | 98 | mac.l %d0, %d3, %acc2 /* rv */ |
82 | 99 | ||
83 | /* luma for (very) first pixel */ | 100 | /* luma for very first pixel (top left) */ |
84 | clr.l %d1 | 101 | clr.l %d1 |
85 | move.b (%a1)+, %d1 | 102 | move.b (%a1, %a3*2), %d1 |
86 | moveq.l #-126, %d0 | 103 | moveq.l #-126, %d0 |
87 | add.l %d1, %d0 /* y' (-0.5 ... +0.5) */ | 104 | add.l %d1, %d0 /* y' (-0.5 ... +0.5) */ |
88 | mac.l %a5, %d0, %acc0 | 105 | mac.l %a5, %d0, %acc0 |
@@ -92,11 +109,11 @@ lcd_write_yuv420_lines: | |||
92 | bra.b .yuv_line_entry | 109 | bra.b .yuv_line_entry |
93 | 110 | ||
94 | .yuv_line_loop: | 111 | .yuv_line_loop: |
95 | /* chroma for first & second pixel */ | 112 | /* chroma for 2x2 pixel block */ |
113 | clr.l %d3 /* load v component */ | ||
114 | move.b (%a2, %a3), %d3 | ||
96 | clr.l %d2 /* load u component */ | 115 | clr.l %d2 /* load u component */ |
97 | move.b (%a2)+, %d2 | 116 | move.b (%a2)+, %d2 |
98 | clr.l %d3 /* load v component */ | ||
99 | move.b (%a3)+, %d3 | ||
100 | moveq.l #-128, %d0 | 117 | moveq.l #-128, %d0 |
101 | add.l %d0, %d2 | 118 | add.l %d0, %d2 |
102 | add.l %d0, %d3 | 119 | add.l %d0, %d3 |
@@ -107,9 +124,9 @@ lcd_write_yuv420_lines: | |||
107 | move.l #26881894, %d0 /* rv factor */ | 124 | move.l #26881894, %d0 /* rv factor */ |
108 | mac.l %d0, %d3, %acc2 /* rv */ | 125 | mac.l %d0, %d3, %acc2 /* rv */ |
109 | 126 | ||
110 | /* luma for first pixel */ | 127 | /* luma for first pixel (top left) */ |
111 | clr.l %d1 | 128 | clr.l %d1 |
112 | move.b (%a1)+, %d1 | 129 | move.b (%a1, %a3*2), %d1 |
113 | moveq.l #-126, %d0 | 130 | moveq.l #-126, %d0 |
114 | add.l %d1, %d0 /* y' (-0.5 ... +0.5) */ | 131 | add.l %d1, %d0 /* y' (-0.5 ... +0.5) */ |
115 | mac.l %a5, %d0, %acc0 | 132 | mac.l %a5, %d0, %acc0 |
@@ -140,9 +157,10 @@ lcd_write_yuv420_lines: | |||
140 | move.w %d4, (%a0) | 157 | move.w %d4, (%a0) |
141 | swap %d4 | 158 | swap %d4 |
142 | 159 | ||
143 | /* luma for second pixel as delta from the first */ | 160 | /* luma for second pixel (bottom left) as delta from the first */ |
144 | clr.l %d0 | 161 | clr.l %d2 |
145 | move.b (%a1)+, %d0 | 162 | move.b (%a1)+, %d2 |
163 | move.l %d2, %d0 | ||
146 | sub.l %d1, %d0 | 164 | sub.l %d1, %d0 |
147 | mac.l %a5, %d0, %acc0 | 165 | mac.l %a5, %d0, %acc0 |
148 | mac.l %a5, %d0, %acc1 | 166 | mac.l %a5, %d0, %acc1 |
@@ -153,13 +171,45 @@ lcd_write_yuv420_lines: | |||
153 | 171 | ||
154 | /* convert to RGB666, pack and output */ | 172 | /* convert to RGB666, pack and output */ |
155 | moveq.l #26, %d0 | 173 | moveq.l #26, %d0 |
156 | movclr.l %acc0, %d4 | 174 | move.l %acc0, %d4 |
157 | movclr.l %acc1, %d3 | 175 | move.l %acc1, %d3 |
158 | movclr.l %acc2, %d2 | 176 | move.l %acc2, %d1 |
159 | lsr.l %d0, %d4 | 177 | lsr.l %d0, %d4 |
160 | lsr.l %d0, %d3 | 178 | lsr.l %d0, %d3 |
161 | lsr.l %d0, %d2 | 179 | lsr.l %d0, %d1 |
180 | |||
181 | lsl.l #6, %d1 | ||
182 | or.l %d3, %d1 /* |00000000|00000000|0000Rrrr|rrGggggg| */ | ||
183 | lsl.l #7, %d1 | ||
184 | or.l %d1, %d3 /* |00000000|00000Rrr|rrrGgggg|g0Gggggg| */ | ||
185 | lsl.l #6, %d3 | ||
186 | or.l %d3, %d4 /* |0000000R|rrrrrGgg|ggg0Gggg|ggBbbbbb| */ | ||
187 | eor.l %d7, %d4 /* |0000000r|rrrrrggg|ggg0gggg|ggbbbbbb| */ | ||
188 | swap %d4 | ||
189 | move.w %d4, (%a0) | ||
190 | swap %d4 | ||
191 | |||
192 | /* luma for third pixel (top right) as delta from the second */ | ||
193 | clr.l %d1 | ||
194 | move.b (%a1, %a3*2), %d1 | ||
195 | move.l %d1, %d0 | ||
196 | sub.l %d2, %d0 | ||
197 | mac.l %a5, %d0, %acc0 | ||
198 | mac.l %a5, %d0, %acc1 | ||
199 | mac.l %a5, %d0, %acc2 | ||
200 | |||
201 | move.w %d4, (%a0) | ||
202 | /* 2nd LCD write is delayed one pixel to use it for filling the EMAC latency */ | ||
162 | 203 | ||
204 | /* convert to RGB666, pack and output */ | ||
205 | moveq.l #26, %d0 | ||
206 | move.l %acc0, %d4 | ||
207 | move.l %acc1, %d3 | ||
208 | move.l %acc2, %d2 | ||
209 | lsr.l %d0, %d4 | ||
210 | lsr.l %d0, %d3 | ||
211 | lsr.l %d0, %d2 | ||
212 | |||
163 | lsl.l #6, %d2 | 213 | lsl.l #6, %d2 |
164 | or.l %d3, %d2 /* |00000000|00000000|0000Rrrr|rrGggggg| */ | 214 | or.l %d3, %d2 /* |00000000|00000000|0000Rrrr|rrGggggg| */ |
165 | lsl.l #7, %d2 | 215 | lsl.l #7, %d2 |
@@ -171,24 +221,45 @@ lcd_write_yuv420_lines: | |||
171 | move.w %d4, (%a0) | 221 | move.w %d4, (%a0) |
172 | swap %d4 | 222 | swap %d4 |
173 | 223 | ||
224 | /* luma for fourth pixel (bottom right) as delta from the thrid */ | ||
225 | clr.l %d2 | ||
226 | move.b (%a1)+, %d2 | ||
227 | move.l %d2, %d0 | ||
228 | sub.l %d1, %d0 | ||
229 | mac.l %a5, %d0, %acc0 | ||
230 | mac.l %a5, %d0, %acc1 | ||
231 | mac.l %a5, %d0, %acc2 | ||
232 | |||
233 | move.w %d4, (%a0) | ||
234 | /* 2nd LCD write is delayed one pixel to use it for filling the EMAC latency */ | ||
235 | |||
236 | /* convert to RGB666, pack and output */ | ||
237 | moveq.l #26, %d0 | ||
238 | movclr.l %acc0, %d4 | ||
239 | movclr.l %acc1, %d3 | ||
240 | movclr.l %acc2, %d1 | ||
241 | lsr.l %d0, %d4 | ||
242 | lsr.l %d0, %d3 | ||
243 | lsr.l %d0, %d1 | ||
244 | |||
245 | lsl.l #6, %d1 | ||
246 | or.l %d3, %d1 /* |00000000|00000000|0000Rrrr|rrGggggg| */ | ||
247 | lsl.l #7, %d1 | ||
248 | or.l %d1, %d3 /* |00000000|00000Rrr|rrrGgggg|g0Gggggg| */ | ||
249 | lsl.l #6, %d3 | ||
250 | or.l %d3, %d4 /* |0000000R|rrrrrGgg|ggg0Gggg|ggBbbbbb| */ | ||
251 | eor.l %d7, %d4 /* |0000000r|rrrrrggg|ggg0gggg|ggbbbbbb| */ | ||
252 | swap %d4 | ||
253 | move.w %d4, (%a0) | ||
254 | swap %d4 | ||
255 | |||
174 | cmp.l %a1, %a4 /* run %a1 up to end of line */ | 256 | cmp.l %a1, %a4 /* run %a1 up to end of line */ |
175 | bhi.w .yuv_line_loop | 257 | bhi.w .yuv_line_loop |
176 | 258 | ||
177 | tst.l (44+4, %sp) /* use original Y pointer as a flag to */ | ||
178 | beq.b .yuv_exit /* distinguish between first and second */ | ||
179 | clr.l (44+4, %sp) /* pixel line */ | ||
180 | |||
181 | /* Rewind chroma pointers */ | ||
182 | movem.l (44+8, %sp), %a2-%a4 /* Cb data, Cr data, width */ | ||
183 | lea.l (%a1, %a4), %a4 /* end address */ | ||
184 | bra.w .yuv_line_loop | ||
185 | |||
186 | .yuv_exit: | ||
187 | move.w %d4, (%a0) /* write (very) last 2nd word */ | 259 | move.w %d4, (%a0) /* write (very) last 2nd word */ |
188 | 260 | ||
189 | movem.l (%sp), %d2-%d7/%a2-%a6 | 261 | movem.l (%sp), %d2-%d7/%a2-%a6 |
190 | lea.l (44, %sp), %sp /* restore registers */ | 262 | lea.l (44, %sp), %sp /* restore registers */ |
191 | |||
192 | rts | 263 | rts |
193 | .yuv_end: | 264 | .yuv_end: |
194 | .size lcd_write_yuv420_lines, yuv_end - lcd_write_yuv420_lines | 265 | .size lcd_write_yuv420_lines, yuv_end - lcd_write_yuv420_lines |
diff --git a/firmware/target/coldfire/iaudio/x5/lcd-x5.c b/firmware/target/coldfire/iaudio/x5/lcd-x5.c index 2cc5b5ba65..5ca2cb508c 100644 --- a/firmware/target/coldfire/iaudio/x5/lcd-x5.c +++ b/firmware/target/coldfire/iaudio/x5/lcd-x5.c | |||
@@ -50,11 +50,6 @@ static unsigned short r_gate_scan_start_pos = 0x0002; | |||
50 | static unsigned short r_drv_output_control = 0x0313; | 50 | static unsigned short r_drv_output_control = 0x0313; |
51 | static unsigned short r_horiz_ram_addr_pos = 0x7f00; | 51 | static unsigned short r_horiz_ram_addr_pos = 0x7f00; |
52 | 52 | ||
53 | /* Dithering */ | ||
54 | #define R_ENTRY_MODE_SOLID 0x1038 | ||
55 | #define R_ENTRY_MODE_DIT 0x9038 | ||
56 | static unsigned short r_entry_mode = R_ENTRY_MODE_SOLID; | ||
57 | |||
58 | /* Forward declarations */ | 53 | /* Forward declarations */ |
59 | static void lcd_display_off(void); | 54 | static void lcd_display_off(void); |
60 | 55 | ||
@@ -97,6 +92,9 @@ static void lcd_display_off(void); | |||
97 | #define R_GAMMA_AMP_ADJ_POS 0x3a | 92 | #define R_GAMMA_AMP_ADJ_POS 0x3a |
98 | #define R_GAMMA_AMP_ADJ_NEG 0x3b | 93 | #define R_GAMMA_AMP_ADJ_NEG 0x3b |
99 | 94 | ||
95 | #define R_ENTRY_MODE_SOLID_VERT 0x1038 | ||
96 | #define R_ENTRY_MODE_DIT_HORZ 0x9030 | ||
97 | |||
100 | /* called very frequently - inline! */ | 98 | /* called very frequently - inline! */ |
101 | static inline void lcd_write_reg(int reg, int val) | 99 | static inline void lcd_write_reg(int reg, int val) |
102 | { | 100 | { |
@@ -113,14 +111,6 @@ static inline void lcd_begin_write_gram(void) | |||
113 | LCD_CMD = R_WRITE_DATA_2_GRAM << 1; | 111 | LCD_CMD = R_WRITE_DATA_2_GRAM << 1; |
114 | } | 112 | } |
115 | 113 | ||
116 | /* set hard dither mode on/off */ | ||
117 | static void hw_dither(bool on) | ||
118 | { | ||
119 | /* DIT=x, BGR=1, HWM=0, I/D1-0=11, AM=1, LG2-0=000 */ | ||
120 | r_entry_mode = on ? R_ENTRY_MODE_DIT : R_ENTRY_MODE_SOLID; | ||
121 | lcd_write_reg(R_ENTRY_MODE, r_entry_mode); | ||
122 | } | ||
123 | |||
124 | /*** hardware configuration ***/ | 114 | /*** hardware configuration ***/ |
125 | 115 | ||
126 | int lcd_default_contrast(void) | 116 | int lcd_default_contrast(void) |
@@ -233,7 +223,7 @@ static void lcd_power_on(void) | |||
233 | /* FLD1-0=01 (1 field), B/C=1, EOR=1 (C-pat), NW5-0=000000 (1 row) */ | 223 | /* FLD1-0=01 (1 field), B/C=1, EOR=1 (C-pat), NW5-0=000000 (1 row) */ |
234 | lcd_write_reg(R_DRV_AC_CONTROL, 0x0700); | 224 | lcd_write_reg(R_DRV_AC_CONTROL, 0x0700); |
235 | /* DIT=x, BGR=1, HWM=0, I/D1-0=11, AM=1, LG2-0=000 */ | 225 | /* DIT=x, BGR=1, HWM=0, I/D1-0=11, AM=1, LG2-0=000 */ |
236 | lcd_write_reg(R_ENTRY_MODE, r_entry_mode); | 226 | lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_SOLID_VERT); |
237 | /* CP15-0=0000000000000000 */ | 227 | /* CP15-0=0000000000000000 */ |
238 | lcd_write_reg(R_COMPARE_REG, 0x0000); | 228 | lcd_write_reg(R_COMPARE_REG, 0x0000); |
239 | /* NO1-0=01, SDT1-0=00, EQ1-0=00, DIV1-0=00, RTN3-00000 */ | 229 | /* NO1-0=01, SDT1-0=00, EQ1-0=00, DIV1-0=00, RTN3-00000 */ |
@@ -377,7 +367,8 @@ void lcd_init_device(void) | |||
377 | lcd_set_contrast(DEFAULT_CONTRAST_SETTING); | 367 | lcd_set_contrast(DEFAULT_CONTRAST_SETTING); |
378 | lcd_set_invert_display(false); | 368 | lcd_set_invert_display(false); |
379 | lcd_set_flip(false); | 369 | lcd_set_flip(false); |
380 | hw_dither(false); /* do this or all bootloaders will need reflashing */ | 370 | lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_SOLID_VERT); |
371 | /* do this or all bootloaders will need reflashing */ | ||
381 | #endif | 372 | #endif |
382 | } | 373 | } |
383 | 374 | ||
@@ -432,13 +423,12 @@ void lcd_blit(const fb_data* data, int x, int by, int width, | |||
432 | } | 423 | } |
433 | 424 | ||
434 | /* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. | 425 | /* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. |
435 | * y should have two lines of Y back to back. | 426 | * y should have two lines of Y back to back, 2nd line first. |
436 | * bu and rv should contain the Cb and Cr data for the two lines of Y. | 427 | * c should contain the Cb and Cr data for the two lines of Y back to back. |
437 | * Needs EMAC set to saturated, signed integer mode. | 428 | * Needs EMAC set to saturated, signed integer mode. |
438 | */ | 429 | */ |
439 | extern void lcd_write_yuv420_lines(const unsigned char *y, | 430 | extern void lcd_write_yuv420_lines(const unsigned char *y, |
440 | const unsigned char *bu, | 431 | const unsigned char *c, int width); |
441 | const unsigned char *rv, int width); | ||
442 | 432 | ||
443 | /* Performance function to blit a YUV bitmap directly to the LCD | 433 | /* Performance function to blit a YUV bitmap directly to the LCD |
444 | * src_x, src_y, width and height should be even and within the LCD's | 434 | * src_x, src_y, width and height should be even and within the LCD's |
@@ -450,25 +440,19 @@ void lcd_yuv_blit(unsigned char * const src[3], | |||
450 | { | 440 | { |
451 | /* IRAM Y, Cb/bu, guv and Cb/rv buffers. */ | 441 | /* IRAM Y, Cb/bu, guv and Cb/rv buffers. */ |
452 | unsigned char y_ibuf[LCD_WIDTH*2]; | 442 | unsigned char y_ibuf[LCD_WIDTH*2]; |
453 | unsigned char bu_ibuf[LCD_WIDTH/2]; | 443 | unsigned char c_ibuf[LCD_WIDTH]; |
454 | unsigned char rv_ibuf[LCD_WIDTH/2]; | ||
455 | const unsigned char *ysrc, *usrc, *vsrc; | 444 | const unsigned char *ysrc, *usrc, *vsrc; |
456 | const unsigned char *ysrc_max; | 445 | const unsigned char *ysrc_max; |
457 | 446 | ||
458 | if (!display_on) | 447 | if (!display_on) |
459 | return; | 448 | return; |
460 | 449 | ||
461 | if (r_entry_mode == R_ENTRY_MODE_SOLID) | ||
462 | hw_dither(true); | ||
463 | |||
464 | width &= ~1; /* stay on the safe side */ | 450 | width &= ~1; /* stay on the safe side */ |
465 | height &= ~1; | 451 | height &= ~1; |
466 | 452 | ||
453 | lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_DIT_HORZ); | ||
467 | /* Set start position and window */ | 454 | /* Set start position and window */ |
468 | lcd_write_reg(R_RAM_ADDR_SET, (x << 8) | (y + y_offset)); | 455 | lcd_write_reg(R_VERT_RAM_ADDR_POS, (LCD_WIDTH-1) << 8); |
469 | lcd_write_reg(R_VERT_RAM_ADDR_POS, ((x + width - 1) << 8) | x); | ||
470 | |||
471 | lcd_begin_write_gram(); | ||
472 | 456 | ||
473 | ysrc = src[0] + src_y * stride + src_x; | 457 | ysrc = src[0] + src_y * stride + src_x; |
474 | usrc = src[1] + (src_y * stride >> 2) + (src_x >> 1); | 458 | usrc = src[1] + (src_y * stride >> 2) + (src_x >> 1); |
@@ -478,11 +462,17 @@ void lcd_yuv_blit(unsigned char * const src[3], | |||
478 | coldfire_set_macsr(EMAC_SATURATE); | 462 | coldfire_set_macsr(EMAC_SATURATE); |
479 | do | 463 | do |
480 | { | 464 | { |
481 | memcpy(y_ibuf, ysrc, width); | 465 | lcd_write_reg(R_HORIZ_RAM_ADDR_POS, ((y + y_offset + 1) << 8) | (y + y_offset)); |
482 | memcpy(y_ibuf + width, ysrc + stride, width); | 466 | lcd_write_reg(R_RAM_ADDR_SET, (x << 8) | (y + y_offset)); |
483 | memcpy(bu_ibuf, usrc, width >> 1); | 467 | lcd_begin_write_gram(); |
484 | memcpy(rv_ibuf, vsrc, width >> 1); | 468 | |
485 | lcd_write_yuv420_lines(y_ibuf, bu_ibuf, rv_ibuf, width); | 469 | memcpy(y_ibuf + width, ysrc, width); |
470 | memcpy(y_ibuf, ysrc + stride, width); | ||
471 | memcpy(c_ibuf, usrc, width >> 1); | ||
472 | memcpy(c_ibuf + (width >> 1), vsrc, width >> 1); | ||
473 | lcd_write_yuv420_lines(y_ibuf, c_ibuf, width >> 1); | ||
474 | |||
475 | y += 2; | ||
486 | ysrc += 2 * stride; | 476 | ysrc += 2 * stride; |
487 | usrc += stride >> 1; | 477 | usrc += stride >> 1; |
488 | vsrc += stride >> 1; | 478 | vsrc += stride >> 1; |
@@ -499,17 +489,16 @@ void lcd_update(void) | |||
499 | if (!display_on) | 489 | if (!display_on) |
500 | return; | 490 | return; |
501 | 491 | ||
502 | if (r_entry_mode == R_ENTRY_MODE_DIT) | 492 | lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_SOLID_VERT); |
503 | hw_dither(false); | ||
504 | |||
505 | /* Set start position and window */ | 493 | /* Set start position and window */ |
506 | lcd_write_reg(R_RAM_ADDR_SET, y_offset); /* X == 0 */ | 494 | lcd_write_reg(R_HORIZ_RAM_ADDR_POS, |
495 | ((y_offset + LCD_HEIGHT-1) << 8) | y_offset); | ||
507 | lcd_write_reg(R_VERT_RAM_ADDR_POS, (LCD_WIDTH-1) << 8); | 496 | lcd_write_reg(R_VERT_RAM_ADDR_POS, (LCD_WIDTH-1) << 8); |
497 | lcd_write_reg(R_RAM_ADDR_SET, y_offset); | ||
508 | 498 | ||
509 | lcd_begin_write_gram(); | 499 | lcd_begin_write_gram(); |
510 | 500 | ||
511 | lcd_write_data((unsigned short *)lcd_framebuffer, | 501 | lcd_write_data((unsigned short *)lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT); |
512 | LCD_WIDTH*LCD_HEIGHT); | ||
513 | } /* lcd_update */ | 502 | } /* lcd_update */ |
514 | 503 | ||
515 | /* Update a fraction of the display. */ | 504 | /* Update a fraction of the display. */ |
@@ -521,9 +510,6 @@ void lcd_update_rect(int x, int y, int width, int height) | |||
521 | if (!display_on) | 510 | if (!display_on) |
522 | return; | 511 | return; |
523 | 512 | ||
524 | if (r_entry_mode == R_ENTRY_MODE_DIT) | ||
525 | hw_dither(false); | ||
526 | |||
527 | if (x + width > LCD_WIDTH) | 513 | if (x + width > LCD_WIDTH) |
528 | width = LCD_WIDTH - x; /* Clip right */ | 514 | width = LCD_WIDTH - x; /* Clip right */ |
529 | if (x < 0) | 515 | if (x < 0) |
@@ -539,9 +525,12 @@ void lcd_update_rect(int x, int y, int width, int height) | |||
539 | if (y >= ymax) | 525 | if (y >= ymax) |
540 | return; /* nothing left to do */ | 526 | return; /* nothing left to do */ |
541 | 527 | ||
528 | lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_SOLID_VERT); | ||
542 | /* Set start position and window */ | 529 | /* Set start position and window */ |
543 | lcd_write_reg(R_RAM_ADDR_SET, (x << 8) | (y + y_offset)); | 530 | lcd_write_reg(R_HORIZ_RAM_ADDR_POS, |
531 | ((y_offset + LCD_HEIGHT-1) << 8) | y_offset); | ||
544 | lcd_write_reg(R_VERT_RAM_ADDR_POS, ((x + width - 1) << 8) | x); | 532 | lcd_write_reg(R_VERT_RAM_ADDR_POS, ((x + width - 1) << 8) | x); |
533 | lcd_write_reg(R_RAM_ADDR_SET, (x << 8) | (y + y_offset)); | ||
545 | 534 | ||
546 | lcd_begin_write_gram(); | 535 | lcd_begin_write_gram(); |
547 | 536 | ||
diff --git a/firmware/target/coldfire/iriver/h300/lcd-as-h300.S b/firmware/target/coldfire/iriver/h300/lcd-as-h300.S index 1873b905c6..9106e22c1c 100644 --- a/firmware/target/coldfire/iriver/h300/lcd-as-h300.S +++ b/firmware/target/coldfire/iriver/h300/lcd-as-h300.S | |||
@@ -44,6 +44,23 @@ | |||
44 | * |B| |19611723 33976259 0| |Cr - 128| >> 27 | 44 | * |B| |19611723 33976259 0| |Cr - 128| >> 27 |
45 | * | 45 | * |
46 | * Needs EMAC set to saturated, signed integer mode. | 46 | * Needs EMAC set to saturated, signed integer mode. |
47 | * | ||
48 | * register usage: | ||
49 | * %a0 - LCD data port | ||
50 | * %a1 - Y pointer | ||
51 | * %a2 - C pointer | ||
52 | * %a3 - C width | ||
53 | * %a4 - Y end address | ||
54 | * %a5 - Y factor | ||
55 | * %a6 - BU factor | ||
56 | * %d0 - scratch | ||
57 | * %d1 - B, previous Y \ alternating | ||
58 | * %d2 - U / B, previous Y / | ||
59 | * %d3 - V / G | ||
60 | * %d4 - R / output pixel | ||
61 | * %d5 - GU factor | ||
62 | * %d6 - GV factor | ||
63 | * %d7 - RGB signed -> unsigned conversion mask | ||
47 | */ | 64 | */ |
48 | .align 2 | 65 | .align 2 |
49 | .global lcd_write_yuv420_lines | 66 | .global lcd_write_yuv420_lines |
@@ -52,10 +69,10 @@ | |||
52 | lcd_write_yuv420_lines: | 69 | lcd_write_yuv420_lines: |
53 | lea.l (-44, %sp), %sp /* free up some registers */ | 70 | lea.l (-44, %sp), %sp /* free up some registers */ |
54 | movem.l %d2-%d7/%a2-%a6, (%sp) | 71 | movem.l %d2-%d7/%a2-%a6, (%sp) |
55 | 72 | ||
56 | lea.l 0xf0000002, %a0 /* LCD data port */ | 73 | lea.l 0xf0000002, %a0 /* LCD data port */ |
57 | movem.l (44+4, %sp), %a1-%a4 /* Y data, Cb data, Cr data, width */ | 74 | movem.l (44+4, %sp), %a1-%a3 /* Y data, C data, C width */ |
58 | lea.l (%a1, %a4), %a4 /* end address */ | 75 | lea.l (%a1, %a3*2), %a4 /* Y end address */ |
59 | 76 | ||
60 | move.l #19611723, %a5 /* y factor */ | 77 | move.l #19611723, %a5 /* y factor */ |
61 | move.l #33976259, %a6 /* bu factor */ | 78 | move.l #33976259, %a6 /* bu factor */ |
@@ -64,11 +81,11 @@ lcd_write_yuv420_lines: | |||
64 | move.l #0x8410, %d7 /* bitmask for signed->unsigned conversion | 81 | move.l #0x8410, %d7 /* bitmask for signed->unsigned conversion |
65 | * of R, G and B within RGB565 at once */ | 82 | * of R, G and B within RGB565 at once */ |
66 | 83 | ||
67 | /* chroma for (very) first & second pixel */ | 84 | /* chroma for first 2x2 pixel block */ |
85 | clr.l %d3 /* load v component */ | ||
86 | move.b (%a2, %a3), %d3 | ||
68 | clr.l %d2 /* load u component */ | 87 | clr.l %d2 /* load u component */ |
69 | move.b (%a2)+, %d2 | 88 | move.b (%a2)+, %d2 |
70 | clr.l %d3 /* load v component */ | ||
71 | move.b (%a3)+, %d3 | ||
72 | moveq.l #-128, %d0 | 89 | moveq.l #-128, %d0 |
73 | add.l %d0, %d2 | 90 | add.l %d0, %d2 |
74 | add.l %d0, %d3 | 91 | add.l %d0, %d3 |
@@ -79,9 +96,9 @@ lcd_write_yuv420_lines: | |||
79 | move.l #26881894, %d0 /* rv factor */ | 96 | move.l #26881894, %d0 /* rv factor */ |
80 | mac.l %d0, %d3, %acc2 /* rv */ | 97 | mac.l %d0, %d3, %acc2 /* rv */ |
81 | 98 | ||
82 | /* luma for (very) first pixel */ | 99 | /* luma for very first pixel (top left) */ |
83 | clr.l %d1 | 100 | clr.l %d1 |
84 | move.b (%a1)+, %d1 | 101 | move.b (%a1, %a3*2), %d1 |
85 | moveq.l #-126, %d0 | 102 | moveq.l #-126, %d0 |
86 | add.l %d1, %d0 /* y' (-0.5 ... +0.5) */ | 103 | add.l %d1, %d0 /* y' (-0.5 ... +0.5) */ |
87 | mac.l %a5, %d0, %acc0 | 104 | mac.l %a5, %d0, %acc0 |
@@ -91,11 +108,11 @@ lcd_write_yuv420_lines: | |||
91 | bra.b .yuv_line_entry | 108 | bra.b .yuv_line_entry |
92 | 109 | ||
93 | .yuv_line_loop: | 110 | .yuv_line_loop: |
94 | /* chroma for first & second pixel */ | 111 | /* chroma for 2x2 pixel block */ |
112 | clr.l %d3 /* load v component */ | ||
113 | move.b (%a2, %a3), %d3 | ||
95 | clr.l %d2 /* load u component */ | 114 | clr.l %d2 /* load u component */ |
96 | move.b (%a2)+, %d2 | 115 | move.b (%a2)+, %d2 |
97 | clr.l %d3 /* load v component */ | ||
98 | move.b (%a3)+, %d3 | ||
99 | moveq.l #-128, %d0 | 116 | moveq.l #-128, %d0 |
100 | add.l %d0, %d2 | 117 | add.l %d0, %d2 |
101 | add.l %d0, %d3 | 118 | add.l %d0, %d3 |
@@ -106,16 +123,16 @@ lcd_write_yuv420_lines: | |||
106 | move.l #26881894, %d0 /* rv factor */ | 123 | move.l #26881894, %d0 /* rv factor */ |
107 | mac.l %d0, %d3, %acc2 /* rv */ | 124 | mac.l %d0, %d3, %acc2 /* rv */ |
108 | 125 | ||
109 | /* luma for first pixel */ | 126 | /* luma for first pixel (top left) */ |
110 | clr.l %d1 | 127 | clr.l %d1 |
111 | move.b (%a1)+, %d1 | 128 | move.b (%a1, %a3*2), %d1 |
112 | moveq.l #-126, %d0 | 129 | moveq.l #-126, %d0 |
113 | add.l %d1, %d0 /* y' (-0.5 ... +0.5) */ | 130 | add.l %d1, %d0 /* y' (-0.5 ... +0.5) */ |
114 | mac.l %a5, %d0, %acc0 | 131 | mac.l %a5, %d0, %acc0 |
115 | mac.l %a5, %d0, %acc1 | 132 | mac.l %a5, %d0, %acc1 |
116 | mac.l %a5, %d0, %acc2 | 133 | mac.l %a5, %d0, %acc2 |
117 | 134 | ||
118 | move.w %d4, (%a0) | 135 | move.w %d4, (%a0) |
119 | /* LCD write is delayed one pixel to use it for filling the EMAC latency */ | 136 | /* LCD write is delayed one pixel to use it for filling the EMAC latency */ |
120 | 137 | ||
121 | /* convert to RGB565, pack and output */ | 138 | /* convert to RGB565, pack and output */ |
@@ -134,22 +151,50 @@ lcd_write_yuv420_lines: | |||
134 | or.l %d2, %d4 | 151 | or.l %d2, %d4 |
135 | eor.l %d7, %d4 | 152 | eor.l %d7, %d4 |
136 | 153 | ||
137 | /* luma for second pixel as delta from the first */ | 154 | /* luma for second pixel (bottom left) as delta from the first */ |
138 | clr.l %d0 | 155 | clr.l %d2 |
139 | move.b (%a1)+, %d0 | 156 | move.b (%a1)+, %d2 |
157 | move.l %d2, %d0 | ||
140 | sub.l %d1, %d0 | 158 | sub.l %d1, %d0 |
141 | mac.l %a5, %d0, %acc0 | 159 | mac.l %a5, %d0, %acc0 |
142 | mac.l %a5, %d0, %acc1 | 160 | mac.l %a5, %d0, %acc1 |
143 | mac.l %a5, %d0, %acc2 | 161 | mac.l %a5, %d0, %acc2 |
144 | 162 | ||
145 | move.w %d4, (%a0) | 163 | move.w %d4, (%a0) |
146 | /* LCD write is delayed one pixel to use it for filling the EMAC latency */ | 164 | /* LCD write is delayed one pixel to use it for filling the EMAC latency */ |
147 | 165 | ||
148 | /* convert to RGB565, pack and output */ | 166 | /* convert to RGB565, pack and output */ |
149 | moveq.l #27, %d0 | 167 | moveq.l #27, %d0 |
150 | movclr.l %acc0, %d2 | 168 | move.l %acc0, %d1 |
151 | movclr.l %acc1, %d3 | 169 | move.l %acc1, %d3 |
152 | movclr.l %acc2, %d4 | 170 | move.l %acc2, %d4 |
171 | lsr.l %d0, %d1 | ||
172 | lsr.l %d0, %d4 | ||
173 | moveq.l #26, %d0 | ||
174 | lsr.l %d0, %d3 | ||
175 | lsl.l #6, %d4 | ||
176 | or.l %d3, %d4 | ||
177 | lsl.l #5, %d4 | ||
178 | or.l %d1, %d4 | ||
179 | eor.l %d7, %d4 | ||
180 | |||
181 | /* luma for third pixel (top right) as delta from the second */ | ||
182 | clr.l %d1 | ||
183 | move.b (%a1, %a3*2), %d1 | ||
184 | move.l %d1, %d0 | ||
185 | sub.l %d2, %d0 | ||
186 | mac.l %a5, %d0, %acc0 | ||
187 | mac.l %a5, %d0, %acc1 | ||
188 | mac.l %a5, %d0, %acc2 | ||
189 | |||
190 | move.w %d4, (%a0) | ||
191 | /* LCD write is delayed one pixel to use it for filling the EMAC latency */ | ||
192 | |||
193 | /* convert to RGB565, pack and output */ | ||
194 | moveq.l #27, %d0 | ||
195 | move.l %acc0, %d2 | ||
196 | move.l %acc1, %d3 | ||
197 | move.l %acc2, %d4 | ||
153 | lsr.l %d0, %d2 | 198 | lsr.l %d0, %d2 |
154 | lsr.l %d0, %d4 | 199 | lsr.l %d0, %d4 |
155 | moveq.l #26, %d0 | 200 | moveq.l #26, %d0 |
@@ -160,24 +205,40 @@ lcd_write_yuv420_lines: | |||
160 | or.l %d2, %d4 | 205 | or.l %d2, %d4 |
161 | eor.l %d7, %d4 | 206 | eor.l %d7, %d4 |
162 | 207 | ||
208 | /* luma for fourth pixel (bottom right) as delta from the third */ | ||
209 | clr.l %d2 | ||
210 | move.b (%a1)+, %d2 | ||
211 | move.l %d2, %d0 | ||
212 | sub.l %d1, %d0 | ||
213 | mac.l %a5, %d0, %acc0 | ||
214 | mac.l %a5, %d0, %acc1 | ||
215 | mac.l %a5, %d0, %acc2 | ||
216 | |||
217 | move.w %d4, (%a0) | ||
218 | /* LCD write is delayed one pixel to use it for filling the EMAC latency */ | ||
219 | |||
220 | /* convert to RGB565, pack and output */ | ||
221 | moveq.l #27, %d0 | ||
222 | movclr.l %acc0, %d1 | ||
223 | movclr.l %acc1, %d3 | ||
224 | movclr.l %acc2, %d4 | ||
225 | lsr.l %d0, %d1 | ||
226 | lsr.l %d0, %d4 | ||
227 | moveq.l #26, %d0 | ||
228 | lsr.l %d0, %d3 | ||
229 | lsl.l #6, %d4 | ||
230 | or.l %d3, %d4 | ||
231 | lsl.l #5, %d4 | ||
232 | or.l %d1, %d4 | ||
233 | eor.l %d7, %d4 | ||
234 | |||
163 | cmp.l %a1, %a4 /* run %a1 up to end of line */ | 235 | cmp.l %a1, %a4 /* run %a1 up to end of line */ |
164 | bhi.w .yuv_line_loop | 236 | bhi.w .yuv_line_loop |
165 | 237 | ||
166 | tst.l (44+4, %sp) /* use original Y pointer as a flag to */ | ||
167 | beq.b .yuv_exit /* distinguish between first and second */ | ||
168 | clr.l (44+4, %sp) /* pixel line */ | ||
169 | |||
170 | /* Rewind chroma pointers */ | ||
171 | movem.l (44+8, %sp), %a2-%a4 /* Cb data, Cr data, width */ | ||
172 | lea.l (%a1, %a4), %a4 /* end address */ | ||
173 | bra.w .yuv_line_loop | ||
174 | |||
175 | .yuv_exit: | ||
176 | move.w %d4, (%a0) /* write (very) last pixel */ | 238 | move.w %d4, (%a0) /* write (very) last pixel */ |
177 | 239 | ||
178 | movem.l (%sp), %d2-%d7/%a2-%a6 | 240 | movem.l (%sp), %d2-%d7/%a2-%a6 |
179 | lea.l (44, %sp), %sp /* restore registers */ | 241 | lea.l (44, %sp), %sp /* restore registers */ |
180 | |||
181 | rts | 242 | rts |
182 | .yuv_end: | 243 | .yuv_end: |
183 | .size lcd_write_yuv420_lines, .yuv_end - lcd_write_yuv420_lines | 244 | .size lcd_write_yuv420_lines, .yuv_end - lcd_write_yuv420_lines |
diff --git a/firmware/target/coldfire/iriver/h300/lcd-h300.c b/firmware/target/coldfire/iriver/h300/lcd-h300.c index 8f76d5255a..00662e16f9 100644 --- a/firmware/target/coldfire/iriver/h300/lcd-h300.c +++ b/firmware/target/coldfire/iriver/h300/lcd-h300.c | |||
@@ -80,6 +80,9 @@ static int xoffset = 0; /* needed for flip */ | |||
80 | #define LCD_CMD (*(volatile unsigned short *)0xf0000000) | 80 | #define LCD_CMD (*(volatile unsigned short *)0xf0000000) |
81 | #define LCD_DATA (*(volatile unsigned short *)0xf0000002) | 81 | #define LCD_DATA (*(volatile unsigned short *)0xf0000002) |
82 | 82 | ||
83 | #define R_ENTRY_MODE_HORZ 0x7030 | ||
84 | #define R_ENTRY_MODE_VERT 0x7038 | ||
85 | |||
83 | /* called very frequently - inline! */ | 86 | /* called very frequently - inline! */ |
84 | static inline void lcd_write_reg(int reg, int val) | 87 | static inline void lcd_write_reg(int reg, int val) |
85 | { | 88 | { |
@@ -307,13 +310,12 @@ void lcd_blit(const fb_data* data, int x, int by, int width, | |||
307 | } | 310 | } |
308 | 311 | ||
309 | /* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. | 312 | /* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. |
310 | * y should have two lines of Y back to back. | 313 | * y should have two lines of Y back to back, 2nd line first. |
311 | * bu and rv should contain the Cb and Cr data for the two lines of Y. | 314 | * c should contain the Cb and Cr data for the two lines of Y back to back. |
312 | * Needs EMAC set to saturated, signed integer mode. | 315 | * Needs EMAC set to saturated, signed integer mode. |
313 | */ | 316 | */ |
314 | extern void lcd_write_yuv420_lines(const unsigned char *y, | 317 | extern void lcd_write_yuv420_lines(const unsigned char *y, |
315 | const unsigned char *bu, | 318 | const unsigned char *c, int cwidth); |
316 | const unsigned char *rv, int width); | ||
317 | 319 | ||
318 | /* Performance function to blit a YUV bitmap directly to the LCD | 320 | /* Performance function to blit a YUV bitmap directly to the LCD |
319 | * src_x, src_y, width and height should be even | 321 | * src_x, src_y, width and height should be even |
@@ -325,8 +327,7 @@ void lcd_yuv_blit(unsigned char * const src[3], | |||
325 | { | 327 | { |
326 | /* IRAM Y, Cb and Cb buffers. */ | 328 | /* IRAM Y, Cb and Cb buffers. */ |
327 | unsigned char y_ibuf[LCD_WIDTH*2]; | 329 | unsigned char y_ibuf[LCD_WIDTH*2]; |
328 | unsigned char bu_ibuf[LCD_WIDTH/2]; | 330 | unsigned char c_ibuf[LCD_WIDTH]; |
329 | unsigned char rv_ibuf[LCD_WIDTH/2]; | ||
330 | const unsigned char *ysrc, *usrc, *vsrc; | 331 | const unsigned char *ysrc, *usrc, *vsrc; |
331 | const unsigned char *ysrc_max; | 332 | const unsigned char *ysrc_max; |
332 | 333 | ||
@@ -336,11 +337,9 @@ void lcd_yuv_blit(unsigned char * const src[3], | |||
336 | width &= ~1; /* stay on the safe side */ | 337 | width &= ~1; /* stay on the safe side */ |
337 | height &= ~1; | 338 | height &= ~1; |
338 | 339 | ||
340 | lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_HORZ); | ||
339 | /* Set start position and window */ | 341 | /* Set start position and window */ |
340 | lcd_write_reg(R_VERT_RAM_ADDR_POS,((x+xoffset+width-1) << 8) | (x+xoffset)); | 342 | lcd_write_reg(R_VERT_RAM_ADDR_POS, ((xoffset + 219) << 8) | xoffset); |
341 | lcd_write_reg(R_RAM_ADDR_SET, ((x+xoffset) << 8) | y); | ||
342 | |||
343 | lcd_begin_write_gram(); | ||
344 | 343 | ||
345 | ysrc = src[0] + src_y * stride + src_x; | 344 | ysrc = src[0] + src_y * stride + src_x; |
346 | usrc = src[1] + (src_y * stride >> 2) + (src_x >> 1); | 345 | usrc = src[1] + (src_y * stride >> 2) + (src_x >> 1); |
@@ -350,11 +349,17 @@ void lcd_yuv_blit(unsigned char * const src[3], | |||
350 | coldfire_set_macsr(EMAC_SATURATE); | 349 | coldfire_set_macsr(EMAC_SATURATE); |
351 | do | 350 | do |
352 | { | 351 | { |
353 | memcpy(y_ibuf, ysrc, width); | 352 | lcd_write_reg(R_HORIZ_RAM_ADDR_POS, ((y + 1) << 8) | y); |
354 | memcpy(y_ibuf + width, ysrc + stride, width); | 353 | lcd_write_reg(R_RAM_ADDR_SET, ((x+xoffset) << 8) | y); |
355 | memcpy(bu_ibuf, usrc, width >> 1); | 354 | lcd_begin_write_gram(); |
356 | memcpy(rv_ibuf, vsrc, width >> 1); | 355 | |
357 | lcd_write_yuv420_lines(y_ibuf, bu_ibuf, rv_ibuf, width); | 356 | memcpy(y_ibuf + width, ysrc, width); |
357 | memcpy(y_ibuf, ysrc + stride, width); | ||
358 | memcpy(c_ibuf, usrc, width >> 1); | ||
359 | memcpy(c_ibuf + (width >> 1), vsrc, width >> 1); | ||
360 | lcd_write_yuv420_lines(y_ibuf, c_ibuf, width >> 1); | ||
361 | |||
362 | y += 2; | ||
358 | ysrc += 2 * stride; | 363 | ysrc += 2 * stride; |
359 | usrc += stride >> 1; | 364 | usrc += stride >> 1; |
360 | vsrc += stride >> 1; | 365 | vsrc += stride >> 1; |
@@ -368,11 +373,12 @@ void lcd_update(void) ICODE_ATTR; | |||
368 | void lcd_update(void) | 373 | void lcd_update(void) |
369 | { | 374 | { |
370 | if(display_on){ | 375 | if(display_on){ |
371 | /* reset update window */ | 376 | lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_VERT); |
377 | /* set start position window */ | ||
378 | lcd_write_reg(R_HORIZ_RAM_ADDR_POS, 175 << 8); | ||
372 | lcd_write_reg(R_VERT_RAM_ADDR_POS,((xoffset+219)<<8) | xoffset); | 379 | lcd_write_reg(R_VERT_RAM_ADDR_POS,((xoffset+219)<<8) | xoffset); |
373 | |||
374 | /* Copy display bitmap to hardware */ | ||
375 | lcd_write_reg(R_RAM_ADDR_SET, xoffset << 8); | 380 | lcd_write_reg(R_RAM_ADDR_SET, xoffset << 8); |
381 | |||
376 | lcd_begin_write_gram(); | 382 | lcd_begin_write_gram(); |
377 | 383 | ||
378 | DAR3 = 0xf0000002; | 384 | DAR3 = 0xf0000002; |
@@ -403,8 +409,9 @@ void lcd_update_rect(int x, int y, int width, int height) | |||
403 | if(y + height > LCD_HEIGHT) | 409 | if(y + height > LCD_HEIGHT) |
404 | height = LCD_HEIGHT - y; | 410 | height = LCD_HEIGHT - y; |
405 | 411 | ||
412 | lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_VERT); | ||
406 | /* set update window */ | 413 | /* set update window */ |
407 | 414 | lcd_write_reg(R_HORIZ_RAM_ADDR_POS, 175 << 8); | |
408 | lcd_write_reg(R_VERT_RAM_ADDR_POS,((x+xoffset+width-1) << 8) | (x+xoffset)); | 415 | lcd_write_reg(R_VERT_RAM_ADDR_POS,((x+xoffset+width-1) << 8) | (x+xoffset)); |
409 | lcd_write_reg(R_RAM_ADDR_SET, ((x+xoffset) << 8) | y); | 416 | lcd_write_reg(R_RAM_ADDR_SET, ((x+xoffset) << 8) | y); |
410 | lcd_begin_write_gram(); | 417 | lcd_begin_write_gram(); |