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, 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. */ |
279 | void lcd_update_rect(int x, int y, int width, int height) | 278 | void 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. |