filename | test/dmac.c |
changeset | 185:6755a04c447f |
next | 190:f7653df5e832 |
author | nkeynes |
date | Tue Jul 11 01:35:27 2006 +0000 (17 years ago) |
permissions | -rw-r--r-- |
last change | First commit of system test framework. 3 initial test cases (incomplete): testide, testmath, and testta |
file | annotate | diff | log | raw |
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +00001.2 +++ b/test/dmac.c Tue Jul 11 01:35:27 2006 +00001.3 @@ -0,0 +1,128 @@1.4 +/**1.5 + * $Id: dmac.c,v 1.1 2006-07-11 01:35:23 nkeynes Exp $1.6 + *1.7 + * DMA support code1.8 + *1.9 + * Copyright (c) 2006 Nathan Keynes.1.10 + *1.11 + * This program is free software; you can redistribute it and/or modify1.12 + * it under the terms of the GNU General Public License as published by1.13 + * the Free Software Foundation; either version 2 of the License, or1.14 + * (at your option) any later version.1.15 + *1.16 + * This program is distributed in the hope that it will be useful,1.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of1.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1.19 + * GNU General Public License for more details.1.20 + */1.21 +1.22 +#include "dma.h"1.23 +#include "asic.h"1.24 +1.25 +#define DMA_BASE 0xFFA000001.26 +1.27 +#define DMA_SAR(c) (DMA_BASE+0x00+(c<<4))1.28 +#define DMA_DAR(c) (DMA_BASE+0x04+(c<<4))1.29 +#define DMA_TCR(c) (DMA_BASE+0x08+(c<<4))1.30 +#define DMA_CHCR(c) (DMA_BASE+0x0C+(c<<4))1.31 +#define DMA_OR (DMA_BASE+0x40)1.32 +1.33 +#define ASIC_BASE 0xA05F60001.34 +#define PVR_DMA_DEST (ASIC_BASE+0x800)1.35 +#define PVR_DMA_COUNT (ASIC_BASE+0x804)1.36 +#define PVR_DMA_CTL (ASIC_BASE+0x808)1.37 +#define PVR_DMA_REGION (ASIC_BASE+0x884)1.38 +1.39 +void dmac_dump_channel( FILE *f, unsigned int channel )1.40 +{1.41 + fprintf( f, "DMAC SAR: %08X Count: %08X Ctl: %08X OR: %08X\n",1.42 + long_read(DMA_SAR(channel)), long_read(DMA_TCR(channel)),1.43 + long_read(DMA_CHCR(channel)), long_read(DMA_OR) );1.44 +}1.45 +1.46 +1.47 +/**1.48 + * Setup the DMAC for a transfer. Assumes 32-byte block transfer.1.49 + * Caller is responsible for making sure no-one else is using the1.50 + * channel already.1.51 + *1.52 + * @param channel DMA channel to use, 0 to 31.53 + * @param source source address (if a memory source)1.54 + * @param dest destination address (if a memory destination)1.55 + * @param length number of bytes to transfer (must be a multiple of1.56 + * 32.1.57 + * @param direction 0 = host to device, 1 = device to host1.58 + */1.59 +void dmac_prepare_channel( int channel, uint32_t source, uint32_t dest,1.60 + uint32_t length, int direction )1.61 +{1.62 + uint32_t control;1.63 +1.64 + if( direction == 0 ) {1.65 + /* DMA Disabled, IRQ disabled, 32 byte transfer, burst mode,1.66 + * Memory => Device, Source addr increment, dest addr fixed1.67 + */1.68 + control = 0x000012C0;1.69 + } else {1.70 + /* DMA Disabled, IRQ disabled, 32 byte transfer, burst mode,1.71 + * Device => Memory, Source addr fixed, dest addr increment1.72 + */1.73 + control = 0x000043C0;1.74 + }1.75 + long_write( DMA_CHCR(channel), control );1.76 + long_write( DMA_SAR(channel), source );1.77 + long_write( DMA_DAR(channel), dest );1.78 + long_write( DMA_TCR(channel), (length >> 5) );1.79 + control |= 0x0001;1.80 + long_write( DMA_CHCR(channel), control ); /* Enable DMA channel */1.81 + long_write( DMA_OR, 0x8201 ); /* Ensure the DMAC config is set */1.82 +}1.83 +1.84 +1.85 +int pvr_dma_write( unsigned int target, char *buf, int len, int region )1.86 +{1.87 + uint32_t addr =(uint32_t)buf;1.88 + int result;1.89 + if( (addr & 0xFFFFFFE0) != addr ) {1.90 + fprintf( stderr, "Address error: Attempting DMA from %08X\n", addr );1.91 + return -1;1.92 + } else {1.93 + fprintf( stderr, "PVR DMA transfer from %08X\n", addr );1.94 + }1.95 + long_write( PVR_DMA_CTL, 0 ); /* Stop PVR dma if it's already running */1.96 + asic_clear();1.97 +1.98 + dmac_prepare_channel( 2, (uint32_t)buf, 0, len, 0 ); /* Allocate channel 2 */1.99 + long_write( PVR_DMA_DEST, target );1.100 + long_write( PVR_DMA_COUNT, len );1.101 + long_write( PVR_DMA_REGION, region );1.102 +1.103 + CHECK_IEQUALS( target, long_read(PVR_DMA_DEST) );1.104 + CHECK_IEQUALS( len, long_read(PVR_DMA_COUNT) );1.105 + CHECK_IEQUALS( 0, long_read(PVR_DMA_REGION) );1.106 + CHECK_IEQUALS( (uint32_t)buf, long_read(DMA_SAR(2)) );1.107 + CHECK_IEQUALS( len/32, long_read(DMA_TCR(2)) );1.108 + CHECK_IEQUALS( 0x12C1, long_read(DMA_CHCR(2)) );1.109 +1.110 + long_write( PVR_DMA_CTL, 1 );1.111 + result = asic_wait(EVENT_PVR_DMA);1.112 +1.113 + if( result != 0 ) {1.114 + fprintf( stderr, "PVR DMA failed (timeout)\n" );1.115 + asic_dump(stderr);1.116 + fprintf( stderr, "Dest: %08X Count: %08X Ctl: %08X\n", long_read(PVR_DMA_DEST),1.117 + long_read(PVR_DMA_COUNT), long_read(PVR_DMA_CTL) );1.118 + dmac_dump_channel(stderr, 2);1.119 + long_write( PVR_DMA_CTL, 0 );1.120 + }1.121 +1.122 + CHECK_IEQUALS( 0, long_read(PVR_DMA_CTL) );1.123 + CHECK_IEQUALS( ((uint32_t)buf)+len, long_read(DMA_SAR(2)) );1.124 + CHECK_IEQUALS( 0, long_read(DMA_TCR(2)) );1.125 + CHECK_IEQUALS( 0x12C3, long_read(DMA_CHCR(2)) );1.126 + CHECK_IEQUALS( target, long_read(PVR_DMA_DEST) );1.127 + CHECK_IEQUALS( 0, long_read(PVR_DMA_COUNT) );1.128 + CHECK_IEQUALS( 0, long_read(PVR_DMA_REGION) );1.129 +1.130 + return result;1.131 +}
.