iotestai.c 5 KB

/*************************************************************************
 *
 *  File: iotestai.c
 *
 *  This file contains test routines for the Audio Interface (AI).
 *
 *  $Header: /root/leakn64/depot/rf/sw/n64os20l/iosim/src/iotestai.c,v 1.2 2002/05/30 05:52:50 whs Exp $
 *
 */

#include <stdio.h>
#include "trace.h"
#include "iomap.h"
#include "iotest.h"


/***********************************************************************
 * Init routine for AI
 */
void
AiInit(unsigned int dacRate, unsigned int bitRate)
{
	/* 
	 * DAC rate value is: at least 131
	 * Bit rate value is: at least 1
	 */
	IO_WRITE(AI_DACRATE_REG, dacRate);
	IO_WRITE(AI_BITRATE_REG, bitRate);
	IO_WRITE(AI_CONTROL_REG, AI_CONTROL_DMA_ON);

}  /* AiInit */


/***********************************************************************
 * Test routines for AI
 */
static int
aiPollStatus(unsigned int statBits)
{
	/* Poll AI status register for the statBits set */

	int stat;

	do {
		stat = IO_READ(AI_STATUS_REG);
		_TRACE(DSTATUS, fprintf(LogFp, "\tAI Status = 0x%08x\n",
			stat));
	} while (stat & statBits);

	return(0);

}  /* aiPollStatus */


int
IoAiDmaCopy(unsigned int dramAddr, int nbytes)
{
	/* dramAddr must be 8-byte aligned */
	/* nbytes specifies number of multiple of 8 bytes (8, 16, 24,...) */

	dramAddr &= 0xFFFFFFF8;
	nbytes  &= 0xFFFFFFF8;

#ifdef CHECK_STATUS
	aiPollStatus(AI_STATUS_FIFO_FULL | PI_STATUS_DMA_BUSY);
#endif
	/* Need to write address first and length second */
	IO_WRITE(AI_DRAM_ADDR_REG, dramAddr);
	IO_WRITE(AI_LEN_REG, (unsigned int)nbytes);

	return(0);

}  /* IoAiDmaCopy */


int	
AiTestInit(int dacRate, int bitRate, int a3, int a4)
{

	AiInit(dacRate, bitRate);
	return(0);

}  /* AiTestInit */


int	
AiTestStatus(int testBits, int a2, int a3, int a4)
{
	/* Read the AI status reg and compare it against testBits */

	aiPollStatus(testBits);

	return(0);

}  /* AiTestStatus */


int	
AiTestReg(int regAddr, int data, int a3, int a4)
{
	/* a1 = register address */
	/* a2 = test data */
	/* Write/Read to/from DRAM address and Cartridge registers */

	unsigned int ret;

	errorCount = 0;

	regAddr &= 0xFFFFFFFC;		/* Make sure that it's word-aligned */

	_TRACE(DLOG, printf("\tAI Status Reg = 0x%08x\n", 
		IO_READ(AI_STATUS_REG)));

	/* Hw reset the address to be 8-byte aligned 
	 * Also, DMA RAM address is only 24-bit, upper 8 bits are
	 * also set to 0?
	 */
	IO_WRITE(regAddr, data);
	ret = IO_READ(regAddr);
	if (data != ret) {
		errorCount++;
		_TRACE(DERROR, LOG_ERROR(data, ret));
	}

	errorTotal += errorCount;
	return((errorCount == 0) ? 0 : -1);

}  /* AiTestReg */


int	
AiCompareData(int regAddr, int data, int a3, int a4)
{
	/* Poll register until content equals to data */
	/* a1 = register address */
	/* a2 = test data */
	unsigned int ret;

	do {
		ret = IO_READ(regAddr);
	} while (ret != data);

	return(1);

}  /* AiCompareData */


int
AiTestDma(int dramAddr, int nbytes, int a3, int a4)
{
	/* CPU issues DMA (write) requests from RDRAM to AI devices */

	errorCount = 0;

	dramAddr &= 0xFFFFFFF8;		/* Make sure it's 8-byte aligned */
	nbytes   &= 0xFFFFFFF8;	

	if (IoAiDmaCopy((unsigned int)dramAddr, nbytes) < 0) {
		errorCount++;
	}

	errorTotal += errorCount;
	return((errorCount == 0) ? 0 : -1);

}  /* AiTestDma */


int
AiTestDmaPg(int dramAddr, int npages, int a3, int a4)
{
	/* 
	 * CPU issues DMA (write) requests between SI devices and 
	 * RDRAM pages
	 *	2 RDRAMs: 1 RDRAM = 1 MBytes = 2 banks;
	 *		  1 bank  = 256 pages; 1 page = 2 KBytes
	 */

	int		i, startPg, nbytes, dir;
	unsigned int	address;

	errorCount = 0;
	nbytes	   = 8;
	dir	   = DIR_TO_RAM;

	dramAddr &= 0xFFFFFFF8;	    /* Make sure addresses are 8B aligned */

	startPg = dramAddr / RDRAM_PAGE_SIZE;
	i = MAX_RDRAM_PAGES - startPg;
	if (npages > i)
		npages = i;

	for (i=0; i < npages; i++) {
		address = (dramAddr + (i*RDRAM_PAGE_SIZE)) & 0xFFFFFFF8;
		if (IoAiDmaCopy((unsigned int)address, nbytes) < 0) {
			errorCount++;
		}
#ifndef CHECK_STATUS
		aiPollStatus(AI_STATUS_FIFO_FULL | PI_STATUS_DMA_BUSY);
#endif
	}
	errorTotal += errorCount;

	return((errorCount == 0) ? 0 : -1);

}  /* AiTestDmaPg */


int
AiStartDma(int dramAddr, int nbytes, int a3, int a4)
{
	/* CPU issues DMA (write) requests from RDRAM to AI devices */

	errorCount = 0;

	dramAddr &= 0xFFFFFFF8;		/* Make sure it's 8-byte aligned */
	nbytes   &= 0xFFFFFFF8;	

	IoAiDmaCopy((unsigned int)dramAddr, nbytes);

	errorTotal += errorCount;
	return((errorCount == 0) ? 0 : -1);

}  /* AiStartDma */

int	
AiCompareLength(int regAddr, int data, int a3, int a4)
{
	/* Poll Length register until content less than to data */
	/* a1 = register address forced to AI_LEN_REG */
	/* a2 = test data for compare */
	unsigned int ret;

	unsigned int stat;
	int errorCount;


	errorCount = -1;
	do {
		stat = IO_READ(AI_STATUS_REG);
		
		ret = IO_READ(AI_LEN_REG);
		_TRACE(DLOG, printf("\tAI Length Reg = 0x%08x\n", ret));

		if (ret <= data) {
		errorCount =0;
		break;
		}


	  /* will not work if length compared with is small */
	} while (stat & AI_STATUS_DMA_BUSY) ;


	return(errorCount);

}  /* AiCompareLength */