diff options
Diffstat (limited to 'firmware/target/arm')
-rw-r--r-- | firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c | 311 |
1 files changed, 113 insertions, 198 deletions
diff --git a/firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c b/firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c index ea723c1dee..fca2af0732 100644 --- a/firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c +++ b/firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c | |||
@@ -33,14 +33,7 @@ | |||
33 | #include "dsp-target.h" | 33 | #include "dsp-target.h" |
34 | #include "dsp/ipc.h" | 34 | #include "dsp/ipc.h" |
35 | 35 | ||
36 | #if CONFIG_ORIENTATION == SCREEN_PORTRAIT | 36 | #define LCD_USE_DMA |
37 | #define PORTRAIT_USE_DMA | ||
38 | #else | ||
39 | /* Very slow - May be faster if the DSP has lower latency access to buffer. | ||
40 | Using the DSP instead of ARM to do transformation has not been tried | ||
41 | */ | ||
42 | //#define LANDSCAPE_USE_DMA | ||
43 | #endif | ||
44 | 37 | ||
45 | /* Copies a rectangle from one framebuffer to another. Can be used in | 38 | /* Copies a rectangle from one framebuffer to another. Can be used in |
46 | single transfer mode with width = num pixels, and height = 1 which | 39 | single transfer mode with width = num pixels, and height = 1 which |
@@ -271,18 +264,21 @@ void lcd_set_mode(int mode) | |||
271 | } | 264 | } |
272 | #endif | 265 | #endif |
273 | 266 | ||
274 | #if defined(PORTRAIT_USE_DMA) | 267 | #if defined(LCD_USE_DMA) |
275 | static void dma_start_transfer16( char *src, char *dst, int stride, | 268 | static void dma_start_transfer16( char *src, int src_x, int src_y, int stride, |
276 | int width, int height, int pix_width) | 269 | int x, int y, |
270 | int width, int height, int pix_width) | ||
277 | __attribute__ ((section(".icode"))); | 271 | __attribute__ ((section(".icode"))); |
278 | 272 | #if CONFIG_ORIENTATION == SCREEN_PORTRAIT | |
279 | static void dma_start_transfer16( char *src, char *dst, int stride, | 273 | static void dma_start_transfer16( char *src, int src_x, int src_y, int stride, |
274 | int x, int y, | ||
280 | int width, int height, int pix_width) { | 275 | int width, int height, int pix_width) { |
281 | int c_width = width; | 276 | char *dst; |
282 | 277 | ||
283 | /* Addresses are relative to start of SDRAM */ | 278 | /* Addresses are relative to start of SDRAM */ |
284 | src-=CONFIG_SDRAM_START; | 279 | src = src + (src_y*LCD_HEIGHT + src_x) * pix_width - CONFIG_SDRAM_START; |
285 | dst-=CONFIG_SDRAM_START; | 280 | dst = (char *)FRAME + (y * LCD_HEIGHT + x) * pix_width |
281 | - CONFIG_SDRAM_START; | ||
286 | 282 | ||
287 | /* Enable Clocks */ | 283 | /* Enable Clocks */ |
288 | IO_CLK_MOD1 |= 1<<8; | 284 | IO_CLK_MOD1 |= 1<<8; |
@@ -294,9 +290,9 @@ static void dma_start_transfer16( char *src, char *dst, int stride, | |||
294 | COP_BUF_MUX0 = 0x0663; | 290 | COP_BUF_MUX0 = 0x0663; |
295 | 291 | ||
296 | /* Setup buffer offsets and transfer width/height */ | 292 | /* Setup buffer offsets and transfer width/height */ |
297 | COP_BUF_LOFST = 32; | 293 | COP_BUF_LOFST = width; |
298 | COP_DMA_XNUM = 32; | 294 | COP_DMA_XNUM = width; |
299 | COP_DMA_YNUM = 32; | 295 | COP_DMA_YNUM = 1; |
300 | 296 | ||
301 | /* ... */ | 297 | /* ... */ |
302 | COP_IMG_MODE = 0x0000; | 298 | COP_IMG_MODE = 0x0000; |
@@ -307,164 +303,109 @@ static void dma_start_transfer16( char *src, char *dst, int stride, | |||
307 | /* Setup SDRAM stride */ | 303 | /* Setup SDRAM stride */ |
308 | COP_SDEM_LOFST = stride; | 304 | COP_SDEM_LOFST = stride; |
309 | do { | 305 | do { |
310 | do { | 306 | int addr; |
311 | int addr; | 307 | addr = (int)src; |
312 | addr = (int)src; | 308 | addr >>= 1; /* Addresses are in 16-bit words */ |
313 | addr >>= 1; /* Addresses are in 16-bit words */ | ||
314 | |||
315 | /* Setup the registers to initiate the read from SDRAM */ | ||
316 | COP_SDEM_ADDRH = addr >> 16; | ||
317 | COP_SDEM_ADDRL = addr & 0xFFFF; | ||
318 | |||
319 | /* Set direction and start */ | ||
320 | COP_DMA_CTRL = 0x0001; | ||
321 | COP_DMA_CTRL |= 0x0003; | ||
322 | |||
323 | /* Wait for read to finish */ | ||
324 | while(COP_DMA_CTRL & 0x02) {}; | ||
325 | |||
326 | addr = (int)dst; | ||
327 | addr >>= 1; | ||
328 | |||
329 | COP_SDEM_ADDRH = addr >> 16; | ||
330 | COP_SDEM_ADDRL = addr & 0xFFFF; | ||
331 | |||
332 | /* Set direction and start transfer */ | ||
333 | COP_DMA_CTRL = 0x0000; | ||
334 | COP_DMA_CTRL = 0x0002; | ||
335 | |||
336 | /* Wait for the transfer to complete */ | ||
337 | while(COP_DMA_CTRL & 0x02) {}; | ||
338 | |||
339 | /* Update source and destination pointers/counters */ | ||
340 | src += 32*pix_width; | ||
341 | dst += 32*pix_width; | ||
342 | c_width -= 32; | ||
343 | } while (c_width>0); | ||
344 | 309 | ||
345 | /* Reset the width, update pointers/counters */ | 310 | /* Setup the registers to initiate the read from SDRAM */ |
346 | c_width = width; | 311 | COP_SDEM_ADDRH = addr >> 16; |
347 | src -= width*pix_width; | 312 | COP_SDEM_ADDRL = addr & 0xFFFF; |
348 | dst -= width*pix_width; | ||
349 | src += (LCD_WIDTH*32*pix_width); | ||
350 | dst += (LCD_WIDTH*32*pix_width); | ||
351 | height -= 32; | ||
352 | } while(height>0); | ||
353 | } | ||
354 | #endif | ||
355 | |||
356 | #if defined(LANDSCAPE_USE_DMA) | ||
357 | static void dma_start_transfer16_r( char *src, int sx, int sy, int sstride, | ||
358 | char *dst, int dx, int dy, int dstride, | ||
359 | int width, int height, int pix_width) { | ||
360 | if(sx & 0x0F) { | ||
361 | int sx2 = sx + width; | ||
362 | 313 | ||
363 | if(sx2 & 0x0F) { | 314 | /* Set direction and start */ |
364 | sx2 = (sx2 + 0x0F) & ~0x0F; | 315 | COP_DMA_CTRL = 0x0001; |
365 | } | 316 | COP_DMA_CTRL |= 0x0003; |
366 | sx = sx & ~0x0F; | ||
367 | 317 | ||
368 | width = sx2 - sx; | 318 | /* Wait for read to finish */ |
369 | } | 319 | while(COP_DMA_CTRL & 0x02) {}; |
370 | |||
371 | if(sy & 0x0F) { | ||
372 | int sy2 = sy + height; | ||
373 | 320 | ||
374 | if(sy2 & 0x0F) { | 321 | addr = (int)dst; |
375 | sy2 = (sy2 + 0x0F) & ~0x0F; | 322 | addr >>= 1; |
376 | } | ||
377 | sy = sy & ~0x0F; | ||
378 | 323 | ||
379 | height = sy2 - sy; | 324 | COP_SDEM_ADDRH = addr >> 16; |
380 | } | 325 | COP_SDEM_ADDRL = addr & 0xFFFF; |
381 | 326 | ||
382 | if(dx & 0x0F) { | 327 | /* Set direction and start transfer */ |
383 | dx = dx & ~0x0F; | 328 | COP_DMA_CTRL = 0x0000; |
384 | } | 329 | COP_DMA_CTRL = 0x0002; |
385 | 330 | ||
386 | if(dy & 0x0F) { | 331 | /* Wait for the transfer to complete */ |
387 | dy = dy & ~0x0F; | 332 | while(COP_DMA_CTRL & 0x02) {}; |
388 | } | 333 | |
389 | 334 | /* Decrease height, update pointers/counters */ | |
390 | src=src+(sy*sstride+sx)*pix_width; | 335 | src += (stride*pix_width); |
391 | 336 | dst += (stride*pix_width); | |
392 | dst=dst + ((LCD_NATIVE_WIDTH*(LCD_NATIVE_HEIGHT-1)) | 337 | height--; |
393 | - LCD_NATIVE_WIDTH*(dx+32) + dy)*pix_width; | 338 | } while(height>0); |
394 | 339 | } | |
395 | int c_width = width; | 340 | #else |
341 | static void dma_start_transfer16( char *src, int src_x, int src_y, int stride, | ||
342 | int x, int y, | ||
343 | int width, int height, int pix_width) { | ||
344 | char *dst; | ||
345 | /* Addresses are relative to start of SDRAM */ | ||
346 | src = src + (src_x*LCD_HEIGHT + src_y) * pix_width - CONFIG_SDRAM_START; | ||
347 | dst = (char *)FRAME + (LCD_HEIGHT*(LCD_WIDTH-1) - x * LCD_HEIGHT + y) | ||
348 | * pix_width - CONFIG_SDRAM_START; | ||
396 | 349 | ||
350 | /* Enable Clocks */ | ||
397 | IO_CLK_MOD1 |= 1<<8; | 351 | IO_CLK_MOD1 |= 1<<8; |
398 | |||
399 | COP_CP_CLKC |= 0x0001; | 352 | COP_CP_CLKC |= 0x0001; |
400 | 353 | ||
354 | /* ... */ | ||
401 | COP_BUF_MUX1 = 0x0005; | 355 | COP_BUF_MUX1 = 0x0005; |
402 | /* Give the DMA access to the buffer */ | 356 | /* Give the DMA access to the buffer */ |
403 | COP_BUF_MUX0 = 0x0663; | 357 | COP_BUF_MUX0 = 0x0663; |
404 | 358 | ||
405 | /* Set the buffer offsets and widths */ | 359 | /* Setup buffer offsets and transfer width/height */ |
406 | COP_BUF_LOFST = 32; | 360 | COP_BUF_LOFST = height; |
407 | COP_DMA_XNUM = 32; | 361 | COP_DMA_XNUM = height; |
408 | COP_DMA_YNUM = 32; | 362 | COP_DMA_YNUM = 1; |
363 | |||
364 | /* ... */ | ||
409 | COP_IMG_MODE = 0x0000; | 365 | COP_IMG_MODE = 0x0000; |
410 | 366 | ||
367 | /* Set the start address of buffer */ | ||
368 | COP_BUF_ADDR = 0x0000; | ||
369 | |||
370 | /* Setup SDRAM stride */ | ||
371 | COP_SDEM_LOFST = stride; | ||
411 | do { | 372 | do { |
412 | char *c_dst = dst; | 373 | int addr; |
413 | do { | 374 | addr = (int)src; |
414 | int addr; | 375 | addr >>= 1; /* Addresses are in 16-bit words */ |
415 | |||
416 | COP_BUF_ADDR = 0x0000; | ||
417 | |||
418 | COP_SDEM_LOFST = sstride; | ||
419 | addr = (int)src - CONFIG_SDRAM_START; | ||
420 | addr >>= 1; | ||
421 | |||
422 | COP_SDEM_ADDRH = addr >> 16; | ||
423 | COP_SDEM_ADDRL = addr & 0xFFFF; | ||
424 | |||
425 | COP_DMA_CTRL = 0x0001; | ||
426 | COP_DMA_CTRL |= 0x0003; | ||
427 | |||
428 | while(COP_DMA_CTRL & 0x02) {}; | ||
429 | |||
430 | /* The ARM can access the buffer after this is set */ | ||
431 | COP_BUF_MUX0 = 0x0660; | ||
432 | |||
433 | int run=1023; | ||
434 | #define IMG_BUF (*(volatile unsigned short *)(0x80000)) | ||
435 | #define IMG_BUF2 (*(volatile unsigned short *)(0x80000 + 2*32*32 + 32*31*2 )) | ||
436 | do { | ||
437 | *(&IMG_BUF2-((run&0x1F)<<5)+(run>>5)) = *(&IMG_BUF+run); | ||
438 | } while(run--); | ||
439 | |||
440 | COP_BUF_MUX0 = 0x0663; | ||
441 | |||
442 | COP_BUF_ADDR = (32*32); | ||
443 | |||
444 | COP_SDEM_LOFST = LCD_NATIVE_WIDTH; | ||
445 | addr = (int)c_dst - CONFIG_SDRAM_START; | ||
446 | addr >>= 1; | ||
447 | |||
448 | COP_SDEM_ADDRH = addr >> 16; | ||
449 | COP_SDEM_ADDRL = addr & 0xFFFF; | ||
450 | |||
451 | COP_DMA_CTRL = 0x0000; | ||
452 | COP_DMA_CTRL = 0x0002; | ||
453 | |||
454 | while(COP_DMA_CTRL & 0x02) {}; | ||
455 | |||
456 | src += 32*pix_width; | ||
457 | c_dst -= 32*pix_width*LCD_NATIVE_WIDTH; | ||
458 | c_width -= 32; | ||
459 | } while (c_width>0); | ||
460 | 376 | ||
461 | c_width = width; | 377 | /* Setup the registers to initiate the read from SDRAM */ |
462 | src += (LCD_WIDTH*31*pix_width); | 378 | COP_SDEM_ADDRH = addr >> 16; |
463 | dst += (32*pix_width); | 379 | COP_SDEM_ADDRL = addr & 0xFFFF; |
464 | height -= 32; | 380 | |
465 | } while(height>0); | 381 | /* Set direction and start */ |
382 | COP_DMA_CTRL = 0x0001; | ||
383 | COP_DMA_CTRL |= 0x0003; | ||
384 | |||
385 | /* Wait for read to finish */ | ||
386 | while(COP_DMA_CTRL & 0x02) {}; | ||
387 | |||
388 | addr = (int)dst; | ||
389 | addr >>= 1; | ||
390 | |||
391 | COP_SDEM_ADDRH = addr >> 16; | ||
392 | COP_SDEM_ADDRL = addr & 0xFFFF; | ||
393 | |||
394 | /* Set direction and start transfer */ | ||
395 | COP_DMA_CTRL = 0x0000; | ||
396 | COP_DMA_CTRL = 0x0002; | ||
397 | |||
398 | /* Wait for the transfer to complete */ | ||
399 | while(COP_DMA_CTRL & 0x02) {}; | ||
400 | |||
401 | /* update the width, update pointers/counters */ | ||
402 | src += (stride*pix_width); | ||
403 | dst -= (stride*pix_width); | ||
404 | width--; | ||
405 | } while(width>0); | ||
466 | } | 406 | } |
467 | #endif | 407 | #endif |
408 | #endif | ||
468 | 409 | ||
469 | /* Update a fraction of the display. */ | 410 | /* Update a fraction of the display. */ |
470 | void lcd_update_rect(int x, int y, int width, int height) | 411 | void lcd_update_rect(int x, int y, int width, int height) |
@@ -488,37 +429,10 @@ void lcd_update_rect(int x, int y, int width, int height) | |||
488 | height += y, y = 0; /* Clip top */ | 429 | height += y, y = 0; /* Clip top */ |
489 | 430 | ||
490 | #if CONFIG_ORIENTATION == SCREEN_PORTRAIT | 431 | #if CONFIG_ORIENTATION == SCREEN_PORTRAIT |
491 | #if defined(PORTRAIT_USE_DMA) | ||
492 | /* Makes sure the update is a ratio of 32x32 */ | ||
493 | if(x & 0x1F) { | ||
494 | int x2 = x + width; | ||
495 | |||
496 | if(x2 & 0x1F) { | ||
497 | x2 = (x2 + 0x1F) & ~0x1F; | ||
498 | } | ||
499 | x = x & ~0x1F; | ||
500 | |||
501 | width = x2 - x; | ||
502 | } | ||
503 | |||
504 | if(y & 0x1F) { | ||
505 | int y2 = y + height; | ||
506 | |||
507 | if(y2 & 0x1F) { | ||
508 | y2 += 0x1F; | ||
509 | y2 &= ~0x1F; | ||
510 | } | ||
511 | y = y & ~0x1F; | ||
512 | |||
513 | height = y2 - y; | ||
514 | } | ||
515 | |||
516 | fb_data *dst; | ||
517 | 432 | ||
518 | dst = (fb_data *)FRAME + LCD_WIDTH*y + x; | 433 | #if defined(LCD_USE_DMA) |
519 | 434 | dma_start_transfer16( (char *)lcd_framebuffer, x, y, LCD_WIDTH, | |
520 | dma_start_transfer16( (char *)&lcd_framebuffer[y][x],(char *)dst, | 435 | x, y, width, height, 2); |
521 | LCD_WIDTH, width, height, 2); | ||
522 | #else | 436 | #else |
523 | register fb_data *dst; | 437 | register fb_data *dst; |
524 | 438 | ||
@@ -536,11 +450,12 @@ void lcd_update_rect(int x, int y, int width, int height) | |||
536 | lcd_copy_buffer_rect(dst, &lcd_framebuffer[y][x], LCD_WIDTH*height, 1); | 450 | lcd_copy_buffer_rect(dst, &lcd_framebuffer[y][x], LCD_WIDTH*height, 1); |
537 | } | 451 | } |
538 | #endif | 452 | #endif |
453 | |||
539 | #else | 454 | #else |
540 | #if defined(LANDSCAPE_USE_DMA) | 455 | |
541 | dma_start_transfer16_r( (char *)lcd_framebuffer, 0, 0, LCD_WIDTH, | 456 | #if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE |
542 | (char *)FRAME, 0, 0, LCD_NATIVE_WIDTH, | 457 | dma_start_transfer16( (char *)lcd_framebuffer, x, y, LCD_HEIGHT, |
543 | LCD_WIDTH, LCD_HEIGHT, 2); | 458 | x, y, width, height, 2); |
544 | #else | 459 | #else |
545 | register fb_data *dst, *src; | 460 | register fb_data *dst, *src; |
546 | src = &lcd_framebuffer[y][x]; | 461 | src = &lcd_framebuffer[y][x]; |
@@ -562,6 +477,7 @@ void lcd_update_rect(int x, int y, int width, int height) | |||
562 | dst++; | 477 | dst++; |
563 | } while(height--); | 478 | } while(height--); |
564 | #endif | 479 | #endif |
480 | |||
565 | #endif | 481 | #endif |
566 | } | 482 | } |
567 | 483 | ||
@@ -583,12 +499,11 @@ void lcd_blit_pal256(unsigned char *src, int src_x, int src_y, int x, int y, | |||
583 | int width, int height) | 499 | int width, int height) |
584 | { | 500 | { |
585 | #if CONFIG_ORIENTATION == SCREEN_PORTRAIT | 501 | #if CONFIG_ORIENTATION == SCREEN_PORTRAIT |
586 | #if defined(PORTRAIT_USE_DMA) | 502 | #if defined(LCD_USE_DMA) |
587 | src = src+src_x+src_y*LCD_WIDTH; | 503 | // char *dst=(char *)FRAME+x+y*(LCD_NATIVE_WIDTH+LCD_FUDGE); |
588 | char *dst=(char *)FRAME+x+y*(LCD_NATIVE_WIDTH+LCD_FUDGE); | 504 | |
589 | 505 | dma_start_transfer16( src, src_x, src_y, LCD_WIDTH, | |
590 | dma_start_transfer16( (char *)src, (char *)dst, LCD_WIDTH>>1, | 506 | x, y, width, height, 1); |
591 | width, height, 1); | ||
592 | #else | 507 | #else |
593 | char *dst=(char *)FRAME+x+y*(LCD_NATIVE_WIDTH+LCD_FUDGE); | 508 | char *dst=(char *)FRAME+x+y*(LCD_NATIVE_WIDTH+LCD_FUDGE); |
594 | 509 | ||