mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-11-09 21:22:39 -05:00
imx233: rewrite dma using new register headers
Change-Id: If73b84d9c9f4a152a54fb9d2dbec895e72d2e753
This commit is contained in:
parent
852a82b90a
commit
8390eb931e
5 changed files with 140 additions and 226 deletions
|
|
@ -36,22 +36,17 @@ void imx233_dma_init(void)
|
|||
|
||||
void imx233_dma_reset_channel(unsigned chan)
|
||||
{
|
||||
volatile uint32_t *ptr;
|
||||
uint32_t bm;
|
||||
uint32_t bm = 1 << APB_GET_DMA_CHANNEL(chan);
|
||||
if(APB_IS_APBX_CHANNEL(chan))
|
||||
{
|
||||
ptr = &HW_APBX_CHANNEL_CTRL;
|
||||
bm = HW_APBX_CHANNEL_CTRL__RESET_CHANNEL(APB_GET_DMA_CHANNEL(chan));
|
||||
BF_SETV(APBX_CHANNEL_CTRL, RESET_CHANNEL, bm);
|
||||
while(BF_RD(APBX_CHANNEL_CTRL, RESET_CHANNEL) & bm);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = &HW_APBH_CTRL0;
|
||||
bm = HW_APBH_CTRL0__RESET_CHANNEL(APB_GET_DMA_CHANNEL(chan));
|
||||
BF_SETV(APBH_CTRL0, RESET_CHANNEL, bm);
|
||||
while(BF_RD(APBH_CTRL0, RESET_CHANNEL) & bm);
|
||||
}
|
||||
__REG_SET(*ptr) = bm;
|
||||
/* wait for end of reset */
|
||||
while(*ptr & bm)
|
||||
;
|
||||
}
|
||||
|
||||
void imx233_dma_clkgate_channel(unsigned chan, bool enable_clock)
|
||||
|
|
@ -59,84 +54,72 @@ void imx233_dma_clkgate_channel(unsigned chan, bool enable_clock)
|
|||
if(APB_IS_APBX_CHANNEL(chan))
|
||||
return;
|
||||
if(enable_clock)
|
||||
__REG_CLR(HW_APBH_CTRL0) =
|
||||
HW_APBH_CTRL0__CLKGATE_CHANNEL(APB_GET_DMA_CHANNEL(chan));
|
||||
BF_CLRV(APBH_CTRL0, CLKGATE_CHANNEL, 1 << APB_GET_DMA_CHANNEL(chan));
|
||||
else
|
||||
__REG_SET(HW_APBH_CTRL0) =
|
||||
HW_APBH_CTRL0__CLKGATE_CHANNEL(APB_GET_DMA_CHANNEL(chan));
|
||||
BF_SETV(APBH_CTRL0, CLKGATE_CHANNEL, 1 << APB_GET_DMA_CHANNEL(chan));
|
||||
}
|
||||
|
||||
void imx233_dma_freeze_channel(unsigned chan, bool freeze)
|
||||
{
|
||||
volatile uint32_t *ptr;
|
||||
uint32_t bm;
|
||||
uint32_t bm = 1 << APB_GET_DMA_CHANNEL(chan);
|
||||
if(APB_IS_APBX_CHANNEL(chan))
|
||||
{
|
||||
ptr = &HW_APBX_CHANNEL_CTRL;
|
||||
bm = HW_APBX_CHANNEL_CTRL__FREEZE_CHANNEL(APB_GET_DMA_CHANNEL(chan));
|
||||
if(freeze)
|
||||
BF_SETV(APBX_CHANNEL_CTRL, FREEZE_CHANNEL, bm);
|
||||
else
|
||||
BF_CLRV(APBX_CHANNEL_CTRL, FREEZE_CHANNEL, bm);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = &HW_APBH_CTRL0;
|
||||
bm = HW_APBH_CTRL0__FREEZE_CHANNEL(APB_GET_DMA_CHANNEL(chan));
|
||||
}
|
||||
|
||||
if(freeze)
|
||||
__REG_SET(*ptr) = bm;
|
||||
BF_SETV(APBH_CTRL0, FREEZE_CHANNEL, bm);
|
||||
else
|
||||
__REG_CLR(*ptr) = bm;
|
||||
BF_CLRV(APBH_CTRL0, FREEZE_CHANNEL, bm);
|
||||
}
|
||||
}
|
||||
|
||||
void imx233_dma_enable_channel_interrupt(unsigned chan, bool enable)
|
||||
{
|
||||
volatile uint32_t *ptr;
|
||||
uint32_t bm;
|
||||
uint32_t bm = 1 << APB_GET_DMA_CHANNEL(chan);
|
||||
if(APB_IS_APBX_CHANNEL(chan))
|
||||
{
|
||||
ptr = &HW_APBX_CTRL1;
|
||||
bm = HW_APBX_CTRL1__CHx_CMDCMPLT_IRQ_EN(APB_GET_DMA_CHANNEL(chan));
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = &HW_APBH_CTRL1;
|
||||
bm = HW_APBH_CTRL1__CHx_CMDCMPLT_IRQ_EN(APB_GET_DMA_CHANNEL(chan));
|
||||
}
|
||||
|
||||
if(enable)
|
||||
{
|
||||
__REG_SET(*ptr) = bm;
|
||||
imx233_dma_clear_channel_interrupt(chan);
|
||||
BF_SETV(APBX_CTRL1, CH_CMDCMPLT_IRQ_EN, bm);
|
||||
else
|
||||
BF_CLRV(APBX_CTRL1, CH_CMDCMPLT_IRQ_EN, bm);
|
||||
}
|
||||
else
|
||||
__REG_CLR(*ptr) = bm;
|
||||
{
|
||||
if(enable)
|
||||
BF_SETV(APBH_CTRL1, CH_CMDCMPLT_IRQ_EN, bm);
|
||||
else
|
||||
BF_CLRV(APBH_CTRL1, CH_CMDCMPLT_IRQ_EN, bm);
|
||||
}
|
||||
imx233_dma_clear_channel_interrupt(chan);
|
||||
}
|
||||
|
||||
void imx233_dma_clear_channel_interrupt(unsigned chan)
|
||||
{
|
||||
uint32_t bm = 1 << APB_GET_DMA_CHANNEL(chan);
|
||||
if(APB_IS_APBX_CHANNEL(chan))
|
||||
{
|
||||
__REG_CLR(HW_APBX_CTRL1) =
|
||||
HW_APBX_CTRL1__CHx_CMDCMPLT_IRQ(APB_GET_DMA_CHANNEL(chan));
|
||||
__REG_CLR(HW_APBX_CTRL2) =
|
||||
HW_APBX_CTRL2__CHx_ERROR_IRQ(APB_GET_DMA_CHANNEL(chan));
|
||||
BF_CLRV(APBX_CTRL1, CH_CMDCMPLT_IRQ, bm);
|
||||
BF_CLRV(APBX_CTRL2, CH_ERROR_IRQ, bm);
|
||||
}
|
||||
else
|
||||
{
|
||||
__REG_CLR(HW_APBH_CTRL1) =
|
||||
HW_APBH_CTRL1__CHx_CMDCMPLT_IRQ(APB_GET_DMA_CHANNEL(chan));
|
||||
__REG_CLR(HW_APBH_CTRL2) =
|
||||
HW_APBH_CTRL2__CHx_ERROR_IRQ(APB_GET_DMA_CHANNEL(chan));
|
||||
BF_CLRV(APBH_CTRL1, CH_CMDCMPLT_IRQ, bm);
|
||||
BF_CLRV(APBH_CTRL2, CH_ERROR_IRQ, bm);
|
||||
}
|
||||
}
|
||||
|
||||
bool imx233_dma_is_channel_error_irq(unsigned chan)
|
||||
{
|
||||
uint32_t bm = 1 << APB_GET_DMA_CHANNEL(chan);
|
||||
if(APB_IS_APBX_CHANNEL(chan))
|
||||
return !!(HW_APBX_CTRL2 &
|
||||
HW_APBX_CTRL2__CHx_ERROR_IRQ(APB_GET_DMA_CHANNEL(chan)));
|
||||
return !!(BF_RD(APBX_CTRL2, CH_ERROR_IRQ) & bm);
|
||||
else
|
||||
return !!(HW_APBH_CTRL2 &
|
||||
HW_APBH_CTRL2__CHx_ERROR_IRQ(APB_GET_DMA_CHANNEL(chan)));
|
||||
return !!(BF_RD(APBH_CTRL2, CH_ERROR_IRQ) & bm);
|
||||
}
|
||||
|
||||
/* Commit and/or discard all DMA descriptors and buffers pointed by them,
|
||||
|
|
@ -151,36 +134,36 @@ static void imx233_dma_commit_and_discard(unsigned chan, struct apb_dma_command_
|
|||
* commit the descriptors */
|
||||
struct apb_dma_command_t *cur = cmd;
|
||||
|
||||
while((cur->cmd & HW_APB_CHx_CMD__UNUSED_BM) != HW_APB_CHx_CMD__UNUSED_MAGIC)
|
||||
while(BF_RDX(cur->cmd, APB_CHx_CMD, UNUSED) != BV_APB_CHx_CMD_UNUSED__MAGIC)
|
||||
{
|
||||
cur->cmd = (cur->cmd & ~HW_APB_CHx_CMD__UNUSED_BM) | HW_APB_CHx_CMD__UNUSED_MAGIC;
|
||||
int op = cur->cmd & HW_APB_CHx_CMD__COMMAND_BM;
|
||||
int sz = __XTRACT_EX(cur->cmd, HW_APB_CHx_CMD__XFER_COUNT);
|
||||
BF_WR_VX(cur->cmd, APB_CHx_CMD, UNUSED, MAGIC);
|
||||
int op = BF_RDX(cur->cmd, APB_CHx_CMD, COMMAND);
|
||||
int sz = BF_RDX(cur->cmd, APB_CHx_CMD, XFER_COUNT);
|
||||
/* device > host: discard */
|
||||
if(op == HW_APB_CHx_CMD__COMMAND__WRITE)
|
||||
if(op == BV_APB_CHx_CMD_COMMAND__WRITE)
|
||||
discard_dcache_range(cur->buffer, sz);
|
||||
/* host > device: commit and discard */
|
||||
else if(op == HW_APB_CHx_CMD__COMMAND__READ)
|
||||
else if(op == BV_APB_CHx_CMD_COMMAND__READ)
|
||||
commit_discard_dcache_range(cur->buffer, sz);
|
||||
if((uint32_t)cur->buffer % CACHEALIGN_SIZE)
|
||||
apb_nr_unaligned[chan]++;
|
||||
/* Virtual to physical buffer pointer conversion */
|
||||
cur->buffer = PHYSICAL_ADDR(cur->buffer);
|
||||
/* chain ? */
|
||||
if(cur->cmd & HW_APB_CHx_CMD__CHAIN)
|
||||
if(cur->cmd & BM_APB_CHx_CMD_CHAIN)
|
||||
cur = cur->next;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
cur = cmd;
|
||||
while((cur->cmd & HW_APB_CHx_CMD__UNUSED_BM) != 0)
|
||||
while(BF_RDX(cur->cmd, APB_CHx, CMD_UNUSED) != 0)
|
||||
{
|
||||
cur->cmd = cur->cmd & ~HW_APB_CHx_CMD__UNUSED_BM;
|
||||
int sz = __XTRACT_EX(cur->cmd, HW_APB_CHx_CMD__CMDWORDS) * sizeof(uint32_t);
|
||||
BF_WRX(cur->cmd, APB_CHx, CMD_UNUSED, 0);
|
||||
int sz = BF_RDX(cur->cmd, APB_CHx_CMD, CMDWORDS) * sizeof(uint32_t);
|
||||
/* commit descriptor and discard descriptor */
|
||||
/* chain ? */
|
||||
if(cur->cmd & HW_APB_CHx_CMD__CHAIN)
|
||||
if(cur->cmd & BM_APB_CHx_CMD_CHAIN)
|
||||
{
|
||||
struct apb_dma_command_t *next = cur->next;
|
||||
cur->next = PHYSICAL_ADDR(cur->next);
|
||||
|
|
@ -200,28 +183,28 @@ void imx233_dma_start_command(unsigned chan, struct apb_dma_command_t *cmd)
|
|||
imx233_dma_commit_and_discard(chan, cmd);
|
||||
if(APB_IS_APBX_CHANNEL(chan))
|
||||
{
|
||||
HW_APBX_CHx_NXTCMDAR(APB_GET_DMA_CHANNEL(chan)) = (uint32_t)PHYSICAL_ADDR(cmd);
|
||||
HW_APBX_CHx_SEMA(APB_GET_DMA_CHANNEL(chan)) = 1;
|
||||
HW_APBX_CHn_NXTCMDAR(APB_GET_DMA_CHANNEL(chan)) = (uint32_t)PHYSICAL_ADDR(cmd);
|
||||
HW_APBX_CHn_SEMA(APB_GET_DMA_CHANNEL(chan)) = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
HW_APBH_CHx_NXTCMDAR(APB_GET_DMA_CHANNEL(chan)) = (uint32_t)PHYSICAL_ADDR(cmd);
|
||||
HW_APBH_CHx_SEMA(APB_GET_DMA_CHANNEL(chan)) = 1;
|
||||
HW_APBH_CHn_NXTCMDAR(APB_GET_DMA_CHANNEL(chan)) = (uint32_t)PHYSICAL_ADDR(cmd);
|
||||
HW_APBH_CHn_SEMA(APB_GET_DMA_CHANNEL(chan)) = 1;
|
||||
}
|
||||
}
|
||||
|
||||
int imx233_dma_wait_completion(unsigned chan, unsigned tmo)
|
||||
{
|
||||
tmo += current_tick;
|
||||
volatile uint32_t *sema;
|
||||
int value = 0;
|
||||
if(APB_IS_APBX_CHANNEL(chan))
|
||||
sema = &HW_APBX_CHx_SEMA(APB_GET_DMA_CHANNEL(chan));
|
||||
else
|
||||
sema = &HW_APBH_CHx_SEMA(APB_GET_DMA_CHANNEL(chan));
|
||||
|
||||
while(*sema & HW_APB_CHx_SEMA__PHORE_BM && !TIME_AFTER(current_tick, tmo))
|
||||
while((value = BF_RDn(APBX_CHn_SEMA, APB_GET_DMA_CHANNEL(chan), PHORE)) && !TIME_AFTER(current_tick, tmo))
|
||||
yield();
|
||||
return __XTRACT_EX(*sema, HW_APB_CHx_SEMA__PHORE);
|
||||
else
|
||||
while((value = BF_RDn(APBH_CHn_SEMA, APB_GET_DMA_CHANNEL(chan), PHORE)) && !TIME_AFTER(current_tick, tmo))
|
||||
yield();
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
struct imx233_dma_info_t imx233_dma_get_info(unsigned chan, unsigned flags)
|
||||
|
|
@ -230,35 +213,29 @@ struct imx233_dma_info_t imx233_dma_get_info(unsigned chan, unsigned flags)
|
|||
memset(&s, 0, sizeof(s));
|
||||
bool apbx = APB_IS_APBX_CHANNEL(chan);
|
||||
int dmac = APB_GET_DMA_CHANNEL(chan);
|
||||
uint32_t bm = 1 << dmac;
|
||||
if(flags & DMA_INFO_CURCMDADDR)
|
||||
s.cur_cmd_addr = apbx ? HW_APBX_CHx_CURCMDAR(dmac) : HW_APBH_CHx_CURCMDAR(dmac);
|
||||
s.cur_cmd_addr = apbx ? HW_APBX_CHn_CURCMDAR(dmac) : HW_APBH_CHn_CURCMDAR(dmac);
|
||||
if(flags & DMA_INFO_NXTCMDADDR)
|
||||
s.nxt_cmd_addr = apbx ? HW_APBX_CHx_NXTCMDAR(dmac) : HW_APBH_CHx_NXTCMDAR(dmac);
|
||||
s.nxt_cmd_addr = apbx ? HW_APBX_CHn_NXTCMDAR(dmac) : HW_APBH_CHn_NXTCMDAR(dmac);
|
||||
if(flags & DMA_INFO_CMD)
|
||||
s.cmd = apbx ? HW_APBX_CHx_CMD(dmac) : HW_APBH_CHx_CMD(dmac);
|
||||
s.cmd = apbx ? HW_APBX_CHn_CMD(dmac) : HW_APBH_CHn_CMD(dmac);
|
||||
if(flags & DMA_INFO_BAR)
|
||||
s.bar = apbx ? HW_APBX_CHx_BAR(dmac) : HW_APBH_CHx_BAR(dmac);
|
||||
s.bar = apbx ? HW_APBX_CHn_BAR(dmac) : HW_APBH_CHn_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);
|
||||
s.ahb_bytes = apbx ? BF_RDn(APBX_CHn_DEBUG2, dmac, AHB_BYTES) : BF_RDn(APBH_CHn_DEBUG2, dmac, 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);
|
||||
s.apb_bytes = apbx ? BF_RDn(APBX_CHn_DEBUG2, dmac, APB_BYTES) : BF_RDn(APBH_CHn_DEBUG2, dmac, 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);
|
||||
s.freezed = !!((apbx ? BF_RD(APBX_CHANNEL_CTRL, FREEZE_CHANNEL) : BF_RD(APBH_CTRL0, FREEZE_CHANNEL)) & bm);
|
||||
if(flags & DMA_INFO_GATED)
|
||||
s.gated = apbx ? false : HW_APBH_CTRL0 & HW_APBH_CTRL0__CLKGATE_CHANNEL(dmac);
|
||||
s.gated = apbx ? false : !!(BF_RD(APBH_CTRL0, CLKGATE_CHANNEL) & bm);
|
||||
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);
|
||||
s.int_enabled = !!((apbx ? BF_RD(APBX_CTRL1, CH_CMDCMPLT_IRQ_EN) : BF_RD(APBH_CTRL1, CH_CMDCMPLT_IRQ_EN)) & bm);
|
||||
s.int_cmdcomplt = !!((apbx ? BF_RD(APBX_CTRL1, CH_CMDCMPLT_IRQ) : BF_RD(APBH_CTRL1, CH_CMDCMPLT_IRQ)) & bm);
|
||||
s.int_error = !!((apbx ? BF_RD(APBX_CTRL2, CH_ERROR_IRQ) : BF_RD(APBH_CTRL2, CH_ERROR_IRQ)) & bm);
|
||||
}
|
||||
s.nr_unaligned = apb_nr_unaligned[chan];
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,91 +25,29 @@
|
|||
#include "system.h"
|
||||
#include "system-target.h"
|
||||
|
||||
/********
|
||||
* APHB *
|
||||
********/
|
||||
#include "regs/regs-apbh.h"
|
||||
#include "regs/regs-apbx.h"
|
||||
|
||||
#define HW_APBH_BASE 0x80004000
|
||||
/************
|
||||
* CHANNELS *
|
||||
************/
|
||||
|
||||
/* APHB channels */
|
||||
#define HW_APBH_SSP(ssp) ssp
|
||||
#define HW_APBH_NAND(dev) (4 + (ssp))
|
||||
#define APBH_DMA_CHANNEL(i) i
|
||||
#define APBX_DMA_CHANNEL(i) ((i) | 0x10)
|
||||
#define APB_IS_APBX_CHANNEL(x) ((x) & 0x10)
|
||||
#define APB_GET_DMA_CHANNEL(x) ((x) & 0xf)
|
||||
|
||||
#define HW_APBH_CTRL0 (*(volatile uint32_t *)(HW_APBH_BASE + 0x0))
|
||||
#define HW_APBH_CTRL0__FREEZE_CHANNEL(i) (1 << (i))
|
||||
#define HW_APBH_CTRL0__CLKGATE_CHANNEL(i) (1 << ((i) + 8))
|
||||
#define HW_APBH_CTRL0__RESET_CHANNEL(i) (1 << ((i) + 16))
|
||||
#define HW_APBH_CTRL0__APB_BURST4_EN (1 << 28)
|
||||
#define HW_APBH_CTRL0__APB_BURST8_EN (1 << 29)
|
||||
// NOTE: although undocumented, the iMX233 channel 0 is actually the LCDIF one
|
||||
#define APB_LCDIF APBH_DMA_CHANNEL(0)
|
||||
|
||||
#define HW_APBH_CTRL1 (*(volatile uint32_t *)(HW_APBH_BASE + 0x10))
|
||||
#define HW_APBH_CTRL1__CHx_CMDCMPLT_IRQ(i) (1 << (i))
|
||||
#define HW_APBH_CTRL1__CHx_CMDCMPLT_IRQ_EN(i) (1 << ((i) + 16))
|
||||
#define APB_SSP(ssp) APBH_DMA_CHANNEL(ssp)
|
||||
#define APB_GPMI(dev) APBH_DMA_CHANNEL(4 + (dev))
|
||||
|
||||
#define HW_APBH_CTRL2 (*(volatile uint32_t *)(HW_APBH_BASE + 0x20))
|
||||
#define HW_APBH_CTRL2__CHx_ERROR_IRQ(i) (1 << (i))
|
||||
#define HW_APBH_CTRL2__CHx_ERROR_STATUS(i) (1 << ((i) + 16))
|
||||
|
||||
#define HW_APBH_CHx_CURCMDAR(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x40 + 0x70 * (i)))
|
||||
|
||||
#define HW_APBH_CHx_NXTCMDAR(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x50 + 0x70 * (i)))
|
||||
|
||||
#define HW_APBH_CHx_CMD(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x60 + 0x70 * (i)))
|
||||
|
||||
#define HW_APBH_CHx_BAR(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x70 + 0x70 * (i)))
|
||||
|
||||
#define HW_APBH_CHx_SEMA(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x80 + 0x70 * (i)))
|
||||
|
||||
#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 *
|
||||
********/
|
||||
|
||||
/* APHX channels */
|
||||
#define HW_APBX_AUDIO_ADC 0
|
||||
#define HW_APBX_AUDIO_DAC 1
|
||||
#define HW_APBX_I2C 3
|
||||
|
||||
#define HW_APBX_BASE 0x80024000
|
||||
|
||||
#define HW_APBX_CTRL0 (*(volatile uint32_t *)(HW_APBX_BASE + 0x0))
|
||||
|
||||
#define HW_APBX_CTRL1 (*(volatile uint32_t *)(HW_APBX_BASE + 0x10))
|
||||
#define HW_APBX_CTRL1__CHx_CMDCMPLT_IRQ(i) (1 << (i))
|
||||
#define HW_APBX_CTRL1__CHx_CMDCMPLT_IRQ_EN(i) (1 << ((i) + 16))
|
||||
|
||||
#define HW_APBX_CTRL2 (*(volatile uint32_t *)(HW_APBX_BASE + 0x20))
|
||||
#define HW_APBX_CTRL2__CHx_ERROR_IRQ(i) (1 << (i))
|
||||
#define HW_APBX_CTRL2__CHx_ERROR_STATUS(i) (1 << ((i) + 16))
|
||||
|
||||
#define HW_APBX_CHANNEL_CTRL (*(volatile uint32_t *)(HW_APBX_BASE + 0x30))
|
||||
#define HW_APBX_CHANNEL_CTRL__FREEZE_CHANNEL(i) (1 << (i))
|
||||
#define HW_APBX_CHANNEL_CTRL__RESET_CHANNEL(i) (1 << ((i) + 16))
|
||||
|
||||
#define HW_APBX_CHx_CURCMDAR(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x100 + (i) * 0x70))
|
||||
|
||||
#define HW_APBX_CHx_NXTCMDAR(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x110 + (i) * 0x70))
|
||||
|
||||
#define HW_APBX_CHx_CMD(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x120 + (i) * 0x70))
|
||||
|
||||
#define HW_APBX_CHx_BAR(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x130 + (i) * 0x70))
|
||||
|
||||
#define HW_APBX_CHx_SEMA(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x140 + (i) * 0x70))
|
||||
|
||||
#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
|
||||
#define APB_AUDIO_ADC APBX_DMA_CHANNEL(0)
|
||||
#define APB_AUDIO_DAC APBX_DMA_CHANNEL(1)
|
||||
#define APB_I2C APBX_DMA_CHANNEL(3)
|
||||
// NOTE: although undocumented, the IMX233 channel 5 is actually the DRI one
|
||||
#define APB_DRI APBX_DMA_CHANNEL(5)
|
||||
|
||||
/**********
|
||||
* COMMON *
|
||||
|
|
@ -154,43 +92,49 @@ struct imx233_dma_info_t
|
|||
int nr_unaligned;
|
||||
};
|
||||
|
||||
#define APBH_DMA_CHANNEL(i) i
|
||||
#define APBX_DMA_CHANNEL(i) ((i) | 0x10)
|
||||
#define APB_IS_APBX_CHANNEL(x) ((x) & 0x10)
|
||||
#define APB_GET_DMA_CHANNEL(x) ((x) & 0xf)
|
||||
|
||||
#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 APB_NAND(dev) APBH_DMA_CHANNEL(HW_APBH_NAND(dev))
|
||||
|
||||
#define HW_APB_CHx_CMD__COMMAND_BM 0x3
|
||||
#define HW_APB_CHx_CMD__COMMAND_BP 0
|
||||
#define HW_APB_CHx_CMD__COMMAND__NO_XFER 0
|
||||
#define HW_APB_CHx_CMD__COMMAND__WRITE 1
|
||||
#define HW_APB_CHx_CMD__COMMAND__READ 2
|
||||
#define HW_APB_CHx_CMD__COMMAND__SENSE 3
|
||||
#define HW_APB_CHx_CMD__CHAIN (1 << 2)
|
||||
#define HW_APB_CHx_CMD__IRQONCMPLT (1 << 3)
|
||||
#define BM_APB_CHx_CMD_COMMAND 0x3
|
||||
#define BP_APB_CHx_CMD_COMMAND 0
|
||||
#define BF_APB_CHx_CMD_COMMAND(v) ((v) & 0x3)
|
||||
#define BF_APB_CHx_CMD_COMMAND_V(v) BF_APB_CHx_CMD_COMMAND(BV_APB_CHx_CMD_COMMAND__##v)
|
||||
#define BV_APB_CHx_CMD_COMMAND__NO_XFER 0
|
||||
#define BV_APB_CHx_CMD_COMMAND__WRITE 1
|
||||
#define BV_APB_CHx_CMD_COMMAND__READ 2
|
||||
#define BV_APB_CHx_CMD_COMMAND__SENSE 3
|
||||
#define BM_APB_CHx_CMD_CHAIN (1 << 2)
|
||||
#define BP_APB_CHx_CMD_CHAIN 2
|
||||
#define BF_APB_CHx_CMD_CHAIN(v) (((v) & 1) << 2)
|
||||
#define BM_APB_CHx_CMD_IRQONCMPLT (1 << 3)
|
||||
#define BP_APB_CHx_CMD_IRQONCMPLT 3
|
||||
#define BF_APB_CHx_CMD_IRQONCMPLT(v) (((v) & 1) << 3)
|
||||
/* those two are only available on APHB */
|
||||
#define HW_APBH_CHx_CMD__NANDLOCK (1 << 4)
|
||||
#define HW_APBH_CHx_CMD__NANDWAIT4READY (1 << 5)
|
||||
#define HW_APB_CHx_CMD__SEMAPHORE (1 << 6)
|
||||
#define HW_APB_CHx_CMD__WAIT4ENDCMD (1 << 7)
|
||||
/* An errata advise not to use it */
|
||||
#define HW_APB_CHx_CMD__HALTONTERMINATE (1 << 8)
|
||||
#define HW_APB_CHx_CMD__CMDWORDS_BM 0xf000
|
||||
#define HW_APB_CHx_CMD__CMDWORDS_BP 12
|
||||
#define HW_APB_CHx_CMD__XFER_COUNT_BM 0xffff0000
|
||||
#define HW_APB_CHx_CMD__XFER_COUNT_BP 16
|
||||
/* For software use */
|
||||
#define HW_APB_CHx_CMD__UNUSED_BP 8
|
||||
#define HW_APB_CHx_CMD__UNUSED_BM (0xf << 8)
|
||||
#define HW_APB_CHx_CMD__UNUSED_MAGIC (0xa << 8)
|
||||
#define BM_APBH_CHx_CMD_NANDLOCK (1 << 4)
|
||||
#define BP_APBH_CHx_CMD_NANDLOCK 4
|
||||
#define BF_APBH_CHx_CMD_NANDLOCK(v) (((v) & 1) << 4)
|
||||
#define BM_APBH_CHx_CMD_NANDWAIT4READY (1 << 5)
|
||||
#define BP_APBH_CHx_CMD_NANDWAIT4READY 5
|
||||
#define BF_APBH_CHx_CMD_NANDWAIT4READY(v) (((v) & 1) << 5)
|
||||
|
||||
#define HW_APB_CHx_SEMA__PHORE_BM 0xff0000
|
||||
#define HW_APB_CHx_SEMA__PHORE_BP 16
|
||||
#define BM_APB_CHx_CMD_SEMAPHORE (1 << 6)
|
||||
#define BP_APB_CHx_CMD_SEMAPHORE 6
|
||||
#define BF_APB_CHx_CMD_SEMAPHORE(v) (((v) & 1) << 6)
|
||||
#define BM_APB_CHx_CMD_WAIT4ENDCMD (1 << 7)
|
||||
#define BP_APB_CHx_CMD_WAIT4ENDCMD 7
|
||||
#define BF_APB_CHx_CMD_WAIT4ENDCMD(v) (((v) & 1) << 7)
|
||||
/** WARNING: An errata advise not to use it */
|
||||
#define BM_APB_CHx_CMD_HALTONTERMINATE (1 << 8)
|
||||
#define BP_APB_CHx_CMD_HALTONTERMINATE 8
|
||||
#define BF_APB_CHx_CMD_HALTONTERMINATE(v) (((v) & 1) << 8)
|
||||
#define BM_APB_CHx_CMD_CMDWORDS 0xf000
|
||||
#define BP_APB_CHx_CMD_CMDWORDS 12
|
||||
#define BF_APB_CHx_CMD_CMDWORDS(v) (((v) & 0xf) << 12)
|
||||
#define BM_APB_CHx_CMD_XFER_COUNT 0xffff0000
|
||||
#define BP_APB_CHx_CMD_XFER_COUNT 16
|
||||
#define BF_APB_CHx_CMD_XFER_COUNT(v) (((v) & 0xffff) << 16)
|
||||
/* For software use */
|
||||
#define BP_APB_CHx_CMD_UNUSED 8
|
||||
#define BM_APB_CHx_CMD_UNUSED (0xf << 8)
|
||||
#define BF_APB_CHx_CMD_UNUSED(v) (((v) & 0xf) << 8)
|
||||
#define BV_APB_CHx_CMD_UNUSED__MAGIC 0xa
|
||||
|
||||
/* A single descriptor cannot transfer more than 2^16 bytes but because of the
|
||||
* weird 0=64KiB, it's safer to restrict to 2^15 */
|
||||
|
|
|
|||
|
|
@ -145,17 +145,15 @@ enum imx233_i2c_error_t imx233_i2c_add(bool start, bool transmit, void *buffer,
|
|||
if(i2c_nr_stages > 0)
|
||||
{
|
||||
i2c_stage[i2c_nr_stages - 1].dma.next = &i2c_stage[i2c_nr_stages].dma;
|
||||
i2c_stage[i2c_nr_stages - 1].dma.cmd |= HW_APB_CHx_CMD__CHAIN;
|
||||
i2c_stage[i2c_nr_stages - 1].dma.cmd |= BM_APB_CHx_CMD_CHAIN;
|
||||
if(!start)
|
||||
i2c_stage[i2c_nr_stages - 1].ctrl0 |= BM_I2C_CTRL0_RETAIN_CLOCK;
|
||||
}
|
||||
i2c_stage[i2c_nr_stages].dma.buffer = i2c_buffer + start_off;
|
||||
i2c_stage[i2c_nr_stages].dma.next = NULL;
|
||||
i2c_stage[i2c_nr_stages].dma.cmd =
|
||||
(transmit ? HW_APB_CHx_CMD__COMMAND__READ : HW_APB_CHx_CMD__COMMAND__WRITE) |
|
||||
HW_APB_CHx_CMD__WAIT4ENDCMD |
|
||||
1 << HW_APB_CHx_CMD__CMDWORDS_BP |
|
||||
size << HW_APB_CHx_CMD__XFER_COUNT_BP;
|
||||
i2c_stage[i2c_nr_stages].dma.cmd = BF_OR4(APB_CHx_CMD,
|
||||
COMMAND(transmit ? BV_APB_CHx_CMD_COMMAND__READ : BV_APB_CHx_CMD_COMMAND__WRITE),
|
||||
WAIT4ENDCMD(1), CMDWORDS(1), XFER_COUNT(size));
|
||||
/* assume that any read is final (send nak on last) */
|
||||
i2c_stage[i2c_nr_stages].ctrl0 = BF_OR6(I2C_CTRL0,
|
||||
XFER_COUNT(size), DIRECTION(transmit), SEND_NAK_ON_LAST(!transmit),
|
||||
|
|
@ -170,8 +168,8 @@ static enum imx233_i2c_error_t imx233_i2c_finalize(void)
|
|||
for(int i = 0; i < i2c_nr_stages; i++)
|
||||
{
|
||||
struct i2c_dma_command_t *c = &i2c_stage[i];
|
||||
if(__XTRACT_EX(c->dma.cmd, HW_APB_CHx_CMD__COMMAND) == HW_APB_CHx_CMD__COMMAND__WRITE)
|
||||
memcpy(c->dst, c->src, __XTRACT_EX(c->dma.cmd, HW_APB_CHx_CMD__XFER_COUNT));
|
||||
if(BF_RDX(c->dma.cmd, APB_CHx_CMD, COMMAND) == BV_APB_CHx_CMD_COMMAND__WRITE)
|
||||
memcpy(c->dst, c->src, BF_RDX(c->dma.cmd, APB_CHx_CMD, XFER_COUNT));
|
||||
}
|
||||
return I2C_SUCCESS;
|
||||
}
|
||||
|
|
@ -180,7 +178,7 @@ enum imx233_i2c_error_t imx233_i2c_end(unsigned timeout)
|
|||
{
|
||||
if(i2c_nr_stages == 0)
|
||||
return I2C_ERROR;
|
||||
i2c_stage[i2c_nr_stages - 1].dma.cmd |= HW_APB_CHx_CMD__SEMAPHORE | HW_APB_CHx_CMD__IRQONCMPLT;
|
||||
i2c_stage[i2c_nr_stages - 1].dma.cmd |= BM_APB_CHx_CMD_SEMAPHORE | BM_APB_CHx_CMD_IRQONCMPLT;
|
||||
|
||||
BF_CLR(I2C_CTRL1, ALL_IRQ);
|
||||
imx233_dma_reset_channel(APB_I2C);
|
||||
|
|
|
|||
|
|
@ -48,10 +48,8 @@ static void play(const void *addr, size_t size)
|
|||
{
|
||||
dac_dma.dma.next = NULL;
|
||||
dac_dma.dma.buffer = (void *)addr;
|
||||
dac_dma.dma.cmd = HW_APB_CHx_CMD__COMMAND__READ |
|
||||
HW_APB_CHx_CMD__IRQONCMPLT |
|
||||
HW_APB_CHx_CMD__SEMAPHORE |
|
||||
size << HW_APB_CHx_CMD__XFER_COUNT_BP;
|
||||
dac_dma.dma.cmd = BF_OR4(APB_CHx_CMD, COMMAND_V(READ),
|
||||
IRQONCMPLT(1), SEMAPHORE(1), XFER_COUNT(size));
|
||||
/* dma subsystem will make sure cached stuff is written to memory */
|
||||
imx233_dma_start_command(APB_AUDIO_DAC, &dac_dma.dma);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -285,13 +285,10 @@ enum imx233_ssp_error_t imx233_ssp_sd_mmc_transfer(int ssp, uint8_t cmd,
|
|||
/* setup the dma parameters */
|
||||
ssp_dma_cmd[ssp - 1].dma.buffer = buffer;
|
||||
ssp_dma_cmd[ssp - 1].dma.next = NULL;
|
||||
ssp_dma_cmd[ssp - 1].dma.cmd =
|
||||
(buffer == NULL ? HW_APB_CHx_CMD__COMMAND__NO_XFER :
|
||||
read ? HW_APB_CHx_CMD__COMMAND__WRITE : HW_APB_CHx_CMD__COMMAND__READ) |
|
||||
HW_APB_CHx_CMD__IRQONCMPLT | HW_APB_CHx_CMD__SEMAPHORE |
|
||||
HW_APB_CHx_CMD__WAIT4ENDCMD |
|
||||
(3 << HW_APB_CHx_CMD__CMDWORDS_BP) |
|
||||
(xfer_size << HW_APB_CHx_CMD__XFER_COUNT_BP);
|
||||
ssp_dma_cmd[ssp - 1].dma.cmd = BF_OR6(APB_CHx_CMD,
|
||||
COMMAND(buffer == NULL ? BV_APB_CHx_CMD_COMMAND__NO_XFER :
|
||||
read ? BV_APB_CHx_CMD_COMMAND__WRITE : BV_APB_CHx_CMD_COMMAND__READ),
|
||||
IRQONCMPLT(1), SEMAPHORE(1), WAIT4ENDCMD(1), CMDWORDS(3), XFER_COUNT(xfer_size));
|
||||
|
||||
SSP_CLRn(SSP_CTRL1, ssp, ALL_IRQ);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue