diff options
Diffstat (limited to 'firmware/target/arm/iriver/h10')
-rw-r--r-- | firmware/target/arm/iriver/h10/lcd-h10_5gb.c | 114 |
1 files changed, 39 insertions, 75 deletions
diff --git a/firmware/target/arm/iriver/h10/lcd-h10_5gb.c b/firmware/target/arm/iriver/h10/lcd-h10_5gb.c index 8972fd1e9c..680d2c47a5 100644 --- a/firmware/target/arm/iriver/h10/lcd-h10_5gb.c +++ b/firmware/target/arm/iriver/h10/lcd-h10_5gb.c | |||
@@ -108,6 +108,7 @@ 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 */ | ||
111 | } | 112 | } |
112 | 113 | ||
113 | /*** update functions ***/ | 114 | /*** update functions ***/ |
@@ -289,88 +290,51 @@ void lcd_yuv_blit(unsigned char * const src[3], | |||
289 | 290 | ||
290 | 291 | ||
291 | /* Update a fraction of the display. */ | 292 | /* Update a fraction of the display. */ |
292 | void lcd_update_rect(int x0, int y0, int width, int height) | 293 | void lcd_update_rect(int x, int y, int width, int height) |
293 | { | 294 | { |
294 | int x1, y1; | 295 | const fb_data *addr; |
295 | int newx,newwidth; | 296 | int bytes_to_write; |
296 | unsigned long *addr; | 297 | |
298 | if (x + width >= LCD_WIDTH) | ||
299 | width = LCD_WIDTH - x; | ||
300 | if (y + height >= LCD_HEIGHT) | ||
301 | height = LCD_HEIGHT - y; | ||
302 | |||
303 | if ((width <= 0) || (height <= 0)) | ||
304 | return; /* Nothing left to do. 0 would hang the transfer. */ | ||
305 | |||
306 | /* Ensure x and width are both even, so we can read | ||
307 | * 32-bit aligned data from the framebuffer */ | ||
308 | width = (width + (x & 1) + 1) & ~1; | ||
309 | x &= ~1; | ||
310 | |||
311 | lcd_write_reg(R_VERT_RAM_ADDR_POS, (LCD_HEIGHT-1) << 8); | ||
312 | lcd_write_reg(R_HORIZ_RAM_ADDR_POS, ((x + width - 1) << 8) | x); | ||
313 | lcd_write_reg(R_RAM_ADDR_SET, (y << 8) | x); | ||
297 | 314 | ||
298 | /* Ensure x and width are both even - so we can read 32-bit aligned | ||
299 | data from lcd_framebuffer */ | ||
300 | newx=x0&~1; | ||
301 | newwidth=width&~1; | ||
302 | if (newx+newwidth < x0+width) { newwidth+=2; } | ||
303 | x0=newx; width=newwidth; | ||
304 | |||
305 | /* calculate the drawing region */ | ||
306 | y1 = (y0 + height) - 1; /* max vert */ | ||
307 | x1 = (x0 + width) - 1; /* max horiz */ | ||
308 | |||
309 | |||
310 | /* swap max horiz < start horiz */ | ||
311 | if (y1 < y0) { | ||
312 | int t; | ||
313 | t = y0; | ||
314 | y0 = y1; | ||
315 | y1 = t; | ||
316 | } | ||
317 | |||
318 | /* swap max vert < start vert */ | ||
319 | if (x1 < x0) { | ||
320 | int t; | ||
321 | t = x0; | ||
322 | x0 = x1; | ||
323 | x1 = t; | ||
324 | } | ||
325 | |||
326 | /* max horiz << 8 | start horiz */ | ||
327 | lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (x1 << 8) | x0); | ||
328 | |||
329 | /* max vert << 8 | start vert */ | ||
330 | lcd_write_reg(R_VERT_RAM_ADDR_POS, (y1 << 8) | y0); | ||
331 | |||
332 | /* start vert << 8 | start horiz */ | ||
333 | lcd_write_reg(R_RAM_ADDR_SET, (y0 << 8) | x0); | ||
334 | |||
335 | /* start drawing */ | ||
336 | lcd_send_cmd(R_WRITE_DATA_2_GRAM); | 315 | lcd_send_cmd(R_WRITE_DATA_2_GRAM); |
337 | 316 | ||
338 | addr = (unsigned long*)&lcd_framebuffer[y0][x0]; | 317 | addr = &lcd_framebuffer[y][x]; |
339 | 318 | bytes_to_write = width * height * sizeof(fb_data); | |
340 | while (height > 0) { | 319 | /* must be <= 0x10000, but that's guaranteed on H10. */ |
341 | int c, r; | ||
342 | int h, pixels_to_write; | ||
343 | |||
344 | pixels_to_write = (width * height) * 2; | ||
345 | h = height; | ||
346 | |||
347 | /* calculate how much we can do in one go */ | ||
348 | if (pixels_to_write > 0x10000) { | ||
349 | h = (0x10000/2) / width; | ||
350 | pixels_to_write = (width * h) * 2; | ||
351 | } | ||
352 | |||
353 | LCD2_BLOCK_CTRL = 0x10000080; | ||
354 | LCD2_BLOCK_CONFIG = 0xc0010000 | (pixels_to_write - 1); | ||
355 | LCD2_BLOCK_CTRL = 0x34000000; | ||
356 | 320 | ||
357 | /* for each row */ | 321 | LCD2_BLOCK_CTRL = 0x10000080; |
358 | for (r = 0; r < h; r++) { | 322 | LCD2_BLOCK_CONFIG = 0xc0010000 | (bytes_to_write - 1); |
359 | /* for each column */ | 323 | LCD2_BLOCK_CTRL = 0x34000000; |
360 | for (c = 0; c < width; c += 2) { | 324 | |
361 | while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_TXOK)); | 325 | do |
362 | 326 | { | |
363 | /* output 2 pixels */ | 327 | int w = width >> 1; |
364 | LCD2_BLOCK_DATA = *addr++; | 328 | do |
365 | } | 329 | { |
366 | addr += (LCD_WIDTH - width)/2; | 330 | while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_TXOK)); |
331 | LCD2_BLOCK_DATA = *(unsigned long*)addr; /* output 2 pixels */ | ||
332 | addr += 2; | ||
367 | } | 333 | } |
368 | 334 | while (--w > 0); | |
369 | while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_READY)); | 335 | addr += LCD_WIDTH - width; |
370 | LCD2_BLOCK_CONFIG = 0; | ||
371 | |||
372 | height -= h; | ||
373 | } | 336 | } |
337 | while (--height > 0); | ||
374 | } | 338 | } |
375 | 339 | ||
376 | /* Update the display. | 340 | /* Update the display. |