FreeBSD/sys/arm/ti/ti_sdma.c
/**
 *	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 transferred   = 128 / 512 = 4
 *
 *
 *	LOCKING:
 *	DMA registers protected by internal mutex
 *
 *	RETURNS:
 *	EH_HANDLED or EH_NOT_HANDLED
 */


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.



Total transfer bytes = 1 * 512 = 512 elements or 2048 bytes
Packets transferred   = 128 / 512 = 4

DMA registers protected by internal mutex


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 . Total transfer bytes = 1 * 512 = 512 elements or 2048 bytes Packets transferred = 128 / 512 = 4 DMA registers protected by internal mutex
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;
	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];
	if (channel->need_reg_write)
		ti_sdma_write_4(sc, DMA4_CSDP(ch),
		    channel->reg_csdp | DMA4_CSDP_WRITE_MODE(1));
	ti_sdma_write_4(sc, DMA4_CEN(ch), elmcnt);
	ti_sdma_write_4(sc, DMA4_CFN(ch), frmcnt);
	ti_sdma_write_4(sc, DMA4_CSSA(ch), src_paddr);
	ti_sdma_write_4(sc, DMA4_CDSA(ch), dst_paddr);
	ti_sdma_write_4(sc, DMA4_CCR(ch),
	    channel->reg_ccr | DMA4_CCR_PACKET_TRANS);
	ti_sdma_write_4(sc, DMA4_CSE(ch), 0x0001);
	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_CDF(ch), pktsize);
	ti_sdma_write_4(sc, DMA4_CDE(ch), 0x0001);
	ti_sdma_write_4(sc, DMA4_CSR(ch), 0x1FFE);
	ccr = ti_sdma_read_4(sc, DMA4_CCR(ch));
	ccr |= (1 << 7);
	ti_sdma_write_4(sc, DMA4_CCR(ch), ccr);
	channel->need_reg_write = 0;
	TI_SDMA_UNLOCK(sc);
	return (0);
}
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 ; 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 ] ; if ( channel -> need_reg_write ) ti_sdma_write_4 ( sc , DMA4_CSDP ( ch ) , channel -> reg_csdp | DMA4_CSDP_WRITE_MODE ( 1 ) ) ; ti_sdma_write_4 ( sc , DMA4_CEN ( ch ) , elmcnt ) ; ti_sdma_write_4 ( sc , DMA4_CFN ( ch ) , frmcnt ) ; ti_sdma_write_4 ( sc , DMA4_CSSA ( ch ) , src_paddr ) ; ti_sdma_write_4 ( sc , DMA4_CDSA ( ch ) , dst_paddr ) ; ti_sdma_write_4 ( sc , DMA4_CCR ( ch ) , channel -> reg_ccr | DMA4_CCR_PACKET_TRANS ) ; ti_sdma_write_4 ( sc , DMA4_CSE ( ch ) , 0x0001 ) ; 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_CDF ( ch ) , pktsize ) ; ti_sdma_write_4 ( sc , DMA4_CDE ( ch ) , 0x0001 ) ; ti_sdma_write_4 ( sc , DMA4_CSR ( ch ) , 0x1FFE ) ; ccr = ti_sdma_read_4 ( sc , DMA4_CCR ( ch ) ) ; ccr |= ( 1 << 7 ) ; ti_sdma_write_4 ( sc , DMA4_CCR ( ch ) , ccr ) ; channel -> need_reg_write = 0 ; TI_SDMA_UNLOCK ( sc ) ; return ( 0 ) ; }
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
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
/* Sanity check */ /* a) Write the CSDP register */ /* b) Set the number of elements to transfer CEN[23:0] */ /* c) Set the number of frames to transfer CFN[15:0] */ /* d) Set the Source/dest start address index CSSA[31:0]/CDSA[31:0] */ /* e) Write the CCR register */ /* f)  - Set the source element index increment CSEI[15:0] */ /*     - Set the packet size, this is dependent on the sync source */ /* - Set the destination frame index increment CDFI[31:0] */ /* Clear the status register */ /* Write the start-bit and away we go */ /* Clear the reg write flag */