Line 237... |
Line 237... |
void dma_write_ch_csr( struct dma_channel *channel, unsigned long value )
|
void dma_write_ch_csr( struct dma_channel *channel, unsigned long value )
|
{
|
{
|
/* Check if we should *start* a transfer */
|
/* Check if we should *start* a transfer */
|
if ( !TEST_FLAG( channel->regs.csr, DMA_CH_CSR, CH_EN ) &&
|
if ( !TEST_FLAG( channel->regs.csr, DMA_CH_CSR, CH_EN ) &&
|
TEST_FLAG( value, DMA_CH_CSR, CH_EN ))
|
TEST_FLAG( value, DMA_CH_CSR, CH_EN ))
|
SCHED_ADD( dma_channel_clock, channel, runtime.sim.cycles + 1 );
|
SCHED_ADD( dma_channel_clock, channel, 1 );
|
else if ( !TEST_FLAG( value, DMA_CH_CSR, CH_EN ) )
|
else if ( !TEST_FLAG( value, DMA_CH_CSR, CH_EN ) )
|
/* The CH_EN flag is clear, check if we have a transfer in progress and
|
/* The CH_EN flag is clear, check if we have a transfer in progress and
|
* clear it */
|
* clear it */
|
SCHED_FIND_REMOVE( dma_channel_clock, channel );
|
SCHED_FIND_REMOVE( dma_channel_clock, channel );
|
|
|
Line 279... |
Line 279... |
}
|
}
|
|
|
/* In HW Handshake mode, only work when dma_req_i asserted */
|
/* In HW Handshake mode, only work when dma_req_i asserted */
|
if ( TEST_FLAG(channel->regs.csr, DMA_CH_CSR, MODE) && !channel->dma_req_i ) {
|
if ( TEST_FLAG(channel->regs.csr, DMA_CH_CSR, MODE) && !channel->dma_req_i ) {
|
/* Reschedule */
|
/* Reschedule */
|
SCHED_ADD( dma_channel_clock, dat, runtime.sim.cycles + 1 );
|
SCHED_ADD( dma_channel_clock, dat, 1 );
|
return;
|
return;
|
}
|
}
|
|
|
/* If this is the first cycle of the transfer, initialize our state */
|
/* If this is the first cycle of the transfer, initialize our state */
|
if ( !TEST_FLAG( channel->regs.csr, DMA_CH_CSR, BUSY ) ) {
|
if ( !TEST_FLAG( channel->regs.csr, DMA_CH_CSR, BUSY ) ) {
|
Line 333... |
Line 333... |
dma_channel_terminate_transfer( channel, 1 );
|
dma_channel_terminate_transfer( channel, 1 );
|
return;
|
return;
|
}
|
}
|
|
|
/* Reschedule to transfer the next chunk */
|
/* Reschedule to transfer the next chunk */
|
SCHED_ADD( dma_channel_clock, dat, runtime.sim.cycles + 1 );
|
SCHED_ADD( dma_channel_clock, dat, 1 );
|
}
|
}
|
|
|
|
|
/* Copy relevant valued from linked list descriptor to channel registers */
|
/* Copy relevant valued from linked list descriptor to channel registers */
|
void dma_load_descriptor( struct dma_channel *channel )
|
void dma_load_descriptor( struct dma_channel *channel )
|
Line 385... |
Line 385... |
/* Might be working in a linked list */
|
/* Might be working in a linked list */
|
if ( channel->load_next_descriptor_when_done ) {
|
if ( channel->load_next_descriptor_when_done ) {
|
dma_load_descriptor( channel );
|
dma_load_descriptor( channel );
|
dma_init_transfer( channel );
|
dma_init_transfer( channel );
|
/* Reschedule */
|
/* Reschedule */
|
SCHED_ADD( dma_channel_clock, channel, runtime.sim.cycles + 1 );
|
SCHED_ADD( dma_channel_clock, channel, 1 );
|
return;
|
return;
|
}
|
}
|
|
|
/* Might be in auto-restart mode */
|
/* Might be in auto-restart mode */
|
if ( TEST_FLAG( channel->regs.csr, DMA_CH_CSR, ARS ) ) {
|
if ( TEST_FLAG( channel->regs.csr, DMA_CH_CSR, ARS ) ) {
|