OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [stable_0_2_0_rc2/] [or1ksim/] [peripheral/] [dma.c] - Diff between revs 1487 and 1491

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 1487 Rev 1491
Line 40... Line 40...
#include "abstract.h"
#include "abstract.h"
#include "fields.h"
#include "fields.h"
#include "sched.h"
#include "sched.h"
#include "debug.h"
#include "debug.h"
 
 
 
DEFAULT_DEBUG_CHANNEL(dma);
 
 
/* We keep a copy of all our controllers because we have to export an interface
/* We keep a copy of all our controllers because we have to export an interface
 * to other peripherals eg. ethernet */
 * to other peripherals eg. ethernet */
static struct dma_controller *dmas = NULL;
static struct dma_controller *dmas = NULL;
 
 
static uint32_t dma_read32( oraddr_t addr, void *dat );
static uint32_t dma_read32( oraddr_t addr, void *dat );
Line 241... Line 243...
{
{
  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" );
    TRACE( "DMA: STOP requested\n" );
    CLEAR_FLAG( channel->regs.csr, DMA_CH_CSR, CH_EN );
    CLEAR_FLAG( channel->regs.csr, DMA_CH_CSR, CH_EN );
    CLEAR_FLAG( channel->regs.csr, DMA_CH_CSR, BUSY );
    CLEAR_FLAG( channel->regs.csr, DMA_CH_CSR, BUSY );
    SET_FLAG( channel->regs.csr, DMA_CH_CSR, ERR );
    SET_FLAG( channel->regs.csr, DMA_CH_CSR, ERR );
 
 
    if ( TEST_FLAG( channel->regs.csr, DMA_CH_CSR, INE_ERR ) &&
    if ( TEST_FLAG( channel->regs.csr, DMA_CH_CSR, INE_ERR ) &&
Line 265... Line 267...
    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 ) ) {
    debug( 4,  "DMA: Starting new transfer\n" );
    TRACE( "DMA: Starting new transfer\n" );
 
 
    CLEAR_FLAG( channel->regs.csr, DMA_CH_CSR, DONE );
    CLEAR_FLAG( channel->regs.csr, DMA_CH_CSR, DONE );
    CLEAR_FLAG( channel->regs.csr, DMA_CH_CSR, ERR );
    CLEAR_FLAG( channel->regs.csr, DMA_CH_CSR, ERR );
    SET_FLAG( channel->regs.csr, DMA_CH_CSR, BUSY );
    SET_FLAG( channel->regs.csr, DMA_CH_CSR, BUSY );
 
 
Line 282... Line 284...
    /* Set our internal status */
    /* Set our internal status */
    dma_init_transfer( channel );
    dma_init_transfer( channel );
 
 
    /* Might need to skip descriptor */
    /* Might need to skip descriptor */
    if ( CHANNEL_ND_I( channel ) ) {
    if ( CHANNEL_ND_I( channel ) ) {
      debug( 3,  "DMA: dma_nd_i asserted before dma_req_i, skipping descriptor\n" );
      TRACE( "DMA: dma_nd_i asserted before dma_req_i, skipping descriptor\n" );
      dma_channel_terminate_transfer( channel, 0 );
      dma_channel_terminate_transfer( channel, 0 );
      return;
      return;
    }
    }
  }
  }
 
 
Line 302... Line 304...
  /* Have we finished a whole chunk? */
  /* Have we finished a whole chunk? */
  channel->dma_ack_o = (channel->words_transferred % channel->chunk_size == 0);
  channel->dma_ack_o = (channel->words_transferred % channel->chunk_size == 0);
 
 
  /* When done with a chunk, check for dma_nd_i */
  /* When done with a chunk, check for dma_nd_i */
  if ( CHANNEL_ND_I( channel ) ) {
  if ( CHANNEL_ND_I( channel ) ) {
    debug( 3,  "DMA: dma_nd_i asserted\n" );
    TRACE( "DMA: dma_nd_i asserted\n" );
    dma_channel_terminate_transfer( channel, 0 );
    dma_channel_terminate_transfer( channel, 0 );
    return;
    return;
  }
  }
 
 
  /* Are we done? */
  /* Are we done? */
Line 358... Line 360...
 
 
 
 
/* Take care of transfer termination */
/* Take care of transfer termination */
void dma_channel_terminate_transfer( struct dma_channel *channel, int generate_interrupt )
void dma_channel_terminate_transfer( struct dma_channel *channel, int generate_interrupt )
{
{
  debug( 4,  "DMA: Terminating transfer\n" );
  TRACE( "DMA: Terminating transfer\n" );
 
 
  /* 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 );

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.