summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/export/dm320.h18
-rw-r--r--firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c312
2 files changed, 299 insertions, 31 deletions
diff --git a/firmware/export/dm320.h b/firmware/export/dm320.h
index 619a77fb9a..f78fc6c6d6 100644
--- a/firmware/export/dm320.h
+++ b/firmware/export/dm320.h
@@ -43,6 +43,9 @@ extern unsigned long _ttbstart;
43#define PHY_IO_BASE2 0x00060000 43#define PHY_IO_BASE2 0x00060000
44#define DM320_REG2(addr) (*(volatile unsigned int *)(PHY_IO_BASE2 + (addr))) 44#define DM320_REG2(addr) (*(volatile unsigned int *)(PHY_IO_BASE2 + (addr)))
45 45
46#define COP_IO_BASE 0x00090000
47#define DM320_COP(addr) (*(volatile unsigned short *)(COP_IO_BASE + (addr)))
48
46/* This needs to be 2048 byte aligned, but USB_QHARRAY_ATTR should take care 49/* This needs to be 2048 byte aligned, but USB_QHARRAY_ATTR should take care
47 * of that */ 50 * of that */
48#define USB_QHARRAY_ATTR __attribute__((section(".qharray"),nocommon,aligned(4))) 51#define USB_QHARRAY_ATTR __attribute__((section(".qharray"),nocommon,aligned(4)))
@@ -708,6 +711,21 @@ extern unsigned long _ttbstart;
708#define VL_INTVEC30_R DM320_REG2(0x03e0) 711#define VL_INTVEC30_R DM320_REG2(0x03e0)
709#define VL_INTVEC74_R DM320_REG2(0x03e4) 712#define VL_INTVEC74_R DM320_REG2(0x03e4)
710 713
714/* Coprocessor Interface */
715#define COP_SDEM_ADDRH DM320_COP(0xe000)
716#define COP_SDEM_ADDRL DM320_COP(0xe002)
717#define COP_SDEM_LOFST DM320_COP(0xe004)
718#define COP_BUF_ADDR DM320_COP(0xe006)
719#define COP_BUF_LOFST DM320_COP(0xe008)
720#define COP_DMA_XNUM DM320_COP(0xe00a)
721#define COP_DMA_YNUM DM320_COP(0xe00c)
722#define COP_DMA_CTRL DM320_COP(0xe00e)
723#define COP_BUF_MUX0 DM320_COP(0xe010)
724#define COP_BUF_MUX1 DM320_COP(0xe012)
725#define COP_IMG_MODE DM320_COP(0xe014)
726#define COP_CP_CLKC DM320_COP(0xe502)
727
728
711/* Taken from linux/include/asm-arm/arch-itdm320/irqs.h 729/* Taken from linux/include/asm-arm/arch-itdm320/irqs.h
712 * 730 *
713 * Copyright (C) 1999 ARM Limited 731 * Copyright (C) 1999 ARM Limited
diff --git a/firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c b/firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c
index 1e4bb85de6..ea723c1dee 100644
--- a/firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c
+++ b/firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c
@@ -30,6 +30,17 @@
30#include "system-target.h" 30#include "system-target.h"
31#include "lcd.h" 31#include "lcd.h"
32#include "lcd-target.h" 32#include "lcd-target.h"
33#include "dsp-target.h"
34#include "dsp/ipc.h"
35
36#if CONFIG_ORIENTATION == SCREEN_PORTRAIT
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
33 44
34/* Copies a rectangle from one framebuffer to another. Can be used in 45/* Copies a rectangle from one framebuffer to another. Can be used in
35 single transfer mode with width = num pixels, and height = 1 which 46 single transfer mode with width = num pixels, and height = 1 which
@@ -260,11 +271,206 @@ void lcd_set_mode(int mode)
260} 271}
261#endif 272#endif
262 273
274#if defined(PORTRAIT_USE_DMA)
275static void dma_start_transfer16( char *src, char *dst, int stride,
276 int width, int height, int pix_width)
277 __attribute__ ((section(".icode")));
278
279static void dma_start_transfer16( char *src, char *dst, int stride,
280 int width, int height, int pix_width) {
281 int c_width = width;
282
283 /* Addresses are relative to start of SDRAM */
284 src-=CONFIG_SDRAM_START;
285 dst-=CONFIG_SDRAM_START;
286
287 /* Enable Clocks */
288 IO_CLK_MOD1 |= 1<<8;
289 COP_CP_CLKC |= 0x0001;
290
291 /* ... */
292 COP_BUF_MUX1 = 0x0005;
293 /* Give the DMA access to the buffer */
294 COP_BUF_MUX0 = 0x0663;
295
296 /* Setup buffer offsets and transfer width/height */
297 COP_BUF_LOFST = 32;
298 COP_DMA_XNUM = 32;
299 COP_DMA_YNUM = 32;
300
301 /* ... */
302 COP_IMG_MODE = 0x0000;
303
304 /* Set the start address of buffer */
305 COP_BUF_ADDR = 0x0000;
306
307 /* Setup SDRAM stride */
308 COP_SDEM_LOFST = stride;
309 do {
310 do {
311 int addr;
312 addr = (int)src;
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
345 /* Reset the width, update pointers/counters */
346 c_width = width;
347 src -= width*pix_width;
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)
357static 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
363 if(sx2 & 0x0F) {
364 sx2 = (sx2 + 0x0F) & ~0x0F;
365 }
366 sx = sx & ~0x0F;
367
368 width = sx2 - sx;
369 }
370
371 if(sy & 0x0F) {
372 int sy2 = sy + height;
373
374 if(sy2 & 0x0F) {
375 sy2 = (sy2 + 0x0F) & ~0x0F;
376 }
377 sy = sy & ~0x0F;
378
379 height = sy2 - sy;
380 }
381
382 if(dx & 0x0F) {
383 dx = dx & ~0x0F;
384 }
385
386 if(dy & 0x0F) {
387 dy = dy & ~0x0F;
388 }
389
390 src=src+(sy*sstride+sx)*pix_width;
391
392 dst=dst + ((LCD_NATIVE_WIDTH*(LCD_NATIVE_HEIGHT-1))
393 - LCD_NATIVE_WIDTH*(dx+32) + dy)*pix_width;
394
395 int c_width = width;
396
397 IO_CLK_MOD1 |= 1<<8;
398
399 COP_CP_CLKC |= 0x0001;
400
401 COP_BUF_MUX1 = 0x0005;
402 /* Give the DMA access to the buffer */
403 COP_BUF_MUX0 = 0x0663;
404
405 /* Set the buffer offsets and widths */
406 COP_BUF_LOFST = 32;
407 COP_DMA_XNUM = 32;
408 COP_DMA_YNUM = 32;
409 COP_IMG_MODE = 0x0000;
410
411 do {
412 char *c_dst = dst;
413 do {
414 int addr;
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
461 c_width = width;
462 src += (LCD_WIDTH*31*pix_width);
463 dst += (32*pix_width);
464 height -= 32;
465 } while(height>0);
466}
467#endif
468
263/* Update a fraction of the display. */ 469/* Update a fraction of the display. */
470void lcd_update_rect(int x, int y, int width, int height)
471 __attribute__ ((section(".icode")));
264void lcd_update_rect(int x, int y, int width, int height) 472void lcd_update_rect(int x, int y, int width, int height)
265{ 473{
266 register fb_data *dst, *src;
267
268 if (!lcd_on) 474 if (!lcd_on)
269 return; 475 return;
270 476
@@ -281,76 +487,120 @@ void lcd_update_rect(int x, int y, int width, int height)
281 if (y < 0) 487 if (y < 0)
282 height += y, y = 0; /* Clip top */ 488 height += y, y = 0; /* Clip top */
283 489
490#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;
284 517
285 src = &lcd_framebuffer[y][x]; 518 dst = (fb_data *)FRAME + LCD_WIDTH*y + x;
519
520 dma_start_transfer16( (char *)&lcd_framebuffer[y][x],(char *)dst,
521 LCD_WIDTH, width, height, 2);
522#else
523 register fb_data *dst;
286 524
287#if CONFIG_ORIENTATION == SCREEN_PORTRAIT
288 dst = (fb_data *)FRAME + LCD_WIDTH*y + x; 525 dst = (fb_data *)FRAME + LCD_WIDTH*y + x;
289 526
290 /* Copy part of the Rockbox framebuffer to the second framebuffer */ 527 /* Copy part of the Rockbox framebuffer to the second framebuffer */
291 if (width < LCD_WIDTH) 528 if (width < LCD_WIDTH)
292 { 529 {
293 /* Not full width - do line-by-line */ 530 /* Not full width - do line-by-line */
294 lcd_copy_buffer_rect(dst, src, width, height); 531 lcd_copy_buffer_rect(dst, &lcd_framebuffer[y][x], width, height);
295 } 532 }
296 else 533 else
297 { 534 {
298 /* Full width - copy as one line */ 535 /* Full width - copy as one line */
299 lcd_copy_buffer_rect(dst, src, LCD_WIDTH*height, 1); 536 lcd_copy_buffer_rect(dst, &lcd_framebuffer[y][x], LCD_WIDTH*height, 1);
300 } 537 }
538#endif
301#else 539#else
540#if defined(LANDSCAPE_USE_DMA)
541 dma_start_transfer16_r( (char *)lcd_framebuffer, 0, 0, LCD_WIDTH,
542 (char *)FRAME, 0, 0, LCD_NATIVE_WIDTH,
543 LCD_WIDTH, LCD_HEIGHT, 2);
544#else
545 register fb_data *dst, *src;
546 src = &lcd_framebuffer[y][x];
547
302 dst=FRAME + (LCD_NATIVE_WIDTH*(LCD_NATIVE_HEIGHT-1)) 548 dst=FRAME + (LCD_NATIVE_WIDTH*(LCD_NATIVE_HEIGHT-1))
303 - LCD_NATIVE_WIDTH*x + y ; 549 - LCD_NATIVE_WIDTH*x + y ;
304 550
305 while(height--) 551 height--;
306 { 552 do {
307 register int c_width=width; 553 register int c_width=width-1;
308 register fb_data *c_dst=dst; 554 register fb_data *c_dst=dst;
309 555
310 while(c_width--) 556 do {
311 {
312 *c_dst=*src++; 557 *c_dst=*src++;
313 c_dst-=LCD_NATIVE_WIDTH; 558 c_dst-=LCD_NATIVE_WIDTH;
314 } 559 } while(c_width--);
315 560
316 src+=LCD_WIDTH-width; 561 src+=LCD_WIDTH-width;
317 dst++; 562 dst++;
318 } 563 } while(height--);
319 564#endif
320#endif 565#endif
321} 566}
322 567
323/* Update the display. 568/* Update the display.
324 This must be called after all other LCD functions that change the display. */ 569 This must be called after all other LCD functions that change the display. */
570void lcd_update(void) __attribute__ ((section(".icode")));
325void lcd_update(void) 571void lcd_update(void)
326{ 572{
327 if (!lcd_on) 573 if (!lcd_on)
328 return; 574 return;
329 575
330#if CONFIG_ORIENTATION == SCREEN_PORTRAIT
331 lcd_copy_buffer_rect((fb_data *)FRAME, &lcd_framebuffer[0][0],
332 LCD_WIDTH*LCD_HEIGHT, 1);
333#else
334 lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); 576 lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
335#endif
336} 577}
337 578
338#if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256) 579#if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
339void lcd_blit_pal256(unsigned char *src, int src_x, int src_y, int x, int y, 580void lcd_blit_pal256(unsigned char *src, int src_x, int src_y, int x, int y,
581 int width, int height) __attribute__ ((section(".icode")));
582void lcd_blit_pal256(unsigned char *src, int src_x, int src_y, int x, int y,
340 int width, int height) 583 int width, int height)
341{ 584{
342#if CONFIG_ORIENTATION == SCREEN_PORTRAIT 585#if CONFIG_ORIENTATION == SCREEN_PORTRAIT
343 char *dst=(char *)FRAME+x+y*(LCD_NATIVE_WIDTH+LCD_FUDGE); 586#if defined(PORTRAIT_USE_DMA)
344 587 src = src+src_x+src_y*LCD_WIDTH;
345 src = src+src_x+src_y*LCD_WIDTH; 588 char *dst=(char *)FRAME+x+y*(LCD_NATIVE_WIDTH+LCD_FUDGE);
346 while(height--) 589
347 { 590 dma_start_transfer16( (char *)src, (char *)dst, LCD_WIDTH>>1,
348 memcpy(dst, src, width); 591 width, height, 1);
349 592#else
350 dst = dst + ((LCD_WIDTH -x +LCD_FUDGE)); 593 char *dst=(char *)FRAME+x+y*(LCD_NATIVE_WIDTH+LCD_FUDGE);
351 src = src + (LCD_WIDTH - x); 594
352 } 595 src = src+src_x+src_y*LCD_WIDTH;
353 596 while(height--)
597 {
598 memcpy(dst, src, width);
599
600 dst = dst + ((LCD_WIDTH -x +LCD_FUDGE));
601 src = src + (LCD_WIDTH - x);
602 }
603#endif
354#else 604#else
355 char *dst=(char *)FRAME 605 char *dst=(char *)FRAME
356 + (LCD_NATIVE_WIDTH+LCD_FUDGE)*(LCD_NATIVE_HEIGHT-1) 606 + (LCD_NATIVE_WIDTH+LCD_FUDGE)*(LCD_NATIVE_HEIGHT-1)