summaryrefslogtreecommitdiffstats
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.tar.bz2
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 @@
static bool display_on = false; /* Is the display turned on? */
static bool display_flipped = false;
static int xoffset = 0; /* Needed for flip */
+#ifndef BOOTLOADER
static struct mutex lcd_mtx; /* The update functions use DMA and yield */
unsigned long dma_addr IBSS_ATTR;
unsigned int dma_len IBSS_ATTR;
volatile int dma_count IBSS_ATTR;
+#endif
/* register defines */
#define R_START_OSC 0x00
@@ -139,9 +141,13 @@ void lcd_set_flip(bool yesno)
if (display_on)
{
+#ifndef BOOTLOADER
mutex_lock(&lcd_mtx);
+#endif
flip_lcd(yesno);
+#ifndef BOOTLOADER
mutex_unlock(&lcd_mtx);
+#endif
}
}
@@ -262,6 +268,7 @@ void lcd_init_device(void)
or_l(0x00004000, &GPIO1_OUT);
sleep(1);
+#ifndef BOOTLOADER
DAR3 = 0xf0000002; /* Configure DMA channel 3 */
DSR3 = 1;
DIVR3 = 57; /* DMA3 is mapped into vector 57 in system.c */
@@ -269,6 +276,7 @@ void lcd_init_device(void)
coldfire_imr_mod(0, 1 << 17);
mutex_init(&lcd_mtx);
+#endif
_display_on();
}
@@ -276,7 +284,9 @@ void lcd_enable(bool on)
{
if (display_on != on)
{
+#ifndef BOOTLOADER
mutex_lock(&lcd_mtx);
+#endif
if (on)
{
_display_on();
@@ -304,7 +314,9 @@ void lcd_enable(bool on)
display_on=false;
}
+#ifndef BOOTLOADER
mutex_unlock(&lcd_mtx);
+#endif
}
}
@@ -340,7 +352,9 @@ void lcd_blit_yuv(unsigned char * const src[3],
if (!display_on)
return;
+#ifndef BOOTLOADER
mutex_lock(&lcd_mtx);
+#endif
width &= ~1; /* stay on the safe side */
height &= ~1;
@@ -372,9 +386,12 @@ void lcd_blit_yuv(unsigned char * const src[3],
vsrc += stride >> 1;
}
while (ysrc < ysrc_max);
+#ifndef BOOTLOADER
mutex_unlock(&lcd_mtx);
+#endif
}
+#ifndef BOOTLOADER
/* LCD DMA ISR */
void DMA3(void) __attribute__ ((interrupt_handler, section(".icode")));
void DMA3(void)
@@ -390,6 +407,7 @@ void DMA3(void)
| DMA_DSIZE(DMA_SIZE_WORD) | DMA_START;
}
}
+#endif
/* Update the display.
This must be called after all other LCD functions that change the display. */
@@ -397,7 +415,9 @@ void lcd_update(void)
{
if (display_on)
{
+#ifndef BOOTLOADER
mutex_lock(&lcd_mtx);
+#endif
lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_VERT);
/* set start position window */
@@ -407,8 +427,9 @@ void lcd_update(void)
lcd_begin_write_gram();
+#ifndef BOOTLOADER
dma_count = 1;
- SAR3 = (unsigned long)FBADDR(0,0);
+ SAR3 = (unsigned long)FBADDR(0, 0);
BCR3 = LCD_WIDTH*LCD_HEIGHT*sizeof(fb_data);
DCR3 = DMA_INT | DMA_AA | DMA_BWC(1)
| DMA_SINC | DMA_SSIZE(DMA_SIZE_LINE)
@@ -418,6 +439,17 @@ void lcd_update(void)
yield();
mutex_unlock(&lcd_mtx);
+#else
+ DAR3 = 0xf0000002;
+ SAR3 = (unsigned long)FBADDR(0, 0);
+ BCR3 = LCD_WIDTH*LCD_HEIGHT*sizeof(fb_data);
+ DCR3 = DMA_AA | DMA_BWC(1)
+ | DMA_SINC | DMA_SSIZE(DMA_SIZE_LINE)
+ | DMA_DSIZE(DMA_SIZE_WORD) | DMA_START;
+
+ while (!(DSR3 & 1));
+ DSR3 = 1;
+#endif
}
}
@@ -434,7 +466,9 @@ void lcd_update_rect(int x, int y, int width, int height)
if (width <= 0 || height <= 0) /* nothing to do */
return;
+#ifndef BOOTLOADER
mutex_lock(&lcd_mtx);
+#endif
lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_VERT);
/* set update window */
@@ -444,6 +478,7 @@ void lcd_update_rect(int x, int y, int width, int height)
lcd_begin_write_gram();
+#ifndef BOOTLOADER
if (width == LCD_WIDTH)
{
dma_count = 1;
@@ -453,7 +488,7 @@ void lcd_update_rect(int x, int y, int width, int height)
else
{
dma_count = height;
- SAR3 = dma_addr = (unsigned long)FBADDR(x,y);
+ SAR3 = dma_addr = (unsigned long)FBADDR(x, y);
BCR3 = dma_len = width * sizeof(fb_data);
}
DCR3 = DMA_INT | DMA_AA | DMA_BWC(1)
@@ -464,5 +499,24 @@ void lcd_update_rect(int x, int y, int width, int height)
yield();
mutex_unlock(&lcd_mtx);
+#else
+ DAR3 = 0xf0000002;
+ unsigned long dma_addr = (unsigned long)FBADDR(x, y);
+ width *= sizeof(fb_data);
+
+ for (; height > 0; height--)
+ {
+ SAR3 = dma_addr;
+ BCR3 = width;
+ DCR3 = DMA_AA | DMA_BWC(1)
+ | DMA_SINC | DMA_SSIZE(DMA_SIZE_LINE)
+ | DMA_DSIZE(DMA_SIZE_WORD) | DMA_START;
+
+ dma_addr += LCD_WIDTH*sizeof(fb_data);
+
+ while (!(DSR3 & 1));
+ DSR3 = 1;
+ }
+#endif
}
}