コード例 #1
0
static  void clear_chan_interrupts(int c)
{
    out_le32(&(host_pvt.sata_dma_regs->interrupt_clear.tfr.low),
             DMA_CHANNEL(c));
    out_le32(&(host_pvt.sata_dma_regs->interrupt_clear.block.low),
             DMA_CHANNEL(c));
    out_le32(&(host_pvt.sata_dma_regs->interrupt_clear.srctran.low),
             DMA_CHANNEL(c));
    out_le32(&(host_pvt.sata_dma_regs->interrupt_clear.dsttran.low),
             DMA_CHANNEL(c));
    out_le32(&(host_pvt.sata_dma_regs->interrupt_clear.error.low),
             DMA_CHANNEL(c));
}
コード例 #2
0
/*
 * Function: dma_request_channel
 * arguments: None
 * returns channel number if available else -1
 * This function assigns the next available DMA channel from the list to the
 * requester
 */
static int dma_request_channel(void)
{
	/* Check if the channel is not currently in use */
	if (!(in_le32(&(host_pvt.sata_dma_regs->dma_chan_en.low)) &
		DMA_CHANNEL(host_pvt.dma_channel)))
		return host_pvt.dma_channel;
	dev_err(host_pvt.dwc_dev, "%s Channel %d is currently in use\n",
		__func__, host_pvt.dma_channel);
	return -1;
}
コード例 #3
0
ファイル: au1xmmc.c プロジェクト: prime5711/blackbox
static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status) 
{

	struct mmc_request *mrq = host->mrq;
	struct mmc_data *data;
	u32 crc;

	WARN_ON(host->status != HOST_S_DATA && host->status != HOST_S_STOP);

	if (host->mrq == NULL)
		return;

	data = mrq->cmd->data;

	if (status == 0)
		status = au_readl(HOST_STATUS(host));

	/* The transaction is really over when the SD_STATUS_DB bit is clear */

	while((host->flags & HOST_F_XMIT) && (status & SD_STATUS_DB)) 
		status = au_readl(HOST_STATUS(host));

	data->error = MMC_ERR_NONE;
	dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, host->dma.dir);

        /* Process any errors */

	crc = (status & (SD_STATUS_WC | SD_STATUS_RC));
	if (host->flags & HOST_F_XMIT) 
		crc |= ((status & 0x07) == 0x02) ? 0 : 1;
	
	if (crc) 
		data->error = MMC_ERR_BADCRC;

	/* Clear the CRC bits */
	au_writel(SD_STATUS_WC | SD_STATUS_RC, HOST_STATUS(host));

	data->bytes_xfered = 0;

	if (data->error == MMC_ERR_NONE) {
		if (host->flags & HOST_F_DMA) {
			u32 chan = DMA_CHANNEL(host);

			chan_tab_t *c = *((chan_tab_t **) chan);
			au1x_dma_chan_t *cp = c->chan_ptr;
			data->bytes_xfered = cp->ddma_bytecnt;
		}
		else 
			data->bytes_xfered = 
				(data->blocks * (1 << data->blksz_bits)) - 
				host->pio.len;
	}

	au1xmmc_finish_request(host);
}
コード例 #4
0
static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status)
{
	struct mmc_request *mrq = host->mrq;
	struct mmc_data *data;
	u32 crc;

	WARN_ON((host->status != HOST_S_DATA) && (host->status != HOST_S_STOP));

	if (host->mrq == NULL)
		return;

	data = mrq->cmd->data;

	if (status == 0)
		status = au_readl(HOST_STATUS(host));

	
	while ((host->flags & HOST_F_XMIT) && (status & SD_STATUS_DB))
		status = au_readl(HOST_STATUS(host));

	data->error = 0;
	dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, host->dma.dir);

        
	crc = (status & (SD_STATUS_WC | SD_STATUS_RC));
	if (host->flags & HOST_F_XMIT)
		crc |= ((status & 0x07) == 0x02) ? 0 : 1;

	if (crc)
		data->error = -EILSEQ;

	
	au_writel(SD_STATUS_WC | SD_STATUS_RC, HOST_STATUS(host));

	data->bytes_xfered = 0;

	if (!data->error) {
		if (host->flags & HOST_F_DMA) {
#ifdef CONFIG_SOC_AU1200	
			u32 chan = DMA_CHANNEL(host);

			chan_tab_t *c = *((chan_tab_t **)chan);
			au1x_dma_chan_t *cp = c->chan_ptr;
			data->bytes_xfered = cp->ddma_bytecnt;
#endif
		} else
			data->bytes_xfered =
				(data->blocks * data->blksz) - host->pio.len;
	}

	au1xmmc_finish_request(host);
}
コード例 #5
0
static int dma_request_channel(void)
{
    int i;

    for (i = 0; i < DMA_NUM_CHANS; i++) {
        if (!(in_le32(&(host_pvt.sata_dma_regs->dma_chan_en.low)) &\
                DMA_CHANNEL(i)))
            return i;
    }
    dev_err(host_pvt.dwc_dev, "%s NO channel chan_en: 0x%08x\n", __func__,
            in_le32(&(host_pvt.sata_dma_regs->dma_chan_en.low)));
    return -1;
}
コード例 #6
0
ファイル: xdma.c プロジェクト: Limius/cox
//! This function dynamic allocate a channel according the DMA requests.
//! The \ref ulDMASrcRequest and \ref ulDMADestRequest can be:
//! - \ref DMA_REQUEST_ADC0_RX
//! - \ref DMA_REQUEST_TIM2_CH3
//! - \ref DMA_REQUEST_TIM4_CH1
//! - \ref DMA_REQUEST_UART3_TX
//! - \ref DMA_REQUEST_TIM1_CH1
//! - \ref DMA_REQUEST_TIM2_UP
//! - \ref DMA_REQUEST_TIM3_CH3
//! - \ref DMA_REQUEST_SPI1_RX
//! - \ref DMA_REQUEST_UART3_RX
//! - \ref DMA_REQUEST_TIM1_CH2
//! - \ref DMA_REQUEST_TIM3_CH4
//! - \ref DMA_REQUEST_TIM3_UP
//! - others refrence \ref STM32F1xx_DMA_Request_Connections
//! .
//!
//! \note ulDMASrcRequest can only be XX_RX and TIMx_CHx
//! ulDMADestRequest can only be XX_TX,TIMx_TRIG,TIMx_COM and TIMx_UP.
//!
//! \return Returns a Channel ID that dynamic assignment.
//! The channel ID can be:
//! - DMA1_CHANNEL_1
//! - DMA1_CHANNEL_2
//! - others refrence \ref STM32F1xx_DMA_Channel_IDs
//! .
//
//*****************************************************************************
unsigned long 
DMAChannelDynamicAssign(unsigned long ulDMASrcRequest,    
                         unsigned long ulDMADestRequest)
{
    unsigned long ulChannelID;
    //
    // Check the arguments.
    //
    xASSERT((ulDMASrcRequest == DMA_REQUEST_ADC0_RX) || 
           (ulDMASrcRequest == DMA_REQUEST_TIM2_CH3) || 
           (ulDMASrcRequest == DMA_REQUEST_TIM4_CH1) || 
           (ulDMASrcRequest == xDMA_REQUEST_MEM) || 
           (ulDMASrcRequest == DMA_REQUEST_TIM1_CH1)  ||     
           (ulDMASrcRequest == DMA_REQUEST_TIM3_CH3)  ||
           (ulDMASrcRequest == DMA_REQUEST_SPI1_RX)  ||     
           (ulDMASrcRequest == DMA_REQUEST_TIM3_CH4)  ||
           (ulDMASrcRequest == DMA_REQUEST_TIM1_CH4)  ||
           (ulDMASrcRequest == DMA_REQUEST_TIM4_CH2)  ||
           (ulDMASrcRequest == DMA_REQUEST_SPI2_RX)  ||
           (ulDMASrcRequest == DMA_REQUEST_I2S2_RX)  ||
           (ulDMASrcRequest == DMA_REQUEST_TIM2_CH1)  ||
           (ulDMASrcRequest == DMA_REQUEST_TIM4_CH3)  ||
           (ulDMASrcRequest == DMA_REQUEST_I2C2_RX)  ||
           (ulDMASrcRequest == DMA_REQUEST_TIM1_CH3)  ||
           (ulDMASrcRequest == DMA_REQUEST_TIM3_CH1)  ||
           (ulDMASrcRequest == DMA_REQUEST_TIM2_CH2)  ||
           (ulDMASrcRequest == DMA_REQUEST_TIM2_CH4)  ||
           (ulDMASrcRequest == DMA_REQUEST_I2C1_RX)  ||
           (ulDMASrcRequest == DMA_REQUEST_TIM5_CH4)  ||
           (ulDMASrcRequest == DMA_REQUEST_TIM8_CH3)  ||
           (ulDMASrcRequest == DMA_REQUEST_SPI3_RX)  ||
           (ulDMASrcRequest == DMA_REQUEST_I2S3_RX)  ||
           (ulDMASrcRequest == DMA_REQUEST_TIM8_CH4)  ||
           (ulDMASrcRequest == DMA_REQUEST_TIM5_CH3)  ||
           (ulDMASrcRequest == DMA_REQUEST_TIM8_CH1)  ||
           (ulDMASrcRequest == DMA_REQUEST_TIM5_CH2)  ||
           (ulDMASrcRequest == DMA_REQUEST_SDIO_RX)  ||
           (ulDMASrcRequest == DMA_REQUEST_ADC3_RX)  ||
           (ulDMASrcRequest == DMA_REQUEST_TIM8_CH2)  ||
           (ulDMASrcRequest == DMA_REQUEST_TIM5_CH1)  ||
           (ulDMASrcRequest == DMA_REQUEST_TIM1_CH2)     
           );
    xASSERT((ulDMADestRequest == DMA_REQUEST_UART3_TX) || 
           (ulDMADestRequest == DMA_REQUEST_TIM1_UP) ||  
           (ulDMADestRequest == xDMA_REQUEST_MEM) || 
           (ulDMADestRequest == DMA_REQUEST_TIM3_UP)  ||     
           (ulDMADestRequest == DMA_REQUEST_SPI1_TX)  ||
           (ulDMADestRequest == DMA_REQUEST_UART1_TX)  ||     
           (ulDMADestRequest == DMA_REQUEST_TIM1_TRIG)  ||
           (ulDMADestRequest == DMA_REQUEST_TIM1_COM)  ||
           (ulDMADestRequest == DMA_REQUEST_I2C2_TX)  ||
           (ulDMADestRequest == DMA_REQUEST_TIM1_UP)  ||
           (ulDMADestRequest == DMA_REQUEST_SPI2_TX)  ||
           (ulDMADestRequest == DMA_REQUEST_I2S2_TX)  ||
           (ulDMADestRequest == DMA_REQUEST_TIM3_TRIG)  ||
           (ulDMADestRequest == DMA_REQUEST_I2C1_TX)  ||
           (ulDMADestRequest == DMA_REQUEST_UART2_TX)  ||
           (ulDMADestRequest == DMA_REQUEST_TIM4_UP)  ||
           (ulDMADestRequest == DMA_REQUEST_TIM5_TRIG)  ||
           (ulDMADestRequest == DMA_REQUEST_TIM8_UP)  ||
           (ulDMADestRequest == DMA_REQUEST_TIM8_TRIG)  ||
           (ulDMADestRequest == DMA_REQUEST_TIM8_COM)  ||
           (ulDMADestRequest == DMA_REQUEST_TIM5_UP)  ||
           (ulDMADestRequest == DMA_REQUEST_SPI3_TX)  ||
           (ulDMADestRequest == DMA_REQUEST_I2S3_TX)  ||
           (ulDMADestRequest == DMA_REQUEST_TIM6_UP)  ||
           (ulDMADestRequest == DMA_REQUEST_DAC_CH1)  ||
           (ulDMADestRequest == DMA_REQUEST_SDIO_TX)  ||
           (ulDMADestRequest == DMA_REQUEST_TIM7_UP)  ||
           (ulDMADestRequest == DMA_REQUEST_DAC_CH2)  ||
           (ulDMADestRequest == DMA_REQUEST_UART4_TX)     
           );

    //
    // STM32F1xx DMA support P to P
    //
    if((ulDMASrcRequest != xDMA_REQUEST_MEM) &&
       (ulDMADestRequest != xDMA_REQUEST_MEM))
    {
        if(g_psDMAChannelAssignTable[DMA_CHANNEL(ulDMASrcRequest)].bChannelAssigned == 
            xfalse)
        {  
            g_psDMAChannelAssignTable[DMA_CHANNEL(ulDMASrcRequest)].bChannelAssigned = 
            xtrue;
            xHWREG(DMA_ADDR(ulDMASrcRequest)) &= 
            ~(DMA_CCR1_DIR | DMA_CCR1_MEM2MEM);
            xHWREG(DMA_ADDR(ulDMASrcRequest)) |= 
            DMA_CCR1_DIR;
            return g_psDMAChannelAssignTable[DMA_CHANNEL(ulDMASrcRequest)].ulChannelID;
        }
        else
        {
            return xDMA_CHANNEL_NOT_EXIST;
        }
    }
    
    if((ulDMASrcRequest == xDMA_REQUEST_MEM) && (ulDMADestRequest & 0x00000100))
    {
        if(g_psDMAChannelAssignTable[DMA_CHANNEL(ulDMADestRequest)].bChannelAssigned == 
            xfalse)
        {  
            g_psDMAChannelAssignTable[DMA_CHANNEL(ulDMADestRequest)].bChannelAssigned = 
            xtrue;
            xHWREG(DMA_ADDR(ulDMADestRequest)) &= 
            ~(DMA_CCR1_DIR | DMA_CCR1_MEM2MEM);
            xHWREG(DMA_ADDR(ulDMADestRequest)) |= 
            DMA_CCR1_DIR;
            return g_psDMAChannelAssignTable[DMA_CHANNEL(ulDMADestRequest)].ulChannelID;
        }
        else
        {
            return xDMA_CHANNEL_NOT_EXIST;
        }
    }
    if((ulDMADestRequest == xDMA_REQUEST_MEM) && (ulDMASrcRequest != xDMA_REQUEST_MEM) &&
       !(ulDMASrcRequest & 0x00000100))
    {
        if(g_psDMAChannelAssignTable[DMA_CHANNEL(ulDMASrcRequest)].bChannelAssigned == 
            xfalse)
        {  
            g_psDMAChannelAssignTable[DMA_CHANNEL(ulDMASrcRequest)].bChannelAssigned = 
            xtrue;
            xHWREG(DMA_ADDR(ulDMASrcRequest)) &= ~(DMA_CCR1_DIR | DMA_CCR1_MEM2MEM);

            return g_psDMAChannelAssignTable[DMA_CHANNEL(ulDMASrcRequest)].ulChannelID;
        }
        else
        {
            return xDMA_CHANNEL_NOT_EXIST;
        }
    }
    
    //
    // Mem to Mem type
    //
    if((ulDMASrcRequest & xDMA_REQUEST_MEM) &&
       (ulDMADestRequest & xDMA_REQUEST_MEM))
    {
        for(ulChannelID = 0; 
            g_psDMAChannelAssignTable[ulChannelID].ulChannelID != xDMA_CHANNEL_NOT_EXIST;
            ulChannelID++)
        {
            if(g_psDMAChannelAssignTable[ulChannelID].bChannelAssigned == xfalse)
            {
                g_psDMAChannelAssignTable[ulChannelID].bChannelAssigned = xtrue;
                break;
            }
        }
        xHWREG(g_psDMAChannel[ulChannelID]) &= ~(DMA_CCR1_DIR | DMA_CCR1_MEM2MEM);
        xHWREG(g_psDMAChannel[ulChannelID]) |= (DMA_CCR1_MEM2MEM);
        return g_psDMAChannelAssignTable[ulChannelID].ulChannelID;
        
    }

    //
    // when the src request is tx type, or dest request is rx type, assign false.
    //
    return xDMA_CHANNEL_NOT_EXIST;
}
コード例 #7
0
ファイル: setup-r8a7740.c プロジェクト: 1youhun1/linux
		.addr		= 0xfe1f0064,
		.chcr		= CHCR_TX(XMIT_SZ_32BIT),
		.mid_rid	= 0xb5,
	},
};

#define DMA_CHANNEL(a, b, c)			\
{						\
	.offset		= a,			\
	.dmars		= b,			\
	.dmars_bit	= c,			\
	.chclr_offset	= (0x220 - 0x20) + a	\
}

static const struct sh_dmae_channel r8a7740_dmae_channels[] = {
	DMA_CHANNEL(0x00, 0, 0),
	DMA_CHANNEL(0x10, 0, 8),
	DMA_CHANNEL(0x20, 4, 0),
	DMA_CHANNEL(0x30, 4, 8),
	DMA_CHANNEL(0x50, 8, 0),
	DMA_CHANNEL(0x60, 8, 8),
};

static struct sh_dmae_pdata dma_platform_data = {
	.slave		= r8a7740_dmae_slaves,
	.slave_num	= ARRAY_SIZE(r8a7740_dmae_slaves),
	.channel	= r8a7740_dmae_channels,
	.channel_num	= ARRAY_SIZE(r8a7740_dmae_channels),
	.ts_low_shift	= TS_LOW_SHIFT,
	.ts_low_mask	= TS_LOW_BIT << TS_LOW_SHIFT,
	.ts_high_shift	= TS_HI_SHIFT,
コード例 #8
0
namespace chip
{

#ifdef DISTORTOS_CHIP_SPI1_ENABLE

/*---------------------------------------------------------------------------------------------------------------------+
| SPI1
+---------------------------------------------------------------------------------------------------------------------*/

namespace
{

/**
 * \brief Low-level chip initializer for SPI1
 *
 * This function is called before constructors for global and static objects via BIND_LOW_LEVEL_INITIALIZER().
 */

void spi1LowLevelInitializer()
{
#if defined(RCC_APB1ENR_SPI1EN)
	RCC->APB1ENR |= RCC_APB1ENR_SPI1EN;
#elif defined(RCC_APB1ENR1_SPI1EN)
	RCC->APB1ENR1 |= RCC_APB1ENR1_SPI1EN;
#elif defined(RCC_APB2ENR_SPI1EN)
	RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
#else
	#error "Unsupported bus for SPI1!"
#endif
}

BIND_LOW_LEVEL_INITIALIZER(50, spi1LowLevelInitializer);

/// raw SPI1 peripheral
const SpiPeripheral spi1Peripheral {SPI1_BASE};

}	// namespace

#ifdef DISTORTOS_CHIP_SPI1_DMA_BASED

SpiMasterLowLevelDmaBased spi1
{
		spi1Peripheral,
		DMA_CHANNEL(DISTORTOS_CHIP_SPI1_RX_DMA, DISTORTOS_CHIP_SPI1_RX_DMA_CHANNEL),
		DISTORTOS_CHIP_SPI1_RX_DMA_REQUEST,
		DMA_CHANNEL(DISTORTOS_CHIP_SPI1_TX_DMA, DISTORTOS_CHIP_SPI1_TX_DMA_CHANNEL),
		DISTORTOS_CHIP_SPI1_TX_DMA_REQUEST
};

#else	// !def DISTORTOS_CHIP_SPI1_DMA_BASED

SpiMasterLowLevelInterruptBased spi1 {spi1Peripheral};

/**
 * \brief SPI1 interrupt handler
 */

extern "C" void SPI1_IRQHandler()
{
	spi1.interruptHandler();
}

#endif	// !def DISTORTOS_CHIP_SPI1_DMA_BASED

#endif	// def DISTORTOS_CHIP_SPI1_ENABLE

#ifdef DISTORTOS_CHIP_SPI2_ENABLE

/*---------------------------------------------------------------------------------------------------------------------+
| SPI2
+---------------------------------------------------------------------------------------------------------------------*/

namespace
{

/**
 * \brief Low-level chip initializer for SPI2
 *
 * This function is called before constructors for global and static objects via BIND_LOW_LEVEL_INITIALIZER().
 */

void spi2LowLevelInitializer()
{
#if defined(RCC_APB1ENR_SPI2EN)
	RCC->APB1ENR |= RCC_APB1ENR_SPI2EN;
#elif defined(RCC_APB1ENR1_SPI2EN)
	RCC->APB1ENR1 |= RCC_APB1ENR1_SPI2EN;
#elif defined(RCC_APB2ENR_SPI2EN)
	RCC->APB2ENR |= RCC_APB2ENR_SPI2EN;
#else
	#error "Unsupported bus for SPI2!"
#endif
}

BIND_LOW_LEVEL_INITIALIZER(50, spi2LowLevelInitializer);

/// raw SPI2 peripheral
const SpiPeripheral spi2Peripheral {SPI2_BASE};

}	// namespace

#ifdef DISTORTOS_CHIP_SPI2_DMA_BASED

SpiMasterLowLevelDmaBased spi2
{
		spi2Peripheral,
		DMA_CHANNEL(DISTORTOS_CHIP_SPI2_RX_DMA, DISTORTOS_CHIP_SPI2_RX_DMA_CHANNEL),
		DISTORTOS_CHIP_SPI2_RX_DMA_REQUEST,
		DMA_CHANNEL(DISTORTOS_CHIP_SPI2_TX_DMA, DISTORTOS_CHIP_SPI2_TX_DMA_CHANNEL),
		DISTORTOS_CHIP_SPI2_TX_DMA_REQUEST
};

#else	// !def DISTORTOS_CHIP_SPI2_DMA_BASED

SpiMasterLowLevelInterruptBased spi2 {spi2Peripheral};

/**
 * \brief SPI2 interrupt handler
 */

extern "C" void SPI2_IRQHandler()
{
	spi2.interruptHandler();
}

#endif	// !def DISTORTOS_CHIP_SPI2_DMA_BASED

#endif	// def DISTORTOS_CHIP_SPI2_ENABLE

#ifdef DISTORTOS_CHIP_SPI3_ENABLE

/*---------------------------------------------------------------------------------------------------------------------+
| SPI3
+---------------------------------------------------------------------------------------------------------------------*/

namespace
{

/**
 * \brief Low-level chip initializer for SPI3
 *
 * This function is called before constructors for global and static objects via BIND_LOW_LEVEL_INITIALIZER().
 */

void spi3LowLevelInitializer()
{
#if defined(RCC_APB1ENR_SPI3EN)
	RCC->APB1ENR |= RCC_APB1ENR_SPI3EN;
#elif defined(RCC_APB1ENR1_SPI3EN)
	RCC->APB1ENR1 |= RCC_APB1ENR1_SPI3EN;
#elif defined(RCC_APB2ENR_SPI3EN)
	RCC->APB2ENR |= RCC_APB2ENR_SPI3EN;
#else
	#error "Unsupported bus for SPI3!"
#endif
}

BIND_LOW_LEVEL_INITIALIZER(50, spi3LowLevelInitializer);

/// raw SPI3 peripheral
const SpiPeripheral spi3Peripheral {SPI3_BASE};

}	// namespace

#ifdef DISTORTOS_CHIP_SPI3_DMA_BASED

SpiMasterLowLevelDmaBased spi3
{
		spi3Peripheral,
		DMA_CHANNEL(DISTORTOS_CHIP_SPI3_RX_DMA, DISTORTOS_CHIP_SPI3_RX_DMA_CHANNEL),
		DISTORTOS_CHIP_SPI3_RX_DMA_REQUEST,
		DMA_CHANNEL(DISTORTOS_CHIP_SPI3_TX_DMA, DISTORTOS_CHIP_SPI3_TX_DMA_CHANNEL),
		DISTORTOS_CHIP_SPI3_TX_DMA_REQUEST
};

#else	// !def DISTORTOS_CHIP_SPI3_DMA_BASED

SpiMasterLowLevelInterruptBased spi3 {spi3Peripheral};

/**
 * \brief SPI3 interrupt handler
 */

extern "C" void SPI3_IRQHandler()
{
	spi3.interruptHandler();
}

#endif	// !def DISTORTOS_CHIP_SPI3_DMA_BASED

#endif	// def DISTORTOS_CHIP_SPI3_ENABLE

#ifdef DISTORTOS_CHIP_SPI4_ENABLE

/*---------------------------------------------------------------------------------------------------------------------+
| SPI4
+---------------------------------------------------------------------------------------------------------------------*/

namespace
{

/**
 * \brief Low-level chip initializer for SPI4
 *
 * This function is called before constructors for global and static objects via BIND_LOW_LEVEL_INITIALIZER().
 */

void spi4LowLevelInitializer()
{
#if defined(RCC_APB1ENR_SPI4EN)
	RCC->APB1ENR |= RCC_APB1ENR_SPI4EN;
#elif defined(RCC_APB1ENR1_SPI4EN)
	RCC->APB1ENR1 |= RCC_APB1ENR1_SPI4EN;
#elif defined(RCC_APB2ENR_SPI4EN)
	RCC->APB2ENR |= RCC_APB2ENR_SPI4EN;
#else
	#error "Unsupported bus for SPI4!"
#endif
}

BIND_LOW_LEVEL_INITIALIZER(50, spi4LowLevelInitializer);

/// raw SPI4 peripheral
const SpiPeripheral spi4Peripheral {SPI4_BASE};

}	// namespace

#ifdef DISTORTOS_CHIP_SPI4_DMA_BASED

SpiMasterLowLevelDmaBased spi4
{
		spi4Peripheral,
		DMA_CHANNEL(DISTORTOS_CHIP_SPI4_RX_DMA, DISTORTOS_CHIP_SPI4_RX_DMA_CHANNEL),
		DISTORTOS_CHIP_SPI4_RX_DMA_REQUEST,
		DMA_CHANNEL(DISTORTOS_CHIP_SPI4_TX_DMA, DISTORTOS_CHIP_SPI4_TX_DMA_CHANNEL),
		DISTORTOS_CHIP_SPI4_TX_DMA_REQUEST
};

#else	// !def DISTORTOS_CHIP_SPI4_DMA_BASED

SpiMasterLowLevelInterruptBased spi4 {spi4Peripheral};

/**
 * \brief SPI4 interrupt handler
 */

extern "C" void SPI4_IRQHandler()
{
	spi4.interruptHandler();
}

#endif	// !def DISTORTOS_CHIP_SPI4_DMA_BASED

#endif	// def DISTORTOS_CHIP_SPI4_ENABLE

#ifdef DISTORTOS_CHIP_SPI5_ENABLE

/*---------------------------------------------------------------------------------------------------------------------+
| SPI5
+---------------------------------------------------------------------------------------------------------------------*/

namespace
{

/**
 * \brief Low-level chip initializer for SPI5
 *
 * This function is called before constructors for global and static objects via BIND_LOW_LEVEL_INITIALIZER().
 */

void spi5LowLevelInitializer()
{
#if defined(RCC_APB1ENR_SPI5EN)
	RCC->APB1ENR |= RCC_APB1ENR_SPI5EN;
#elif defined(RCC_APB1ENR1_SPI5EN)
	RCC->APB1ENR1 |= RCC_APB1ENR1_SPI5EN;
#elif defined(RCC_APB2ENR_SPI5EN)
	RCC->APB2ENR |= RCC_APB2ENR_SPI5EN;
#else
	#error "Unsupported bus for SPI5!"
#endif
}

BIND_LOW_LEVEL_INITIALIZER(50, spi5LowLevelInitializer);

/// raw SPI5 peripheral
const SpiPeripheral spi5Peripheral {SPI5_BASE};

}	// namespace

#ifdef DISTORTOS_CHIP_SPI5_DMA_BASED

SpiMasterLowLevelDmaBased spi5
{
		spi5Peripheral,
		DMA_CHANNEL(DISTORTOS_CHIP_SPI5_RX_DMA, DISTORTOS_CHIP_SPI5_RX_DMA_CHANNEL),
		DISTORTOS_CHIP_SPI5_RX_DMA_REQUEST,
		DMA_CHANNEL(DISTORTOS_CHIP_SPI5_TX_DMA, DISTORTOS_CHIP_SPI5_TX_DMA_CHANNEL),
		DISTORTOS_CHIP_SPI5_TX_DMA_REQUEST
};

#else	// !def DISTORTOS_CHIP_SPI5_DMA_BASED

SpiMasterLowLevelInterruptBased spi5 {spi5Peripheral};

/**
 * \brief SPI5 interrupt handler
 */

extern "C" void SPI5_IRQHandler()
{
	spi5.interruptHandler();
}

#endif	// !def DISTORTOS_CHIP_SPI5_DMA_BASED

#endif	// def DISTORTOS_CHIP_SPI5_ENABLE

#ifdef DISTORTOS_CHIP_SPI6_ENABLE

/*---------------------------------------------------------------------------------------------------------------------+
| SPI6
+---------------------------------------------------------------------------------------------------------------------*/

namespace
{

/**
 * \brief Low-level chip initializer for SPI6
 *
 * This function is called before constructors for global and static objects via BIND_LOW_LEVEL_INITIALIZER().
 */

void spi6LowLevelInitializer()
{
#if defined(RCC_APB1ENR_SPI6EN)
	RCC->APB1ENR |= RCC_APB1ENR_SPI6EN;
#elif defined(RCC_APB1ENR1_SPI6EN)
	RCC->APB1ENR1 |= RCC_APB1ENR1_SPI6EN;
#elif defined(RCC_APB2ENR_SPI6EN)
	RCC->APB2ENR |= RCC_APB2ENR_SPI6EN;
#else
	#error "Unsupported bus for SPI6!"
#endif
}

BIND_LOW_LEVEL_INITIALIZER(50, spi6LowLevelInitializer);

/// raw SPI6 peripheral
const SpiPeripheral spi6Peripheral {SPI6_BASE};

}	// namespace

#ifdef DISTORTOS_CHIP_SPI6_DMA_BASED

SpiMasterLowLevelDmaBased spi6
{
		spi6Peripheral,
		DMA_CHANNEL(DISTORTOS_CHIP_SPI6_RX_DMA, DISTORTOS_CHIP_SPI6_RX_DMA_CHANNEL),
		DISTORTOS_CHIP_SPI6_RX_DMA_REQUEST,
		DMA_CHANNEL(DISTORTOS_CHIP_SPI6_TX_DMA, DISTORTOS_CHIP_SPI6_TX_DMA_CHANNEL),
		DISTORTOS_CHIP_SPI6_TX_DMA_REQUEST
};

#else	// !def DISTORTOS_CHIP_SPI6_DMA_BASED

SpiMasterLowLevelInterruptBased spi6 {spi6Peripheral};

/**
 * \brief SPI6 interrupt handler
 */

extern "C" void SPI6_IRQHandler()
{
	spi6.interruptHandler();
}

#endif	// !def DISTORTOS_CHIP_SPI6_DMA_BASED

#endif	// def DISTORTOS_CHIP_SPI6_ENABLE

}	// namespace chip
コード例 #9
0
ファイル: dma.c プロジェクト: 0xroot/Blackphone-BP1-Kernel
 * DMA M2P channels.
 *
 * On the EP93xx chip the following peripherals my be allocated to the 10
 * Memory to Internal Peripheral (M2P) channels (5 transmit + 5 receive).
 *
 *	I2S	contains 3 Tx and 3 Rx DMA Channels
 *	AAC	contains 3 Tx and 3 Rx DMA Channels
 *	UART1	contains 1 Tx and 1 Rx DMA Channels
 *	UART2	contains 1 Tx and 1 Rx DMA Channels
 *	UART3	contains 1 Tx and 1 Rx DMA Channels
 *	IrDA	contains 1 Tx and 1 Rx DMA Channels
 *
 * Registers are mapped statically in ep93xx_map_io().
 */
static struct ep93xx_dma_chan_data ep93xx_dma_m2p_channels[] = {
	DMA_CHANNEL("m2p0", EP93XX_DMA_BASE + 0x0000, IRQ_EP93XX_DMAM2P0),
	DMA_CHANNEL("m2p1", EP93XX_DMA_BASE + 0x0040, IRQ_EP93XX_DMAM2P1),
	DMA_CHANNEL("m2p2", EP93XX_DMA_BASE + 0x0080, IRQ_EP93XX_DMAM2P2),
	DMA_CHANNEL("m2p3", EP93XX_DMA_BASE + 0x00c0, IRQ_EP93XX_DMAM2P3),
	DMA_CHANNEL("m2p4", EP93XX_DMA_BASE + 0x0240, IRQ_EP93XX_DMAM2P4),
	DMA_CHANNEL("m2p5", EP93XX_DMA_BASE + 0x0200, IRQ_EP93XX_DMAM2P5),
	DMA_CHANNEL("m2p6", EP93XX_DMA_BASE + 0x02c0, IRQ_EP93XX_DMAM2P6),
	DMA_CHANNEL("m2p7", EP93XX_DMA_BASE + 0x0280, IRQ_EP93XX_DMAM2P7),
	DMA_CHANNEL("m2p8", EP93XX_DMA_BASE + 0x0340, IRQ_EP93XX_DMAM2P8),
	DMA_CHANNEL("m2p9", EP93XX_DMA_BASE + 0x0300, IRQ_EP93XX_DMAM2P9),
};

static struct ep93xx_dma_platform_data ep93xx_dma_m2p_data = {
	.channels		= ep93xx_dma_m2p_channels,
	.num_channels		= ARRAY_SIZE(ep93xx_dma_m2p_channels),
};
コード例 #10
0
static irqreturn_t dma_dwc_interrupt(int irq, void *hsdev_instance)
{
    int chan;
    u32 tfr_reg, err_reg;
    unsigned long flags;
    struct sata_dwc_device *hsdev =
        (struct sata_dwc_device *)hsdev_instance;
    struct ata_host *host = (struct ata_host *)hsdev->host;
    struct ata_port *ap;
    struct sata_dwc_device_port *hsdevp;
    u8 tag = 0;
    unsigned int port = 0;

    spin_lock_irqsave(&host->lock, flags);
    ap = host->ports[port];
    hsdevp = HSDEVP_FROM_AP(ap);
    tag = ap->link.active_tag;

    tfr_reg = in_le32(&(host_pvt.sata_dma_regs->interrupt_status.tfr\
                        .low));
    err_reg = in_le32(&(host_pvt.sata_dma_regs->interrupt_status.error\
                        .low));

    dev_dbg(ap->dev, "eot=0x%08x err=0x%08x pending=%d active port=%d\n",
            tfr_reg, err_reg, hsdevp->dma_pending[tag], port);

    for (chan = 0; chan < DMA_NUM_CHANS; chan++) {

        if (tfr_reg & DMA_CHANNEL(chan)) {
            host_pvt.dma_interrupt_count++;
            sata_dwc_clear_dmacr(hsdevp, tag);

            if (hsdevp->dma_pending[tag] ==
                    SATA_DWC_DMA_PENDING_NONE) {
                dev_err(ap->dev, "DMA not pending eot=0x%08x "
                        "err=0x%08x tag=0x%02x pending=%d\n",
                        tfr_reg, err_reg, tag,
                        hsdevp->dma_pending[tag]);
            }

            if ((host_pvt.dma_interrupt_count % 2) == 0)
                sata_dwc_dma_xfer_complete(ap, 1);


            out_le32(&(host_pvt.sata_dma_regs->interrupt_clear\
                       .tfr.low),
                     DMA_CHANNEL(chan));
        }


        if (err_reg & DMA_CHANNEL(chan)) {

            dev_err(ap->dev, "error interrupt err_reg=0x%08x\n",
                    err_reg);


            out_le32(&(host_pvt.sata_dma_regs->interrupt_clear\
                       .error.low),
                     DMA_CHANNEL(chan));
        }
    }
    spin_unlock_irqrestore(&host->lock, flags);
    return IRQ_HANDLED;
}
コード例 #11
0
/*
 * Function: dma_dwc_interrupt
 * arguments: irq, dev_id, pt_regs
 * returns channel number if available else -1
 * Interrupt Handler for DW AHB SATA DMA
 */
static irqreturn_t dma_dwc_interrupt(int irq, void *hsdev_instance)
{
	int chan;
	u32 tfr_reg, err_reg;
	unsigned long flags;
	struct sata_dwc_device *hsdev = hsdev_instance;
	struct ata_host *host = (struct ata_host *)hsdev->host;
	struct ata_port *ap;
	struct sata_dwc_device_port *hsdevp;
	u8 tag = 0;
	unsigned int port = 0;

	spin_lock_irqsave(&host->lock, flags);
	ap = host->ports[port];
	hsdevp = HSDEVP_FROM_AP(ap);
	tag = ap->link.active_tag;

	tfr_reg = in_le32(&(host_pvt.sata_dma_regs->interrupt_status.tfr\
			.low));
	err_reg = in_le32(&(host_pvt.sata_dma_regs->interrupt_status.error\
			.low));

	dev_dbg(ap->dev, "eot=0x%08x err=0x%08x pending=%d active port=%d\n",
		tfr_reg, err_reg, hsdevp->dma_pending[tag], port);

	chan = host_pvt.dma_channel;
	if (chan >= 0) {
		/* Check for end-of-transfer interrupt. */
		if (tfr_reg & DMA_CHANNEL(chan)) {
			/*
			 * Each DMA command produces 2 interrupts.  Only
			 * complete the command after both interrupts have been
			 * seen. (See sata_dwc_isr())
			 */
			host_pvt.dma_interrupt_count++;
			sata_dwc_clear_dmacr(hsdevp, tag);

			if (hsdevp->dma_pending[tag] ==
			    SATA_DWC_DMA_PENDING_NONE) {
				dev_err(ap->dev, "DMA not pending eot=0x%08x "
					"err=0x%08x tag=0x%02x pending=%d\n",
					tfr_reg, err_reg, tag,
					hsdevp->dma_pending[tag]);
			}

			if ((host_pvt.dma_interrupt_count % 2) == 0)
				sata_dwc_dma_xfer_complete(ap, 1);

			/* Clear the interrupt */
			out_le32(&(host_pvt.sata_dma_regs->interrupt_clear\
				.tfr.low),
				 DMA_CHANNEL(chan));
		}

		/* Check for error interrupt. */
		if (err_reg & DMA_CHANNEL(chan)) {
			/* TODO Need error handler ! */
			dev_err(ap->dev, "error interrupt err_reg=0x%08x\n",
				err_reg);

			/* Clear the interrupt. */
			out_le32(&(host_pvt.sata_dma_regs->interrupt_clear\
				.error.low),
				 DMA_CHANNEL(chan));
		}
	}
	spin_unlock_irqrestore(&host->lock, flags);
	return IRQ_HANDLED;
}