atspeed_comp_aisp.c 8.05 KB

#include <regdef.h>
#include <asm.h>
#include <R4300.h>
#include <PR/bcp.h>
#include <PR/bbdebug.h>
#include "test_vector.h"

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
   Memory allocation
   0x7FFF80 --- 0x800000: store test parameter
   0x7fff00 --- 0x7fff80: inter-communication between bd and cpu
   0x600000 --- 0x7FFF00: store sp dmem/imem code  
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#define  TEST_PARAM_ADDR   (0x7FFF80 | K1BASE)
#define  RSP_RET_ADDR      (0x7FFFC0 | K1BASE)

#define  RDP_COMM_ADDR     (0x7FFF00 | K1BASE)
#define  RSP_CODE_TEST     0x00000001
#define  RDP_TEST          0x00000010
#define  AI_TEST           0x00000100
#define  VI_TEST           0x00001000
#define  UI_TEST           0x00010000
#define  PI_TEST           0x00100000

#define  RDP_ONE_TEST      0x00000001
#define  RDP_LAST_TEST     0x00000002
#define  RDP_TEST_DONE     0x00000010

static inline int rspcode_test();
static inline int rdp_test();
static inline int vpll_init();
static inline int ai_test();
static inline int vi_test();
static inline int ui_test();
static inline int pi_test();

void main()
{
    int err=0;
    int param;

    param  = * ((int *) TEST_PARAM_ADDR);

    if (param & RSP_CODE_TEST) 
        err += rspcode_test();

    if (param & RDP_TEST) 
        err += rdp_test();

    if (param & AI_TEST) 
        err += ai_test();

    if (param & VI_TEST) 
        err += vi_test();

    if (param & UI_TEST) 
        err += ui_test();

    if (param & PI_TEST) 
        err += pi_test();

    if (err) { 
        TEST_ERROR;
    } else {
        TEST_PASS;
    }

    for (;;) ;
    return 0;
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    RSP Test 
    Reading from DDR address at RSP_CODE_START
       4 Bytes: #of Test
       4 Bytes: Padding to 8 bytes align
       4 Bytes:  test i Dmem offset(from RSP_CODE_START)
       4 Bytes:  test i Dmem size
       4 Bytes:  test i Imem offset(from RSP_CODE_START)
       4 Bytes:  test i Imem size
       ... 
       code(dmem+imem) 
   Note: offset and size should be 8 bytes aligned
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#define RSP_CODE_START 0x600000
#define RSP_DEVICE_BUSY (SP_STATUS_DMA_FULL | SP_STATUS_DMA_BUSY | SP_STATUS_IO_FULL)

static inline int rspcode_test()
{
    int i, num, err=0, ret;
    int *pdata;
    
    pdata = (int *) (RSP_CODE_START | K0BASE);
    num = *pdata;
    pdata += 2;
    IO_WRITE(0x04000f84, 0);
    for (i=0; i<num; i++) {
        if (pdata[1] > 0) { /* dmem data */
            IO_WRITE(SP_MEM_ADDR_REG, SP_DMEM_START);
            IO_WRITE(SP_DRAM_ADDR_REG, pdata[0] + RSP_CODE_START);
            IO_WRITE(SP_RD_LEN_REG, pdata[1] - 1);
            do {
                 ret =  IO_READ(SP_STATUS_REG);
            } while (ret & RSP_DEVICE_BUSY);  
        }
        pdata += 2;

        if (pdata[1] > 0) { /* imem data */
            IO_WRITE(SP_MEM_ADDR_REG, SP_IMEM_START);
            IO_WRITE(SP_DRAM_ADDR_REG, pdata[0] +  RSP_CODE_START);
            IO_WRITE(SP_RD_LEN_REG, pdata[1] - 1);
            do {
                 ret =  IO_READ(SP_STATUS_REG);
            } while (ret & RSP_DEVICE_BUSY);  
        } 
        pdata += 2;

        /* set PC to 0 and run it */
        IO_WRITE(SP_PC_REG, 0);
        IO_WRITE(SP_STATUS_REG, SP_CLR_BROKE | SP_CLR_HALT);
        do {
            ret = IO_READ(SP_STATUS_REG);
        } while (! (ret & SP_STATUS_BROKE));

        do {
            ret =  IO_READ(SP_STATUS_REG);
        }  while (ret & SP_STATUS_IO_FULL);

        ret = IO_READ(0x04000f84);
        if (ret != 0x0000feed && ret != 0xfeed0000) 
            err++;
    }

    IO_WRITE(RSP_RET_ADDR, num);
    return err;
}

static inline int rdp_test()
{
    int ret, err=0;
    int dp_start, dp_count, cur;

    for (; ;) {
        do {
            ret = IO_READ(RDP_COMM_ADDR);
        } while (ret == 0);
        if (ret == RDP_LAST_TEST) break;

        IO_WRITE(RDP_COMM_ADDR, 0);   
        IO_WRITE(RDP_COMM_ADDR+4, 0);   

        dp_start = IO_READ(RDP_COMM_ADDR+8) & 0x00ffffff;
        dp_count = IO_READ(RDP_COMM_ADDR+0xC) & 0x00ffffff;

        IO_WRITE(DPC_START_REG, dp_start);
        IO_WRITE(DPC_END_REG, dp_start+dp_count);
        
        do {
            cur = IO_READ(DPC_CURRENT_REG) & 0x00ffffff;
        } while (cur < dp_start+dp_count);

        do {
            cur = IO_READ(DPC_STATUS_REG);
        } while (cur & DPC_STATUS_PIPE_BUSY);

        IO_WRITE(RDP_COMM_ADDR+4, RDP_TEST_DONE);
    } 

    return err;
}

static inline int vpll_init()
{
    IO_WRITE(MI_AVCTRL_REG, 0x01194245);
    IO_WRITE(MI_AVCTRL_REG, 0x03194244); 
    IO_WRITE(MI_AVCTRL_REG, 0x03994244);
    IO_WRITE(MI_AVCTRL_REG, 0x03194244);
    IO_WRITE(MI_AVCTRL_REG, 0x03994244);
    IO_WRITE(MI_AVCTRL_REG, 0x03194244);

    return 0;
}

#define AI_INIT(DacRate, Bitrate) { IO_WRITE(AI_DACRATE_REG, DacRate); \
                                    IO_WRITE(AI_BITRATE_REG, Bitrate); \
                                    IO_WRITE(AI_CONTROL_REG, AI_CONTROL_DMA_ON); }
