/*  ============================================================================
 *   Copyright (c) Texas Instruments Inc 2011
 *
 *   Use of this software is controlled by the terms and conditions found in the
 *   license agreement under which this software has been supplied.
 *   ===========================================================================
 */

/** ============================================================================
 *   @n This is an example to benchmark the IDMA performance
 * ============================================================================
 *  Revision History
 *  ===============
 *  11-Jan-2011 Brighton Feng   File Created
 * ============================================================================
 */

#include <stdio.h>
#include <csl_cacheAux.h>
#include "KeyStone_common.h"

#define 	L1D_TEST_SRC 	(0x00f00000)
#define 	L1D_TEST_DST 	(0x00f02000)
#define 	L1D_TEST_CNT 	((L1D_TEST_DST-L1D_TEST_SRC))

#define 	L1P_TEST_SRC 	(0x00e00000)
#define 	L1P_TEST_DST 	(0x00e02000)
#define 	L1P_TEST_CNT 	((L1P_TEST_DST-L1P_TEST_SRC))

#define 	L2_TEST_SRC 	(0x00820000)
#define 	L2_TEST_DST 	(0x00840000)
#define 	L2_TEST_CNT 	(32*1024)

void IDMA1_performance_Test(Uint32 srcBuff, Uint32 dstBuff, Uint32 size)
{
	unsigned int cycles;
	Uint32 loopIndex;
	Uint32 *src=(Uint32 *)srcBuff;
	Uint32 *dst=(Uint32 *)dstBuff;

	/* Initialize data buffers */
	for (loopIndex = 0; loopIndex < size/4; loopIndex++) {
		src[loopIndex] = srcBuff+loopIndex;
		dst[loopIndex] = 0xaa;
	}      
	
	gpCGEM_regs->IDMA1_SOURCE= srcBuff;
	gpCGEM_regs->IDMA1_DEST= dstBuff;
	gpCGEM_regs->IDMA1_COUNT= size&0xFFFC;

	cycles= TSCL;
	/* Wait until copying is completed */
	while (gpCGEM_regs->IDMA1_STAT); //Wait for transfer completion
	cycles= TSC_count_cycle_from(cycles);

	printf("IDMA1 transfer %6d Bytes from 0x%8x to 0x%8x, consumes %d cycles, achieve bandwidth %5lld MB/s\n", 
		size, srcBuff, dstBuff, cycles, (unsigned long long)size*gDSP_Core_Speed_Hz/cycles/1000000);

	/* Verify data transfered */
	if((dstBuff&0xffffff)>=0xe00000&&(dstBuff&0xffffff)<0xf00000)
		return; 	//L1P can't be verified by following codes
	for (loopIndex = 0; loopIndex < size/4; loopIndex++) {
		if(dst[loopIndex] != srcBuff+loopIndex)
		{
			printf("IDMA data transfer failed at 0x%x\n", dst+loopIndex);
			break;
		}
	}

}


void IDMA1_test(void)
{   
	//Configure L1 as 16KB cache, 16K RAM for test
	CACHE_setL1PSize(CACHE_L1_16KCACHE);
	CACHE_setL1DSize(CACHE_L1_16KCACHE);
	CACHE_setL2Size(CACHE_0KCACHE);

#if 1
	puts("IDMA1 overhead test");
	IDMA1_performance_Test(L1D_TEST_SRC, L1D_TEST_DST, 4);
	IDMA1_performance_Test(L1D_TEST_SRC, L2_TEST_DST, 4);
	IDMA1_performance_Test(L2_TEST_SRC, L1D_TEST_DST, 4);
	IDMA1_performance_Test(L2_TEST_SRC, L2_TEST_DST, 4);

#endif
	puts("IDMA1 throughput test");	
	IDMA1_performance_Test(L1D_TEST_SRC, L1D_TEST_DST, L1D_TEST_CNT);
	IDMA1_performance_Test(L1D_TEST_SRC, L1P_TEST_DST, L1D_TEST_CNT);
	IDMA1_performance_Test(L1D_TEST_SRC, L2_TEST_DST, L1D_TEST_CNT);
	IDMA1_performance_Test(L2_TEST_SRC, L1D_TEST_DST, L1D_TEST_CNT);
	IDMA1_performance_Test(L2_TEST_SRC, L1P_TEST_DST, L1P_TEST_CNT);
	IDMA1_performance_Test(L2_TEST_SRC, L2_TEST_DST, L2_TEST_CNT);

	return;
}

