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