Hi,
We are usign c6657 DSPs which is connected to cavium octeon processor. The interface between c6657 and cavium octeon processor is PCIe bus. The PCIe driver which we used was given as sample program by TI which TI tested between x86 and c6657 and we developed our driver on top of this by doing the required changes for cavium octeon in place of x86. All the data transfer between cavium octen and DSP is working fine without using DMA.
Now we want to use DSP DMA for data transfer between DSP and octeon. So Can I get help from TI how to use DSP DMA for data transfer? The help from TI will be really great. Actually the sample code TI gave at that time has one dma transfer API but this is not working as it is , modifications are required so we want to understand it specially the address translation part, if TI suggests to use the same API. This API uses eDMA transfer.
Here is the PCIE configuration:
Cavium octem => root complex, master, 64 bit processor
DSP => c6657, end point mode, 32 bit
Following is the API:
/* ============================================================================
* @func gauss_write_dma
*
* @desc Move DMAs contents from GPP memory to DSP Memory. For DSP this is
* outbound read.
* flag: 0: Move data inside DSP; 1: Move data between GPP and DSP
*
* @modif None.
* ============================================================================
*/
void gauss_write_dma(gauss_device_t *gss_dev, uint32_t srcAddr, uint32_t dstAddr, uint32_t size, uint32_t flag)
{
uint32_t *pReg, tmp, pageBase, i, tSize;
pReg = (uint32_t *)gss_dev->regVirt; /* Point to PCIE application registers */
/* Move data between GPP and DSP, need to program PCIE OB registers */
if (flag) {
iowrite32(0x0, pReg + OB_SIZE/4); /* 1MB outbound translation size */
if (size <= PCIE_ADLEN_1MB) {
pageBase = srcAddr & PCIE_1MB_BITMASK;
iowrite32(pageBase|0x1, pReg + OB_OFFSET_INDEX(0)/4);
iowrite32(0x0, pReg + OB_OFFSET_HI(0)/4);
}
else {
for (tmp = size, i = 0; tmp > 0; tmp -= PCIE_ADLEN_1MB, i++) {
pageBase = (srcAddr + (PCIE_ADLEN_1MB * i)) & PCIE_1MB_BITMASK;
iowrite32(pageBase|0x1, pReg + OB_OFFSET_INDEX(i)/4);
iowrite32(0x0, pReg + OB_OFFSET_HI(i)/4);
}
}
}
/* Temporarily re-map IB region 3 from DDR memory to EDMA registers */
iowrite32(EDMA_TPCC0_BASE_ADDRESS, pReg + IB_OFFSET(3)/4);
pReg = (uint32_t*)gss_dev->ddrVirt; /* Now it points to the start of EDMA_TPCC0_BASE_ADDRESS */
while (true) {
/* Use TC0 for DBS = 128 bytes */
myIowrite32(0x0, pReg + DMAQNUM0/4);
/* Set the interrupt enable for 1st Channel (IER). */
myIowrite32(0x1, pReg + IESR/4);
/* Clear any pending interrupt (IPR). */
myIowrite32(0x1, pReg + ICR/4);
/* Populate the Param entry. */
myIowrite32(0x00100004, pReg + PARAM_0_OPT/4); /* Enable SYNCDIM and TCINTEN, TCC = 0 */
if (flag == 1) {
/* Calculate the DSP PCI address for the PC address */
tmp = PCIE_DATA + (srcAddr & ~PCIE_1MB_BITMASK);
myIowrite32(tmp, pReg + PARAM_0_SRC/4);
} else {
myIowrite32(srcAddr, pReg + PARAM_0_SRC/4);
}
/* Calculate the A & B count */
if (size > PCIE_TRANSFER_SIZE) {
tmp = size/PCIE_TRANSFER_SIZE;
tSize = tmp*PCIE_TRANSFER_SIZE;
size -= (tmp*PCIE_TRANSFER_SIZE);
tmp <<= 16;
tmp |= PCIE_TRANSFER_SIZE;
}
else {
tmp = 0x10000|size;
tSize = size;
size = 0;
}
myIowrite32(tmp, pReg + PARAM_0_A_B_CNT/4);
myIowrite32(dstAddr, pReg + PARAM_0_DST/4);
myIowrite32(((PCIE_TRANSFER_SIZE<<16)|PCIE_TRANSFER_SIZE), pReg + PARAM_0_SRC_DST_BIDX/4);
myIowrite32(0xFFFF, pReg + PARAM_0_LINK_BCNTRLD/4);
myIowrite32(0x0, pReg + PARAM_0_SRC_DST_CIDX/4);
/* C Count is set to 1 since mostly size will not be more than 1.75GB */
myIowrite32(0x1, pReg + PARAM_0_CCNT/4);
/* Set the Event Enable Set Register. */
myIowrite32(0x1, pReg + EESR/4);
/* Set the event set register. */
myIowrite32(0x1, pReg + ESR/4);
/* wait for current DMA to finish. */
while (true) {
/* check in steps of 10 usec. */
udelay(10);
tmp = myIoread32(pReg + IPR/4);
if ((tmp & 0x1) == 1) {
break;
}
}
if (size != 0) {
srcAddr += tSize;
dstAddr += tSize;
} else {
break;
}
}
/* Clear any pending interrupt. */
myIowrite32(1, pReg + ICR/4);
/* Restore pointer */
pReg = (uint32_t *)gss_dev->regVirt; //Point to PCIE application registers
iowrite32(DDR_START, pReg + IB_OFFSET(3)/4);
}
In case TI has some other sample PCIe dma transfer code in similar PCIe configuration, please share.
Thanks
Kashif