Line 237... |
Line 237... |
* This does the actual "DMA" operation.
|
* This does the actual "DMA" operation.
|
* One chunk is transferred per clock.
|
* One chunk is transferred per clock.
|
*/
|
*/
|
void dma_channel_clock( void *dat )
|
void dma_channel_clock( void *dat )
|
{
|
{
|
int breakpoint = 0;
|
|
struct dma_channel *channel = dat;
|
struct dma_channel *channel = dat;
|
|
|
/* Do we need to abort? */
|
/* Do we need to abort? */
|
if ( TEST_FLAG( channel->regs.csr, DMA_CH_CSR, STOP ) ) {
|
if ( TEST_FLAG( channel->regs.csr, DMA_CH_CSR, STOP ) ) {
|
debug( 3, "DMA: STOP requested\n" );
|
debug( 3, "DMA: STOP requested\n" );
|
Line 290... |
Line 289... |
return;
|
return;
|
}
|
}
|
}
|
}
|
|
|
/* Transfer one word */
|
/* Transfer one word */
|
set_direct32( channel->destination, eval_direct32( channel->source,
|
set_direct32( channel->destination, eval_direct32( channel->source, 0, 0 ),
|
&breakpoint, 0, 0 ),
|
0, 0 );
|
&breakpoint, 0, 0 );
|
|
|
|
/* Advance the source and destionation pointers */
|
/* Advance the source and destionation pointers */
|
masked_increase( &(channel->source), channel->source_mask );
|
masked_increase( &(channel->source), channel->source_mask );
|
masked_increase( &(channel->destination), channel->destination_mask );
|
masked_increase( &(channel->destination), channel->destination_mask );
|
++ channel->words_transferred;
|
++ channel->words_transferred;
|
Line 323... |
Line 321... |
|
|
|
|
/* 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 )
|
{
|
{
|
int breakpoint = 0;
|
unsigned long desc_csr = eval_direct32( channel->regs.desc + DMA_DESC_CSR, 0, 0 );
|
unsigned long desc_csr = eval_direct32( channel->regs.desc + DMA_DESC_CSR, &breakpoint, 0, 0 );
|
|
|
|
channel->load_next_descriptor_when_done = !TEST_FLAG( desc_csr, DMA_DESC_CSR, EOL );
|
channel->load_next_descriptor_when_done = !TEST_FLAG( desc_csr, DMA_DESC_CSR, EOL );
|
|
|
ASSIGN_FLAG( channel->regs.csr, DMA_CH_CSR, INC_SRC, TEST_FLAG( desc_csr, DMA_DESC_CSR, INC_SRC ) );
|
ASSIGN_FLAG( channel->regs.csr, DMA_CH_CSR, INC_SRC, TEST_FLAG( desc_csr, DMA_DESC_CSR, INC_SRC ) );
|
ASSIGN_FLAG( channel->regs.csr, DMA_CH_CSR, INC_DST, TEST_FLAG( desc_csr, DMA_DESC_CSR, INC_DST ) );
|
ASSIGN_FLAG( channel->regs.csr, DMA_CH_CSR, INC_DST, TEST_FLAG( desc_csr, DMA_DESC_CSR, INC_DST ) );
|
ASSIGN_FLAG( channel->regs.csr, DMA_CH_CSR, SRC_SEL, TEST_FLAG( desc_csr, DMA_DESC_CSR, SRC_SEL ) );
|
ASSIGN_FLAG( channel->regs.csr, DMA_CH_CSR, SRC_SEL, TEST_FLAG( desc_csr, DMA_DESC_CSR, SRC_SEL ) );
|
ASSIGN_FLAG( channel->regs.csr, DMA_CH_CSR, DST_SEL, TEST_FLAG( desc_csr, DMA_DESC_CSR, DST_SEL ) );
|
ASSIGN_FLAG( channel->regs.csr, DMA_CH_CSR, DST_SEL, TEST_FLAG( desc_csr, DMA_DESC_CSR, DST_SEL ) );
|
|
|
SET_FIELD( channel->regs.sz, DMA_CH_SZ, TOT_SZ, GET_FIELD( desc_csr, DMA_DESC_CSR, TOT_SZ ) );
|
SET_FIELD( channel->regs.sz, DMA_CH_SZ, TOT_SZ, GET_FIELD( desc_csr, DMA_DESC_CSR, TOT_SZ ) );
|
|
|
channel->regs.a0 = eval_direct32( channel->regs.desc + DMA_DESC_ADR0, &breakpoint, 0, 0 );
|
channel->regs.a0 = eval_direct32( channel->regs.desc + DMA_DESC_ADR0, 0, 0 );
|
channel->regs.a1 = eval_direct32( channel->regs.desc + DMA_DESC_ADR1, &breakpoint, 0, 0 );
|
channel->regs.a1 = eval_direct32( channel->regs.desc + DMA_DESC_ADR1, 0, 0 );
|
|
|
channel->current_descriptor = channel->regs.desc;
|
channel->current_descriptor = channel->regs.desc;
|
channel->regs.desc = eval_direct32( channel->regs.desc + DMA_DESC_NEXT, &breakpoint, 0, 0 );
|
channel->regs.desc = eval_direct32( channel->regs.desc + DMA_DESC_NEXT, 0, 0 );
|
}
|
}
|
|
|
|
|
/* Initialize internal parameters used to implement transfers */
|
/* Initialize internal parameters used to implement transfers */
|
void dma_init_transfer( struct dma_channel *channel )
|
void dma_init_transfer( struct dma_channel *channel )
|