summaryrefslogtreecommitdiff
path: root/firmware/target/arm/iriver/h10/lcd-h10_5gb.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/iriver/h10/lcd-h10_5gb.c')
-rw-r--r--firmware/target/arm/iriver/h10/lcd-h10_5gb.c114
1 files changed, 75 insertions, 39 deletions
diff --git a/firmware/target/arm/iriver/h10/lcd-h10_5gb.c b/firmware/target/arm/iriver/h10/lcd-h10_5gb.c
index 669654f5c3..5b022e09c5 100644
--- a/firmware/target/arm/iriver/h10/lcd-h10_5gb.c
+++ b/firmware/target/arm/iriver/h10/lcd-h10_5gb.c
@@ -108,7 +108,6 @@ void lcd_init_device(void)
108{ 108{
109 CLCD_CLOCK_SRC |= 0xc0000000; /* Set LCD interface clock to PLL */ 109 CLCD_CLOCK_SRC |= 0xc0000000; /* Set LCD interface clock to PLL */
110 /* H10 LCD is initialised by the bootloader */ 110 /* H10 LCD is initialised by the bootloader */
111 lcd_write_reg(R_ENTRY_MODE, 0x1030); /* BGR =1, ID1 = 1, ID0 = 1 */
112} 111}
113 112
114/*** update functions ***/ 113/*** update functions ***/
@@ -276,51 +275,88 @@ void lcd_blit_yuv(unsigned char * const src[3],
276 275
277 276
278/* Update a fraction of the display. */ 277/* Update a fraction of the display. */
279void lcd_update_rect(int x, int y, int width, int height) 278void lcd_update_rect(int x0, int y0, int width, int height)
280{ 279{
281 const fb_data *addr; 280 int x1, y1;
282 int bytes_to_write; 281 int newx,newwidth;
283 282 unsigned long *addr;
284 if (x + width >= LCD_WIDTH)
285 width = LCD_WIDTH - x;
286 if (y + height >= LCD_HEIGHT)
287 height = LCD_HEIGHT - y;
288
289 if ((width <= 0) || (height <= 0))
290 return; /* Nothing left to do. 0 would hang the transfer. */
291
292 /* Ensure x and width are both even, so we can read
293 * 32-bit aligned data from the framebuffer */
294 width = (width + (x & 1) + 1) & ~1;
295 x &= ~1;
296
297 lcd_write_reg(R_VERT_RAM_ADDR_POS, (LCD_HEIGHT-1) << 8);
298 lcd_write_reg(R_HORIZ_RAM_ADDR_POS, ((x + width - 1) << 8) | x);
299 lcd_write_reg(R_RAM_ADDR_SET, (y << 8) | x);
300 283
284 /* Ensure x and width are both even - so we can read 32-bit aligned
285 data from lcd_framebuffer */
286 newx=x0&~1;
287 newwidth=width&~1;
288 if (newx+newwidth < x0+width) { newwidth+=2; }
289 x0=newx; width=newwidth;
290
291 /* calculate the drawing region */
292 y1 = (y0 + height) - 1; /* max vert */
293 x1 = (x0 + width) - 1; /* max horiz */
294
295
296 /* swap max horiz < start horiz */
297 if (y1 < y0) {
298 int t;
299 t = y0;
300 y0 = y1;
301 y1 = t;
302 }
303
304 /* swap max vert < start vert */
305 if (x1 < x0) {
306 int t;
307 t = x0;
308 x0 = x1;
309 x1 = t;
310 }
311
312 /* max horiz << 8 | start horiz */
313 lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (x1 << 8) | x0);
314
315 /* max vert << 8 | start vert */
316 lcd_write_reg(R_VERT_RAM_ADDR_POS, (y1 << 8) | y0);
317
318 /* start vert << 8 | start horiz */
319 lcd_write_reg(R_RAM_ADDR_SET, (y0 << 8) | x0);
320
321 /* start drawing */
301 lcd_send_cmd(R_WRITE_DATA_2_GRAM); 322 lcd_send_cmd(R_WRITE_DATA_2_GRAM);
302 323
303 addr = &lcd_framebuffer[y][x]; 324 addr = (unsigned long*)&lcd_framebuffer[y0][x0];
304 bytes_to_write = width * height * sizeof(fb_data);
305 /* must be <= 0x10000, but that's guaranteed on H10. */
306 325
307 LCD2_BLOCK_CTRL = 0x10000080; 326 while (height > 0) {
308 LCD2_BLOCK_CONFIG = 0xc0010000 | (bytes_to_write - 1); 327 int c, r;
309 LCD2_BLOCK_CTRL = 0x34000000; 328 int h, pixels_to_write;
310 329
311 do 330 pixels_to_write = (width * height) * 2;
312 { 331 h = height;
313 int w = width >> 1; 332
314 do 333 /* calculate how much we can do in one go */
315 { 334 if (pixels_to_write > 0x10000) {
316 while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_TXOK)); 335 h = (0x10000/2) / width;
317 LCD2_BLOCK_DATA = *(unsigned long*)addr; /* output 2 pixels */ 336 pixels_to_write = (width * h) * 2;
318 addr += 2;
319 } 337 }
320 while (--w > 0); 338
321 addr += LCD_WIDTH - width; 339 LCD2_BLOCK_CTRL = 0x10000080;
340 LCD2_BLOCK_CONFIG = 0xc0010000 | (pixels_to_write - 1);
341 LCD2_BLOCK_CTRL = 0x34000000;
342
343 /* for each row */
344 for (r = 0; r < h; r++) {
345 /* for each column */
346 for (c = 0; c < width; c += 2) {
347 while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_TXOK));
348
349 /* output 2 pixels */
350 LCD2_BLOCK_DATA = *addr++;
351 }
352 addr += (LCD_WIDTH - width)/2;
353 }
354
355 while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_READY));
356 LCD2_BLOCK_CONFIG = 0;
357
358 height -= h;
322 } 359 }
323 while (--height > 0);
324} 360}
325 361
326/* Update the display. 362/* Update the display.