mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-11-09 21:22:39 -05:00
imx233: workaround hardware dma bug
This bug mostly affects the ZEN and ZEN X-Fi and hangs the lcdif dma randomly on boot. Change-Id: I4255db90d87737b7a70d1d53e3ef84e4e14c8c13
This commit is contained in:
parent
ed6526404f
commit
42e54c508f
1 changed files with 34 additions and 0 deletions
|
|
@ -32,8 +32,42 @@
|
|||
// statistics about unaligned transfers
|
||||
static int apb_nr_unaligned[32];
|
||||
|
||||
static void safe_reset_channel(int chan)
|
||||
{
|
||||
bool apbx_running = !BF_RD(APBX_CTRL0, SFTRST) && !BF_RD(APBX_CTRL0, CLKGATE);
|
||||
bool apbh_running = !BF_RD(APBH_CTRL0, SFTRST) && !BF_RD(APBH_CTRL0, CLKGATE);
|
||||
if(APB_IS_APBX_CHANNEL(chan))
|
||||
{
|
||||
if(!apbx_running)
|
||||
return; /* don't reset if block is not running */
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!apbh_running)
|
||||
return; /* don't reset if block is not running */
|
||||
if(BF_RD(APBH_CTRL0, CLKGATE_CHANNEL) & (1 << chan))
|
||||
return; /* don't reset a gated channel */
|
||||
}
|
||||
imx233_dma_reset_channel(chan);
|
||||
}
|
||||
|
||||
void imx233_dma_init(void)
|
||||
{
|
||||
/* BUG The stmp3700 (and probably stmp3780) have a hardware bug related to
|
||||
* resetting the block when channel is running. It appears that at least
|
||||
* for the LCDIF channel, resetting the block while the channel is running
|
||||
* will make the channel hang. Once the channel hang, it cannot be recovered
|
||||
* except by a chip reset. On most devices this situation will never arise
|
||||
* but on the Creative ZEN (X-Fi), the OF bootloader leaves the channel
|
||||
* running (to display the logo) when booting. It is unclear if this bug only
|
||||
* affects the APBH or also the APBX. I believe it is related to the errata about
|
||||
* channels not clearing the fifo on abrupt termination which affects both
|
||||
* dma engines. Also note that we can't safely reset 'all' the channels by
|
||||
* setting the reset mask to 0xffff since non-implemented channels don't clear
|
||||
* their reset bit... Also reset won't work on gated channels and won't work if
|
||||
* block is in reset or gated, in which case this situation is assumed not
|
||||
* to exists */
|
||||
safe_reset_channel(APB_LCDIF);
|
||||
/* Enable APHB and APBX */
|
||||
imx233_reset_block(&HW_APBH_CTRL0);
|
||||
imx233_reset_block(&HW_APBX_CTRL0);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue