We have done some tests to establish DMA performance on our board. We are using TMS320DM647 with DDR2 using a 25Mhz clk for PLL2(DDR2's PLL). We have 16Mx32 configuration. We expected our max BW should be 25Mhz x 20 x 4Byte= 2GB/sec, however our test which transferred 48kb blocks from L2 to DDR2 achieves approx 500 MB/Sec using EDMA. A similar test which transferred, using the same EDMA code, from L2 to a host on the pci bus achieved 80 MB/S which seems reasonable.
Are there factors we missed in calculating the theoretical maximum for DDR2? Do you have tips for optimizing setup of the DMA to achieve good performance? Example code?
Here's the DDR2 setup code - called like this: Set_DDR2( dsp, 250000000 );
/****************************************************************************
*
* NAME
* Set_DDR2
*
* PURPOSE:
* Configure DDR2 to run at specified frequency on a 32 bits bus.
*
* USAGE
* This routine can be called as:
*
* Set_DDR2(ddr2_freq)
*
* ddr2_freq - (i) Running desired frequency in Hz for DDR2 memory.
*
* RETURN VALUE
* NONE
*
* REFERENCE
*
****************************************************************************/
static void Set_DDR2( dm647_t *dsp, int ddr2_freq )
{
int iSdcfg,iCas;
// ************************************************************************
// SL DDR2 Memory timing info
// Config 4 banks, page size=512word, (Clk>200 MHz CAS=4, Clk<=200 MHz CAS=3)
// 32 bits data bus
// Adjust CAS latency/SDCFG depending of clock speed around 200 MHZ
if (ddr2_freq>200000000)
{
// CAS 4 and config for CAS4, set bank=4 and Page=512
iCas = 4;
iSdcfg = 0x00570821;
}
else
{
// CAS 3 and config for CAS3, set bank=4 and Page=512
iCas = 3;
iSdcfg = 0x00570621;
}
// Setup for 250.0 MHz DDR (CAS4)
//#define DDR_SDCFG 0x00000821
#define DDR_SDRFC 0x000003DE
#define DDR_SDTIM1 0x24DB5B91
#define DDR_SDRIM2 0x0095C722
#define DDR_DMCCTL 0x50006405
// ************************************************************************
// Gives power to ddr2 just in case
Set_PSC_State(dsp, DM647_PD0, DM647_LPSC_DDR2, DM647_PSC_ENABLE);
// *******************************************************
// 1- DDR2 Module Initialization
// ***** Set DDR2 drive strength to weak **********
dm647_writereg( dsp, DM647_DDR_SDCFG_ADR, (iSdcfg | DM647_BOOT_UNLOCK)); //Unlock upper section
dm647_writereg( dsp, DM647_DDR_SDCFG_ADR, iSdcfg ); //lock again
// ***** Assert Reset for DDR2 Interface **********
dm647_writereg( dsp, DM647_DDR_DMCCTL_ADR, 0x50006420 | ( iCas + 1));
dm647_writereg( dsp, DM647_DDR_SDCFG_ADR, (iSdcfg | DM647_TIMUNLOCK));
// Refresh Rate - Freq (Hz) * 3.96e-6 (sec) for Industrial Temp
dm647_writereg( dsp, DM647_DDR_SDRFC_ADR, DDR_SDRFC);
// set SDTIM registers timing from memory specs
dm647_writereg( dsp, DM647_DDR_SDTIM1_ADR, DDR_SDTIM1);
dm647_writereg( dsp, DM647_DDR_SDTIM2_ADR, DDR_SDRIM2);
// Lock DDR Bank timing
dm647_writereg( dsp, DM647_DDR_SDCFG_ADR, iSdcfg);
// ***** Release Reset for DDR2 Interface **********
// ReadLatency = CAS +1 with default bits
dm647_writereg( dsp, DM647_DDR_DMCCTL_ADR, 0x50006400 | ( iCas + 1));
// ***** Set DDR2 Controller Priority **********
dm647_writereg( dsp, DM647_DDR_BPRIO_ADR, 0x00000080 ); //To avoid starvation, raise oldest cmd priority after 128 transfers
Wait_Soft( 1500 );
}
Thanks,
Geoff