mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-11-09 21:22:39 -05:00
imx233/fuze+: allow dma info retrieval; wait for end of channel reset before returning; fix typo
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30795 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
e428717d30
commit
b0a20dbc99
2 changed files with 115 additions and 5 deletions
|
|
@ -24,6 +24,8 @@
|
|||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "dma-imx233.h"
|
||||
#include "lcd.h"
|
||||
#include "string.h"
|
||||
|
||||
void imx233_dma_init(void)
|
||||
{
|
||||
|
|
@ -34,12 +36,22 @@ void imx233_dma_init(void)
|
|||
|
||||
void imx233_dma_reset_channel(unsigned chan)
|
||||
{
|
||||
volatile uint32_t *ptr;
|
||||
uint32_t bm;
|
||||
if(APB_IS_APBX_CHANNEL(chan))
|
||||
__REG_SET(HW_APBX_CHANNEL_CTRL) =
|
||||
HW_APBX_CHANNEL_CTRL__RESET_CHANNEL(APB_GET_DMA_CHANNEL(chan));
|
||||
{
|
||||
ptr = &HW_APBX_CHANNEL_CTRL;
|
||||
bm = HW_APBX_CHANNEL_CTRL__RESET_CHANNEL(APB_GET_DMA_CHANNEL(chan));
|
||||
}
|
||||
else
|
||||
__REG_SET(HW_APBH_CTRL0) =
|
||||
HW_APBH_CTRL0__RESET_CHANNEL(APB_GET_DMA_CHANNEL(chan));
|
||||
{
|
||||
ptr = &HW_APBH_CTRL0;
|
||||
bm = HW_APBH_CTRL0__RESET_CHANNEL(APB_GET_DMA_CHANNEL(chan));
|
||||
}
|
||||
__REG_SET(*ptr) = bm;
|
||||
/* wait for end of reset */
|
||||
while(*ptr & bm)
|
||||
;
|
||||
}
|
||||
|
||||
void imx233_dma_clkgate_channel(unsigned chan, bool enable_clock)
|
||||
|
|
@ -54,6 +66,27 @@ void imx233_dma_clkgate_channel(unsigned chan, bool enable_clock)
|
|||
HW_APBH_CTRL0__CLKGATE_CHANNEL(APB_GET_DMA_CHANNEL(chan));
|
||||
}
|
||||
|
||||
void imx233_dma_freeze_channel(unsigned chan, bool freeze)
|
||||
{
|
||||
volatile uint32_t *ptr;
|
||||
uint32_t bm;
|
||||
if(APB_IS_APBX_CHANNEL(chan))
|
||||
{
|
||||
ptr = &HW_APBX_CHANNEL_CTRL;
|
||||
bm = HW_APBX_CHANNEL_CTRL__FREEZE_CHANNEL(APB_GET_DMA_CHANNEL(chan));
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = &HW_APBH_CTRL0;
|
||||
bm = HW_APBH_CTRL0__FREEZE_CHANNEL(APB_GET_DMA_CHANNEL(chan));
|
||||
}
|
||||
|
||||
if(freeze)
|
||||
__REG_SET(*ptr) = bm;
|
||||
else
|
||||
__REG_CLR(*ptr) = bm;
|
||||
}
|
||||
|
||||
void imx233_dma_enable_channel_interrupt(unsigned chan, bool enable)
|
||||
{
|
||||
volatile uint32_t *ptr;
|
||||
|
|
@ -65,7 +98,7 @@ void imx233_dma_enable_channel_interrupt(unsigned chan, bool enable)
|
|||
}
|
||||
else
|
||||
{
|
||||
ptr = &HW_APBH_CTRL1;;
|
||||
ptr = &HW_APBH_CTRL1;
|
||||
bm = HW_APBH_CTRL1__CHx_CMDCMPLT_IRQ_EN(APB_GET_DMA_CHANNEL(chan));
|
||||
}
|
||||
|
||||
|
|
@ -186,3 +219,41 @@ void imx233_dma_wait_completion(unsigned chan)
|
|||
while(*sema & HW_APB_CHx_SEMA__PHORE_BM)
|
||||
yield();
|
||||
}
|
||||
|
||||
struct imx233_dma_info_t imx233_dma_get_info(unsigned chan, unsigned flags)
|
||||
{
|
||||
struct imx233_dma_info_t s;
|
||||
memset(&s, 0, sizeof(s));
|
||||
bool apbx = APB_IS_APBX_CHANNEL(chan);
|
||||
int dmac = APB_GET_DMA_CHANNEL(chan);
|
||||
if(flags & DMA_INFO_CURCMDADDR)
|
||||
s.cur_cmd_addr = apbx ? HW_APBX_CHx_CURCMDAR(dmac) : HW_APBH_CHx_CURCMDAR(dmac);
|
||||
if(flags & DMA_INFO_NXTCMDADDR)
|
||||
s.nxt_cmd_addr = apbx ? HW_APBX_CHx_NXTCMDAR(dmac) : HW_APBH_CHx_NXTCMDAR(dmac);
|
||||
if(flags & DMA_INFO_CMD)
|
||||
s.cmd = apbx ? HW_APBX_CHx_CMD(dmac) : HW_APBH_CHx_CMD(dmac);
|
||||
if(flags & DMA_INFO_BAR)
|
||||
s.bar = apbx ? HW_APBX_CHx_BAR(dmac) : HW_APBH_CHx_BAR(dmac);
|
||||
if(flags & DMA_INFO_AHB_BYTES)
|
||||
s.ahb_bytes = apbx ? __XTRACT_EX(HW_APBX_CHx_DEBUG2(dmac), HW_APBX_CHx_DEBUG2__AHB_BYTES) :
|
||||
__XTRACT_EX(HW_APBH_CHx_DEBUG2(dmac), HW_APBH_CHx_DEBUG2__AHB_BYTES);
|
||||
if(flags & DMA_INFO_APB_BYTES)
|
||||
s.apb_bytes = apbx ? __XTRACT_EX(HW_APBX_CHx_DEBUG2(dmac), HW_APBX_CHx_DEBUG2__APB_BYTES) :
|
||||
__XTRACT_EX(HW_APBH_CHx_DEBUG2(dmac), HW_APBH_CHx_DEBUG2__APB_BYTES);
|
||||
if(flags & DMA_INFO_FREEZED)
|
||||
s.freezed = apbx ? HW_APBX_CHANNEL_CTRL & HW_APBX_CHANNEL_CTRL__FREEZE_CHANNEL(dmac) :
|
||||
HW_APBH_CTRL0 & HW_APBH_CTRL0__FREEZE_CHANNEL(dmac);
|
||||
if(flags & DMA_INFO_GATED)
|
||||
s.gated = apbx ? false : HW_APBH_CTRL0 & HW_APBH_CTRL0__CLKGATE_CHANNEL(dmac);
|
||||
if(flags & DMA_INFO_INTERRUPT)
|
||||
{
|
||||
s.int_enabled = apbx ? HW_APBX_CTRL1 & HW_APBX_CTRL1__CHx_CMDCMPLT_IRQ_EN(dmac) :
|
||||
HW_APBH_CTRL1 & HW_APBH_CTRL1__CHx_CMDCMPLT_IRQ_EN(dmac);
|
||||
s.int_cmdcomplt = apbx ? HW_APBX_CTRL1 & HW_APBX_CTRL1__CHx_CMDCMPLT_IRQ(dmac) :
|
||||
HW_APBH_CTRL1 & HW_APBH_CTRL1__CHx_CMDCMPLT_IRQ(dmac);
|
||||
s.int_error = apbx ? HW_APBX_CTRL2 & HW_APBX_CTRL2__CHx_ERROR_IRQ(dmac) :
|
||||
HW_APBH_CTRL2 & HW_APBH_CTRL2__CHx_ERROR_IRQ(dmac);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -65,6 +65,10 @@
|
|||
#define HW_APBH_CHx_DEBUG1(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x90 + 0x70 * (i)))
|
||||
|
||||
#define HW_APBH_CHx_DEBUG2(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0xa0 + 0x70 * (i)))
|
||||
#define HW_APBH_CHx_DEBUG2__AHB_BYTES_BP 0
|
||||
#define HW_APBH_CHx_DEBUG2__AHB_BYTES_BM 0xffff
|
||||
#define HW_APBH_CHx_DEBUG2__APB_BYTES_BP 16
|
||||
#define HW_APBH_CHx_DEBUG2__APB_BYTES_BM 0xffff0000
|
||||
|
||||
/********
|
||||
* APHX *
|
||||
|
|
@ -104,6 +108,10 @@
|
|||
#define HW_APBX_CHx_DEBUG1(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x150 + (i) * 0x70))
|
||||
|
||||
#define HW_APBX_CHx_DEBUG2(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x160 + (i) * 0x70))
|
||||
#define HW_APBX_CHx_DEBUG2__AHB_BYTES_BP 0
|
||||
#define HW_APBX_CHx_DEBUG2__AHB_BYTES_BM 0xffff
|
||||
#define HW_APBX_CHx_DEBUG2__APB_BYTES_BP 16
|
||||
#define HW_APBX_CHx_DEBUG2__APB_BYTES_BM 0xffff0000
|
||||
|
||||
/**********
|
||||
* COMMON *
|
||||
|
|
@ -117,6 +125,32 @@ struct apb_dma_command_t
|
|||
/* PIO words follow */
|
||||
};
|
||||
|
||||
#define DMA_INFO_CURCMDADDR (1 << 0)
|
||||
#define DMA_INFO_NXTCMDADDR (1 << 1)
|
||||
#define DMA_INFO_CMD (1 << 2)
|
||||
#define DMA_INFO_BAR (1 << 3)
|
||||
#define DMA_INFO_APB_BYTES (1 << 4)
|
||||
#define DMA_INFO_AHB_BYTES (1 << 5)
|
||||
#define DMA_INFO_FREEZED (1 << 6)
|
||||
#define DMA_INFO_GATED (1 << 7)
|
||||
#define DMA_INFO_INTERRUPT (1 << 8)
|
||||
#define DMA_INFO_ALL 0x1ff
|
||||
|
||||
struct imx233_dma_info_t
|
||||
{
|
||||
unsigned long cur_cmd_addr;
|
||||
unsigned long nxt_cmd_addr;
|
||||
unsigned long cmd;
|
||||
unsigned long bar;
|
||||
unsigned apb_bytes;
|
||||
unsigned ahb_bytes;
|
||||
bool freezed;
|
||||
bool gated;
|
||||
bool int_enabled;
|
||||
bool int_cmdcomplt;
|
||||
bool int_error;
|
||||
};
|
||||
|
||||
#define APBH_DMA_CHANNEL(i) i
|
||||
#define APBX_DMA_CHANNEL(i) ((i) | 0x10)
|
||||
#define APB_IS_APBX_CHANNEL(x) ((x) & 0x10)
|
||||
|
|
@ -124,6 +158,7 @@ struct apb_dma_command_t
|
|||
|
||||
#define APB_SSP(ssp) APBH_DMA_CHANNEL(HW_APBH_SSP(ssp))
|
||||
#define APB_AUDIO_ADC APBX_DMA_CHANNEL(HW_APBX_AUDIO_ADC)
|
||||
#define APB_AUDIO_DAC APBX_DMA_CHANNEL(HW_APBX_AUDIO_DAC)
|
||||
#define APB_I2C APBX_DMA_CHANNEL(HW_APBX_I2C)
|
||||
|
||||
#define HW_APB_CHx_CMD__COMMAND_BM 0x3
|
||||
|
|
@ -160,6 +195,7 @@ void imx233_dma_reset_channel(unsigned chan);
|
|||
/* only apbh channel have clkgate control */
|
||||
void imx233_dma_clkgate_channel(unsigned chan, bool enable_clock);
|
||||
|
||||
void imx233_dma_freeze_channel(unsigned chan, bool freeze);
|
||||
void imx233_dma_enable_channel_interrupt(unsigned chan, bool enable);
|
||||
/* clear both channel complete and error bits */
|
||||
void imx233_dma_clear_channel_interrupt(unsigned chan);
|
||||
|
|
@ -167,5 +203,8 @@ bool imx233_dma_is_channel_error_irq(unsigned chan);
|
|||
/* assume no command is in progress */
|
||||
void imx233_dma_start_command(unsigned chan, struct apb_dma_command_t *cmd);
|
||||
void imx233_dma_wait_completion(unsigned chan);
|
||||
/* get some info
|
||||
* WARNING: if channel is not freezed, data might not be coherent ! */
|
||||
struct imx233_dma_info_t imx233_dma_get_info(unsigned chan, unsigned flags);
|
||||
|
||||
#endif // __DMA_IMX233_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue