int stmp3xxx_arch_dma_is_interrupt(int channel)
{
	int dmabus = channel / 16;
	int r = 0;

	switch (dmabus) {
	case STMP3XXX_BUS_APBH:
		r = HW_APBH_CTRL1_RD() & (1 << (channel % 16));
		break;

	case STMP3XXX_BUS_APBX:
		r = HW_APBX_CTRL1_RD() & (1 << (channel % 16));
		break;
	}
	return r;
}
예제 #2
0
파일: gpmi.cpp 프로젝트: Alexlcb/rt-thread
int gpmi_run_dma(apbh_dma_t * theDma, unsigned chipSelect, uint16_t waitMask, uint32_t timeout)
{
    uint32_t    physicalCommandAddress;
    reg32_t     r32ChipDmaNumber        = (NAND0_APBH_CH); //+chipSelect);
    reg32_t     r32ChannelMask          = (0x1 << r32ChipDmaNumber);
    bool        bDmaIsRunning;
    int  rtStatus = SUCCESS;

    // Save off the chip that we're watching in the DMA completion structure.
    g_gpmi.dmaInfo.u16CurrentChip = chipSelect;
    
    // We're using DMA channel 0 for all DMAs.
    g_gpmi.dmaInfo.dmaChannel = 0;

    // Set the criteria for finishing this DMA.
    g_gpmi.dmaInfo.u16DmaWaitMask      = waitMask;

    // Clear the status word used to check the criteria for finishing this DMA.
    g_gpmi.dmaInfo.u16DmaWaitStatus    = kNandGpmiDmaWaitMask_Nothing;

    // Alert me if a DMA chain is currently running!!
    // Note that this checks the SEMA.PHORE register field for the DMA.
    bDmaIsRunning = gpmi_is_dma_active(chipSelect);

    if (bDmaIsRunning)
    {
        rtStatus = ERROR_DDI_NAND_GPMI_DMA_BUSY;

        goto _standardExit;
    }

    // At this point, there should be no DMA running.
    // Sanity-test to make sure the DMA channel IRQ is deasserted.
    // (Note that the optimizing compiler will probably combine the
    // body of this section with the previous section.)
    if ( 0 != (HW_APBH_CTRL1_RD() & (r32ChannelMask << BP_APBH_CTRL1_CH0_CMDCMPLT_IRQ)) )
    {
        rtStatus = ERROR_DDI_NAND_GPMI_DMA_BUSY;

        goto _standardExit;
    }

    // Get the physical address of the DMA chain.
    physicalCommandAddress = (uint32_t)nand_virtual_to_physical(theDma);

    // Flush the data cache. We don't need to invalidate since the hardware is only reading
    // the DMA chain, not writing to it. If the caller set the length to 0, then they don't
    // want us to flush the cache, probably because they just flushed the entire cache already.
//     if (dmaCommandLength > 0)
//     {
//         hw_core_clean_DCache_MVA_BySize((uint32_t)pDmaCmd, dmaCommandLength);
//     }
    
    // Initialize DMA by setting up NextCMD field
    HW_APBH_CHn_NXTCMDAR_WR(r32ChipDmaNumber, (reg32_t)physicalCommandAddress);

    // Start DMA by incrementing the semaphore.
    BW_APBH_CHn_SEMA_INCREMENT_SEMA(r32ChipDmaNumber, 1);

    // Record the time that I started the transaction
    // Used in the NAND_HAL_Dma_Status function below and the ddi_gpmi_wait_for_dma
    // function above to determine timeouts.
    g_gpmi.dmaInfo.uStartDMATime = time_get_microseconds();

    rtStatus = gpmi_wait_for_dma(timeout, chipSelect);

_standardExit:

    return rtStatus;
}