h300: fix one long-standing bootloader bug

This was introduced in e13c600133 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
This commit is contained in:
James Buren 2020-11-12 14:02:23 +00:00 committed by William Wilgus
parent 362f7a3220
commit 8ac46f844f

View file

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