#ifndef _DMASCHEDULER_H_
#define _DMASCHEDULER_H_

#define QDMA_OPT		*(volatile unsigned int *)0x2000000
#define QDMA_SRC		*(volatile unsigned int *)0x2000004
#define QDMA_CNT		*(volatile unsigned int *)0x2000008
#define QDMA_DST		*(volatile unsigned int *)0x200000C
#define QDMA_IDX		*(volatile unsigned int *)0x2000010
#define QDMA_RLD		*(volatile unsigned int *)0x2000014

#define S_QDMA_OPT		*(volatile unsigned int *)0x2000020
#define S_QDMA_SRC		*(volatile unsigned int *)0x2000024
#define S_QDMA_CNT		*(volatile unsigned int *)0x2000028
#define S_QDMA_DST		*(volatile unsigned int *)0x200002C
#define S_QDMA_IDX		*(volatile unsigned int *)0x2000030

// DMA Finish Value
#define DMA_FINISH_VALUE		1

/*
// DMA Default OPT list
#define DMA_OPT_COUNT 				6
#define EDMA_CFG_NO_NONE_NO_INC		0
#define EDMA_CFG_NO_INC_NO_INC		1
#define EDMA_CFG_YES_INC_NO_INC		2
#define EDMA_CFG_NO_INC_NO_NONE		3
#define EDMA_CFG_NO_INC_NO_DEC		4
#define EDMA_CFG_NO_INC_NO_INC_8BIT	5
*/

#define DMA_CFG_COUNT				6
#define EDMA_CFG_NO_NONE_NO_NONE	0
#define EDMA_CFG_NO_NONE_NO_INC		1
#define EDMA_CFG_NO_INC_NO_NONE		2
#define EDMA_CFG_NO_INC_NO_INC		3
#define EDMA_CFG_YES_INC_NO_INC		4
#define EDMA_CFG_NO_INC_NO_DEC		5

#define MAX_DMA_TRANSFER_SIZE_SDRAM		(16 * 1024)
#define MAX_DMA_TRANSFER_SIZE_HPI_WRITE	(2 * 1024)
#define MAX_DMA_TRANSFER_SIZE_HPI_READ	128				// read 속도 때문이 아니다.

typedef struct tagDMATableUnit
{
	unsigned int Opt;
	unsigned int Src;
	unsigned int Dst;
	unsigned int Cnt;
	unsigned int Idx;	
	unsigned int *Fin;
	struct tagDMATableUnit *Link;
} TDMATableUnit;

typedef struct
{
	TDMATableUnit *DMATable;
	int CellCount;
	int CurrentIndex;
} TCaptureJobUnit;

typedef struct
{
	TDMATableUnit *DMATable;
	int CellCount;
	int CurrentIndex;
} TDMAJobUnit;

typedef struct
{
	TDMATableUnit *DMATable;
	int CellCount;
	int CurrentIndex;
	unsigned int IsSend;
	int CPBIndex;
} THPIJobUnit;

typedef struct
{
	TDMATableUnit *DMATable;
	int CellCount;
	int CurrentIndex;
	unsigned int IsSend;
	unsigned int Length;
} TUSBJobUnit;


extern int jobTcc;

//extern int DMAIdle;
extern TDMATableUnit *CurrentCaptureDMAPtr;	
extern TDMATableUnit *CurrentDMAPtr;

void CaptureJobAdd(TDMATableUnit *captureDMATable);
void CaptureJobReset();

int DMAJob_IsFull();
void DMAJobAdd(TDMATableUnit *table, int cellCount);

int HPIJob_IsFull();
void HPIJobAdd(TDMATableUnit *table, int cellCount, unsigned int isSend, int cpbIndex);

int USBJob_IsFull();
void USBJobAdd(TDMATableUnit *table, int cellCount, unsigned int isSend, unsigned int length);

typedef struct
{
  	unsigned int *src1;
  	unsigned int *src2;
  	unsigned int *dst1;  	
  	unsigned int *dst2;
  	unsigned int *finish;
} TEmifJob;


#define DMA_JOB_SIZE		64
#define DMA_JOB_MASK		(DMA_JOB_SIZE - 1)
#define DMA_JOB_COUNT		(DMA_JOB_SIZE - 1)

#define USB_JOB_SIZE		16
#define USB_JOB_MASK		(USB_JOB_SIZE - 1)

#define HPI_JOB_SIZE		SYSTEM_CPB_COUNT * 2
#define HPI_JOB_MASK		(HPI_JOB_SIZE - 1)
#define HPI_JOB_COUNT		(HPI_JOB_SIZE - 1)

#define EMIF_JOB_SIZE		256
#define EMIF_JOB_MASK		(EMIF_JOB_SIZE - 1)
#define EMIF_JOB_COUNT		(EMIF_JOB_SIZE - 1)

unsigned int MakeDMAOpt(unsigned int eSize, unsigned int cfg);


void EmifJob_Insert(unsigned int *src1, unsigned int *dst1, unsigned int *fin);
void EmifJob_Insert2(unsigned int *src1, unsigned int *dst1, unsigned int *src2, unsigned int *dst2, unsigned int *fin);
int EmifJob_IsFull();
#endif
