diff options
Diffstat (limited to 'firmware/target/arm')
-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 5b022e09c5..669654f5c3 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 ***/ |
@@ -275,88 +276,51 @@ void lcd_blit_yuv(unsigned char * const src[3], | |||
275 | 276 | ||
276 | 277 | ||
277 | /* Update a fraction of the display. */ | 278 | /* Update a fraction of the display. */ |
278 | void lcd_update_rect(int x0, int y0, int width, int height) | 279 | void lcd_update_rect(int x, int y, int width, int height) |
279 | { | 280 | { |
280 | int x1, y1; | 281 | const fb_data *addr; |
281 | int newx,newwidth; | 282 | int bytes_to_write; |
282 | unsigned long *addr; | 283 | |
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); | ||
283 | 300 | ||
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 */ | ||
322 | lcd_send_cmd(R_WRITE_DATA_2_GRAM); | 301 | lcd_send_cmd(R_WRITE_DATA_2_GRAM); |
323 | 302 | ||
324 | addr = (unsigned long*)&lcd_framebuffer[y0][x0]; | 303 | addr = &lcd_framebuffer[y][x]; |
325 | 304 | bytes_to_write = width * height * sizeof(fb_data); | |
326 | while (height > 0) { | 305 | /* must be <= 0x10000, but that's guaranteed on H10. */ |
327 | int c, r; | ||
328 | int h, pixels_to_write; | ||
329 | |||
330 | pixels_to_write = (width * height) * 2; | ||
331 | h = height; | ||
332 | |||
333 | /* calculate how much we can do in one go */ | ||
334 | if (pixels_to_write > 0x10000) { | ||
335 | h = (0x10000/2) / width; | ||
336 | pixels_to_write = (width * h) * 2; | ||
337 | } | ||
338 | |||
339 | LCD2_BLOCK_CTRL = 0x10000080; | ||
340 | LCD2_BLOCK_CONFIG = 0xc0010000 | (pixels_to_write - 1); | ||
341 | LCD2_BLOCK_CTRL = 0x34000000; | ||
342 | 306 | ||
343 | /* for each row */ | 307 | LCD2_BLOCK_CTRL = 0x10000080; |
344 | for (r = 0; r < h; r++) { | 308 | LCD2_BLOCK_CONFIG = 0xc0010000 | (bytes_to_write - 1); |
345 | /* for each column */ | 309 | LCD2_BLOCK_CTRL = 0x34000000; |
346 | for (c = 0; c < width; c += 2) { | 310 | |
347 | while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_TXOK)); | 311 | do |
348 | 312 | { | |
349 | /* output 2 pixels */ | 313 | int w = width >> 1; |
350 | LCD2_BLOCK_DATA = *addr++; | 314 | do |
351 | } | 315 | { |
352 | addr += (LCD_WIDTH - width)/2; | 316 | while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_TXOK)); |
317 | LCD2_BLOCK_DATA = *(unsigned long*)addr; /* output 2 pixels */ | ||
318 | addr += 2; | ||
353 | } | 319 | } |
354 | 320 | while (--w > 0); | |
355 | while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_READY)); | 321 | addr += LCD_WIDTH - width; |
356 | LCD2_BLOCK_CONFIG = 0; | ||
357 | |||
358 | height -= h; | ||
359 | } | 322 | } |
323 | while (--height > 0); | ||
360 | } | 324 | } |
361 | 325 | ||
362 | /* Update the display. | 326 | /* Update the display. |