/*  ============================================================================
 *   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.
* ============================================================================
Example to show the performance of Multicore Navigator on Keystone DSP
* =============================================================================
 *  Revision History
 *  ===============
 *  May 15, 2011 Brighton Feng   File Created
 * ============================================================================
 */

#include <stdio.h>
#include <c6x.h>
#include <csl_cacheAux.h>
#include <csl_cache.h>
#include <csl_qm_queue.h>
#include "KeyStone_common.h"
#include "KeyStone_DDR_Init.h"
#include "MNav_QM_Intc_setup.h"
#include "MNav_Test.h"

void QueuePushPopTest(Uint32 uiQueueNumber)
{
	Uint32 uiDescriptorNumber;

	uiDescriptorNumber= queueStatusConfigRegs[uiQueueNumber].REG_A_EntryCount;
	if(uiDescriptorNumber>TEST_DESC_BUF_SIZE)
		uiDescriptorNumber=TEST_DESC_BUF_SIZE;

	printf("Queue %d push test through Queue Manage Registers\n", uiQueueNumber);
	QueuePushCycleTest(&queueManageRegs[uiQueueNumber], uiDescriptorNumber, &queueManageRegs[uiQueueNumber]);
	checkQueues(); 	//for debug

	printf("Queue %d push test through Queue Manage Proxy Registers\n", uiQueueNumber);
	QueuePushCycleTest(&queueManageProxyRegs[uiQueueNumber], uiDescriptorNumber, &queueManageRegs[uiQueueNumber]);
	checkQueues(); 	//for debug

	printf("Queue %d push test through Queue Manage VBUSM Data Space\n", uiQueueNumber);
	QueuePushCycleTest(&queueManageData[uiQueueNumber], uiDescriptorNumber, &queueManageRegs[uiQueueNumber]);
	checkQueues(); 	//for debug

	printf("Queue %d push test through Queue Manage proxy VBUSM Data Space\n", uiQueueNumber);
	QueuePushCycleTest(&queueManageProxyData[uiQueueNumber], uiDescriptorNumber, &queueManageRegs[uiQueueNumber]);
	checkQueues(); 	//for debug


	printf("Queue %d pop test through Queue Manage Registers\n", uiQueueNumber);
	QueuePopCycleTest(&queueManageRegs[uiQueueNumber], uiDescriptorNumber);
	checkQueues(); 	//for debug

	printf("Queue %d pop test through Queue Manage VBUSM Data Space\n", uiQueueNumber);
	QueuePopCycleTest(&queueManageData[uiQueueNumber], uiDescriptorNumber);
	checkQueues(); 	//for debug

	printf("Empty Queue %d pop test through Queue Manage Registers\n", EMPTY_FDQ);
	QueuePopCycleTest(&queueManageRegs[EMPTY_FDQ], uiDescriptorNumber);
	checkQueues(); 	//for debug


	printf("Queue %d push to pop delay test through Queue Manage Registers\n", uiQueueNumber);
	QueuePushToPopDelayTest(&queueManageRegs[uiQueueNumber], uiDescriptorNumber);
	checkQueues(); 	//for debug

	printf("Queue %d push to pop delay test through Queue Manage VBUSM Data Space\n", uiQueueNumber);
	QueuePushToPopDelayTest(&queueManageData[uiQueueNumber], uiDescriptorNumber);
	checkQueues(); 	//for debug

}

void DSPCoreAccessQueueTest()
{
	puts("Queue Push/Pop test on descriptors with internal linking RAM");
	QueuePushPopTest(DDR_MONO_LINK_RAM0_FDQ);

	puts("Queue Push/Pop test on descriptors with external linking RAM");
	QueuePushPopTest(DDR_MONO_LINK_RAM1_FDQ);

}

void QueuePendInterruptTest()
{
	puts("\nQueue pend interrupt test on descriptors with internal linking RAM");
	QueuePushToPendInterruptDelayTest(&queueManageRegs[DDR_MONO_LINK_RAM0_FDQ]);

	puts("Queue pend interrupt test on descriptors with external linking RAM");
	QueuePushToPendInterruptDelayTest(&queueManageRegs[DDR_MONO_LINK_RAM1_FDQ]);
}

void PktDmaThroughputTest(Uint32 uiSrcQuNum, Uint32 uiTxQuNum, 
	Uint32 uiFlowID, Uint32 uiMaxBytes, Uint32 uiNumCh)
{
	int i;

	for(i=4; i<=uiMaxBytes; i*=2)
		PktDmaThroughput(uiSrcQuNum, uiTxQuNum, uiFlowID, i, uiNumCh);
}

void PktDmaTest(Uint32 uiTxQuNum, Uint32 uiNumCh)
{
	printf("host Packet DMA test with %d channels\n", uiNumCh);

	/*Packet DMA transfer from LL2 to another core's LL2*/
	PktDmaThroughputTest(CORE0_LL2_HOST_SIZE3_FDQ, uiTxQuNum, RX_FLOW_LL2_HOST, LL2_PACKET_BUFFER_SIZE3, uiNumCh);
	/*Packet DMA transfer from LL2 to SL2*/
	PktDmaThroughputTest(CORE0_LL2_HOST_SIZE3_FDQ, uiTxQuNum, RX_FLOW_SL2_HOST, LL2_PACKET_BUFFER_SIZE3, uiNumCh);
	/*Packet DMA transfer from LL2 to DDR*/
	PktDmaThroughputTest(CORE0_LL2_HOST_SIZE3_FDQ, uiTxQuNum, RX_FLOW_DDR_HOST, LL2_PACKET_BUFFER_SIZE3, uiNumCh);
	/*Packet DMA transfer from SL2 to LL2*/
	PktDmaThroughputTest(SL2_HOST_SIZE3_FDQ, uiTxQuNum, RX_FLOW_LL2_HOST, LL2_PACKET_BUFFER_SIZE3, uiNumCh);
	/*Packet DMA transfer from SL2 to DDR*/
	PktDmaThroughputTest(SL2_HOST_SIZE3_FDQ, uiTxQuNum, RX_FLOW_DDR_HOST, LL2_PACKET_BUFFER_SIZE3, uiNumCh);
	/*Packet DMA transfer from DDR to LL2*/
	PktDmaThroughputTest(DDR_HOST_SIZE3_FDQ, uiTxQuNum, RX_FLOW_LL2_HOST, LL2_PACKET_BUFFER_SIZE3, uiNumCh);
	/*Packet DMA transfer from DDR to SL2*/
	PktDmaThroughputTest(DDR_HOST_SIZE3_FDQ, uiTxQuNum, RX_FLOW_SL2_HOST, LL2_PACKET_BUFFER_SIZE3, uiNumCh);

	printf("monolithic Packet DMA test with %d channels\n", uiNumCh);

	/*Packet DMA transfer from LL2 to another core's LL2*/
	PktDmaThroughputTest(CORE0_LL2_MONOLITHIC_FDQ, uiTxQuNum, RX_FLOW_LL2_MONO, L2_MONO_DESCRIPTOR_SIZE, uiNumCh);
	/*Packet DMA transfer from LL2 to SL2*/
	PktDmaThroughputTest(CORE0_LL2_MONOLITHIC_FDQ, uiTxQuNum, RX_FLOW_SL2_MONO, L2_MONO_DESCRIPTOR_SIZE, uiNumCh);
	/*Packet DMA transfer from LL2 to DDR*/
	PktDmaThroughputTest(CORE0_LL2_MONOLITHIC_FDQ, uiTxQuNum, RX_FLOW_DDR_MONO, L2_MONO_DESCRIPTOR_SIZE, uiNumCh);
	/*Packet DMA transfer from SL2 to LL2*/
	PktDmaThroughputTest(SL2_MONOLITHIC_FDQ, uiTxQuNum, RX_FLOW_LL2_MONO, L2_MONO_DESCRIPTOR_SIZE, uiNumCh);
	/*Packet DMA transfer from SL2 to DDR*/
	PktDmaThroughputTest(SL2_MONOLITHIC_FDQ, uiTxQuNum, RX_FLOW_DDR_MONO, L2_MONO_DESCRIPTOR_SIZE, uiNumCh);
	/*Packet DMA transfer from DDR to LL2*/
	PktDmaThroughputTest(DDR_MONO_LINK_RAM0_FDQ, uiTxQuNum, RX_FLOW_LL2_MONO, L2_MONO_DESCRIPTOR_SIZE, uiNumCh);
	/*Packet DMA transfer from DDR to SL2*/
	PktDmaThroughputTest(DDR_MONO_LINK_RAM0_FDQ, uiTxQuNum, RX_FLOW_SL2_MONO, L2_MONO_DESCRIPTOR_SIZE, uiNumCh);
}

void main(void)
{   
	int i;
	TDSP_Type dspType;

	dspType= Get_dsp_type();
	if(TCI6616==dspType||TCI6618==dspType)
	{
		//DSP core speed
		KeyStone_main_PLL_init (236, 29); 	//for 122.88MHz input clock

		//DDR speed = 66.67*20/1= 1333
		KeyStone_DDR_PLL_init (20, 1);

		TCI6618_EVM_DDR_Init(666.667); 	//for 1333Mbps

	}
	else if(TCI6608==dspType)
	{
		//DSP core speed
		//KeyStone_main_PLL_init (20, 1); 	//for 50MHz input clock
		KeyStone_main_PLL_init (10, 1); 	//for 100MHz input clock

		//DDR speed = 66.67*20/1= 1333
		KeyStone_DDR_PLL_init (20, 1);

		TCI6608_EVM_DDR_Init(666.667); 	//for 1333Mbps
	}
	else if(TCI6614==dspType)
	{
		//DSP core speed
		KeyStone_main_PLL_init (236, 29); 	//for 122.88MHz input clock

		//DDR speed = 66.67*n
		KeyStone_DDR_PLL_init (18, 1);

		TCI6614_VDB_DDR_Init(600);

	}
	else
	{
		puts("Unknown DSP type!");
		return;
	}
	//enable SRIO for test
	Keystone_enable_PSC_module(CSL_PSC_PD_SRIO, CSL_PSC_LPSC_SRIO);

	//enable PA for test
	Keystone_enable_PSC_module(CSL_PSC_PD_PASS, CSL_PSC_LPSC_PKTPROC);

	//Configure L1 as 32KB cache, L2 cache 256KB
	CACHE_setL1PSize(CACHE_L1_32KCACHE);
	CACHE_setL1DSize(CACHE_L1_32KCACHE);
	CACHE_setL2Size(CACHE_256KCACHE);

	/*make DDR cacheable and prefetchable*/
	for(i=0; i<128; i++)
		CGEM_regs->MAR[128+i]=1|(1<<CSL_CGEM_MAR0_PFX_SHIFT);	

	QMSS_init();
	PktDMA_init();
	checkQueues(); 	//for debug
	
	QM_Interrupts_Init();

	/* Initialize Time stamp counter to measure cycles*/
	TSC_init();

	DSPCoreAccessQueueTest();
	checkQueues(); 	//for debug

	QueuePendInterruptTest();
	checkQueues(); 	//for debug

	QueueReclamationDelayTest(DDR_HOST_SIZE3_FDQ);
	checkQueues(); 	//for debug

	QueuePushToAccumulationDelayTest(DDR_MONO_LINK_RAM0_FDQ);
	checkQueues(); 	//for debug

	puts("test Packet DMA in QMSS");
	for(i= 1; i<=8; i*=2)
		PktDmaTest(QMSS_INFRASTRUCTURE_QUEUE_BASE, i);
	checkQueues(); 	//for debug

	puts("test Packet DMA in PA");
	PktDmaTest(QMSS_PASS_QUEUE_BASE, 1);
	checkQueues(); 	//for debug

	puts("test Packet DMA in SRIO");
	PktDmaTest(QMSS_SRIO_QUEUE_BASE, 1);
	checkQueues(); 	//for debug

	puts("Test complete");
    
    return;
}

