mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-09 13:15:18 -05:00
Jz4740 targets: make sure you don't yield when in interrupt mode
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19309 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
0e97b1a1eb
commit
815998c669
3 changed files with 52 additions and 16 deletions
|
|
@ -23,7 +23,7 @@
|
|||
#include "jz4740.h"
|
||||
#include "lcd.h"
|
||||
#include "lcd-target.h"
|
||||
#include "system-target.h"
|
||||
#include "system.h"
|
||||
#include "kernel.h"
|
||||
|
||||
static volatile bool _lcd_on = false;
|
||||
|
|
@ -56,39 +56,63 @@ bool lcd_enabled(void)
|
|||
return _lcd_on;
|
||||
}
|
||||
|
||||
/* Don't switch threads when in interrupt mode! */
|
||||
static void lcd_lock(void)
|
||||
{
|
||||
if(LIKELY(!in_interrupt_mode()))
|
||||
mutex_lock(&lcd_mtx);
|
||||
else
|
||||
while( !(REG_DMAC_DCCSR(DMA_LCD_CHANNEL) & DMAC_DCCSR_TT));
|
||||
}
|
||||
|
||||
static void lcd_unlock(void)
|
||||
{
|
||||
if(LIKELY(!in_interrupt_mode()))
|
||||
mutex_unlock(&lcd_mtx);
|
||||
else
|
||||
while( !(REG_DMAC_DCCSR(DMA_LCD_CHANNEL) & DMAC_DCCSR_TT));
|
||||
}
|
||||
|
||||
/* Update a fraction of the display. */
|
||||
void lcd_update_rect(int x, int y, int width, int height)
|
||||
{
|
||||
mutex_lock(&lcd_mtx);
|
||||
lcd_lock();
|
||||
|
||||
lcd_set_target(x, y, width, height);
|
||||
|
||||
REG_DMAC_DCCSR(DMA_LCD_CHANNEL) = 0;
|
||||
REG_DMAC_DRSR(DMA_LCD_CHANNEL) = DMAC_DRSR_RS_SLCD; /* source = SLCD */
|
||||
REG_DMAC_DSAR(DMA_LCD_CHANNEL) = ((unsigned int)&lcd_framebuffer[y][x]) & 0x1FFFFFFF;
|
||||
REG_DMAC_DTAR(DMA_LCD_CHANNEL) = 0x130500B0; /* SLCD_FIFO */
|
||||
REG_DMAC_DTCR(DMA_LCD_CHANNEL) = width*height;
|
||||
REG_DMAC_DRSR(DMA_LCD_CHANNEL) = DMAC_DRSR_RS_SLCD; /* source = SLCD */
|
||||
REG_DMAC_DSAR(DMA_LCD_CHANNEL) = ((unsigned int)&lcd_framebuffer[y][x]) & 0x1FFFFFFF;
|
||||
REG_DMAC_DTAR(DMA_LCD_CHANNEL) = 0x130500B0; /* SLCD_FIFO */
|
||||
REG_DMAC_DTCR(DMA_LCD_CHANNEL) = width*height;
|
||||
|
||||
REG_DMAC_DCMD(DMA_LCD_CHANNEL) = (DMAC_DCMD_SAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 /* (1 << 23) | (0 << 16) | (0 << 14) */
|
||||
| DMAC_DCMD_DWDH_16 | DMAC_DCMD_DS_16BIT); /* | (2 << 12) | (3 << 8) */
|
||||
REG_DMAC_DCCSR(DMA_LCD_CHANNEL) = DMAC_DCCSR_NDES; /* (1 << 31) */
|
||||
REG_DMAC_DCMD(DMA_LCD_CHANNEL) = ( DMAC_DCMD_SAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32
|
||||
| DMAC_DCMD_DWDH_16 | DMAC_DCMD_DS_16BIT );
|
||||
REG_DMAC_DCCSR(DMA_LCD_CHANNEL) = DMAC_DCCSR_NDES;
|
||||
|
||||
__dcache_writeback_all(); /* Size of framebuffer is way bigger than cache size */
|
||||
__dcache_writeback_all(); /* Size of framebuffer is way bigger than cache size;
|
||||
we need to find a way to make the framebuffer uncached, so this statement can get removed. */
|
||||
|
||||
while(REG_SLCD_STATE & SLCD_STATE_BUSY);
|
||||
REG_SLCD_CTRL = SLCD_CTRL_DMA_EN;
|
||||
|
||||
REG_SLCD_CTRL |= SLCD_CTRL_DMA_EN;
|
||||
REG_DMAC_DCCSR(DMA_LCD_CHANNEL) |= DMAC_DCCSR_EN;
|
||||
|
||||
while( !(REG_DMAC_DCCSR(DMA_LCD_CHANNEL) & DMAC_DCCSR_TT) )
|
||||
yield();
|
||||
if(LIKELY(!in_interrupt_mode()))
|
||||
{
|
||||
while( !(REG_DMAC_DCCSR(DMA_LCD_CHANNEL) & DMAC_DCCSR_TT) )
|
||||
yield();
|
||||
}
|
||||
else
|
||||
while( !(REG_DMAC_DCCSR(DMA_LCD_CHANNEL) & DMAC_DCCSR_TT));
|
||||
|
||||
REG_DMAC_DCCSR(DMA_LCD_CHANNEL) &= ~DMAC_DCCSR_EN;
|
||||
|
||||
while(REG_SLCD_STATE & SLCD_STATE_BUSY);
|
||||
REG_SLCD_CTRL = 0;
|
||||
|
||||
mutex_unlock(&lcd_mtx);
|
||||
REG_SLCD_CTRL &= ~SLCD_CTRL_DMA_EN;
|
||||
|
||||
lcd_unlock();
|
||||
}
|
||||
|
||||
/* Update the display.
|
||||
|
|
|
|||
|
|
@ -322,6 +322,13 @@ static int get_irq_number(void)
|
|||
return irq;
|
||||
}
|
||||
|
||||
static bool intr_mode = false;
|
||||
|
||||
bool in_interrupt_mode(void)
|
||||
{
|
||||
return intr_mode;
|
||||
}
|
||||
|
||||
void intr_handler(void)
|
||||
{
|
||||
int irq = get_irq_number();
|
||||
|
|
@ -330,7 +337,11 @@ void intr_handler(void)
|
|||
|
||||
ack_irq(irq);
|
||||
if(irq > 0)
|
||||
{
|
||||
intr_mode = true;
|
||||
irqvector[irq-1]();
|
||||
intr_mode = false;
|
||||
}
|
||||
}
|
||||
|
||||
#define EXC(x,y) if(_cause == (x)) return (y);
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ static inline int disable_interrupt_save(int mask)
|
|||
unsigned int oldstatus;
|
||||
|
||||
oldstatus = read_c0_status();
|
||||
write_c0_status(oldstatus | mask);
|
||||
write_c0_status(oldstatus & ~mask);
|
||||
|
||||
return oldstatus;
|
||||
}
|
||||
|
|
@ -101,6 +101,7 @@ void udelay(unsigned int usec);
|
|||
void mdelay(unsigned int msec);
|
||||
void power_off(void);
|
||||
void system_reboot(void);
|
||||
bool in_interrupt_mode(void);
|
||||
|
||||
#define DMA_LCD_CHANNEL 0
|
||||
#define DMA_NAND_CHANNEL 1
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue