summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Buren <braewoods+rb@braewoods.net>2020-11-12 14:02:23 +0000
committerWilliam Wilgus <me.theuser@yahoo.com>2020-11-13 18:08:01 +0000
commit8ac46f844f437a31f72d73a41a6d3852d8b96143 (patch)
tree7811361e2f0ab38a8479b2658f168dbb0dbf36c8
parent362f7a3220d6e3306f714d43c3fc5371abead712 (diff)
downloadrockbox-8ac46f844f437a31f72d73a41a6d3852d8b96143.tar.gz
rockbox-8ac46f844f437a31f72d73a41a6d3852d8b96143.zip
h300: fix one long-standing bootloader bug
This was introduced in e13c6001332882291363bdf2f1155875439fe187 back when the author was trying to optimize the LCD code with DMA. For whatever reason this broke the bootloader for the last 10 years or so and no one could figure out why. This is now fixed. However the bootloader is still currently broken in HEAD due to recent changes to the LCD code. A fix for that is not yet known. Change-Id: I046d53f9f391f558c391f2fadb6b260fe3be4d92
-rw-r--r--firmware/target/coldfire/iriver/h300/lcd-h300.c58
1 files changed, 56 insertions, 2 deletions
diff --git a/firmware/target/coldfire/iriver/h300/lcd-h300.c b/firmware/target/coldfire/iriver/h300/lcd-h300.c
index 312bd70ccc..c415ed6c37 100644
--- a/firmware/target/coldfire/iriver/h300/lcd-h300.c
+++ b/firmware/target/coldfire/iriver/h300/lcd-h300.c
@@ -35,11 +35,13 @@
35static bool display_on = false; /* Is the display turned on? */ 35static bool display_on = false; /* Is the display turned on? */
36static bool display_flipped = false; 36static bool display_flipped = false;
37static int xoffset = 0; /* Needed for flip */ 37static int xoffset = 0; /* Needed for flip */
38#ifndef BOOTLOADER
38static struct mutex lcd_mtx; /* The update functions use DMA and yield */ 39static struct mutex lcd_mtx; /* The update functions use DMA and yield */
39 40
40unsigned long dma_addr IBSS_ATTR; 41unsigned long dma_addr IBSS_ATTR;
41unsigned int dma_len IBSS_ATTR; 42unsigned int dma_len IBSS_ATTR;
42volatile int dma_count IBSS_ATTR; 43volatile int dma_count IBSS_ATTR;
44#endif
43 45
44/* register defines */ 46/* register defines */
45#define R_START_OSC 0x00 47#define R_START_OSC 0x00
@@ -139,9 +141,13 @@ void lcd_set_flip(bool yesno)
139 141
140 if (display_on) 142 if (display_on)
141 { 143 {
144#ifndef BOOTLOADER
142 mutex_lock(&lcd_mtx); 145 mutex_lock(&lcd_mtx);
146#endif
143 flip_lcd(yesno); 147 flip_lcd(yesno);
148#ifndef BOOTLOADER
144 mutex_unlock(&lcd_mtx); 149 mutex_unlock(&lcd_mtx);
150#endif
145 } 151 }
146} 152}
147 153
@@ -262,6 +268,7 @@ void lcd_init_device(void)
262 or_l(0x00004000, &GPIO1_OUT); 268 or_l(0x00004000, &GPIO1_OUT);
263 sleep(1); 269 sleep(1);
264 270
271#ifndef BOOTLOADER
265 DAR3 = 0xf0000002; /* Configure DMA channel 3 */ 272 DAR3 = 0xf0000002; /* Configure DMA channel 3 */
266 DSR3 = 1; 273 DSR3 = 1;
267 DIVR3 = 57; /* DMA3 is mapped into vector 57 in system.c */ 274 DIVR3 = 57; /* DMA3 is mapped into vector 57 in system.c */
@@ -269,6 +276,7 @@ void lcd_init_device(void)
269 coldfire_imr_mod(0, 1 << 17); 276 coldfire_imr_mod(0, 1 << 17);
270 277
271 mutex_init(&lcd_mtx); 278 mutex_init(&lcd_mtx);
279#endif
272 _display_on(); 280 _display_on();
273} 281}
274 282
@@ -276,7 +284,9 @@ void lcd_enable(bool on)
276{ 284{
277 if (display_on != on) 285 if (display_on != on)
278 { 286 {
287#ifndef BOOTLOADER
279 mutex_lock(&lcd_mtx); 288 mutex_lock(&lcd_mtx);
289#endif
280 if (on) 290 if (on)
281 { 291 {
282 _display_on(); 292 _display_on();
@@ -304,7 +314,9 @@ void lcd_enable(bool on)
304 314
305 display_on=false; 315 display_on=false;
306 } 316 }
317#ifndef BOOTLOADER
307 mutex_unlock(&lcd_mtx); 318 mutex_unlock(&lcd_mtx);
319#endif
308 } 320 }
309} 321}
310 322
@@ -340,7 +352,9 @@ void lcd_blit_yuv(unsigned char * const src[3],
340 if (!display_on) 352 if (!display_on)
341 return; 353 return;
342 354
355#ifndef BOOTLOADER
343 mutex_lock(&lcd_mtx); 356 mutex_lock(&lcd_mtx);
357#endif
344 width &= ~1; /* stay on the safe side */ 358 width &= ~1; /* stay on the safe side */
345 height &= ~1; 359 height &= ~1;
346 360
@@ -372,9 +386,12 @@ void lcd_blit_yuv(unsigned char * const src[3],
372 vsrc += stride >> 1; 386 vsrc += stride >> 1;
373 } 387 }
374 while (ysrc < ysrc_max); 388 while (ysrc < ysrc_max);
389#ifndef BOOTLOADER
375 mutex_unlock(&lcd_mtx); 390 mutex_unlock(&lcd_mtx);
391#endif
376} 392}
377 393
394#ifndef BOOTLOADER
378/* LCD DMA ISR */ 395/* LCD DMA ISR */
379void DMA3(void) __attribute__ ((interrupt_handler, section(".icode"))); 396void DMA3(void) __attribute__ ((interrupt_handler, section(".icode")));
380void DMA3(void) 397void DMA3(void)
@@ -390,6 +407,7 @@ void DMA3(void)
390 | DMA_DSIZE(DMA_SIZE_WORD) | DMA_START; 407 | DMA_DSIZE(DMA_SIZE_WORD) | DMA_START;
391 } 408 }
392} 409}
410#endif
393 411
394/* Update the display. 412/* Update the display.
395 This must be called after all other LCD functions that change the display. */ 413 This must be called after all other LCD functions that change the display. */
@@ -397,7 +415,9 @@ void lcd_update(void)
397{ 415{
398 if (display_on) 416 if (display_on)
399 { 417 {
418#ifndef BOOTLOADER
400 mutex_lock(&lcd_mtx); 419 mutex_lock(&lcd_mtx);
420#endif
401 421
402 lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_VERT); 422 lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_VERT);
403 /* set start position window */ 423 /* set start position window */
@@ -407,8 +427,9 @@ void lcd_update(void)
407 427
408 lcd_begin_write_gram(); 428 lcd_begin_write_gram();
409 429
430#ifndef BOOTLOADER
410 dma_count = 1; 431 dma_count = 1;
411 SAR3 = (unsigned long)FBADDR(0,0); 432 SAR3 = (unsigned long)FBADDR(0, 0);
412 BCR3 = LCD_WIDTH*LCD_HEIGHT*sizeof(fb_data); 433 BCR3 = LCD_WIDTH*LCD_HEIGHT*sizeof(fb_data);
413 DCR3 = DMA_INT | DMA_AA | DMA_BWC(1) 434 DCR3 = DMA_INT | DMA_AA | DMA_BWC(1)
414 | DMA_SINC | DMA_SSIZE(DMA_SIZE_LINE) 435 | DMA_SINC | DMA_SSIZE(DMA_SIZE_LINE)
@@ -418,6 +439,17 @@ void lcd_update(void)
418 yield(); 439 yield();
419 440
420 mutex_unlock(&lcd_mtx); 441 mutex_unlock(&lcd_mtx);
442#else
443 DAR3 = 0xf0000002;
444 SAR3 = (unsigned long)FBADDR(0, 0);
445 BCR3 = LCD_WIDTH*LCD_HEIGHT*sizeof(fb_data);
446 DCR3 = DMA_AA | DMA_BWC(1)
447 | DMA_SINC | DMA_SSIZE(DMA_SIZE_LINE)
448 | DMA_DSIZE(DMA_SIZE_WORD) | DMA_START;
449
450 while (!(DSR3 & 1));
451 DSR3 = 1;
452#endif
421 } 453 }
422} 454}
423 455
@@ -434,7 +466,9 @@ void lcd_update_rect(int x, int y, int width, int height)
434 if (width <= 0 || height <= 0) /* nothing to do */ 466 if (width <= 0 || height <= 0) /* nothing to do */
435 return; 467 return;
436 468
469#ifndef BOOTLOADER
437 mutex_lock(&lcd_mtx); 470 mutex_lock(&lcd_mtx);
471#endif
438 472
439 lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_VERT); 473 lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_VERT);
440 /* set update window */ 474 /* set update window */
@@ -444,6 +478,7 @@ void lcd_update_rect(int x, int y, int width, int height)
444 478
445 lcd_begin_write_gram(); 479 lcd_begin_write_gram();
446 480
481#ifndef BOOTLOADER
447 if (width == LCD_WIDTH) 482 if (width == LCD_WIDTH)
448 { 483 {
449 dma_count = 1; 484 dma_count = 1;
@@ -453,7 +488,7 @@ void lcd_update_rect(int x, int y, int width, int height)
453 else 488 else
454 { 489 {
455 dma_count = height; 490 dma_count = height;
456 SAR3 = dma_addr = (unsigned long)FBADDR(x,y); 491 SAR3 = dma_addr = (unsigned long)FBADDR(x, y);
457 BCR3 = dma_len = width * sizeof(fb_data); 492 BCR3 = dma_len = width * sizeof(fb_data);
458 } 493 }
459 DCR3 = DMA_INT | DMA_AA | DMA_BWC(1) 494 DCR3 = DMA_INT | DMA_AA | DMA_BWC(1)
@@ -464,5 +499,24 @@ void lcd_update_rect(int x, int y, int width, int height)
464 yield(); 499 yield();
465 500
466 mutex_unlock(&lcd_mtx); 501 mutex_unlock(&lcd_mtx);
502#else
503 DAR3 = 0xf0000002;
504 unsigned long dma_addr = (unsigned long)FBADDR(x, y);
505 width *= sizeof(fb_data);
506
507 for (; height > 0; height--)
508 {
509 SAR3 = dma_addr;
510 BCR3 = width;
511 DCR3 = DMA_AA | DMA_BWC(1)
512 | DMA_SINC | DMA_SSIZE(DMA_SIZE_LINE)
513 | DMA_DSIZE(DMA_SIZE_WORD) | DMA_START;
514
515 dma_addr += LCD_WIDTH*sizeof(fb_data);
516
517 while (!(DSR3 & 1));
518 DSR3 = 1;
519 }
520#endif
467 } 521 }
468} 522}