/** * ti_sdma_start_xfer_packet - starts a packet DMA transfer * @ch: the channel number to use for the transfer * @src_paddr: the source physical address * @dst_paddr: the destination physical address * @frmcnt: the number of frames to transfer * @elmcnt: the number of elements in a frame, an element is either an 8, 16 * or 32-bit value as defined by ti_sdma_set_xfer_burst() * @pktsize: the number of elements in each transfer packet * * The @frmcnt and @elmcnt define the overall number of bytes to transfer, * typically @frmcnt is 1 and @elmcnt contains the total number of elements. * @pktsize is the size of each individual packet, there might be multiple * packets per transfer. i.e. for the following with element size of 32-bits * * frmcnt = 1, elmcnt = 512, pktsize = 128 * * Total transfer bytes = 1 * 512 = 512 elements or 2048 bytes * Packets transfered = 128 / 512 = 4 * * * LOCKING: * DMA registers protected by internal mutex * * RETURNS: * EH_HANDLED or EH_NOT_HANDLED */ int ti_sdma_start_xfer_packet(unsigned int ch, unsigned int src_paddr, unsigned long dst_paddr, unsigned int frmcnt, unsigned int elmcnt, unsigned int pktsize) { struct ti_sdma_softc *sc = ti_sdma_sc; struct ti_sdma_channel *channel; uint32_t ccr; /* Sanity check */ if (sc == NULL) return (ENOMEM); TI_SDMA_LOCK(sc); if ((sc->sc_active_channels & (1 << ch)) == 0) { TI_SDMA_UNLOCK(sc); return (EINVAL); } channel = &sc->sc_channel[ch]; /* a) Write the CSDP register */ if (channel->need_reg_write) ti_sdma_write_4(sc, DMA4_CSDP(ch), channel->reg_csdp | DMA4_CSDP_WRITE_MODE(1)); /* b) Set the number of elements to transfer CEN[23:0] */ ti_sdma_write_4(sc, DMA4_CEN(ch), elmcnt); /* c) Set the number of frames to transfer CFN[15:0] */ ti_sdma_write_4(sc, DMA4_CFN(ch), frmcnt); /* d) Set the Source/dest start address index CSSA[31:0]/CDSA[31:0] */ ti_sdma_write_4(sc, DMA4_CSSA(ch), src_paddr); ti_sdma_write_4(sc, DMA4_CDSA(ch), dst_paddr); /* e) Write the CCR register */ ti_sdma_write_4(sc, DMA4_CCR(ch), channel->reg_ccr | DMA4_CCR_PACKET_TRANS); /* f) - Set the source element index increment CSEI[15:0] */ ti_sdma_write_4(sc, DMA4_CSE(ch), 0x0001); /* - Set the packet size, this is dependent on the sync source */ if (channel->reg_ccr & DMA4_CCR_SEL_SRC_DST_SYNC(1)) ti_sdma_write_4(sc, DMA4_CSF(ch), pktsize); else ti_sdma_write_4(sc, DMA4_CDE(ch), pktsize); /* - Set the destination frame index increment CDFI[31:0] */ ti_sdma_write_4(sc, DMA4_CDF(ch), 0x0001); /* Clear the status register */ ti_sdma_write_4(sc, DMA4_CSR(ch), 0x1FFE); /* Write the start-bit and away we go */ ccr = ti_sdma_read_4(sc, DMA4_CCR(ch)); ccr |= (1 << 7); ti_sdma_write_4(sc, DMA4_CCR(ch), ccr); /* Clear the reg write flag */ channel->need_reg_write = 0; TI_SDMA_UNLOCK(sc); return (0); }
/** Configure OMAP DMA Channel @param Channel DMA Channel to configure @param Dma4 Pointer to structure used to initialize DMA registers for the Channel @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes. @retval EFI_INVALID_PARAMETER Channel is not valid @retval EFI_DEVICE_ERROR The system hardware could not map the requested information. **/ EFI_STATUS EFIAPI EnableDmaChannel ( IN UINTN Channel, IN OMAP_DMA4 *DMA4 ) { UINT32 RegVal; if (Channel > DMA4_MAX_CHANNEL) { return EFI_INVALID_PARAMETER; } /* 1) Configure the transfer parameters in the logical DMA registers */ /*-------------------------------------------------------------------*/ /* a) Set the data type CSDP[1:0], the Read/Write Port access type CSDP[8:7]/[15:14], the Source/dest endianism CSDP[21]/CSDP[19], write mode CSDP[17:16], source/dest packed or nonpacked CSDP[6]/CSDP[13] */ // Read CSDP RegVal = MmioRead32 (DMA4_CSDP (Channel)); // Build reg RegVal = ((RegVal & ~ 0x3) | DMA4->DataType ); RegVal = ((RegVal & ~(0x3 << 7)) | (DMA4->ReadPortAccessType << 7)); RegVal = ((RegVal & ~(0x3 << 14)) | (DMA4->WritePortAccessType << 14)); RegVal = ((RegVal & ~(0x1 << 21)) | (DMA4->SourceEndiansim << 21)); RegVal = ((RegVal & ~(0x1 << 19)) | (DMA4->DestinationEndianism << 19)); RegVal = ((RegVal & ~(0x3 << 16)) | (DMA4->WriteMode << 16)); RegVal = ((RegVal & ~(0x1 << 6)) | (DMA4->SourcePacked << 6)); RegVal = ((RegVal & ~(0x1 << 13)) | (DMA4->DestinationPacked << 13)); // Write CSDP MmioWrite32 (DMA4_CSDP (Channel), RegVal); /* b) Set the number of element per frame CEN[23:0]*/ MmioWrite32 (DMA4_CEN (Channel), DMA4->NumberOfElementPerFrame); /* c) Set the number of frame per block CFN[15:0]*/ MmioWrite32 (DMA4_CFN (Channel), DMA4->NumberOfFramePerTransferBlock); /* d) Set the Source/dest start address index CSSA[31:0]/CDSA[31:0]*/ MmioWrite32 (DMA4_CSSA (Channel), DMA4->SourceStartAddress); MmioWrite32 (DMA4_CDSA (Channel), DMA4->DestinationStartAddress); /* e) Set the Read Port addressing mode CCR[13:12], the Write Port addressing mode CCR[15:14], read/write priority CCR[6]/CCR[26] I changed LCH CCR[20:19]=00 and CCR[4:0]=00000 to LCH CCR[20:19]= DMA4->WriteRequestNumber and CCR[4:0]=DMA4->ReadRequestNumber */ // Read CCR RegVal = MmioRead32 (DMA4_CCR (Channel)); // Build reg RegVal = ((RegVal & ~0x1f) | DMA4->ReadRequestNumber); RegVal = ((RegVal & ~(BIT20 | BIT19)) | DMA4->WriteRequestNumber << 19); RegVal = ((RegVal & ~(0x3 << 12)) | (DMA4->ReadPortAccessMode << 12)); RegVal = ((RegVal & ~(0x3 << 14)) | (DMA4->WritePortAccessMode << 14)); RegVal = ((RegVal & ~(0x1 << 6)) | (DMA4->ReadPriority << 6)); RegVal = ((RegVal & ~(0x1 << 26)) | (DMA4->WritePriority << 26)); // Write CCR MmioWrite32 (DMA4_CCR (Channel), RegVal); /* f)- Set the source element index CSEI[15:0]*/ MmioWrite32 (DMA4_CSEI (Channel), DMA4->SourceElementIndex); /* - Set the source frame index CSFI[15:0]*/ MmioWrite32 (DMA4_CSFI (Channel), DMA4->SourceFrameIndex); /* - Set the destination element index CDEI[15:0]*/ MmioWrite32 (DMA4_CDEI (Channel), DMA4->DestinationElementIndex); /* - Set the destination frame index CDFI[31:0]*/ MmioWrite32 (DMA4_CDFI (Channel), DMA4->DestinationFrameIndex); MmioWrite32 (DMA4_CDFI (Channel), DMA4->DestinationFrameIndex); // Enable all the status bits since we are polling MmioWrite32 (DMA4_CICR (Channel), DMA4_CICR_ENABLE_ALL); MmioWrite32 (DMA4_CSR (Channel), DMA4_CSR_RESET); /* 2) Start the DMA transfer by Setting the enable bit CCR[7]=1 */ /*--------------------------------------------------------------*/ //write enable bit MmioOr32 (DMA4_CCR(Channel), DMA4_CCR_ENABLE); //Launch transfer return EFI_SUCCESS; }