#define AI_DMA(addr, len) { IO_WRITE(AI_DRAM_ADDR_REG, addr); \
                            IO_WRITE(AI_LEN_REG, len); }
#define POLLING_SET(addr, data) { do { } while (!(IO_READ(addr) & (data)));}
#define POLLING_CLEAR(addr, data) { do {} while (IO_READ(addr) & (data));}
#define __REG(x) "$" #x
#define getcp0reg(source)					\
({ int __res;                                                   \
        __asm__ __volatile__(                                   \
	".set\tpush\n\t"					\
	".set\treorder\n\t"					\
        "mfc0\t%0,"__REG(source)"\n\t"                          \
	".set\tpop"						\
        : "=r" (__res));                                        \
        __res;})


static inline int wait_cycles(int cycles)
{
    int count, diff;

    count = getcp0reg(C0_COUNT);  
    do { 
       diff = getcp0reg(C0_COUNT) - count;
    } while (diff < cycles); 

    return 0;
}

static inline int ai_test()
{
    int err = 0, ret, stat, i;

    vpll_init();
    IO_WRITE(VI_CONTROL_REG, 0); /* init vi to get proper vclk */
 
    /*  ported from iosim test */

    /* 1st part */
    AI_INIT(0x86, 0x1);      /* 003 */
    AI_DMA(0, 0x14);         /* 043 */ 
    IO_READ(8);              /* 100 */
    POLLING_CLEAR(AI_STATUS_REG, AI_STATUS_DMA_BUSY);  /* 104 */
    IO_WRITE(AI_CONTROL_REG, AI_CONTROL_DMA_OFF);      /* 102 */
    IO_WRITE(0x10, 0x010f0A05);
    if (IO_READ(0x10) != 0x010f0A05) err++;
    POLLING_SET(MI_INTR_REG, MI_INTR_AI);             
    POLLING_CLEAR(AI_STATUS_REG, AI_STATUS_DMA_BUSY);
    IO_WRITE(AI_CONTROL_REG, AI_CONTROL_DMA_ON);
    POLLING_SET(MI_INTR_REG, MI_INTR_AI);             
    IO_WRITE(AI_STATUS_REG, 0); /* clear interrupt */
    POLLING_CLEAR(MI_INTR_REG, MI_INTR_AI);             
    AI_DMA(8, 8);
    POLLING_CLEAR(AI_STATUS_REG, AI_STATUS_DMA_BUSY);

    /* 2nd part */
    wait_cycles(3000);
    AI_INIT(0x90, 0x1);
    AI_DMA(0x20, 0x10);
    IO_READ(0x10);
    IO_WRITE(AI_CONTROL_REG, AI_CONTROL_DMA_OFF);      /* 102 */
    IO_WRITE(0x10, 0x10f0a050);
    if (IO_READ(0x10) != 0x10f0a050) err++;
    POLLING_SET(MI_INTR_REG, MI_INTR_AI);             
    POLLING_CLEAR(AI_STATUS_REG, AI_STATUS_DMA_BUSY);
    IO_WRITE(AI_CONTROL_REG, AI_CONTROL_DMA_ON);
    POLLING_SET(MI_INTR_REG, MI_INTR_AI);             
    IO_WRITE(AI_STATUS_REG, 1); /* clear interrupt */
    POLLING_CLEAR(MI_INTR_REG, MI_INTR_AI);             
    POLLING_CLEAR(AI_STATUS_REG, AI_STATUS_DMA_BUSY);
     
    /* 3rd part */ 
    wait_cycles(4000);
    IO_WRITE(VI_CONTROL_REG, 0); 

    for (i=0x20000; i>=8; i>>=1) {
        AI_INIT(0x86, 0x1);
        AI_DMA(0, i); 
        err++;
        do {
            stat = IO_READ(AI_STATUS_REG);
            ret = IO_READ(AI_LEN_REG);
            if (ret <= (i-8)) {
                err--;
                break;
            }
        } while (stat & AI_STATUS_DMA_BUSY);
        AI_INIT(0, 0);
    }

    IO_WRITE(RSP_RET_ADDR, 1);
    return err;
}

static inline int vi_test()
{
    int err = 0;

    return err;
}

static inline int ui_test()
{
    int err = 0;

    return err;
}

static inline int pi_test()
{
    int err = 0;

    return err;
}